全体見積

全体見積

私はなぜこの3つのコマンドが3つの異なる答えを与えるのか尋ねました。

$ printf "%s\n"   `echo ../.. | sed 's/[.]/\\&/g'`
&&/&&
$ printf "%s\n"  $(echo ../.. | sed 's/[.]/\\&/g')
../.. 
$ printf "%s\n" "$(echo ../.. | sed 's/[.]/\\&/g')"
\.\./\.\.

ベストアンサー1

これは答えにくい質問です。最後の説明の最も簡単な例です。

全体見積

実際に完全に引用された例は次のとおりです。

$ printf "%s\n"    "$(   echo "../.." | sed 's/[.]/\\&/g'   )"
\.\./\.\.

すべてが引用されるので、シェルはここで何のトリックも変更も行いません。最も内側の内容はecho "../.."引用されるため、ファイル名拡張の影響を受けません。変更せずにsedに移動し、sedは各点をに変更します\&。その後、コマンドの結果も引用さ"$(...)"れ(再び)シェルへの変更を防ぎ、printfコマンドも\.\./\.\.ここに印刷します。

に変更 ##/##

ファイル名拡張子(ワイルドカード)がある場合は../..とにかく../..。したがって、最終文字列は同じです。しかし、この問題をテストしてみましょう。

$ echo ../../t*
../../test2.txt ../../tested ../../test.txt

$ set -f     # remove all filename expansion

$ echo ../../t*     ../..
../../t* ../..

*そしてどんな場合でも、?a、a、またはaを含まない文字列は[次の影響を受けません。パターンマッチング表記

証明:GLOBIGNORE設定

$ (GLOBIGNORE='.*:..*'; echo "any" ../../t* ../.. "value")
any ../.. value

globbing(ファイル名拡張)の影響を受けた場合は、../..GLOBIGNORE値が原因で削除されます。

ただし、ファイル名拡張子がないことを確認するために、存在しないファイル名に切り替えることができます。##/##

引用符なしでコマンドを実行する

\引用符なしで(コマンドが実行されても)シェルがaを削除する理由はありません。

$ printf '%s\n' $(printf '%s\n' '\#\#/\#\#')
\#\#/\#\#

実際、私がテストしたシェルのどれも、2番目の例で報告したものを示していません。 (修正してください!)

編集:bash 5.0.17にバグがあります。しかし、ポイントでのみ。

$ b50sh
$ echo $BASH_VERSION
5.0.17(3)-release

$ printf '%s\n' $(printf '%s\n' '\.\./\.\.')
../..

$ printf '%s\n' $(printf '%s\n' '\#\#/\#\#')
\#\#/\#\#

$ printf '%s\n' $(printf '%s\n' '\>\>/\>\>')
\>\>/\>\>

$ exit
$ echo $BASH_VERSION
5.1.4(1)-release

$ printf '%s\n' $(printf '%s\n' '\.\./\.\.')
\.\./\.\.

$ printf '%s\n' $(printf '%s\n' '\#\#/\#\#')
\#\#/\#\#

bash 5.1.4で解決されたようです。

バックティック

これは最も難しい問題です。内部のすべてのバックティックはに\\なります\

したがって、sedコマンド(sedに示すように)は次のようになりますs/[#]/\&/g。私の考えでは、あなたが意味するものを行うには、sをコピーする必要があります\

$ printf '%s\n'  `printf '%s\n' '##/##' | sed 's/[#]/\\&/g'`
&&/&&

$ printf '%s\n' "`printf '%s\n' '##/##' | sed 's/[#]/\\&/g'`"
&&/&&

$ printf '%s\n' "`printf '%s\n' '##/##' | sed 's/[#]/\\\\&/g'`"
\#\#/\#\#

おすすめ記事