4 ポイント 投稿者 GN⁺ 2024-12-09 | 1件のコメント | WhatsAppで共有
  • このWikiは単に長いスクリプトではなく、手書きで、データ構造とアルゴリズムまで活用する「実質的な」Shellプログラムを集めた一覧
  • 基準はおおむね5K行以上で、自動生成スクリプトや反復的なcompletionスクリプトは主要事例から除外される
  • 代表例は ble.sh 87K行、kalua 約56K SLoC/行、Relax-and-Recover 35K行、nb 26K行、winetricks 22K行のように、一般的なShellスクリプトのイメージを大きく超える
  • 一覧には、対話型ラインエディタ、OpenWRTアドオン、Bashデバッガ、TLSテストツール、Kubernetes実装、バックアップ・復旧ツール、証明書発行ツール、リソースモニターなど、実用ツールが幅広く含まれる
  • OSH “Wild”テストは100万行以上のShellをパースするが、その大半は小さなプログラムや反復的なディストリビューション用パッケージ定義であり、大型Shellプログラムとは区別される

何を「大きなShellプログラム」と見るか

  • ここでいう「biggest」は単なる生の行数よりも、「substantial」、つまり実質的な規模と複雑さを意味する
  • 対象は基本的に手書きのShellスクリプト
    • autoconfが生成した大きなスクリプトは例外扱い
    • 70K行のcoreutilsスクリプトのような自動生成物は、実質的な意味での大型Shellプログラムとは見なさない
  • データ構造とアルゴリズムを使うShellプログラムを特に重視する
    • bash-completionは精巧だが、Unixマシン上の各コマンドごとに比較的単純な関数を置く反復的な構造なので、反例に近い
  • おおよその基準線は5K行超
    • 反復的でない最大級のShellプログラムは、概して10K+行の範囲にある
    • 100K行を超えるプログラムは確認できていない

最大級のShellプログラム事例

  • akinomyoga/ble.sh: 合計87K行、コメント除外で63K LoC
    • 純粋なbashで書かれた、fishのような対話型ラインエディタ
    • メインファイル out/ble.sh は39K行、コメント除外で29K LoCで、モジュールファイルまで合わせると合計80K+行
    • 日本語コメントが多い
    • bind -xで端末のraw bytesを読み、複数の明示的な状態機械で直接デコードし、drawing bufferを維持・更新する
    • timingと「fibers」も含む
    • Shell parserに関する詳細はissue 663のコメントにあり、Shellでデータ構造を最も精巧に使った事例の一つと評価されている
    • OSHで実行しようとする試みがあり、大部分はパースされる
    • 最初のコミットは2015年で8K行 / 6K LoC、実際の開発は2013年に始まった
  • kalua: OpenWRTアドオンで、約56K SLoC/行のPOSIX shellで書かれている
  • Relax-and-Recover: 35K行、24K LoCのバックアップ・復旧ツール
    • 最初のgitコミットは2009年3月で、当時は4K行 / 3K LoCだった
  • xwmx/nb: nb自体が26K行、22K LoCのbashで書かれている
    • batsテストをbashとして数えると、追加で91K行、61K LoCがある
    • 最初のコミットは2014年で、活発なコミット履歴は2016年初めから始まる
  • vegardit/bash-funk: 合計27K行、24K LoCのBashライブラリ
    • 最初のコミットは2017年5月で、当時は10K行 / 8K LoCだった
  • winetricks: 22K行のShellスクリプトで、Wine上にさまざまなWindowsプログラムをインストールする
  • drwetter/testssl.sh: 単一ファイルに21K行のbashが入っている
    • 手書きと見られる
    • 2006年にいくつかの openssl コマンドから始まった
    • パース中にissue #606に引っかかる
  • rkhunter: 2003年から2018年まで書かれた21K行のBourne shellプログラム
  • Simplenetes: 「Kubernetes in 17K lines of Shell」として紹介されている
    • 驚くべき事例として示されているが、休眠状態に見える
    • 関連するHacker News Threadがリンクされている
  • inxi 2.3.56: obsoleteと表示された16K行のbashプログラム
    • 2008年に infobash からforkされた
    • 当時 infobash は889行で、infobash は2005年に始まった
    • v2.9から inxi はPerl実装に置き換えられた
  • bashdb: Bashデバッガで、約14K行のbashで書かれている
  • romkatv/powerlevel10k: internal/ ディレクトリに12K行のzshスクリプトがある
    • さらにconfigとhelper scriptが8K行ある
    • 最初のコミットは2014年
  • dylanaraps/neofetch: Bash 3.2で書かれた10K行のプログラムで、システム情報を表示する
    • 画像に関する興味深い機能も実行できる
    • 最初のコミットは2015年
  • distrobox: 7K行以上のbashスクリプトで、端末内で任意のLinuxディストリビューションを使えるようにする
  • acme.sh: 8K行のShellスクリプトで、証明書を発行・更新する

