echo \\* - bash バックスラッシュエスケープ動作、逆に評価されますか?

echo \\* - bash バックスラッシュエスケープ動作、逆に評価されますか?

だから私がするときbashで

echo \*
*

*がエスケープされ、文字通り使用されるので、これは正しいようです。

でもそうすれば理解できません。

echo \\*
\*

最初のバックスラッシュが2番目のバックスラッシュをエスケープすると思うので、2つのバックスラッシュ「\\」は文字通り「\」を提供します。次の*には特別な意味があります。私はそれを楽しみにしています:

echo \\*
\file1 file2 file3

回答の概要:\は文字通り使用されるため、文字「a」で始まるファイルを見つけたecho \*かのように動作します。echo a*

後続の質問、まったく同じように印刷するには

\file1 file2 file3

どのコマンドを使用する必要がありますか?たとえば、以下のようにするのにスペースは必要ありません。

echo \\ * 
\ file1 file2 file3

答え1

これは、現在のディレクトリにバックスラッシュで始まる名前のファイルがない場合に予想される動作です。吹く*既存のファイル名と一致するように拡張されますが、:

パターンが既存のファイル名またはパス名と一致しない場合は、パターン文字列を変更しないでください。

で始まるファイル名がないため、\パターンはそのままにしてechoパラメータを指定します\*。この動作はしばしば混乱し、他のいくつかのシェル(例zshこれは、Bash で次のコマンドを使用して変更できます。shopt -o failglobすると、エラーが発生しzsh、故障ではなく問題を診断するのに役立ちます。

*パターン文字は?単語のどこにでも表示でき、前後の文字は文字通り一致します。したがって、異なる出力をecho \\*提供しecho \\ *ます。 1つ目は次のすべてのエントリと一致し\(失敗)、2つ目はaを出力してからすべての\ファイル名を出力します。


おそらく、目的の出力を安全に取得する最も簡単な方法は、次を使用することです。印刷機能:

printf '\\'; printf "%s " *

echo *-とにかく、珍しいファイル名が含まれていても安全ではありません\

答え2

この試み:

printf "\\%s" "$(echo *)"

説明する:

  • printf型引数と型文字列に置き換えられるゼロ個以上の引数を受け入れます。
  • \\形式の意味は形式と同じです。echo \\
  • %s次の引数を取り、結果に代入することを示します。
  • "$(echo *)"意味:echo *結果を実行して単一のパラメータに入れますprintf。動作原理のため、printfパラメータに入れる必要があります。

答え3

頑張って...

set file*
printf %s\  "\\$@"

配列の先頭にバックスラッシュを追加するため、最初の要素のみが追加されます。エンディングも同じようにしてください。次のようにバックスラッシュですべて区別できます\\

printf \\%s file*

...または...

set file*; IFS=\\; printf %s\\n "$*"

答え4

私は質問の後半(「どのコマンドを使うべきですか?」)に対する他のすべての答えは、技術的にも極端な場合でも間違っていると思います。私はこれが他の答えの問題を解決すると信じています。

(set -- *; echo "\\$*")


そして(FWIW)すべての書き込みは(とは異なり)単一のコマンドで実行されますprintf '\\'; printf "%s " *; echo

  • サブシェルを使用すると、外部範囲/コンテキストでの位置パラメータの設定/変更を回避できます。
  • 単純にset *位置パラメータ($1、など)$2$3現在のディレクトリのファイル名に設定します。 (ファイル名は.dotglob(ドット)は、このオプションを設定するかどうかに応じて含まれます。 )
  • set *次の名前で始まるファイルがあると失敗する可能性があります。-*(ダッシュ)(リストの最初のファイルです)。set -- *これを処理してください。 --「これ以降のすべては、オプション/フラグではなくパラメータです」と言います。
  • $*$1 $2 $3 …スペースで区切られた位置パラメータ()のリスト。理由は(質問の例のコマンド)のように行の先頭に出力され\\ますが、それに続く内容を妨げることはありません。\echo \\ *$*
  • $*位置パラメータリスト($1 $2 $3 …)。 パラメータは最初の文字で区切られます。$IFS。の最初の文字が$IFS空白でない可能性がある場合は、次のようにします。
(set -- *; IFS=" "; echo "\\$*")

やや詳細なオプションは次のとおりです。

(set -- *; printf "%s\n" "\\$*")

そして

(set -- *; printf "\\%s\n" "$*")

echoこれは、オプションなしでパラメータ文字列のバックスラッシュが解釈される可能性がある環境でより安全です-e

繰り返しますが、IFS=" ";の最初の文字が空白で$IFSない場合は追加してください。

関連情報