「ディレクトリの変更」オプションを使用してtarグロビングを機能させる方法


8

私は次のディレクトリ構造を持っています:

base/
   files/
   archives/
   scripts/

スクリプトをから実行しscripts/、一致results.*.logするファイルをfiles/のgzip圧縮されたtarアーカイブに圧縮しますarchives/

私は次のコマンドを試しています:

tar czfC ../archives/archive.tar.gz ../files results.*.log

しかし、私は得る

tar: results.*.log: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors

ながら

tar czfC ../archives/archive.tar.gz ../files results.a.log

期待どおりに動作します。また

tar czf ../archives/archive.tar.gz ../files/results.*.log

プレフィックスfiles/をファイルに追加し、警告を発することを除いて、私が望むように動作します:

tar: Removing leading `../' from member names

したがって、私の結論は、tarこの-Cオプションを使用するとグロビングが正しく機能しないことです。これを簡単に機能させる方法についてのアドバイスはありますか?

回答:


3

より移植性の高い方法で記述します。

(cd ../files && tar cf - results.*.log) | 
  gzip -9 > ../archives/archive.tar.gz

グロブは、cd発生する前に、現在のディレクトリで引き続き解釈されます。
フォンブランド2013

1
@vonbrand、いいえ、もちろんありません。&&;改行のようなもので、2つのコマンドを区切ります。これは、を実行した後cd、グロブが前のディレクトリのファイルを展開すると言っているようなものです。
ステファンChazelas

あなたが正しいです。人は学習を終えることはありません。
フォンブランド2013

5

「tar globbing」はなく、シェルによってグロビングが行われます。そして、シェルはで機能tar -C somedirすることをsomedir知りません。グロブは現在のディレクトリに展開されます。


実際、results.a.logスクリプトが実行されるディレクトリに存在する場合、スクリプトは機能します。しかし、私はこれがなぜ起こるのか理解していません、なぜなら-C変更ディレクトリを表すので、現在のディレクトリはであるはずresults.a.logです あなたが解決策を提供しないので、私はあなたの答えを受け入れることができません。
ユヴァル2013

2
シェルはコマンドを受け取り、現在のディレクトリのglobを展開し、上記の引数を作成し、tarプログラムを起動します。これにより、ディレクトリが大幅に変更されます。問題を "解決"できません。申し訳ありません。唯一の方法は、グロブを作成するディレクトリに移動するか、ディレクトリでグロビングを実行して、その結果をファイルまたは変数に保存することです。
フォンブランド2013

1

あなたはさせることができfindグロブを行うとする「ディレクトリ変更」オプションを省略しtar除去することにより、files/tarファイルを作成する前に接頭辞を。

--no-recursionオプションはtar何のディレクトリをアーカイブするつもりはありませんので、任意です。

cd base/scripts

# gnutar
# printf '%s\000' ../files/results.*.log |  # find alternative
find ../files -maxdepth 1 -type f -name "results.*.log" -print0 | 
   gnutar --transform="s|^\.\{0,1\}\.\{0,1\}/\{0,1\}files/||" -cf - --null --no-recursion -T - | 
   gzip -9 > ../archives/archive.tar.gz
gnutar -tf ../archives/archive.tar.gz | nl
gnutar -xzf ../archives/archive.tar.gz

# bsdtar
find ../files -maxdepth 1 -type f -name "results.*.log" -print0 | 
   bsdtar -s "|^\.\{0,1\}\.\{0,1\}/\{0,1\}files/||" -cf - --null --no-recursion -T - | 
   gzip -9 > ../archives/archive.tar.gz
bsdtar -tf ../archives/archive.tar.gz | nl
bsdtar -xzf ../archives/archive.tar.gz

0

やっと使った

tar czfC ../archives/archive.tar.gz ../files `find ../files/results.*.log -printf "%f\n"`

それはあなたのために働くかもしれませんが、それを行うにはかなり複雑な方法です。さらに、空白などの特殊文字を含むファイル名では機能しません。回答で提案されている正気な方法の1つを使用してください。
Gilles「SO-邪悪なことをやめなさい」

0

それを行う方法は、次のようなものを書くことです:

#!/bin/sh

cd ../files
tar zcf ../archives/archive.tar.gz results.*.log
cd ../scripts

0

グロビングを行うのはtarではなく、シェルです。最初にシェルにグロビングを行うように指示し、次にtarにディレクトリを変更するよう指示します。tarは元のディレクトリに関連するファイル名のリストを受け取っているため、これは機能しません。

はるかに簡単な解決策は、シェルにディレクトリを変更させることです。インタラクティブに:

cd ../files
tar czf ../archives/archive.tar.gz  results.*.log
cd -

スクリプトで:

(
  cd ../files &&
    tar czf ../archives/archive.tar.gz  results.*.log
)

または

(
  cd ../files &&
    tar czf -  results.*.log
) >../archives/archive.tar.gz
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.