規模は小さくても目を引く実装

  • bashforth: 約3,800行で非常に大きいわけではないが、実際のプログラミング言語を実装している
    • 空白とコメントが多い
  • yoda: bashforthの半分ほどのサイズだが、インタプリタとコンパイラ全体を実装している
    • 同じ作者による20年若い実装で、より多くの機能を備える
    • “What learned you have, unlearn you must!”というコメントが付いている

その他の主要なShellプログラム

  • abcde / A Better CD Encoder: CD rippingに使われ、約5.5K LoC
  • thc-segfault: 3.3K LoCで、大部分をBashで作ったpubnixサーバー
  • ffmpeg/configure: FFmpegの手書きconfigureスクリプトで、8.4K LoC
  • ffhevc: FFmpegとlibx265でHEVC動画をエンコードする完全手書きのBash wrapperで、4K LoC
  • ffx264: FFmpegとlibx264でH.264/AVC動画をエンコードする完全手書きのBash wrapperで、3.9K LoC
  • h264enc: MEncoderでH.264/AVC動画をエンコードする完全手書きのBash wrapperで、9.2K LoC
  • bashtop: 5.3K LoCのリソースモニター
  • halcyon: Haskellアプリのインストールシステムで、6.6K LoC
    • bash semanticsとエラーチェックに注意を払った手書きコードで、関数型プログラミングから着想を得た独特のスタイル
  • wordshell: 約7K行のコードで、コマンドラインから複数のWordPressサイトを管理する
  • BaCon: 約10K行で、BASICで書かれたプログラムをCに変換する
    • BASIC実装とShellスクリプト実装の2種類がある
  • FireHOL: メインスクリプトが9K行、FireQOSツールが追加で3K行
    • 人間が読みやすい設定からsecureでstatefulなfirewallを作る言語であり実行プログラム
  • gxadmin: 11K LoCで、科学ワークフローエンジンGalaxy管理のためのtemplated SQL queryとデータ処理ユーティリティ集
  • mulle-bashfunctions: 約6K行のbash/zsh用関数ライブラリ
    • mulle-sdeで使われており、mulle-sdeはさらに別の100K行のShellスクリプト
  • x11docker: 11.6K行で、dockerまたはpodmanコンテナ内でGUIアプリケーションを実行する

Shell風言語とDSL

  • modernish: Shellで書かれたportable shell dialect
  • bats: テストを書くためのDSLで、bashコードを生成する
  • bashible: bashで書かれたAnsible風DSL
    • 関連するcommentsがリンクされている
  • clash: すべての現代的なPOSIX shellと互換性のあるオブジェクト指向フレームワーク
  • bash Infinity: bash用の標準ライブラリとboilerplateフレームワーク

より小さなプログラムと関連エコシステム

  • Alpine、Aboriginal、Debianスクリプトは別のblog postにリンクされている
  • completionスクリプトは大きいが、しばしば反復的
    • _git Zsh completionは8.3K行のコード
    • git-completion.bash とDocker completionも例に挙げられている
  • dyne/Tomb: 約3,500行のzshスクリプト
  • Basalt: 純粋なBashで書かれたfull-featured package manager
    • 数千行規模だが、15個以上のアプリとライブラリを含むrich ecosystemがある
    • bash-core: trapshopt builtinを拡張し、stacktraceと必須の利便機能を追加するライブラリ
    • bash-object: 純粋なBashで任意のネストしたデータ構造を構成するライブラリで、テストがほぼ200個ある
    • bash-json: 純粋なBashでJSONをパースして出力するライブラリ
  • tablespoon/fun/cli-clock: bashで書かれた複数行文字時計
  • json.bash / jb: JSONを作るコマンドラインツール兼bashライブラリ
    • 1,700行で、テストが約3,000行ある

