* shシェルのバックティック(つまり、 `cmd`)は廃止されましたか?


118

Bash&Zshなどのシェルに関して、「バックティックは廃止されました」という表現を使用する他のサイトと同様に、UnixとLinuxでこのコメントを何度も見ました。

この声明は真ですか、それとも偽ですか?


ネストされた逆引用符よりも表記が使いやすい理由の例については、なぜシェルスクリプトで引用符を逆引きしないのcdがディレクトリに役立つかを参照してください$(...)
ジョナサンレフラー14


1
少なくとも1つのUnix(AIX)は、バックティックが廃止されたことを文書化しました。「逆引用符構文はkshで受け入れられますが、X / Open Portability Guide Issue 4およびPOSIX規格では廃止されていると見なされます。これらの規格は、ポータブルアプリケーションで$(command)構文を使用することを推奨しています。」ibm.com/support/knowledgecenter/ssw_aix_71/com.ibm.aix.osdevice/…–
クリストファー

Mac 10.10の「GNU bash、バージョン3.2.57(1)-release(x86_64-apple-darwin14)」には明確な違いがあります:matchingLines=$( grep -n '\$-PARAMETER' ... | ... )動作しますが、matchingLines= backtick the same stuff backtick動作しません-バックスラッシュ-ドルでバックスラッシュを失うようです。(それは私のスクリプトではありません...)
denis

回答:


126

「非推奨」には2つの異なる意味があります。

非推奨:(主にソフトウェア機能の)使用可能であるが、一般的に取って代わられたために、時代遅れであり、回避が最も良いと見なされている。

—新しいオックスフォードアメリカ辞書

この定義により、バックティック非推奨になりました。

非推奨ステータスは、機能が将来削除されることを示す場合もあります。

ウィキペディア

この定義により、バックティックは非推奨ではありません。

引き続きサポート:

シェルコマンド言語オープングループ仕様、特にセクション「2.6.3コマンド置換」を引用すると、仕様が進む限り、コマンド置換の両方の形式のバックティック(`..cmd..`)またはドル記号($(..cmd..))が引き続きサポートされていることがわかります。

抜粋

コマンド置換を使用すると、コマンド名自体の代わりにコマンドの出力を置換できます。コマンド置換は、コマンドが次のように囲まれている場合に発生します。

          $(command)

          or (backquoted version):

          `command`

シェルは、サブシェル環境(シェル実行環境を参照)でコマンドを実行し、コマンド置換(コマンドのテキストと囲み文字$()または逆引用符)をコマンドの標準出力で置き換え、1つ以上のシーケンスを削除することにより、コマンド置換を拡張します。置換の最後にある<newline>文字。出力の最後の前に埋め込まれた<newline>文字は削除されません。ただし、有効なIFSおよび引用符の値に応じて、フィールド区切り文字として扱われ、フィールド分割中に削除される場合があります。出力にヌルバイトが含まれる場合、動作は指定されません。

コマンド置換の逆引用符スタイル内で、<backslash>は、その後に続く場合を除き、リテラルの意味を保持します: '$'、 ' \`'、または<backslash>。一致するバッククォートの検索は、最初のクォートされていないエスケープされていないバッククォートによって満たされます。この検索中に、シェルコメント、ヒアドキュメント、$(command)フォームの埋め込みコマンド置換、または引用符付き文字列内でエスケープされていない逆引用符が検出されると、未定義の結果が発生します。「`...`」シーケンス内で始まるが終了しない単一引用符または二重引用符で囲まれた文字列は、未定義の結果を生成します。

この$(command)フォームでは、開き括弧から対応する閉じ括弧までのすべての文字がコマンドを構成します。任意の有効なシェルスクリプトをコマンドに使用できますが、不特定の結果を生成するリダイレクトのみで構成されるスクリプトを除きます。

それでは、なぜバックティックが廃止されたとみんなが言うのでしょうか?

ユースケースのほとんどは、バックティックの代わりにドル記号を使用する必要があるためです。(上記の第1の意味で非推奨。)最も評判の高いサイト(U&Lを含む)の多くは、これもよく一貫して述べているため、適切なアドバイスです。このアドバイスを、シェルからバックティックのサポートを削除する存在しない計画と混同しないでください。

  • BashFAQ#082-なぜ$(...)が `...`(バックティック)よりも優先されるのですか?

    抜粋

    `...`最も古い非POSIX互換のボーンシェルのみが必要とするレガシー構文です。常に$(...)構文を好むいくつかの理由があります:

    ...

  • Bash Hackers Wiki-廃止され廃止された構文

    抜粋

    これは、コマンド置換の古いBourne互換形式です。両方`COMMANDS`$(COMMANDS)構文は、POSIXによって指定されているが、後者はされ大幅前者は、残念ながらまだスクリプトで非常に流行しているが、好ましいです。新しいスタイルのコマンド置換は、現代のすべてのシェル(および一部)によって広く実装されています。バックティックを使用する唯一の理由は、実際のBourneシェル(Heirloomなど)との互換性のためです。Backtickコマンドの置換では、ネストされた場合に特別なエスケープが必要であり、野生で見つかった例は、頻繁に不適切に引用されます。参照: なぜ$(...)が `...`(バックティック)よりも優先されるのですか?

  • POSIX標準原理

    抜粋

    これらの一貫性のない動作のため、コマンド置換のネストや複雑なスクリプトの埋め込みを試みる新しいアプリケーションでは、逆引用符で囲まれたさまざまなコマンド置換はお勧めしません。

注:この3番目の抜粋(上記)は、バックティックが単に機能しない状況を示していますが、次の段落から始まる新しいドル記号の方法は機能します。

