web-dev-qa-db-ja.com

コマンド置換:バッククォートまたはドル記号/カッコ付き?

Bashでコマンド置換を行うための好ましい方法は何ですか?

私はいつもこのようにしました:

echo "Hello, `whoami`."

しかし最近、私はそれが次のように書かれているのをよく見ました。

echo "Hello, $(whoami)."

推奨される構文は何ですか?その理由は何ですか?それとも、ほとんど交換可能ですか?

私のテキストエディターはそれが何であるかを知っているようで、構文の強調表示を適切に行うため、私は最初の方を好む傾向があります。

私は here と読みますが、エスケープされた文字はそれぞれの場合に少し異なる動作をしますが、どの動作が望ましいか、または状況に応じてどうなるかはわかりません。

副次的な質問:bothフォームを1つのスクリプトで使用するのは悪い習慣ですか(たとえば、コマンド置換をネストする場合)?

154
Dagg Nabbit

ここにはいくつかの質問/問題がありますので、ポスターのテキストの各セクションを繰り返し、ブロック引用し、その後に回答を続けます。

推奨される構文は何ですか?その理由は何ですか?それとも、ほとんど交換可能ですか?

`some_command`フォームよりも$(some_command)フォームの方が好ましいと思います。 2つ目の形式は、バッククォートのペア(「 `」文字、バックティックおよびGraveアクセントとも呼ばれます)を使用して、それを行う歴史的な方法です。ドル記号と括弧を使用する最初の形式は、新しいPOSIX形式です。つまり、おそらくより標準的な方法です。順番に、私はそれが異なるシェルと異なる* nix実装で正しく動作する可能性が高いことを意味すると思います。

最初の(POSIX)形式を好むもう1つの理由は、特にコマンド置換がネストされている場合、読みやすいことです。さらに、バックティックフォームでは、ネストされた(内部)コマンド置換でバックティック文字をバックスラッシュでエスケープする必要があります。

POSIXフォームを使用すると、その必要はありません。

互換性があるかどうかについては、エスケープ文字について述べた例外を除き、一般的には互換性があると思います。ただし、すべての最新のシェルとすべての最新の* nixが両方の形式をサポートしているかどうかはわかりません。特に古いシェル/古い* nixがそうだとは思わない。私があなたなら、最初に完成したスクリプトを実行する予定のShell/* nix実装で各フォームの簡単なテストをいくつか実行することなく、互換性に依存しません。

私のテキストエディターはそれが何であるかを知っているようで、構文の強調表示を適切に行うため、私は最初の方を好む傾向があります。

エディタがPOSIXフォームをサポートしていないように見えるのは残念です。 POSIXの方法をサポートしているエディターの更新があるかどうかを確認する必要があるかもしれません。ロングショットかもしれませんが、誰が知っていますか?または、別のエディターを試すことを検討してください。

GGG、どのテキストエディタを使用していますか?

私はここで、エスケープされた文字がそれぞれの場合に少し異なる動作をすることを読みましたが、どちらの動作が望ましいか、それが状況に依存するだけなのか、私にはわかりません。

それはあなたが何を達成しようとしているかに依存すると思います。言い換えれば、コマンド置換にエスケープ文字を使用しているかどうか。

副次的な質問:たとえば、コマンド置換をネストする場合、1つのスクリプトで両方のフォームを使用するのは悪い習慣ですか?

まあ、それはスクリプトを少し読みやすくするかもしれませんが(表記上)、理解するのは難しくなります!スクリプトを読んでいる人(または、6か月後に読んでいるあなた!)は、コメントでこれを行った理由について何らかのメモを入れない限り、なぜあなたは1つのフォームだけに固執しなかったのか疑問に思うでしょう。さらに、両方のフォームを1つのスクリプトに混在させると、そのスクリプトの移植性が低下します。スクリプトが適切に機能するためには、実行するシェルが1つのフォームだけでなく、両方のフォームをサポートする必要があります。

シェルスクリプトを理解しやすくするために、特に技術的な理由がない限り、スクリプト全体を通して1つのフォームまたは他のスクリプトに固執することを個人的に好みます。さらに、古い形式よりもPO​​SIX形式の方が好きです。繰り返しますが、特に技術的な理由がない限りは別です。

コマンド置換のトピックとそれを行うための2つの異なる形式の詳細については、ロビンズとビービー​​によるO'Reillyの書籍「Classic Shell Scripting」第2版のコマンド置換に関するセクションを参照することをお勧めします。そのセクションでは、著者は、コマンド置換のPOSIXフォームは「すべての新しい開発に推奨される」と述べています。この本には金銭的な興味はありません。シェルスクリプトについては私が持っている(そして愛している)ものの1つにすぎませんが、シェルスクリプトの開始には向いておらず、中級または上級のシェルスクリプト用です。

-B。

152
Bruce Brown

bash manual から違いを読むことができます。ほとんどの場合、それらは交換可能です。


言及すべきことの1つは、コマンドをネストするにはbackquoteをエスケープする必要があるということです。

$ echo $(echo hello $(echo Word))
hello Word    

$ echo `echo hello \`echo Word\``
hello Word

41
kev

バックティックは古代のシェルと互換性があるため、移植性が必要なスクリプト(GNU autoconfスニペットなど)はそれらを優先する必要があります。

$()フォームは、特に目に優しいです。いくつかのレベルのエスケープの後。

8
phs