2013-10-07 22 views
15

は、$'string'拡張を許可します。私のman bashさんの言葉:

$'string'の言葉は特別に扱われます。 単語はstringに展開され、バックスラッシュエスケープ文字はANSI C標準の指定に従って置き換えられます。次のように バックスラッシュエスケープシーケンスは、存在する場合、復号化される:
\aアラート(ベル)
\bバックスペース
\e
\Eエスケープ文字
\f
\n改行
\r復帰
\t水平タブ
\v垂直タブ
\バックスラッシュ
\'単一引用符
\"二重引用符
\nnn値である8進値nnn(1〜3桁)8ビット文字
\xHH 8ビット文字値は16進数値HH(1桁または2桁の16進数)
\cxコントロール - x文字

ドル記号が存在していなかったかのように拡張された結果は、単一引用符で囲まれています。

しかしなぜヌル文字に$'\0'$'\x0'を変換しないのですか?
これは文書化されていますか?理由はありますか?

> hexdump -c < <(echo -e '_\x0\x1\x2\x3_') 
0000000 _ \0 001 002 003 _ \n 
0000007 

私のbashのバージョンecho $'foo\0bar'が動作しないのはなぜ

$ bash --version | head -n 1 
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu) 

:(?それは機能や制限、あるいはバグです)

$ hexdump -c <<< _$'\0'$'\x1\x2\x3\x4_' 
0000000 _ 001 002 003 004 _ \n 
0000007 

echoは、期待される結果を与えますとしてecho -e 'foo\0bar'

+3

良い質問!多分それはPosixのことですか?がんばろう。 – shellter

+0

すべての答えをありがとう。 netcatを使用してSGCIインターフェースをサーバーにテストしているときに、同じ問題が発生しています。 SCGIヘッダーにはNUL文字があります。ここで、特にパイプの使用を提案した後、私は回避策を開発しました。私はNUL文字を必要とする8進数の377(ASCII 255)を使用し、それをnetcat xmlreq = '<?xml version = "1.0" encoding = "UTF-8"にパイプする直前にtrを通してパイプしますか?> system.client_version 'scgihdr = CONTENT_LENGTH $' \ 377 '$ {#のxmlreq} $' \ 377'SCGI $ '\ 377'1 $は' \ 377' $ {#1 scgihdr –

答えて

20

これは制限事項です。 bashでは、文字列値に内部NULバイトを含めることはできません。

Posix(およびC)文字列に内部NULを含めることはできません。例えば、文字列(強調追加)のPosix definitionを参照してください。

3.92文字列

最初のnullバイト含めで終了した文字の連続配列。

同様に、標準Cは文字列でNUL文字約合理明示的である:

§ 5.2.1p2&hellip; 0に設定されたすべてのビットを有するバイト、ヌル文字と呼ばれる、に存在しなければなりません基本実行文字セット。それは文字列を終了するにはに使用されています。この中

はPosixが明示的にファイル名(XBD 3.170)、または環境変数(XBD 8.1でNULの使用(および/)を禁じ "... NULLバイトで終わると考えている。"

NULを自由にbashパイプで渡すことができます。もちろん、bashを含むシェルコマンド言語は、文字列の同じ定義を1つのNULで終了する非NUL文字のシーケンスとして使用する傾向があります。 NULバイトを出力するプログラムの出力にシェル変数を代入するのを止めるものはありませんが、その結果は "不定"です。 Posixによると(XSH 2.6.3 "出力にヌルバイトが含まれている場合、その動作は指定されていません")。 bashのCエスケープ構文()を使用してNULを文字列に挿入しないと、NULは値を終了させません。実用的なノートで

、ユーティリティのstdinにNULを挿入しようとする2次の方法の違いを考慮してください。

$ # Prefer printf to echo -n 
$ printf $'foo\0bar' | wc -c 
3 
$ printf 'foo\0bar' | wc -c 
7 
$ # Bash extension which is better for strings which might contain % 
$ printf %b 'foo\0bar' | wc -c 
7 
+1

グレート情報を-nエコー。 Re: "NULを出力するプログラムの出力にシェル変数を割り当てるのを止めるものは何もありません" - 変数の値が常に最初に見つかったNULで切り捨てられることを指摘する価値があります。 Re "bashのバックスラッシュエスケープシーケンス($ '\ 0')のいずれかを使用して文字列にNULを挿入すると、値の終了が終了します。 - 明確にする: '$ '\ 0''を_another_文字列に挿入すると、文字列全体が終了することはありませんが、単純に' $' \ 0 "を無視します。例えば ​​'a $ '\ 0'b' - >' ab'; '\ 0' _inside_' $ '...' 'しかし、_will_はその文字列を切り捨てます。例えば、 '$ 'a \ 0b'' - >' a'。 – mklement0

+1

@ mklement0:ええ、私は2年前に間違っていました。ありがとう。修正されました、今、私は信じています。 – rici

+0

更新していただきありがとうございます。コマンド出力を変数に代入する: 'bash'変数の値が内部的にCの文字列として格納されているので、決してNULを含むことはできません。しかし、(a) 'var = $(...)'を区別する価値があります。その場合、すべてのNULは単純に_stripped_なので、定義によって割り当てられた値にはNULは含まれませんが、_all other_文字(b) 'read -rd '' var <<(....)'で、入力にはNULが含まれているかもしれませんが、 'read'は最初のNULを越えて読むことができません。最初のNUL。 – mklement0

3

これはヌル文字ですが、それはあなたが意味するものによって異なります。

ヌル文字は、空の文字列を表します。空の文字列は、その文字列を展開するときに表示されます。それは特別なケースであり、私はそれがドキュメントによって暗示されているとは思うが、実際には述べていない。

Cバイナリでは、'\0'は文字列を終了し、それ自体は空の文字列も表します。 BashはC言語で書かれているので、おそらくそれに続くでしょう。

編集:POSIXは、いくつかの場所でヌル文字列を記述しています。その最初のバイトヌルバイト文字列

3.146空の文字列(またはヌル文字列):それはとしてNULL文字列を定義し、「基本定義」で。

5

しかし、なぜbashはヌル文字に$'\0'$'\x0'を変換しないのですか?

null文字は文字列を終了するためです。

$ echo $'hey\0you' 
hey 
関連する問題