GNU/Linux >> Linux の 問題 >  >> Linux

echo バイナリを呼び出す最も安全で移植性の高い方法は何ですか?

02 に注意してください GNU プロジェクトによって開発されたソフトウェア バンドルであり、GNU システムに一連の Unix 基本ユーティリティを提供します。 coreutils 19 しか見つかりません GNU システムではすぐに使える (2936435963 ...)。他のシステムでは、異なる (一般に 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 互換のコマンドです (296308317322335349353 )、したがって、どこでも同じように動作するはずです。 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

Linux
  1. Linuxの歴史の中で最も重要な瞬間は何でしたか?

  2. ルート権限を取得する最も安全な方法はどれですか:Sudo、Su、またはログイン?

  3. ターミナルエミュレータを起動する最もポータブルな方法は?

  1. クラウドバックアップとローカルバックアップ:データを保存する最も安全な方法

  2. *nixでディレクトリを空にする最も安全な方法は何ですか?

  3. inotify を使用する適切な方法は何ですか?

  1. sedにタブを挿入する正しい方法は何ですか?

  2. Linuxにjdkをインストールする正しい方法は何ですか

  3. Linuxを分割する最も安全な方法は?