プロが教えるわが家の防犯対策術!

aaa下の中身を圧縮して test.tar.gz を作り、これを bbb下に移動させるのを
以下のようにshで行っています。

#!/bin/bash
cd /aaa
tar zcf test.tar.gz *
mv test.tar.gz /bbb

これを、なにか圧縮コマンドのオプションを使って
圧縮元と圧縮ファイル作成先を指定して、1行で済ますことは出来ますか?

tar zcf /bbb/test.tar.gz /aaa/*  
を試してみましたが、

-bash: /bin/tar: Argument list too long

と出てしまいます。ご教授宜しく御願いいたします。

A 回答 (6件)

ようやくやりたいことがわかってきました。

そういうことであれば、tarするファイル名はパスを含めちゃ駄目です。

<(...) が使えるなら、

tar czf /bbb/test.tar.gz -C /aaa -T <(cd /aaa;/bin/ls -1)

だめなら、

(cd /aaa; /bin/ls -1 > /tmp/filelist )
tar czf /bbb/test.tar.gz -C /aaa -T /tmp/filelist

#1の人が、作成時には -C オプションが効かないと書いてますけど、私の手元だと効きますね(Fedora9)。
    • good
    • 0
この回答へのお礼

両方、できました!ありがとうございました。
-Cオプション効きました。

お礼日時:2008/11/08 01:40

tar の -T オプションで、アーカイブするファイル名を、コマンドラインでなくファイルで指定できます。



cd /aaa
ls -1 > /bbb/filelist # アーカイブしたいファイル名を1行ずつ書く
tar czf /bbb/test.tar.gz -T /bbb/filelist

またはcdせずに、

find /aaa -maxdepth 1 -type f > /bbb/filelist # findのオプションは希望に応じて適当に
tar czf /bbb/test.tar.gz -T /bbb/filelist

後者はワークファイルを作らずに bash の <( ) というコマンド置換を使って、こうも書けます。
tar czf /bbb/test.tar.gz -T <(find /aaa -maxdepth 1 -type f)
ただ、これはエラーになる環境もあるようです。Fedora9では出来ました。

>(| xargs tar rfz /bbb/test.tar.gz のように)、xargs: tar: terminated by signal 6 というエラーが出ました。

引数が長すぎる対処として、一度のtarでアーカイブするファイルをコマンドラインの制限長まで減らして何度かに分けてアーカイブするというのがxargsを使う方法ですが、
tar の r オプションはファイルにどんどん追加していくので、圧縮されていては追加できないと言うことでしょう。

この回答への補足

-Tオプションをつけても、圧縮元ファイルを絶対パスで指定すると
以下のようなエラーになりました。

tar: Removing leading `/' from member names

/aaa/の中身は
1 (/aaa/1)
2 (/aaa/2)
なのですが、
/bbb に test.tar.gz は出来ますが、これを解凍してみると
以下のように、圧縮したいデータの絶対パスの
ディレクトリー構造そのままが出来てしまいました。

/bbb/aaa/1
/bbb/aaa/2

環境はredhat linux4 です。

>tar の r オプションはファイルにどんどん追加していくので、圧縮されていては追加できないと言うことでしょう。

なるほど、そういうことだったんですね。ありがとうございました。

補足日時:2008/11/07 12:14
    • good
    • 0

*だと、.で始まるファイルが含まれないので


tarで .(カレントディレクトリ指定) のほうがいいんじゃないですか?
    • good
    • 0
この回答へのお礼

なるほど、ありがとうございます。

お礼日時:2008/11/07 05:01

>>・* だとすべてのファイルをアーカイブするとは限らない


>そうなんですか、ディレクトリー下のファイル全部を一括で指定するにはどうしたらいいんでしょう
ANo.1の人が*でなく.を使った意味を理解しましょう

xargs を使うなら
find /aaa/ -type f | xargs tar rf test.tar ; gzip test.tar
ただしGNU tarでないとtarファイルがない状態からrオプションの使用は出来ません

この回答への補足

>ANo.1の人が*でなく.を使った意味を理解しましょう

ということで、以下でも出来ました。

cd /aaa; echo * | xargs tar rf /bbb/test.tar; cd /bbb; gzip test.tar

ところで tar するとき、zオプションで一気に tar.gz にしようとおもったのですが、(| xargs tar rfz /bbb/test.tar.gz のように)、xargs: tar: terminated by signal 6 というエラーが出ました。教えて頂いたように、まず tar にして、gzip にするのと、どのように違っているのでしょうか。

補足日時:2008/11/06 00:27
    • good
    • 0

「圧縮元と圧縮ファイル作成先を指定する」ことと argument list too long とは関係ありません. 区別してください. argument list too long の意味は (ただの英語なので) 推測すること.


とりあえず tar の f ではディレクトリも指定できるので
cd /aaa
tar zcf /bbb/test.tar.gz *
でいいし, これを 1行にするだけなら ; で区切って
cd /aaa; tar zcf /bbb/test.tar.gz *
とすればいい.
ところで,
・(tar によっては)「アーカイブするファイルを絶対パスで指定するのは危険」
・* だとすべてのファイルをアーカイブするとは限らない
・cd /aaa; tar zcf /bbb/test.tar.gz * と cd /; tar zcf /bbb/test.tar.gz /aaa/* は意味が違う
んだけど, その辺は大丈夫?
実は
tar zcf /bbb/test.tar.gz /aaa
とか
tar zcf /bbb/test.tar.gz -C /aaa .
でよかったりして....

この回答への補足

>・(tar によっては)「アーカイブするファイルを絶対パスで指定するのは危険」

やってみると、/aaa/* の * を圧縮するのではなく、
/aaa/* というディレクトリー構造をそのまま圧縮しており、
解凍すると、このままの構造が展開されてしまいました。
-Cオプションでは、変なエラーが出て進みませんでした。

>・* だとすべてのファイルをアーカイブするとは限らない

そうなんですか、ディレクトリー下のファイル全部を一括で指定するにはどうしたらいいんでしょう

>・cd /aaa; tar zcf /bbb/test.tar.gz * と cd /; tar zcf /bbb/test.tar.gz /aaa/* は意味が違う
んだけど, その辺は大丈夫?

大丈夫です。

argument list too long  は、仰るとおり、別の問題で、
圧縮しようとしているファイルが多すぎるために出るエラーです。
xarge を使って回避する方法があったと思いますが、引き続き
みなさんのご回答をお待ちしています。

補足日時:2008/11/05 20:05
    • good
    • 0

展開時なら、-Cオプションが使えるのですが、アーカイブ時では使えないようです。



(cd /aaa ; tar zcf /bbb/test.tar.gz .)

では駄目でしょうか。

参考URL:http://www.astro.phys.s.chiba-u.ac.jp/~miyaji/UN …

この回答への補足

cd /aaa; tar zcf /bbb/test.tar.gz *
で1行にまとまり、動作オッケーでした。ありがとうございます。

argument list too long というエラーが出るのは、また別の問題で、tarしようとしているaaa下に大量のディレクトリーとファイルがあるためです。

‘argument list too long‘を回避するために
xarge を使った方法があったと思いますが、引き続き
皆さんのご回答をお待ちしています。

補足日時:2008/11/05 20:01
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!