2009-05-11 12 views
7

は、私はそのように見える簡単なテストbashスクリプトを持っている:コマンドラインVSスクリプトファイル:rsyncのと--exclude

#!/bin/bash 

cmd="rsync -rv --exclude '*~' ./dir ./new" 
$cmd # execute command 

私はそれがまた~で終わるファイルをコピーするスクリプトを実行すると、私はそれらを除外することを意味しました。非常に同じrsyncコマンドをコマンドラインから直接実行すると、うまくいきます!なぜ誰かがbashスクリプトを動作させる方法を知っていますか?

Btwも私は--exclude-fromと一緒に作業できることを知っていますが、これはどういうふうに動作するのか知りたいのです。

答えて

5

のeval試してみてください。問題は、スクリプトでそれを実行している、それはあなたが変数にコマンドを入れ、その後、拡張変数を実行することだということではありません

#!/bin/bash 

cmd="rsync -rv --exclude '*~' ./dir ./new" 
eval $cmd # execute command 
0

あなたは(manページにaccoding)のような単純な--eclude '~'を使用することができます。

  • パターンが/それはファイルの 階層内の特定の場所に固定されているで始まる場合、そうでありません は、 パス名の末尾に一致します。これは、正規表現の先頭にある ^に似ています。したがって、 "/ foo" は の "転送のルート"( グローバルルールの場合)またはマージファイルの ディレクトリの場合(ディレクトリごとのルールの場合) "foo"という名前と一致します。 アルゴリズムが を上から下に再帰的に適用するため、修飾されていない "foo"は、 という名前の "foo"とツリー のどこにでも一致します。 は、各パスコンポーネントが の末尾になるように、 となるように動作します。 unchchored "sub/foo"は、 のどの時点でも、 "foo"が見つかった階層で一致するでしょう "sub"という名前のディレクトリ内にあります。 転送のルートに一致するパターン を指定する方法の詳細については、 埋め込み/除外パターンのセクションを参照して、完全な の説明を参照してください。
  • パターンが/で終わる場合は、 通常ファイル、シンボリックリンク、またはデバイスではなく、ディレクトリにのみ一致します。
  • rsyncがパターン これら3つのワイルドカード 文字のいずれかが含まれているかどうかをチェックすることにより、単純な文字列の一致とワイルドカード マッチングを行うことの間で選択:、「*」、および「[」「?」。
  • '*'は任意のパスコンポーネントに一致しますが、スラッシュで停止します。
  • 「**」を使用して、スラッシュを含む何でも一致させます。
4

を。そして変数の展開はすでに引用符の削除が行われた後に起こるので、除外パターンの前後の一重引用符は決して削除されません。したがって、rsyncは名前が '〜で始まり〜で終わるファイルを除外します。、この問題を解決するだけでパターン(全部が二重引用符ですでにあるので、彼らが必要とされていない)の周りに引用符を削除するには:

#!/bin/bash 

cmd="rsync -rv --exclude *~ ./dir ./new" 
$cmd # execute command 

...といえば、なぜあなたはコマンドを入れています変数を実行する前に?一般的に、これは、コードを必要以上に混乱させ、奇妙な解析(これよりも奇妙なもの)を引き起こすのに適しています。だから約:

#!/bin/bash 

rsync -rv --exclude '*~' ./dir ./new 
+0

これを変数に入れてデバッグします。私は一重引用符なしで始まり、それはさらに悪化しました(実際には、私がそこに置く理由です)。例えば。 "rsync -r --exclude *〜.dir ./new"を "rsync -r --exclude foo〜bar〜foobar.sh〜./dir ./new"に展開しました – Chris

+0

一重引用符で試しましたか?変数に入れることなく(私の2番目の勧告のように)?それは正常に動作するはずです(と私はそれをテストしたときに見えた)。 –