また、逆引用符で囲まれた構文には、埋め込みコマンドの内容に関する歴史的な制限があります。新しい「$()」フォームはあらゆる種類の有効な埋め込みスクリプトを処理できますが、逆引用符付きフォームは逆引用符を含む有効なスクリプトを処理できません。

そのセクションを読み続けると、バックティックを使用してどのように失敗するかを示す失敗が強調表示されますが、新しいドル記号表記を使用して動作します。

結論

したがって、バックティックの代わりにドル記号を使用することをお勧めしますが、「これは計画された時点で完全に機能しなくなります」のように技術的に「非推奨」になっているものは使用していません。

これをすべて読んだ後、実際のオリジナルの非POSIX Bourneシェルとの互換性を特に必要としない限り、ドル記号を使用することを強くお勧めします。


26
意味のほとんどは非推奨、I(あなたは)バッククォートがあると言うだろうされている非推奨します。主に用語の質問です。
ステファンシャゼル14

4
@StephaneChazelas-合意!引き続き非推奨ですが、近い将来シェルのコードベースから積極的に削除されるという意味で、バックティックは公式に「非推奨」ではありません。少なくとも私が知っていることはありません。
slm

3
私の解釈では、バッククォートは既存のコードに定着しすぎて正式に廃止できないため、純粋にサポートされています。新しいコードでそれらを使い続けるという議論を聞いたことはありません。
chepner

3
@slmええ、私はあなたがそれを手に入れたと思う-私は引き離されて気づかなかった。これらのものを使用する理由はほとんどありませんが、サブシェルをレイヤー化するときに少しきれいになる可能性があるので$( cmd `cmd`)、混乱が少し少なくなります$( cmd $(cmd))-読みやすくなります。ソフトウェアの非推奨機能は、アップストリームによる削除が公式にマークされていると常に考えていましたが、そのようなことは聞いたことがありません。私は気にしません-墓を愛していません。
mikeserv 14

3
あなたは、次からの引用を追加することもできPOSIX標準的根拠ので、これらの矛盾した行動の、コマンド置換のバッククォート様々な巣のコマンド置換や試みが複雑なスクリプトを埋め込むための新しいアプリケーションのために推奨されていません。根拠のセクションは参考であり規範的ではないため、これは正式な非推奨ではありませんが、逆ティックの継続的な使用は避ける必要があることを示唆しています。
jw013 14

15

非推奨ではありませんが、バックティック(`...`)は、非常に古い非POSIX互換ボーンシェルでのみ必要なレガシー構文であり、$(...)POSIXであり、いくつかの理由でより好まれています。

  • バックティック\内のバックスラッシュ()は、非自明な方法で処理されます。

    $ echo "`echo \\a`" "$(echo \\a)"
    a \a
    $ echo "`echo \\\\a`" "$(echo \\\\a)"
    \a \\a
    # Note that this is true for *single quotes* too!
    $ foo=`echo '\\'`; bar=$(echo '\\'); echo "foo is $foo, bar is $bar" 
    foo is \, bar is \\
  • 入れ子になった引用$()は、はるかに便利です。

    echo "x is $(sed ... <<<"$y")"

    の代わりに:

    echo "x is `sed ... <<<\"$y\"`"

    または次のようなものを書く:

    IPs_inna_string=`awk "/\`cat /etc/myname\`/"'{print $1}' /etc/hosts`

    $()引用にまったく新しいコンテキストを使用するため

    BourneおよびKornシェルではこれらのバックスラッシュが必要ですが、Bashおよびdashでは必要ないため、移植性はありません。

  • ネストされたコマンド置換の構文は簡単です:

    x=$(grep "$(dirname "$path")" file)

    より:

    x=`grep "\`dirname \"$path\"\`" file`

    理由は$()引用のための全く新しいコンテキストを強制するので、各コマンドの置換が保護されており、引用とエスケープを超える特別な心配せずに独自に処理することができます。バックティックを使用すると、2つ以上のレベルの後に、よりくなります。

    その他の例:

    echo `echo `ls``      # INCORRECT
    echo `echo \`ls\``    # CORRECT
    echo $(echo $(ls))    # CORRECT
  • バッククォートを使用するときの一貫性のない動作の問題を解決します。

    • echo '\$x' 出力 \$x
    • echo `echo '\$x'` 出力 $x
    • echo $(echo '\$x') 出力 \$x
  • Backticks構文には埋め込みコマンドの内容に歴史的な制限があり、バッククォートを含むいくつかの有効なスクリプトを処理できませんが、新しい$()フォームはあらゆる種類の有効な埋め込みスクリプトを処理できます。

    たとえば、そうでなければ有効な埋め込みスクリプトは左の列では機能しませんが、右のIEEEでは機能します。

    echo `                         echo $(
    cat <<\eof                     cat <<\eof
    a here-doc with `              a here-doc with )
    eof                            eof
    `                              )
    
    
    echo `                         echo $(
    echo abc # a comment with `    echo abc # a comment with )
    `                              )
    
    
    echo `                         echo $(
    echo '`'                       echo ')'
    `                              )

したがって、$-prefixed コマンド置換の構文は、きれいな構文で視覚的に明確であり(人間と機械の可読性が向上する)、ネスト可能で直感的であり、その内部解析が分離されており、(ダブルクォート内から解析される他のすべての展開)では、バックティックが唯一の例外であり、特に小さいフォントや珍しいフォントの`場合、文字"を読むのがさらに難しくなるので、文字が簡単に偽装されます。

出典:(逆ティック)より$(...)優先される理由 `...`BashFAQで

こちらもご覧ください:

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.