特殊文字を通常の文字として使用する方法は?


13

「二重引用符文字( ")の入力方法?"などの多くの質問 求められている、と我々は同じ答え(と、それを入力して、私たちのコミュニティを乱雑にしたくない\"で囲まれていない場合は'、S "で囲まれている場合'、S。)だから、質問はここにあります。

通常のような特殊な文字を端末に入力することはできません。たとえば、次のコマンドは失敗します。

echo Updates (11)

それでは、これらの文字を通常の文字であるかのように端末に入力する方法は?

!#$^&*?[](){}<>~;'"\|<space><tab><newline>

改行が特殊な場所を知っているUnixシェルはありません。=@および%一部のコンテキストの一部のシェルでは特別です。
ステファンシャゼル16

@StéphaneChazelasUmm ...キャリッジリターン(^M)は^J、私へ​​の改行()のように動作します(Ubuntu 14.04、sh)。
EKons

いいえ、ターミナルドライバーは入力時に変換^M^Jれますが^M、シェルにとって特別なものではなく、引用符で囲む必要はありません。入力するecho ^V^M | hdと、0d文字が表示されます(0aにエコーが追加されます)。
ステファンシャゼラス

@StéphaneChazelasうーん...なんだか分からないけどhd、たぶんxxd16進ビューアとしてはもっといいかも。
EKons

どっちでも。持っていない場合は、POSIX od -tx1またはsed -n lvimのxxdを使用しますhd。いくつかのシステムはまた、持っていますcat -vtecat -A
ステファンChazelas

回答:


26

それはシェルに大きく依存します。詳細については、シェルのマニュアルを確認してください。

また、一部の文字は一部のコンテキストでのみ特別であることに注意してください。例えば、ほとんどのシェルでは、*?リストコンテキストでのみ特別なものは、POSIXまたはcshのようなシェルで、~単語など一部の文字を次の先頭にのみ特別です:。以下のための同じ=の中でzsh。一部のシェルで[は、に一致する場合(制限付き)のみが特別]です。

bashやなどの一部のシェルではyash、空白トークン区切り文字などの特殊文字もロケールによって異なります。

引用演算子(これらの文字の特別な意味を削除するため)も、シェルによって大きく異なります。

ボーンのようなシェル

Bourneのようなシェル(つまりsh、80年代以降、何らかのシステムで呼び出されることが知られているシェル)の概要:

ボーンシェル

特殊文字:

  • "\'&|;()^`<>$、スペース、改行、およびタブは、引用されていない場合、単純なコマンドラインでは特別です。
  • #(初期バージョンを除く)は、行頭または引用符で囲まれていないスペース、タブ、または&|()^<>;`
  • {そして}、それらがシェルキーワードであるという点でのみ特別です(したがって、コマンド位置にある単語のみ)。
  • *?[グロビング演算子として特別なので、リストコンテキストでのみ。の場合[、それ[...]はグロビング演算子です、[または]のみ特別な意味を取り除くために引用符で囲む必要があります。
  • =代入演算子として扱われるコンテキストでは特別です。つまり、単純なコマンドでは、引数の後に続かないすべての単語に対して(を除くset -k)。

引用演算子

  • \改行を除くすべての特殊文字を引用符で囲みます(\<newline>長い論理行を次の物理行に続ける方法であるため、そのシーケンスは削除されます)。バックティック\は、それらの内部に追加の複雑さを追加することに注意してください。これは、最初に閉じているバックティックをエスケープし、パーサーを支援するために使用されます。二重引用符の中では、\それ自体をエスケープするためにのみ使用できます"$および`\<newline>まだ行継続です)。ヒアドキュメント内、を除いて同じ"\hereドキュメント内の文字をエスケープする唯一の方法です。
  • "..."二重引用符は、すべての文字をエスケープするが、それ自体、\$`
  • '...' 単一引用符は、それ以外のすべての文字をエスケープします。

POSIXシェル

POSIXシェルは、Bourneシェルとほとんど同じように動作しますが、次の点が異なります。

ksh

以下を除いてPOSIXに似ています:

  • {string}文字列が引用符で囲まれていない場合,(または..場合によってはバージョンによっては)特別です。
  • ksh93には、追加の特別な引用演算子があります:$'...'複雑なルールです。すなわち、オペレータはまた、(いくつかのバリエーションで)発見されbashzshmkshおよびFreeBSDとbusyboxのsh
  • ksh93また、文字列がローカライズの対象となることを除いて$"..."同様に機能する引用演算子もあり"..."ます(ユーザーの言語に翻訳するように構成できます)。inをmksh無視$$"..."ます。

bash

ksh93、しかし:

  • シングルバイト文字ロケールでは、すべて空白(ロケールによる)文字は区切り文字(スペースやタブなど)と見なされます。つまり、一部のロケールで空白文字になる可能性がある場合に備えて、すべてのバイトを8番目のビットセットで引用する必要があるということです。
  • 対話型インスタンスのようにcsh履歴展開が有効になっている場合、!一部のコンテキストでは特殊であり、二重引用符は常にエスケープされません。また^、コマンドの先頭では特別です。

zsh

ksh93、しかし:

  • bashcsh履歴展開の場合と同じ注意
  • =単語の最初の文字として特殊です(に=ls展開されます/bin/ls)。
  • {また、}区切られていないときにコマンドグループを開いたり閉じたりすることもできます({echo text}Bourneのような作品のように{ echo text;})。
  • [単独での[場合を除き、aで閉じられていなくても引用符で囲む必要があります]
  • ではextendedglobオプション、有効#^および~演算子をグロブしています。
  • ではbracecclオプションで、{non-empty-string}特別です。
  • $"..." サポートされていません。
  • 特別な癖として、単語の先頭で(引用または展開されていても)?続く場合は特別ではありません%%?nameジョブの指定を可能にするため)
  • rcquotes(デフォルトでは有効になっていません)オプションは、1のように単一引用符を入力することができます''ラà内部の単一引用符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

    上記では、a \が前にあるスペース文字のみが文字通りに渡されprintfます。他のものは、シェルによってトークン区切り文字として扱われます。

  • 使用"..."まだパラメータ展開(可能にしながら、文字を引用するために$var$#${foo#bar}...)、(算術展開$((1+1))も、$[1+1]一部のシェルでは)とコマンド置換$(...)または古い形式を`...`。実際には、ほとんどの時間は、あなたが内側にそれらの拡張を入れたいですいずれの場合も二重引用符.withinを使用\"..."て、まだ特別な文字(ただしそれらだけ)の特別な意味を削除できます。
  • 文字列に文字が含まれている場合'でも'...'、残りに使用したり、またはまたは(利用可能な場合)の'ように引用できる他の引用メカニズムを使用できます。"'"\'$'\''

    echo 'This is "tricky", isn'\''t it?'
  • 最新の$(...)形式のコマンド置換を使用します。`...`Bourneシェルとの互換性のためにのみ、つまり非常に古いシステムで、変数の割り当てでのみ使用します。使用しないでください。

    echo "`echo "foo bar"`"

    BourneシェルまたはkshのAT&Tバージョンでは機能しません。または:

    echo "`echo \"foo bar\"`"

    これはBourneおよびAT&T kshで動作しますが、では動作しませんがyash、次を使用します:

    var=`echo "foo bar"`; echo "$var"

    すべてで動作します。

    二重引用符で移植可能にネストすることもできないため、変数を使用します。特別なバックスラッシュ処理にも注意してください:

    var=`printf '%s\n' '\\'`

    バックスラッシュ内$varにはバックスラッシュ処理の追加レベルがあるため(\、 `、および$(および"を除くyash

    var=`printf '%s\n' '\\\\'`

    または

    var=`printf '%s\n' '\\\'

    代わりに。

Cshファミリー

cshとtcshの構文は大きく異なりますが、Bourneシェルには共通の遺産があるため、まだ多くの共通点があります。

特殊文字:

  • "\'&|;()^`<>$、スペース、改行、およびタブは、引用されていない場合はどこでも特別です。
  • #(cshは#コメントリーダーとして導入されたシェルです)スクリプトの開始時、または引用符で囲まれていないスペース、タブ、改行の後に特別です。
  • *?[ グロビング演算子として特別なので、リストコンテキストで
  • {non-empty-string} 特別です(cshはブレース拡張を導入したシェルです)。
  • !そして^、歴史の拡大の一部として特別であり(再びcshの発明)、引用ルールは特別です。
  • ~ (チルダ展開もcshの発明)は、一部のコンテキストでは特別です。

引用演算子

これらはBourneシェルの場合と同じですが、動作が異なります。tcshは構文の観点からはcshのように動作しますが、cshの多くのバージョンには厄介なバグがあることがわかります。最新バージョンのtcshを入手して、おおよそ動作するバージョンのcshを入手してください。

  • \改行を除く1文字をエスケープします(Bourneシェルと同じ)。エスケープできる唯一の引用演算子です!\<newline>エスケープしませんが、コマンド区切り文字からトークン区切り文字(スペースなど)に変換します
  • "..."、自分自身を除くすべての文字をエスケープし$`改行と!。Bourneシェルとは異なり、\エスケープ$および`insideには使用できませ"..."んが\、エスケープ!または改行には使用できます(ただし、a !またはnewlineの前を除き、それ自体は使用できません)。リテラル!はで"\!"あり、リテラル\!"\\!"です。
  • '...' それ自身!と改行を除くすべての文字をエスケープします。二重引用符と同様に!、改行はバックスラッシュでエスケープできます。
  • コマンド置換は`...`構文を介してのみ行われ、確実に使用することはほとんどできません。
  • また、変数の置換は非常に不適切に設計され、エラーが発生しやすくなります。$var:qオペレータは、変数を含むより信頼性の高いコードを書くのに役立ちます。

概要

可能であれば、cshから離れてください。使用できない場合:

  • ほとんどの文字を引用する単一引用符。!と改行はまだ必要\です。
  • \ ほとんどの文字をエスケープできます
  • "..."その中にいくつかの展開を許可することができますが、改行文字やバックスラッシュ文字を埋め込む場合はかなりバグが多く、単一の引用符のみを使用し$var:qて変数を展開することをお勧めします。配列の要素を確実に結合するには、ループを使用する必要があります。

rc 家族

rcあるplan9シェルは、その子孫のようにesし、akangaUnixと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展開の場合)他のシェルとの重要な違いであり、`特別ではないことに注意してください)
  • # (コメント)引用符で囲まれていないスペース、タブ、改行、または ;&|^<>
  • *?(ただしではない[...])グロビング演算子

引用演算子

  • \改行を除く単一の特殊文字を引用しますが、Cエスケープシーケンス(\n\b...)イントロデューサーとしても機能することに注意してください。IOW \nは、引用符ではなくn改行です。
  • "..."それ自体を除くすべてを引用し$、バックスラッシュとバックスラッシュを使用してそれらをエスケープできます。\<newline>内部の行継続(削除)"..."です。
  • '...'それ自体とを除くすべてを引用し、\バックスラッシュを使用してそれらをエスケープできます。

すべてのコンテキストに特別なものだけを含めました(そのためc、同じよう\cc動作しc: command not found、STDERRには出力されません、など)そして、shここで話しています。また、これは「クリーンアップ」質問であることに注意してください。つまり、このようなキャラクターをすべてカバーするためにここにあるので、19以上の質問をする必要はありません。質問は、そのようなキャラクターごとに異なる質問が要求されるという事件のおかげで投稿されました。きっとここで整理したいと思います!
EKons

まあ、?[オペレータをグロブしているが、すべてのコンテキストで特別なものではなく、*ので、であるように思わecho *ひどくecho(何をエスケープしない)現在のディレクトリの内容をES。echo ?リテラル?をエコーし、リテラルをecho [エコーし[ます。また、]グロブするオベレーターでもあります。
EKons

1
@ΈρικΚωνσταντόπουλος:*グロブは、すべての非隠しファイル、?非隠し単一文字ファイル、[a-z]名前がaとzの間の単一文字であるファイルなどに拡張します。ファイルに一致しない場合(の場合のように?)、シェルに応じて、不一致エラーが発生するか、パターンがそれ自体に展開されます。いずれにせよ、自分自身に展開するシェル上であっても、ファイルに一致する可能性がある場合に備えて引用符で囲む必要があります。
ステファンシャゼラス16

しかし、グロブとしてではなく、*まだ何かに拡大しています。
EKons

@ΈρικΚωνσταντόπουλοςの*ように?、一致しない場合(*単独の場合は、現在のディレクトリに隠しファイルのみa*があり、名前がa...で始まるファイルがない場合)、自身(ほとんどのボーンのようなシェル)、または不一致エラー(発生させcshtcshfish、(警告)zshbash -O failglob別のパターンがあります、(または膨張し、いくつかのシェルの場合やnullglobオプションで何も、初期のUnixシェル)を膨張すると、そのcsh、tcsh、zsh -o cshnullglob、初期のUNIXシェルなど)。
ステファンシャゼラス

4

1.エスケープ

次のように、これらの文字をすべてa \でエスケープします(改行/キャリッジリターンでは機能しません)。

$ echo Use a \"\\\" symbol to escape characters.
Use a "\" symbol to escape characters.

2.二重引用符

次の"ように、テキスト全体を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!!!

3.シングルクォート

二重引用符と同じですが、特別なトークンはありません。

$ proof=proveit;echo 'This should not read "proveit": $proof'
This should not read "proveit": $proof

1
fish単一引用符ですべての文字を引用するBourneのようなシェルではなく、シェルの動作を説明しています(バックスラッシュは内では特別ではありません'...')。fish%も特殊文字であることに注意してください。
ステファンシャゼラス16

@StéphaneChazelas私はどのようにfish機能するのかわかりませんが、私の経験では、、echoes shecho '\\'echoesに\ なりecho '\''ます'
EKons

1
echo '\\'あなたがechoANSI Cエスケープシーケンスを展開するので\を出力します(いくつかのecho実装はそれを必要echo -e '\\'とします)。printf '%s\n' '\\'\\を出力します。
ステファンシャゼラス16

sh特定のシェルを識別するものではないことに注意してください。多くの異なる、しばしば互換性のないシェルがありshます。
ステファンシャゼラス16

@StéphaneChazelasわかりました、今すぐ変更します。ところで、\'一重引用符で囲まれた文字列の中に特別なトークンはありますか?
EKons
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.