$(stuff)と `stuff`の違いは何ですか?


265

コマンド置換には、2つの構文があります:ドル括弧とバッククォートを使用します。実行するtop -p $(pidof init)top -p `pidof init`、同じ出力が得られます。これら2つの方法は同じことですか、それとも違いがありますか?


18
BashFAQ / 082も参照してください。
デニスウィリアムソン

42
ちょっとの間、これはjQueryの質問だと思いました。
デヴィッドマードック

結果はシェルに依存する可能性があります-一部は両方をサポートします。
-artdanil

回答:


359

古いスタイルのバッククォートで` `は、バックスラッシュとネストが少し異なります。新しいスタイル$()は、その間のすべてを( )コマンドとして解釈します。

echo $(uname | $(echo cat))
Linux

echo `uname | `echo cat``
bash: command substitution: line 2: syntax error: unexpected end of file
echo cat

ネストされた逆引用符がエスケープされている場合に機能します。

echo `uname | \`echo cat\``
Linux

バックスラッシュの楽しみ:

echo $(echo '\\')
\\

echo `echo '\\'`
\

新しいスタイル$()は、すべてのPOSIX準拠のシェルに適用されます。
以下のようmouvicielは指摘し、古いスタイルは` `、古いシェルのために必要であるかもしれません。

技術的な観点とは別に、古いスタイルに` `は視覚的な欠点もあります。

  • 気づきにくい: I like $(program) better than `program`
  • 単一引用符と簡単に混同する: '`'`''`''`'`''`'
  • 入力するのはそれほど簡単ではありません(キーボードの標準レイアウトでもないかもしれません)

(そしてSEは` `自分の目的のために使用します、この答えを書くのは苦労しました:)


10
私が追加することになります唯一の事は、私が「(」括弧ではなく、ブラケット(ある「[」)を呼び出すことである。
ケンドールHelmstetter Gelner

@Kendall:そしてここで私は「{」...すべてのそれらの年のために左のブラケットと思った
SAMB

5
@Samは:{ }通常、「中括弧」または「ブレース」と呼ばれているen.wikipedia.org/wiki/Braces_(punctuation)#Braces
ジョーンSchouの-Rodeの

2
また、「{」を中括弧と呼びます。奇妙なように思えますが、他のことをブラケットと呼ぶ場合、修飾子「curly」を追加する必要があります...実際にカールしているからだと思います。
ケンドールヘルムステッターゲルナー

1
@slim US / UKキーボードではわかりませんが、スペイン語のキーボードで`はデッドキーです。そのため、二重バックティック(通常は忘れることができること)またはバックティックを入力する必要があります。疼痛。
ダークホッグ14

41

私が観察する明らかな違いは、あなたが巣を作ることができる間、あなたがbackticksを巣に入れることができないことです$()。おそらく両方がレガシーの理由で存在します。同様に、.sourceコマンドは同義語です。


10
一部のBourne派生シェルはを認識しませんsource。ダッシュはその一例です。
デニスウィリアムソン

14
それは真実ではない。バックティックを任意のレベルにネストできます。両方のことに注意してください$(...)`...`(後者は廃止されている)標準であり、一方が.標準ではなく、source
ステファンChazelas

3
修正は、(t)csh入れ子にすることはできません。ただし、(t)cshサポートしません$(...)。ただし、サポートしますsource(サポートしません.)。
ステファンシャゼル14

28

$()古いBourneシェルでは機能しません。しかし、それはされている年間、私は昔のBourneシェルで働いていたので、何十年。


1970年代から1980年代初頭のように古いですか?
クリストファー

6

もう1つの注意事項は、$()バックティックを使用するよりも多くのシステムリソースを使用しますが、わずかに高速です。

マスタリングUnixシェルスクリプト、ランダルK.マイケルは、「ファイルの行ごとを処理する24個の方法」という名前の章のテストを行っていました。


2
この主張はナンセンスです。パーサーに別の表記法を使用しているだけなので、高速化する理由はありません。
気味悪い

@schily:たぶん、私は本から引用するだけです。詳細についてはそれを読むことができます。
クオンルム

3
私は@schilyに同意する傾向があります...なぜもっとリソースが必要ですか?
ワイルドカード

2
@Wildcard、$()スクリプトを使用した場合よりも1バイト大きくするためだと思います`(ネストせず、バックスラッシュを使用しないと仮定)。どちらを解析するのが速いかについては、シェル間で異なり、パイプの作成とコマンド置換に伴うプロセスの分岐のコストと比較すると無視できるほど重要ではありません。
ステファンシャゼル16

5

ここで他の人が言ったことに追加するには、バックコメントを使用してインラインコメントをシミュレートできます。

echo foo `# I'm a comment!` bar

出力は次のとおりfoo barです。

詳細については、次を参照してください。https : //stackoverflow.com/a/12797512(その投稿の下のコメントにも注意してください。)


1

この$()構文は、古いbourneシェルでは機能しません。
新しいシェル` `$()は同等で$()あり、複数のコマンドをネストする必要がある場合に使用する方がはるかに便利です。

例えば ​​:

echo $(basename $(dirname $(dirname /var/adm/sw/save )))

を入力してデバッグするのは簡単です:

echo `basename \`dirname \\\`dirname /var/adm/sw/save \\\`\``

1
$()は見栄えが良いかもしれませんが、デュアルパーサーを必要とするため、関連するパーサーを実装するのは苦痛です。
気味悪い

6
@schily反対に、優れたパーサーのないシェルはどうでしょう。
エマニュエル

1
問題は、パーサーを呼び出す前に、文字列がどこで終わるかを知る必要があるということです。これはバックティックでは比較的簡単ですが、ブラケットはシェルでさまざまな目的に使用されるため、ブラケットでは困難です。そのため、Bourne Shellには存在しない方法で、パーサーを2回必要とします。
気味悪い
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.