OSHテストとShell使用上の注意点

  • OSH "Wild" Testsは100万行以上のShellをパースする
    • 大半は小さなプログラムと、Alpine PKGBUILD、Gentoo ebuild のような反復的なディストリビューション用パッケージ定義
  • Shell Programs That Run Under OSHは、OSHで実行されるShellプログラム一覧にリンクされている
  • shell script are dangerousは、Shellはシステム内部を対話型コンソールまたは非対話型で扱うプログラムであり、機能が多く、非常に危険で、アプリケーション制作向けに作られたものではないと警告している

1件のコメント

 
GN⁺ 2024-12-09
Hacker News のコメント
  • 約25年前に Sony で働いていたとき、非常に遅く、頻繁に落ちる注文管理システムを修正するプロジェクトを担当した。
    掘り下げてみると、OMS は AIX サーバー上で動く巨大なシェルスクリプト群で、10年以上進化した末に放置された状態だった。コードは5万行を超え、注文・決済・その他の情報は FTP でサーバー間を移動したあと、複雑な sed/awk でパースしており、在庫もテキストファイルで追跡しつつ FTP で移動していた。
    当時は、この混沌を移行するには Perl が最も実用的に見えたので、いちばん単純な部分から小さな Perl モジュールに置き換え、より大きな Perl アプリケーションの中で段階的にリファクタリングした。3か月で全体を約5千行の Perlまで削減でき、元のシステムの障害はほぼ消えたまま、10〜100倍高速になった。ひどい代物だったが、今までやった仕事の中でも最も満足度の高いものの一つだった。
    • たった3か月とは、毎日800行ずつ削除した計算になる。
      元のコードを全部読んで深く理解したうえで挙動を正確に合わせたのか、それとも大きな塊は捨てて「こう動くべきだ」と思う形で書き直したのか気になる。すばやく置き換えられる定型処理が多かったのかも気になる。
    • そういうシェルスクリプトの怪物を和らげるには、今でも Perl が最も実用的だ。Tcl も良い選択肢だ。
  • 昔書いたものをもう一度掘り返してみる必要がありそう。
    最初に書いた本当に大きなスクリプトは、Enrust CA とディレクトリ向けの約7千行のインストーラで、当時のほぼすべての Unix で動かなければならなかった。最初からそうだったわけではないが、顧客の要求に応じて大きくなっていった。
    インストール自体はそれほど複雑ではなかったが、アップグレードは少し複雑で、当時は Unix ごとにあらゆるユーティリティが少しずつ違っていた。スクリプトのかなりの部分は、そうした違いを検出して管理するコードで、エラー検出・復旧・ロールバック、ごく原始的なパッケージと依存関係の管理も含まれていた。
    DEC の Unix、Ultrix ではないほうが最も難解だった。すべてのコマンドラインユーティリティが出力を端末の列幅で切り詰めることに気づくまで数日かかり、30年たった今でもそれを覚えている。
    HP-UX はリリースごとに破壊的変更があり、記憶が正しければ 6.5 から 11 までサポートした。Ultrix、Novell 系、NeXT、Sequent はほとんど覚えていない。AIX は変だったことは覚えているが、理由は忘れた。Sun の3つか4つの OS にも違いはあったが、マニュアルは素晴らしく、最高だった。
    • その列幅で切り詰められる出力は本当に奇妙に聞こえる。端末に横スクロールのような機能がなかったのか、気になる。
    • DEC の Unix というと、OSF/1、Digital Unix、Tru64 Unix のどれを指しているのか気になる。
    • 自分も数千行までは行ったが、だいたい2千行くらいだった。それでもサポート対象が最新の Red Hat と Ubuntu だけで済んだのは幸いだった。
    • 昨年のあるプロジェクトで、メインバイナリと補助ライブラリに wc をかけてみたら、これまでで6,224行だった。
      入力プロトコルアダプタ、1つ以上のフィルタ、出力プロトコルアダプタからなるコンテナ群で、線形保証パイプラインを管理するスクリプトだった。コンテナやプロトコルの専門家でなくても、ファイルがパイプラインを通る際にどうフィルタリング・変換されてほしいかを知っている人が使えるようにするのが目標だった。
      最上位バイナリは git [ git options ] < git action> [action options]systemctl のようにサブ機能を持つ構造になっている。新しいサブコマンドを追加するサブコマンドもあり、必要なライブラリを作成し、テンプレートから関数定義をあらかじめ埋める。テンプレートには短い/長い使い方関数があり、cbap -hcbap pipeline -h が有用な案内を出す。
      ベースイメージ、コンポーネント、パイプラインを操作するサブコマンドがある。コードのかなりの部分は、コンポーネントとパイプライン定義が正しく書かれているかを確認するテスト用だ。パイプラインはほぼ TOML に近い形式なので、TOML のパース、セクションを配列に変換するコードがあり、コンポーネントは単純な key=value ファイルなので、左辺・右辺の抽出とスキーマ検証コードがある。
      パイプラインコンポーネントは属性を共有できるため、varetc ファイルから共通属性を探し、コンポーネント属性を指定するコードもある。セキュリティ要件に合わせたユーザー・グループ・ディレクトリ・FIFO 操作関数も多い。パイプラインを設定すると、ユーザー、グループ、SELinux タイプ、MCS カテゴリを作成・適用したうえで、コンポーネントを起動するサービスファイルにマッピングするので、systemd 操作も多い。
      最大の呼び出し群は、おそらくコンポーネント属性、実際にはコンテナ属性を取得・設定する関数群だ。各属性ごとに取得関数、検証関数、パイプライン内インライン版を用意し、データ駆動のコンテナ定義をできるだけ柔軟にした。
      ファイル、環境変数、コマンドラインから変数を設定するために Bash の参照を多用するコードもあり、高速なテストが可能だ。ユーザーレベルも、コード自体を扱う保守担当者、コンポーネント定義を開発する開発者、コンポーネントでパイプラインを作るインテグレータ、パイプラインをインストールする運用者まで4段階をサポートし、各レベルのユーザーへ配布するために自分自身をコピー・パッケージ化できる。
      対象システムはどんな Linux でもあり得るため、makeself でパッケージ化して展開する。たとえばインテグレータがパイプライン定義を作ると makeself ファイルが生成され、対象システムで実行すると、すべてのユーザー・グループ・ディレクトリ・FIFO、つまりコンポーネント間 IPC を作成し、DAC/MAC を適用し、systemd ファイルを作成し、各ユーザーにイメージをコピーしたうえでパイプラインを実行する。削除オプションでこれらすべてを元に戻すこともできる。
      seccomp も一部入っているが、許可リストとブロックリストのバランスを見つける必要があるため、しばらく止まっている。ShellCheck は本当に徹底的に使っている。
  • 自分のスクリプト言語 Lil のインタプリタを、移植性を最大化するために Bash で書こうかと考えたことがあるが、浮動小数点演算が極度に苦痛になるだろうとすぐに悟った。
    すべての環境に bc/dc があるとは期待できないし、手元の一部のマシンは Bash のバージョンが古く、連想配列のサポートも非常に限られていた。妥協案として AWK をターゲットにしたが、AWK は大半のシェルよりずっと快適な汎用言語で、POSIX 環境ならどこにでもある: https://beyondloom.com/blog/lila.html
    • 自分も言語をシェル対象にしていて、bc/dc をすべての環境で期待できないことを身をもって知った

