次の操作を実行するとき:
echo 'Hello World'
または次のようになります。
x=12345
echo "x is: $x"
最初の例では、echo
コマンドはreceiveですか'Hello World'
、それともreceiveですかHello World
?
2番目の例では、echo
コマンドはreceiveですか"x is: $x"
、それともreceiveですかx is: 12345
?
だから基本的に私の質問は:一重引用符と二重引用符がbash
処理されるのか、それとも処理されますかecho
?
ベストアンサー1
引用符、変数拡張、ワイルドカード、その他すべての項目に記載されている内容拡張の bash マニュアルbashとして扱われます。
たとえば、bashコマンドを実行すると、bashはコマンドを解析してコマンドを実行するために1つの引数(たとえば)がecho "x is: $x"
必要かどうかを確認します。が与えられると、bashは2つの引数で実行されます。そして - これが引用符の中の2つの空白が保持される理由です(未修正の引数をエコー印刷する部分です)。ただし、引用符の外にある2つのスペースは保持されません(シェルの場合は2つのスペース)、引数を区切ることは単一の引数と同じくらい良いです。常に中間にスペースを印刷します。echo
x is: 12345
echo "x is" "$x"
echo
x is
12345
echo
このコマンド(または他のコマンド)は、どのシェルコマンドが引数を生成したのか、シェルが実際に関連しているのかはecho
わかりません。x is: 12345
以下は、このパラメータを生成するいくつかのコマンドの例です。
echo "x is: 12345"
echo 'x is: 12345'
echo x\ is:\ 12345
echo "x is: $x"
echo 'x is:'\ "$x"
echo "$(echo "x ")is: $x"
# Assume there is no other file whose name begins with x in the current directory
touch "x is: $x"; echo x*
あるいは、exec "echo", "x is: 12345"
Perlやexeclp("echo", "echo", "x is: 12345")
Cのような言語かもしれません。
これはすべてのコマンドに適用されます。同じ原則が他のシェルにも適用されますが、各拡張セットは若干(または大きく)異なります。
一方、オプションコマンドとして扱われます。たとえば、ls -l -t
bash ls -l "-t"
(または同様のシェル)では、両方ともls
2つの引数-l
と-t
。そのため、ls
.txtというファイルに関する情報を表示するために実行したい場合は、どのようなシェル引用符も役に立ちません-t
。を使用してこれを行うことができますls -l -- -t
。つまり、--
パラメータとして渡すだけです。これはほとんどのコマンドが従うルールです。次のすべてのコマンドは--
オプションで解析されません。繰り返しますが、これはコマンドの機能です。シェルの先行ダッシュは特別なものではありません。
難しいことの1つはバックスラッシュです。 Bashや他のシェルでは、引用符の外側のバックスラッシュは、次の文字が特別な意味を失うことを意味します。たとえば、バックスラッシュの前にある各文字は、特別な意味(の場合は引用構文、単語区切り文字の場合は空白)を失うため、echo \"x\ is:\ 12345\"
印刷します。しかし、いくつかのコマンドはバックスラッシュも解釈します。その場合、バックスラッシュが到達していることを確認する必要があります。たとえば、bashでは、コマンドはデフォルトでバックスラッシュを文字通り印刷しますが、オプションを渡すか最初に実行すると独自のエスケープシーケンスがあります。特別扱いバックスラッシュです)。たとえば、印刷時に-newline-を印刷します。なぜなら、「newline」を意味するからです。一方、印刷後はシェルによって拡張され、「次の文字を引用する」という意味を持ちます。"x is: 12345"
"
echo
-e
shopt xpg_echo
echo
echo
echo 'a\nb'
a\nb
echo -e 'a\nb'
a
b
\n
echo -e
echo a\nb
anb
\n
\
また、複数のシェルが関連している場合(SSHを使用するなど)に注意してください。ssh
シェルで実行すると、ローカルシェルは通常どおりコマンドを解析します。 SSH クライアントは、オプションではなく引数を中間スペースに関連付け、結果文字列を SSH サーバーに送信します。 SSHサーバーはこの文字列をリモートシェルに渡します。これは、端末またはシェルスクリプトに入力したものとリモートシステムで実行されているものとの間に2つの完全なシェル拡張ラウンドがあることを意味します。