このドキュメントでnull文字をどのようにエスケープできますか? (バッシュおよび/またはダッシュ)

このドキュメントでnull文字をどのようにエスケープできますか? (バッシュおよび/またはダッシュ)

shuf --zero-terminatedここでは、ドキュメントを使用して複数行の文字列を操作したいと思います。

答え1

Bashとdashのここのドキュメントはこれをサポートしていません。 NULL は変数に格納できず、コマンド置換から削除され、NULL を文字通り書き込むことができず、この資料では ANSI-C 引用符を使用できません。両方のシェルはヌルフレンドリーではなく、入力されると通常は(Cスタイル)文字列終端として扱われます。

いくつかのオプションがあります。物理ファイルの使用、zsh 使用、プロセス置換使用、または標準入力使用。


あなたできるnull フレンドリーな zsh で必要な操作を正確に実行します。

zsh% null=$(printf '\x00')
zsh% hexdump -C <<EOT
heredoc> a${null}b${null}
heredoc> EOT
00000000  61 00 62 00 0a                                    |a.b..|
00000005

shufheredocsには暗黙的に終了する改行文字がありますが、これは理想的ではないかもしれません(最後のnull値の後に追加のフィールドになります)。


Bashの場合は、次のものを使用できます。プロセスの交換null値をインラインで結合printfまたは生成するheredocとほぼ同じです。echo -e

bash$ hexdump -C < <(
printf 'item 1\x00item\n2\x00'
)
00000000  69 74 65 6d 20 31 00 69  74 65 6d 0a 32 00        |item 1.item.2.|
0000000e

これらのファイルはしばしばシェルによって実際のファイルに密かに保存されるため、これは必ずしもここにある文書とまったく同じではありません(検索の可能性などに重要です)。

終了する改行文字を抑制したい場合もあるため、コマンド内でheredocを使用することもできません。printf/echo -ne出力をきめ細かく制御することは安全でなければなりません。


ダッシュではプロセス置換を実行できませんが、すべてのシェルはサブシェルから標準入力をパイプできます。

dash$ (
printf 'item 1\x00'
printf 'item\n2\x00'
) | hexdump -C
00000000  69 74 65 6d 20 31 00 69  74 65 6d 0a 32 00        |item 1.item.2.|
0000000e

shufデフォルトは標準入力から読むことをお勧めします。したがって、私が理解したのは、これがあなたの特定のユースケースに適していることです。より複雑なコマンドがある場合は、パイプの右側にある場合は、スコープに関する混乱を招く可能性があります。


printf最後に、このファイルを使用して、ここで説明されている内容の代わりに実際のファイルにデータを書き込むことができます。このオプションは以下に含まれています。もう一つの答え。後でファイルを整理したい場合があります。mktempあるいは、同様のもの(リアルタイムのセキュリティ上の問題がある場合)を使用して安全なファイル名を作成できます。

答え2

みんなありがとうございます。皆さんが持っていることに基づいて回答を投稿します。おそらくそれが私にとって最も良いでしょう。

スクリプトはbashとdashでうまく動作し、実際のファイルやファイルは必要ありません。Bashでプロセスを置き換える%s、さらに遅い外部プログラム呼び出しを必要とせず、次のエンティティのエスケープ問題について心配する必要もありません。印刷物しかし、それでもシェル自体の文字列エスケープに注意を払う必要があります。

#!/bin/sh
printf '%s\0' "[tag1]
key1=value1
key2=value2
[/tag1]
" "[tag2]
key3=value3
key4=value4
[/tag2]
" | shuf --zero-terminated
#also see man printf(1)

~のためshufのみ(ここの一般文書を置き換える意図はありません):

shuf --echo "[tag1]
key1=value1
key2=value2
[/tag1]" "[tag2]
key3=value3
key4=value4
[/tag2]"

答え3

私はheredocであなたが望むことができないと思います。ただし、echo次の例のように使いやすいです。

$ cat demo
#!/bin/bash

echo -ne "one\0" > outfile
echo -ne "two\0" >> outfile
echo -ne "three\0" >> outfile

$ ./demo
$ od -a outfile
0000000   o   n   e nul   t   w   o nul   t   h   r   e   e nul
0000016
$ 

答え4

私は結局「トリック」を使うようになった

cat <<EOS | cat - <(echo -e "\0") | most
{
  "version":"1.1",
  "gelf-toekn":"SOMETHIN",
  "host": "api.ivsdev.net",
  "short_message": "foo",
   "full_message": "bar",
   "level": 1
}
EOS

最初の区切り文字 cat は 2 番目の区切り文字 cat にパイプされ、null バイトに関連付けられます。

関連情報