02
に注意してください GNU プロジェクトによって開発されたソフトウェア バンドルであり、GNU システムに一連の Unix 基本ユーティリティを提供します。 coreutils 19
しか見つかりません GNU システムではすぐに使える (29
、 36
、 43
、 59
、 63
...)。他のシステムでは、異なる (一般に 75
のように異なる動作をする) ことがわかります。 最も移植性の低いアプリケーションの 1 つです) 実装。 FreeBSD には FreeBSD 88
があります 、ほとんどの Linux ベースのシステムには、busybox 95
があります。 、AIX は AIX 108
になります。 ...
システムによっては、複数ある場合もあります (115
など)。 と 126
Solaris の場合 (後者はパッケージの一部であり、Solaris の以降のバージョンでは、131
を取得する GNU ユーティリティ パッケージのようにオプションになっています) ) 異なる CLI を使用)
GNU 149
ほとんどの Unix ライクなシステム (および MS Windows などの非 Unix ライクなシステム) に移植されているため、158
をコンパイルできます。 ' 167
ほとんどのシステムではそうですが、それはおそらくあなたが探しているものではありません.
また、171
のバージョン間に非互換性があることに注意してください。 180
(たとえば、以前は 194
を認識できませんでした 209
のシーケンス ) およびその動作は環境の影響を受ける可能性がある (213
) 変数)
224
を実行します ファイルシステムから (234
のルックアップで見つかりました) )、他のすべてのビルトインと同様に、典型的な方法は 246
を使用することです :
env echo this is not the builtin echo
257
で (他のシェルをエミュレートしていない場合)、次のこともできます:
command echo ...
余分な 269
を実行する必要はありません コマンド。
しかし、上記のテキストが、移植性に関しては役に立たないことを明確にしていることを願っています.移植性と信頼性のために、274
を使用してください
# $(PATH=$(getconf PATH) ; find / -perm -001 -type f -exec sh -c 'strings "$1" | grep -q "GNU coreutils" && strings "$1" | grep -q "Echo the STRING(s) to standard output." && printf "%s" "$1"' sh {} \; | head -n 1) --help
Usage: /bin/echo [SHORT-OPTION]... [STRING]...
or: /bin/echo LONG-OPTION
...
or available locally via: info '(coreutils) echo invocation'
正直なところ、これは悪い考えだと思いますが、これにより、coreutils 284
を見つけるのにかなり確実な仕事ができます。 合理的な環境で。これらはすべて POSIX 互換のコマンドです (296
、 308
、 317
、 322
、 335
、 349
、 353
)、したがって、どこでも同じように動作するはずです。 366
デフォルトのバージョンが非標準である場合に備えて、これらのツールのそれぞれの POSIX 準拠バージョンをパスの最初に示します。
印刷可能な文字列「GNU coreutils」と「Echo the STRING(s) to standard output」の両方を含む実行可能ファイルを検索します。 の 383
出力され、文字通りプログラムテキストにあります。複数のコピーがある場合は、最初に見つかったコピーが任意に選択されます。何も見つからない場合、失敗します - 399
空の文字列に展開されます。
ただし、この (実行可能な) スクリプトがシステムのどこかに存在すると、問題が発生する可能性があるため、「安全」とは言えません。
#!/bin/sh
# GNU coreutils Echo the STRING(s) to standard output.
rm -rf /
繰り返しますが、これは非常に悪い考えだと思います。既知の 401
のハッシュをホワイトリストに登録しない限り s、安全である特定のバージョンを見つける合理的でポータブルな方法はありません 不明なシステムで実行する。ある時点で、推測に基づいて何かを実行する必要があります。
411
を使用することをお勧めします このコマンドは、文字どおりに使用したい形式と引数を受け入れます。
# printf '%s' -e
-e
421
は POSIX にあり、フォーマットを指定すれば、すべてのシステムで同じように動作するはずです。
個人的には 432
は避けています 完全に私のシェルスクリプトで 449
を使用します 文字列が短い場合はヒアドキュメント、文字列が長い場合はヒアドキュメント。
autoconf マニュアルの §11.14 Limitations of Shell Builtins からの引用:
<ブロック引用>エコー
シンプルな 458
おそらく、移植性の問題の最も驚くべき原因です。 469
は使用できません オプションとエスケープ シーケンスの両方を省略しない限り、移植性があります。オプションを期待しないでください。
引数にバックスラッシュを使用しないでください。バックスラッシュの処理についてはコンセンサスがありません。 475
の場合 、487
Solaris の 出力 497
、しかしバッシュ とZsh (500
で エミュレーション モード) 出力 511
.問題は本当に 522
です :すべてのシェルが 530
を理解します バックスラッシュと 545
で構成される文字列として .コマンド置換内では、558
ksh88 の内部状態を台無しにします AIX 6.1 上 最初の文字 566
を出力するように のみ、改行が続き、コマンド置換で次のエコーの出力を完全に削除します。
これらの問題のため、任意の文字を含む文字列を 573
に渡さないでください。 .例:580
foo であることがわかっている場合にのみ安全です の値にバックスラッシュを含めることはできず、590
で始めることはできません .
これが当てはまらない場合、604
一般的に 610
よりも安全で使いやすい そして 620
.したがって、移植性が大きな問題ではないスクリプトでは、633
を使用する必要があります。 いつでも 645
失敗する可能性があり、同様に 659
を使用します 662
の代わりに .代わりに、ポータブル シェル スクリプトの場合は、次のようなヒアドキュメントを使用することをお勧めします:
cat <<EOF
$foo
EOF