* shシェルではバックティック(「cmd」など)は使用されなくなりましたか?

* shシェルではバックティック(「cmd」など)は使用されなくなりましたか?

私はUnix、Linux、Bash、Zshなどのシェルに関して、「バックティックはもう使用されていません」というフレーズを使用している他のサイトでこのコメントを数回見ました。

この声明は本当ですか、偽ですか?

答え1

「未使用」には2つの異なる意味があります。

廃止予定:(主にソフトウェア機能)は使用できますが、使用されなくなったため、一般的に置き換えられているので避けるのが最善です。

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

この定義によると、バックティックはい廃止予定です。

廃止予定また可能この機能は、今後削除される予定です。

ウィキペディア

この定義によると、バックティックはいいえ廃止予定です。

引き続きサポート:

Open Group Shell コマンド言語仕様、特にセクションへの参照2.6.3 コマンドの置換、仕様の範囲内で、バックティック(`..cmd..`)またはドル括弧()の2つの形式のコマンド置換がまだサポートされていることがわかります。$(..cmd..)

コマンド置換を使用すると、コマンド名自体をコマンドの出力に置き換えることができます。コマンド置換は、コマンドに次のものが含まれている場合に発生します。

$(command)
          

または(バックティックバージョン):

`command`

$()シェルはサブシェル環境(シェル実行環境を参照)でコマンドを実行し、コマンド置換(引用符または逆引用符付きのコマンドテキスト)をコマンドの標準出力に置き換えてコマンド置換を拡張する必要があります。シーケンス置換。改行>文字。出力が終わる前に挿入された<newline>文字は削除しないでください。ただし、IFS値と有効な引用符に応じてフィールド区切り文字として扱われ、フィールド分割中に削除される可能性があります。出力に null バイトが含まれている場合、動作は指定されません。

バックティックスタイルのコマンド置換では<バックスラッシュ>`"$"、" "、または""が後に来ない限り、文字通りの意味を維持する必要があります。<バックスラッシュ>。一致する逆引用符検索は、この検索中に引用されず、エスケープされていない最初の逆引用符で満たされます。エスケープされ$(command)ていない逆引用符に対して未定義の結果が発生します。シーケンスで始まるが終わらない一重引用符または二重引用符文字列は、`...`未定義の結果を生成します。

この$(command)形式では、左角かっこの後から一致する右角かっこまでのすべての文字がコマンドを構成します。指定されていない結果を生成するリダイレクトのみを含むスクリプトを除いて、すべての有効なシェルスクリプトをコマンドと共に使用できます。

それでは、なぜ誰もがバックティックが使用されなくなったと言うのでしょうか?

ほとんどのユースケースのためしなければならないバックティックの代わりにドル括弧形式を使用してください。 (上記の最初の意味では使用されなくなりました。)最も評判の高いサイト(U&Lを含む)でもこの内容によく言及するので、これは健全なアドバイスです。この推奨事項は、シェルからバックティックサポートを削除する予定の存在しない計画と混同しないでください。

メモ:3番目の抜粋(上記)では、バックティックはまったく機能しませんが、次の段落から始めて、最新のドル角括弧アプローチが機能するいくつかの状況を示しています。

また、バックティック構文には、含まれるコマンドの内容に対する歴史的な制限があります。最新の「$()」フォームはすべての種類の有効な組み込みスクリプトを処理できますが、バックティックフォームはバックティックを含む一部の有効なスクリプトを処理できません。

そのセクションを読み続けると、失敗は強調表示され、バックティックの使用が失敗した方法を示していますが、最新のドル角括弧表記を使用すると機能します。

結論として

したがって、バックティックの代わりにドル括弧を使用する方が良いですが、実際には、「これはどの計画時点でも完全には機能しません」など、技術的に「廃止予定」の項目を使用しません。

これらすべてを読んだ後は、ドル括弧を使用することが非常に推奨されることを理解する必要があります。具体的にPOSIXではなく、実際のBourneシェルとの互換性が必要です。

答え2

廃止予定ですが、逆引用符(`...`)は、最も古い非POSIX準拠のbourne-shellにのみ必要なレガシー構文であり、$(...)次の理由で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 やダッシュには必要ないため、移植性はありません。

  • 入れ子になったコマンド代替構文はより簡単です。

    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
  • バックティック構文には、埋め込みコマンドの内容に対する歴史的な制限があり、バックティックを含む特定の有効なスクリプトを処理できませんが、最新の形式ではすべての種類の$()有効な埋め込みスクリプトを処理できます。

    たとえば、これらの有効なインクルードスクリプトは左側の列では機能しませんが、右側の列では機能します。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構文はコマンドの置き換え視覚的に明確で構文が明確であり(人と機械の読みやすさの向上)、ネスト可能で直感的で、内部構文解析が独立しており、一貫性が高いため、好ましいアプローチです(他のすべての拡張は内部で構文解析されています)。 )(バックティックが唯一の例外である)、`文字が隣接している場合は簡単に偽装することができ、"特に小さいフォントまたは珍しいフォントの場合は読みにくくなります。

源泉:なぜ(バックティック)$(...)よりも優先しますか?`...`バッシュFAQ

また見なさい:

答え3

あなたのタイトルが少し誤解を招くことがあり、あなたの質問とは異なることに注意してください。返品タイトルの質問に答えてください(そしてsh / bashの変形に関する正解に同意しないでください)。

あなたの質問テキストは特にbash / zshを参照していますが、タイトルは*について尋ねます。シェル。話す*シェルより広く問題を解決し、まだよく使用されているcshやtcshなどのシェルを正式に含めます。

はい、多くの人がtcshを嫌い、しばしばtcshを次のように使用しないでください。スクリプト言語(同意します) 単に対話型シェルとして使用する可能性を無視します。 (正直なぜ*shをプログラミング言語で使うのかよくわかりません...しかし、続行します)。

csh/tcsh では、バックティックは次のようになります。いいえ部分的には廃止されました。いいえ$() がサポートされます。

したがって、私たちは、バックティックが使用されなくなったので、bashバリアントがバックティックを「もはや使用しない」ことを知っています。いいえある意味、まもなく(または永遠に)削除されます。私たちはcsh / tcshがバックティックをサポートしていることを知っています。

まあ、stackexchangeのようなサイトで質問に答えるとき、$()ソリューションを好む複雑な引用を含まない簡単な例に実際にバックティックを使用する必要があるというまともな主張をすることができます。これは、bashユーザーのために直接答えを解決し、他のシェルを使用し、$()bourne構文を知らないあまり上級ユーザーを混乱させるのではなく、答えの移植性を高めます。

注意事項と別のFAQではなく、環境変数をコマンドとしてエクスポートする例を提供する方が便利です。

% VAR=value some_command arg1 arg2 ...

これはsh / bashバリアントでのみ機能し、次のように簡単に実行できます。

% env VAR=value some_command arg1 arg2 ...

奇跡的にあなたの答えは、ほとんどのシェルで動作します。

Stackexchangeなどのサイトのグローバルな回答は、一般的にどのシェルを使用するかについての立場をとるのではなく、できるだけ混乱を最小限に抑えながら、できるだけ多くのユーザーにとって問題を解決することです。

私はこれがあなたの元の(明らかに古い)質問と多少関連していることを知っていますが、問題は、この質問に対する答えが人々が$()スタック交換の答えに使用するべきであることを示唆しているので引用されたので、脚注に言及する価値があるでしょうです。

関連情報