「二重引用符( ")を入力する方法」のような多くの質問質問され、同じ答えでコミュニティを混乱させたくありません(
\"
sで囲まれていない場合は'
と入力し、"
で囲まれている場合は'
と入力します。 。)それで、質問はここにあります。
通常のようにターミナルに特殊文字を入力することはできません。このコマンドは失敗します:
echo Updates (11)
では、これらの文字を通常の文字のようにターミナルに入力する方法は?
!#$^&*?[](){}<>~;'"\|<space><tab><newline>
それはシェルに大きく依存します。詳細については、シェルのマニュアルを確認してください。
また、一部の文字は特定のコンテキストでのみ特殊であることにも注意してください。たとえば、ほとんどのシェルでは、*
と?
はリストコンテキストでのみ特別であり、POSIXまたはcshのようなシェルでは、~
はWordの先頭または:
などの一部の文字でのみ特別です。 zsh
の=
についても同様です。一部のシェルでは、[
は、]
によって(いくつかの制限付きで)一致する場合にのみ特別です。
bash
やyash
などの一部のシェルでは、空白のトークン区切り文字などの特殊文字もロケールによって異なります。
(これらの文字の特別な意味を取り除くための)引用演算子も、シェルによって大きく異なります。
Bourneに似たシェル(80年代以降、システムによってはsh
と呼ばれていることが知られているシェル)の要約:
"\'&|;()^`<>$
、スペース、改行、タブは、引用符で囲まれていない場合、単純なコマンドラインでは特別です。#
(初期バージョンを除く)は、行の先頭、または引用符で囲まれていないスペース、タブ、または&|()^<>;`
に続く特別なものです。{
と}
は、Shellキーワードであるという点で特別です(したがって、コマンド位置にある単語のみ)。*?[
はグロビング演算子として特別なので、リストコンテキストでのみ使用できます。 [
の場合、グロビング演算子は[...]
であり、[
または]
のいずれかを引用符で囲むだけで、特別な意味を取り除くことができます。=
は、代入演算子として扱われるコンテキストでは特別です。つまり、単純なコマンドで、引数に続かないすべての単語に対して(set -k
の後を除く)。\
は、改行を除くすべての特殊文字を引用します(\<newline>
は、長いlogical行を次のphysical行に続けるための方法です。シーケンスは削除されます)。バッククォートはその内部に追加の複雑さを追加することに注意してください。\
は、最初に閉じバックティックをエスケープしてパーサーを支援するために使用されます。二重引用符内では、\
は、"
、$
、および`
自体をエスケープするためにのみ使用できます(\<newline>
は、行の継続です)。ヒアドキュメントの中では、"
を除いて同じです。 \
は、ヒアドキュメント内の文字をエスケープする唯一の方法です。"..."
の二重引用符は、それ自体を除くすべての文字をエスケープします。\
、$
、および`
。'...'
単一引用符は、それ自体を除くすべての文字をエスケープします。POSIXシェルは、次の点を除いて、ほとんどBourneシェルと同様に動作します。
^
は特殊文字ではなくなりました~
は 一部のコンテキストでは特別{
は特別であることが許可されているため、引用する必要があります。ksh
pOSIXに似ていますが、
{string}
は、stringに引用符で囲まれていない,
(または場合によっては、一部のバージョンでは..
)が含まれている場合に特別です。$'...'
があります。その演算子は、bash
、zsh
、mksh
、およびFreeBSDとbusybox sh
にも(いくつかのバリエーションがあります)あります。ksh93
には、$"..."
引用演算子もあり、"..."
のように機能しますが、文字列はローカライズされます(ユーザーの言語に翻訳されるように構成できます)。 mksh
は、$
の$"..."
を無視します。bash
ksh93
に似ていますが、
!
は一部のコンテキストでは特別であり、二重引用符が常にエスケープするとは限りません。また、^
は、コマンドの先頭では特別です。zsh
ksh93
に似ていますが、
bash
と同じメモ=
は、Wordの最初の文字として特別です(=ls
は/bin/ls
に展開されます)。{
と}
は、区切られていない場合にもコマンドグループを開いたり閉じたりできます({echo text}
はBourneの{ echo text;}
のように機能します)。[
だけを除いて、[
は、]
で閉じていなくても引用符で囲む必要があります。extendedglob
オプションを有効にすると、#
、^
、~
がグロブ演算子になります。braceccl
オプションでは、{non-empty-string}
は特別です。$"..."
はサポートされていません。?
は、(%
ジョブ仕様を許可するために)Wordの先頭で%?name
(引用符で囲まれていても展開されていても)をフォローする場合は特別ではありません。rcquotes
オプション(デフォルトでは有効になっていません)を使用すると、単一引用符をrc
内の単一引用符内に''
として入力できます(下記参照)。yash
それ以外はPOSIX
に似ています。
brace-expand
オプションを使用して、zshスタイルのブレース展開を実装します。すべてのシェルについて、引用が異なる特別なコンテキストがあります。ここではドキュメントとバッククォートについてすでに説明しましたが、kshと他のいくつかのシェルには[[...]]
もあり、POSIX $((...))
、case
構文...
また、(二重引用符を使用した)展開の場合、またはここのドキュメントの区切り文字に適用される場合、引用符には他の副作用がある可能性があることに注意してください。また、予約語を無効にし、エイリアスの展開に影響します。
Bourneのようなシェルでは、!#$^&*?[(){}<>~;'"`\|=
、SPC、TAB、NEWLINE、および8番目のビットが設定された一部のバイトは、特別な場合があります(少なくとも一部のコンテキストでは)。
特別な意味を取り除いて文字どおりに処理するには、引用符を使用します。
使用する:
'...'
は、すべての文字の特別な意味を削除します。
printf '%s\n' '\/\/ Those $quoted$ strings are passed literally as
single arguments (without the enclosing quotes) to `printf`'
\
は、1つの文字のみの特別な意味を削除します。
printf '<%s>\n' foo bar\ baz #comment
上記では、\
が前に付いている空白文字のみが文字通りprintf
に渡されます。他のものは、シェルによってトークン区切り文字として扱われます。
"..."
を使用して文字を引用しながら、パラメーター展開($var
、$#
、${foo#bar}
...)、算術展開($((1+1))
、一部のシェルでは$[1+1]
)およびコマンド置換($(...)
または古い形式の`...`
。実際には、ほとんどの場合、次のようにします どのような場合でも、これらの展開を二重引用符で囲みます 。\
は、 "..."
は、まだ特別な文字(ただし、それらのみ)の特別な意味を削除します。文字列に'
文字が含まれている場合でも、残りの部分には'...'
を使用でき、'
または"'"
または(利用可能な場合)\'
のような$'\''
を引用できる他の引用メカニズムを使用できます。
echo 'This is "tricky", isn'\''t it?'
最新の$(...)
形式のコマンド置換を使用します。 Bourne Shellとの互換性のために、古い`...`
のみを使用してください。これは、非常に古いシステムに対するものであり、変数の割り当てでのみ使用します。
echo "`echo "foo bar"`"
これは、Bourne ShellまたはAT&Tバージョンのkshでは機能しません。または:
echo "`echo \"foo bar\"`"
これは、BourneおよびAT&T kshでは機能しますが、yash
では機能しませんが、以下を使用します。
var=`echo "foo bar"`; echo "$var"
すべてで動作します。
二重引用符で移植可能にネストすることも不可能であるため、ここでも変数を使用します。また、特殊なバックスラッシュ処理にも注意してください。
var=`printf '%s\n' '\\'`
バックスラッシュ内にバックスラッシュ処理($var
、 `、および\
(およびyash
を除いて引用符で囲まれた場合は$
)の追加レベルのバックスラッシュ処理があるため、"
内にバックスラッシュを1つだけ格納します。
var=`printf '%s\n' '\\\\'`
または
var=`printf '%s\n' '\\\'
代わりに。
cshとtcshの構文は大きく異なりますが、共通の遺産を共有しているため、Bourne Shellにはまだ多くの共通点があります。
"\'&|;()^`<>$
、スペース、改行、タブは、引用符で囲まれていない場合はどこでも特別です。#
(cshは、コメントリーダーとして#
を導入したシェルです)は、スクリプトの最初、または引用符で囲まれていないスペース、タブ、または改行に続く特別なものです。*?[
はグロビング演算子として特別なので、リストのコンテキストでは{non-empty-string}
は特別です(cshはブレース展開を導入したシェルです)。!
および^
は履歴拡張の一部として特別であり(これもcshの発明です)、引用規則は特別です。~
(チルド展開もcshの発明)は、一部のコンテキストでは特別です。これらはBourne Shellの場合と同じですが、動作が異なります。 tcshは構文の観点からcshのように動作します。cshの多くのバージョンには厄介なバグがあることがわかります。大まかに機能するバージョンのcshを入手するには、tcshの最新バージョンを入手してください。
\
は、改行以外の1文字をエスケープします(Bourne Shellと同じ)。これは、!
をエスケープできる唯一の引用演算子です。 \<newline>
はエスケープしませんが、コマンドセパレーターからトークンセパレーター(スペースなど)に変換します"..."
は、それ自体、$
、`
、改行、および!
を除くすべての文字をエスケープします。 Bourne Shellとは異なり、\
を使用して$
内の`
および"..."
をエスケープすることはできませんが、\
を使用して!
または改行をエスケープすることはできます(ただし、!
または改行の前を除く)。リテラル!
は"\!"
であり、リテラル\!
は"\\!"
です。'...'
は、それ自体、!
および改行を除くすべての文字をエスケープします。二重引用符と同様に、!
と改行はバックスラッシュでエスケープできます。`...`
構文を介してのみ行われ、確実に使用することはほとんどできません。$var:q
演算子は、変数を含むより信頼性の高いコードを書くのに役立ちます。可能であればcshに近づかないでください。使用できない場合:
!
および改行には、\
が必要です。\
はほとんどの文字をエスケープできます"..."
はその内部でいくつかの展開を許可できますが、改行文字やバックスラッシュ文字を埋め込む場合はかなりバグがあります。変数の展開には一重引用符のみと$var:q
を使用するのが最善です。配列の要素を確実に結合したい場合は、ループを使用する必要があります。rc
ファミリrc
はplan9
シェルであり、その子孫のes
とakanga
はUnixやunixに移植されています。これは、はるかに簡潔で優れた構文を備えたシェルであり、下位互換性のためにBourneのようなシェルを使用していなければ誰もが使用するシェルです。
rc
/akanga
#;&|^$=`'{}()<>
、SPC、TAB、およびNEWLINEは、引用されていない場合は常に特別です。*?[
はグロビング演算子です。'...'
が唯一の引用演算子です。リテラル'
は、次のように''
を単一引用符で囲んで記述します。
echo 'it''s so simple isn''t it?'
es
es
は、rc
に基づく実験的シェルと見なすことができます。
ただし、いくつかの違いがあります。このQ/Aで興味深いのは、\
が引用符演算子(改行を除くすべての特殊文字を引用する)でもあり、改行の\n
、バックスラッシュの\b
などのエスケープシーケンスの導入にも使用できることです。
fishは比較的新しい(2005年頃)で、主にインタラクティブな使用を目的としており、他のシェルとは構文が大きく異なります。
"'\()$%{}^<>;&|
引用符で囲まれていない場合は常に特殊です(%
(pid展開の場合)は他のシェルとの大きな違いであり、`
は特殊ではありません)#
(コメント)引用符で囲まれていないスペース、タブ、改行、または;&|^<>
をフォローする場合は特別*?
([...]
ではない)グロビング演算子\
は、改行以外の1つの特殊文字を引用しますが、Cエスケープシーケンス(\n
、\b
...)のイントロデューサとしても使用されます。 IOW、\n
は、引用符で囲まれたn
ではなく、改行です。"..."
は、それ自体を除くすべてを引用します。$
およびバックスラッシュとバックスラッシュは、それらをエスケープするために使用できます。 \<newline>
は、"..."
内の行の継続(削除)です。'...'
は、それ自体と\
以外のすべてを引用し、バックスラッシュを使用してそれらをエスケープできます。次のように、\
でこれらの文字をすべてエスケープします(改行/改行では機能しません)。
$ echo Use a \"\\\" symbol to escape characters.
Use a "\" symbol to escape characters.
次のように、テキスト全体を"
sで囲みます。
$ var=variables;echo "Enclose text in \"s. You can also use $var in them. `echo Surprise!!!`"
Enclose text in "s. You can also use variables in them. Surprise!!!
二重引用符と同じですが、特別なトークンはありません。
$ proof=proveit;echo 'This should not read "proveit": $proof'
This should not read "proveit": $proof