走り書き
2024/12/27 RHEL9のbashを使う機会があったけど、得た結果はbashでシェルスクリプトは効率良く学べない。
仕方がないので他のシェルスクリプトと言い別けるために1行目に#!/usr/bin/bashなどと書かれたシェルスクリプトをbashスクリプトと書くことにする。
やだこれ、パイプラインや別プロセス使うとものすごく遅い・・・
書いたソースコードを切ったり貼ったりしてみるとどうも別プロセスを作るコマンドがあったりすると劇的に遅くなる傾向がある。
while read args
do
〜if文などの列〜
done < <(zcat -d /path/to/packet_cap.file | strings | awk ... )
最後のargs=$(echo ${args} | cut -b 1-2)を抜いて実行した瞬間、実行時間で180秒が10秒に変わったのは目を点にした。
bashスクリプトはもはやシェルスクリプトとは別の言語、別の処理系といったほうが良いと思われるぐらい早くなった。
移植性が〜やLinuxではbashが標準だから〜じゃなくて、これはbashそのものがシェルスクリプトを学ぶ心を折る作りになってる。そりゃあpythonやawk学んだほうが他に使える気がするように見えるわけだ。
こりゃあbashスクリプトでシェルスクリプト学ぶとパイプラインや別プロセス生成が遅いと勘違いしますわな。
sedコマンドを卒業して高速化ではなく、bashを卒業したほうが良いレベルだと思います。
そもそもパイプラインはファイルI/Oや省メモリ化のためのストリーミング処理で、$( ... )などのサブシェル他プロセス生成は極めて短期間で終わるインスタント物が中心。
これが必要ない単体のアプリケーションの場合ならともかく、細かくプロセスが立ち上がるようなシステムではbashだけに処理系を依存するか、bashを使わない方が良いんじゃないか説まで作れそうである・・・(*1)
もし本気でUNIXコマンドを学習してシェルスクリプトで活かしたいのであれば、ほとんどのLinuxディストリビューションに入っているであろうbusyboxの組み込みシェルを使ったほうがおそらく圧倒的に良いです。
配列や文字列処理などの高機能な機能を使いたければsedやawkやperl、pythonに手を出せば良いんです。
まあ、evalが使えれば連想配列ぐらいは出来なくはないが・・・(*2)
シェルスクリプトはあくまでもバッチ処理のほうが向いているのだから。
おそらくbashそのものの問題だと思うので、そこからforkが必要な外部コマンドを書くと効率が悪いとか、そういう話が生まれたのだと思います。(*3)
納品を待つ相手がいる以上、仕方がないので最小限度のパイプラインとawk、bashの内部処理で書きましたとさ。
*1: 試したことはないけど、find /delete/hugefile/and/manyfile/path | xargs -I% -P32 rm -Rfvみたいなコマンドがあったとき、ものすごく遅いことにならないか? シェルスクリプトを書き始めのころにこういう経験をすると近寄りがたくなるかも・・・
*2: 実際に使うことはないだろうと思うが、str="Oops"; eval $(echo "array_${str}")=${str}; echo ${array_Oops}。配列の宣言も必要ない。
*3: どこかでforkにかかるコストが高いみたいな話を見たが、それが出来ないとしたらプロセスの大量生成に時間がかかる作りになるはずなので、多数のファイルI/Oで高負荷がかかったタイミングで応答が突然ストールしたりしないか?という不安もある。
*4: ビジネス向けのアプリ内のシェルはさておき、生まれ育った故郷をけなされるのは誰だってムッと来るもので、Linuxじゃないからと言う理由で対応終了となってしまう別のUNIXライクなシステムにもたまには目を向けてみてくださいという話。
FreeBSD リリース関係のメモ
- FreeBSD 14.2-RELEASE Announcement
- 2024/12/03 JSTにリリースアナウンスあり。
-
- FreeBSD 14.1-RELEASE Announcement
- 2024/06/03 JSTにリリースアナウンスあり。
-
- FreeBSD 13.4-RELEASE Announcement
- 2024/09/17 JSTにリリースアナウンスあり。
-
- FreeBSD Security Advisories
- セキュリティアドバイザリ。
-
- FreeBSD Errata Notices
- 注意情報。
-