それではいつ?誰でもこれを説明できますか?
echo -e \tr\t\e\\re\e
#eete
echo \tr\t\e\\re\e
#trte\ree
答え1
これは、シェルecho
自体ではなく、シェルがコマンドを解析する方法に関連しています。最初の例を見てください。
echo -e \tr\t\e\\re\e
バックスラッシュは引用符の外側に表示されるため、シェルはこれらのバックスラッシュをエスケープマークとして解釈し、バックスラッシュの後に続く文字の(シェルに対する)特別な意味を削除します。シェルはこのコード行を3つの単語で解析しますecho
。最初の単語は実行されるコマンドになり、次の2つの単語はその引数になります。解析された引数のみが表示されます。このオプションが提供されるため、コマンドは通常エスケープを解釈しますが、文字列内ではシェルが渡す文字列であるためです。-e
trte\ree
echo
-e
echo
trte\ree
2番目の引数を一重引用符で囲むと、シェルは文字を\
解釈できなくなり、そのまま渡すことができますecho
。したがって:
echo -e '\tr\t\e\\re\e'
シェルは、echo
最初-e
と2番目の引数を使用して呼び出されます\tr\t\e\\re\e
。これでecho
、すべてのエスケープシーケンスを解釈する必要があります。
答え2
\
はいシェルの参照演算子。あたかも特別な意味を削除するのと\x
同じです(改行文字を削除する以外)。'x'
x
x
だから:
echo -e \tr\t\e\\re\e
ように:
echo -e 't'r't''e''\'re'e'
t
、、、r
はe
シェル構文では特別ではありません。\
そこに唯一の特別なもの。したがって、本質的にこれは次のようになります。
echo -e trte'\'ree
または:
echo -e 'trte\ree'
あなたのecho
実装は、ANSI Cエスケープシーケンスを解釈するように指示するオプションを受け入れる実装の1つであるように見えるので、キャリッジリターンに-e
変換されます。\r
これは、端末に送信されたときにカーソルを再度移動するように指示する制御文字です。線が最初にあるのでeete
(trte
部分的に覆われているee
)、表示されてtrte\ree
いないことがわかります。
埋め込み引数を出力するよう\tr\t\e\\re\e
に渡すには、シェルがそれを引用演算子として解釈しないようにバックスラッシュ文字を引用/エスケープする必要があります。echo -e
<TAB>r<TAB><ESC>\e<ESC>
echo -e '\tr\t\e\\re\e'
echo -e \\tr\\t\\e\\\\re\\e
echo -e "\\tr\\t\\e\\\\re\\e" # (\ is still special within "..." to escape
# the few characters that are still special
# to the shell within double quotes)
echo -e $'\\tr\\t\\e\\\\re\\e' # (\ is not a quoting operator in $'...'
# but has its own special meaning there
# similar to that it has for echo)
またはこれを行うこともできます:
echo $'\\tr\\t\\e\\\\re\\e'
今回は、 が$'...'
それぞれTAB、ESC、CR、\で拡張され、含まれた引数を受け取ります。そうでない場合は、そのまま表示されます(たとえすべての実装に当てはまるわけではありませんが、多くの人がこれを次のように解釈します。デフォルト値(一部は無効にすることができます))。\t
\e
\r
\\
echo
<TAB>r<TAB><ESC>\e<ESC>
-e
echo
echo
-e
-E