WSL2 の Ubuntu インストールに bc/dc が入っていなかった気がして、かなり驚いた。浮動小数点計算には AWK を使っているが、単に外部プロセスとして呼び出す形になっている

  • キャリアの中で何度も大きな Perl プログラムを書き、保守してきた立場から言うと、人々がこうするのには理由がある
    Java や Python のような言語は、インターフェースと型が定義されていて、OS との相互作用がほとんどない場合にはよく合う。JSON/XML/YAML を使ったり、データベースや他のプログラムと HTTP(S) で通信したりするなら、こうした言語が輝く理想的な状況になる
    しかし大量のテキストと OS との相互作用を扱うとなると、Java と Python は大きな苦痛になる。逆に Shell/Perl は、こうした作業ではずっと楽だと感じる
    ほぼすべての自動化作業、混沌として標準化されていないインターフェース、テキスト/ログファイル、構造化されていない、あるいは十分に構造化されていないデータ形式がこれに当たる。ここに Perl の後方互換性、広いインストールベース、性能まで加えると、こうした作業には Perl 以外の選択肢は事実上ない
    最近の大企業が、ささいに自動化できる仕事のために何千人も雇うような手作業労働を多く抱えている大きな理由の一つは、Perl の利用が減ったからだと以前から見てきた。Python や Java で大きな自動化作業をやろうとしても、書き、保守しなければならないコードの冗長さと全体規模にうんざりして、すぐ諦めてしまう

    • 「Perl が消えたからだ」という点には強く同意しない。複雑性が上がり、スクリプトをつなぎ合わせていた Perl 担当者の仕事が専業になり、Perl だけでも限界があった、ということに近いと思う
      そのため今ではおそらく、高価な正社員が追加で必要な状態になっている。エンドユーザーが Windows なら、すでにデスクトップに Perl に似た選択肢がある。PowerShell であり、Perl と似た役割を果たす
    • 大きな自動化作業をネイティブコードで行った。こういう場合は効率が重要だからだ
      Bash+grep は、テキストの1行ごとに新しいプロセスを実行する方向に流れやすい。効率的にやるには作業を最小化する必要があり、そのためにはバッチ処理と重複排除が必要になる。これは重複排除の文脈を追跡しながら、状態を持つ形でデータを扱わなければならないという意味で、ちゃんとしたプログラミング言語のほうが簡単だ
      Bash+grep はステートレスなテキスト処理に向いているため、作業の重複が大きくなりやすい。作業を減らすもう一つの方法は正確なフィルタリングだが、これはちゃんとした言語で命令型にきれいに表現するほうが簡単だ。grep と正規表現は、こうした用途にはまったく合わない
      行単位の形式を使うと、git は何でも受け入れようとしてエスケープを付けるが、サポートは一貫しておらず、-z オプションで NUL 終端文字列形式を要求して無効化できる。Bash がこれを扱う方法はなさそうで、十分に低レベルな言語なら自然に扱える。また、テキストの1行ごとに新しいプロセスを起動しなくてよい、漸進的なストリーミングも可能だ
      おまけに、途中に HTTP があろうと別のものがあろうと、すべての作業に単一のコードベースを使える
    • 同意する。自分が一番好きな言語は Python だが、特定の低レベル OS 作業では面倒だったり非効率だったりすることがある。そこで https://www.oilshell.org と、リンクされている Wiki ページを作った
      文脈のためのリンクがいくつかある。「Perl を再発明しているのか?」: https://www.oilshell.org/blog/2021/01/why-a-new-shell.html#a...
      「Unix シェルは Perl 6/Raku のようなビッグバンではなく、互換性のあるアップグレードオプションを持つ Perl 5 のように進化すべきだ」: https://www.oilshell.org/blog/2020/07/blog-roadmap.html#the-...
      YSH ツアー: https://www.oilshell.org/release/latest/doc/ysh-tour.html
    • Perl が多くの Linux と BSD システムに標準でインストールされていることに気づいてから、Perl 5 を真剣に学んでみようかと考えている。OpenBSD にも Perl が入った状態で提供されていると理解している
      インターネットから何かをインストールできない、あるいはそもそもインターネットに到達できない環境で働くまでは、これが大きな利点には見えないかもしれない
  • 大きなプログラムを Bash スクリプトで書くときの核心的な問題は、シェルスクリプト言語がそもそも複雑性のために設計されていないことにある
    小さなコマンドを調整し、既存のツールを素早く探索的につなぎ合わせるのには優れているが、Bash が数百行を超え始めると、長期保守と拡張性を厄介にする限界が次々に現れる
    まず可読性が問題だ。Bash の構文は大きくなるほど本当に難解になりうる。変数スコープの規則は微妙で、エラー処理は原始的であり、文字列処理はすぐに汚くなる。結局、保守担当者は何が起きているのか解読するのに時間を浪費し、自信を持って変更することも難しくなる
    次は堅牢なツール不足だ。より成熟した言語には静的解析ツール、リンター、デバッガがあり、よくあるミスを早い段階で捕まえてくれる。Bash ではこうしたものが存在しないか、非常に限られている。こうした安全装置がなければ、大きな Bash プログラムは静かなエラー、リグレッション、微妙なバグにより弱くなる
    テストも問題だ。Bash スクリプトをテストすることはできるが、通常その過程はより面倒で、複雑なロジックやデータ構造があるとさらに厄介になる。ファイル名の空白や予期しない環境条件のような境界ケースに対処していると、検証するのが苦痛な防御的コードが大量に生まれる
    最後に、エコシステム自体が大規模な Bash 開発のために作られていない。モジュール化、パッケージ管理、標準化された依存関係の処理、Python や Go が提供する現代的な開発パターンを失う。時間が経つと、こうした欠落が積み重なって速度を落とす
    一回限りの作業や単純な自動化に Bash を使うのは構わない。それが Bash の得意なことだ。しかし何か大きなものを作るつもりなら、通常は複雑なアプリケーションを作り、保守するよう設計された言語を使うほうがよく、初期の学習曲線や設定が少し高くても長期的には時間を節約できる

  • ShellCheck をリンターとして使えば、ありがちな落とし穴をかなり見つけられる。Bash/シェルには本当に多くの落とし穴や予想外の挙動があり、熟練した Bash 作者でも引っかかることがある
    ただし Bash/シェルは、言語の階層の中で独特な位置を占めている。ほぼどこにでもあり、30年後も残っている可能性が高い。ほぼどこでも実行でき、30年後にも動くプログラムが欲しいなら、シェル/Bash は良い選択肢になる

    • いまの職場でまさにこれを経験している。数千行の Bash を掘り返しているところ
      ずっと昔に書かれたスクリプトでもないのに、なぜ Bash を選んだのかわからない。スクリプトは動くが、コードを変な目で見ただけで何かが壊れそうな感じがする
    • Bash/ksh にはデバッグ・トレース用の引数として -x がある
  • 以前、定期的に使っていた最大の手書きシェルプログラムは、おそらく abcde (A Better CD Encoder) で、約5,500行規模だった
    https://abcde.einval.com
    https://git.einval.com/cgi-bin/gitweb.cgi?p=abcde.git;a=blob...

    • よく知っているとは言いにくいが、以前 What.CD で推奨されていたツールの一つだった。Max も一緒に推奨されていたと友人たちから聞いた: https://github.com/sbooth/Max
    • 使ったことがあるが、本当によく動き、使うのもかなり簡単だった。全体が巨大なシェルスクリプトだとはまったく知らなかった
  • こうしたプログラムの多くは本当に宝石のような存在だ。たとえば rkhunter スクリプトはコードも悪くなく、改善の余地もあり、情報の宝庫でもある
    こうしたスクリプトのコードサイズの多くは、複数のプラットフォームで必要なユーティリティが存在すること、そしてさまざまなコマンドラインオプションで期待どおりに動作することを保証するために使われている。これこそが本格的なシェルスクリプト作者にとって最も苦痛な点で、シグナルやサブプロセスよりもさらに大変だ
    rkhunter が「ちゃんとした」プログラミング言語で書かれていたら、こうした情報はもっと見通しが悪くなっていたと思う。データ構造内のレコードに押し込まれて参照されたり、ネストしたデータ構造の上で複数の関数、あるいはもっと悪ければメソッドとクラスの組み合わせによって動作していたかもしれない。ログも JSON に分割され、データベースに圧縮されて、別のメソッドからアクセスしなければならなかったかもしれない
    シェルスクリプトにはそうした複雑な道具立てがないため、かえって何が起きているのかをそのまま露出する傾向がある。そのため rkhunter は、さまざまなエクスプロイトやルートキットに関する良いドキュメントの役割も果たしており、ファイルからファイルへ、構造から構造へ、データベースからデータベースへと掘り進む必要が少ない

  • FreeBSD Update クライアントは約3,600行の sh コードである
    ここで言及されている他のプログラムに比べれば大きくはないが、「OS 全体をアップデートするツール」という機能量はかなり重いものだと思う。アップデートをビルドするコードは複数のファイルに分かれているので、合わせればもっと多いはずだ

  • 「たった」7.1千行だが、私が好きなのは Let’s Encrypt で証明書を発行・更新するために使われる acme.sh スクリプトだ
    https://github.com/acmesh-official/acme.sh/blob/master/acme....

  • ときには、利用できると保証できるものがシェルだけで、移植性がどうしても必要な状況もある
    しかし一般的には、巨大なシェルアプリケーションがあるなら、人生の選択を考え直すべきかもしれない

    • 問題は「どのシェルか」だ。Bash は普遍的とは程遠い
      そのうえ通常、シェルだけでできることは多くなく、findgrepsedcatheadtailcut のようなコマンドが必要になる。これらのコマンドにもそれぞれ 移植性の問題 がある
      BusyBox を対象にするのが最善かもしれないが、一般的な Linux システムを外れた瞬間、移植可能な Bourne シェルスクリプトを書くことは難しく、ほとんど不可能になる
    • こういう話はかなり頻繁に聞くが、シェルはあるのに C コンパイラ がない、あるいはシェル経由で C コンパイラをインストールできないケースが実際にどれほどあるのか、純粋に気になる
      C コンパイラさえあれば、シェルから抜け出して C プログラムを書き、それをシェルスクリプトで組み合わせることもできるし、Lua のようなより良いスクリプト言語をインストールすることもできる。現時点で必ずシェルだけを使わなければならないケースは、かなりニッチに感じる