web-dev-qa-db-ja.com

`echo -e" \\\ SOME_TEXT "`にバックスラッシュが1つしか表示されないのはなぜですか?

Linuxシェルでキャラクターがエスケープする舞台裏で何が起こっているのかを説明できる人がいますか?私は次のことを試し、たくさんグーグルしましたが、何が(そしてどのように)起こっているのか理解するのに成功しませんでした:

root@sv01:~# echo -e "\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\\\ Hello!"
\\\ Hello!
root@sv01:~# echo -e "\n Hello!"

 Hello!
root@sv01:~# echo -e "\\n Hello!"

 Hello!
root@sv01:~# echo -e "\\\n Hello!"
\n Hello!

私はそこで完全に迷っています。たとえば、3つのバックスラッシュが1つのバックスラッシュしか与えないのはなぜですか。 私は期待します:最初の2つは1つにエスケープされ、3つ目はエスケープするものが何も見つからないため、スラッシュのままです(最初の実験の行)、しかし何が起こっているかは3つ目は消えます。
なぜ4つのバックスラッシュが1つあるのですか\\\\ Hello各ペアが1つのバックスラッシュ-> 2つのバックスラッシュを与えることを期待します。

そして、なぜ最後のケースで\ nエスケープするために3つのバックスラッシュが必要なのですか?それを得るために脱出するバックグラウンドで何が起こっていますか?そして、それは\\nケースとどう違うのですか?

前の行で何が起こっているかについての説明に感謝します。

20

これは、bashecho -eを組み合わせたためです。 man 1 bash から

引用符で囲まれていないバックスラッシュ(\)はエスケープ文字です。 <newline>を除いて、次の文字のリテラル値を保持します。 […]

二重引用符で文字を囲むと、$`\、[…]を除いて、引用符内のすべての文字のリテラル値が保持されます$`"\、または<newline>のいずれかの文字。

重要なのは、二重引用符で囲まれたバックスラッシュは常に特別なわけではないということです。

echoにはさまざまな実装があり、一般的にはbashに組み込まれています。ここで重要なのは、この動作です。

-eが有効な場合、次のシーケンスが認識されます。
\\
バックスラッシュ
[…]
\n
改行

これでデコードできます:

  1. echo -e "\ Hello!"bashに特別なものは何もありません。echoに特別なものは何もありません。 \は残ります。
  2. echo -e "\\ Hello!" –最初の\bashに2番目の\を文字どおりに処理するように指示します。 echo\ Hello!を取得し、上記のように機能します。
  3. echo -e "\\\ Hello!" –最初の\bashに2番目の\を文字どおりに処理するように指示します。 echo\\ Hello!を取得し、(-eのため)\\\として認識します。
  4. echo -e "\\\\ Hello!" –最初の\bashに2番目の\を文字どおりに処理するように指示します。 3番目は4番目について同じことを伝えます。 echo\\ Hello!を取得し、(-eのため)\\\として認識します。
  5. echo -e "\\\\\ Hello!" –最初の\bashに2番目の\を文字どおりに処理するように指示します。 3番目は4番目について同じことを伝えます。最後のものは特別ではありません。 echo\\\ Hello!を取得し、(-eにより)最初の\\\として認識し、最後の\はそのまま残ります。

等々。ご覧のとおり、最大4つの連続したバックスラッシュが結果として1つになります。そのため、3つを取得するには(少なくとも)9つ必要です。 9 = 4 + 4 + 1。

\nを使用して:

  1. echo -e "\n Hello!"bashに特別なものはありません。echoは同じ文字列を取得し、(-eのため)\nを改行として解釈します。
  2. echo -e "\\n Hello!"bash\\\と解釈します。 echo\n Hello!を取得し、結果は上記と同じです。
  3. echo -e "\\\n Hello!"bashは、最初の\\\として解釈します。 echo\\n Hello!を取得し、(-eのため)\\を印刷する必要があるリテラル\として解釈します。

'の代わりに"を使用した場合(bashの動作が異なるため)または-eを使用しない場合(echoの動作が異なる)、結果は異なります。

30