STDINを介して任意のデータを渡し、通常のファイルのように圧縮する方法を探しています。
私はこれを試しました
$ echo test | tar -cf test.tar /dev/stdin
test.tar
これにより、内容を含むファイルが提供されますdev/stdin
。ファイルstdin
はリンクです/proc/self/fd/0
。
私が望むのは、dev/stdin
TARファイル内にtextを含む一般的なファイルがあるということですtest
。次のような状況でも同様の状況が発生します。
$ tar -cf test.tar <(echo test)
しかし、名前は異なります。
これは可能ですか?
答え1
私の考えでは、ここでやりたいことができないと思います。アプローチの問題は、tar
ファイルとディレクトリツリーを処理し、次のコマンドを提供しないことです。
$ echo test | tar -cf test.tar /dev/sdtin
次のサブシェルを使用して一時ファイルの文字列を「ラップ」しようとしても、
$ tar -cf test.tar <(echo test)
コンテンツがまだ TAR 圧縮に次の一時ファイル記述子を使用していることを確認できます。
$ tar tvf test.tar
lr-x------ vagrant/vagrant 0 2018-08-04 23:52 dev/fd/63 -> pipe:[102734]
文字列を圧縮したい場合は、ファイルコンテキストに入れる必要があります。したがって、次のようにする必要があります。
$ echo "test" > somefile && tar -cf /tmp/test.tar somefile
TARファイルにそのファイルが存在することを確認できます。
$ tar tvf /tmp/test.tar
-rw-rw-r-- vagrant/vagrant 5 2018-08-05 00:00 somefile
tarを使用したデータのコピー
長い間Unixを使用してきたほとんどの人は、おそらく次のようなパターンを見たことがあります。
$ (cd /; tar cf - .)|(cd /mnt/newroot; tar pxvf -)
私は過去にある場所から別の場所にデータをコピーするためにこれを使用しました。 SSH経由でも使用できます。他の方法については、U&L Q&Aで次のように議論されています。busyboxを使用したルートディレクトリツリーの複製。
バックアップ/
ハードドライブ全体をバックアップしたい場合でも、この方法を使用できます。
$ sudo tar -cvpzf backup.tar.gz --exclude=/backup.tar.gz --one-file-system /
引用する
答え2
転送する最終サイズ(バイト)がわかっている場合は、tarファイルをストリームとして生成できます。その後、データストリームの前に最初の512バイトヘッダーを生成し、その後に末尾のパディングを生成する必要があります。tar
ファイルの種類が異なるため、ファイルの正確なバリエーションによって異なります。次の手順が役に立ちます。
データストリームと同じサイズの穴ファイルの作成
$ dd if=/dev/zero of=mystream bs=1 count=0 seek=$SIZE
この
mystream
ファイルは「ホール」ファイルで、データストリームと$ SIZEサイズが同じように見えますが、実際にはディスク容量を占有しません。指定されたサイズのファイルの
tar
ヘッダーを作成するために使用されます。mystream
$ tar cf - mystream | head -c 512 > header
脆弱性
tar
のないファイルを生成するには、最初の512バイトを除いてすべてを削除することが重要です。その後、誤ってコピーされないように穴ファイルを削除します。$ rm mystream
512個のブロックを埋めるパディングテールを作成します。
$ head -c $((echo "scale=0; 512 - $SIZE % 512" | bc )) > trailer
ヘッダーとトレーラーを含む$ STREAM(サイズ$ SIZE)のタールストリームを作成します。
$ cat header $STREAM trailer
これを標準出力以外の場所にストリーミングすることもできます。
答え3
を使用すると、パイプの代わりに一時ファイルを使用するプロセス代替形式をzsh
使用できます。 GNUオプションを=(...)
使用すると、アーカイブメンバーの名前を変更できます。tar
--transform
tar --transform='s/.*/test-file/' -zcf file.tar.gz =(echo test)
0600権限とcontent権限を持つメンバーをfile.tar.gz
作成します。test-file
test\n
bash
(または)を使用して、zsh
次のことができます。
tar --transform='s/.*/test-file/' -zchf file.tar.gz /dev/stdin <<< "$(echo test)"
Here-stringsはこれらのシェルでも一時ファイルを使用します。ただし、コマンド置換は削除されることに注意してください。すべて末尾の改行と追加一つ戻るとbash
NULバイトストリップにあります。