スクリプトで、#!/ bin / bash
を入力すると 上部では、これは正常に機能します:
cp directory / {foo、bar} destination
ただし、shを使用すると、「そのようなファイルまたはディレクトリはありません」というエラーが発生します。 shでは、1つのコマンドで同じ最終目標を達成する別の方法はありますか?
承認された回答:
ご覧のとおり、すべてのシェルがブレースの拡張をサポートしているわけではありません。
方法1:2つの別々のパス(つまり、プレフィックスを2回書き込む)
目標が本当に1つのコマンドでそれを実行することである場合、簡単な方法は次のとおりです。
cp directory/file1 directory/file2 destination
cp
コマンドは、複数のソース引数とそれに続く宛先引数をサポートします。実際、それがBashで機能するコマンドで起こっていることです。 Bashはブレース拡張を実行します。これにより、使用していたコマンドが上記のコマンドに変換されます。つまり、 cp directory / {file1、file2} destination
を実行すると Bashでは、 cp
コマンドに中括弧が表示されることはありません。
そのようなコマンドは単純で理解しやすいものです。検討することをお勧めします。
方法2:プレフィックスの変数
ただし、目標が繰り返しを回避することである場合 特にdirectory
の場合は、そうしない方がよいでしょう。 実際には長い道のりです。結局のところ、スクリプトの後半でパスを編集する必要がある場合は、両方のオカレンスに変更を加える必要があります。
ディレクトリ
を保存できます (または、おそらくより長いパス)シェル変数内:
dir='directory'
cp "$dir/file1" "$dir/file2" destination
$ dir
パラメータ展開です。シェルはそれを変数dir
に保持されている値に置き換えます 。パラメータ展開を使用する場合は、省略しないでください 二重引用符-フィールド分割とグロビングを実行するまれな場合を除きます。 (これはBashにも当てはまります。)
これは2つのコマンドですが、実際の目標が自分自身を繰り返さないようにすることである場合は、それが必要な場合があります。あなたは書くことができます
dir='directory'; cp "$dir/file1" "$dir/file2" destination
「1つのコマンド」にするためですが、それは短くはなく、少し読みにくくなっています。
(;
を単純に削除することはできないことに注意してください そこの。実行の結果は整形式のコマンドになりますが、それはあなたが望むことをしません。 cp
を実行します コマンド、 dir
という環境変数を渡します 値がdirectory
cp
に コマンドの環境。 シェルなので cp
ではありません dir
を展開するコマンド 、これは機能しません。)
方法3: cd
プレフィックスへのig
この操作を実行した後、スクリプトが他に何もしていない場合、または後続のコマンドの現在のディレクトリが何であるかは問題ではない場合は、 if destination
絶対パスです 、次を使用できます:
cd directory
cp file1 file2 destination
ただし、スクリプトがそのディレクトリから実行することでメリットが得られる後続のアクションを実行する場合、またはそのディレクトリから実行するときにスクリプトをより簡潔に、または単純に記述できる場合を除いて、スクリプトを作成することはお勧めしません。スクリプトが実行されるディレクトリが意味がある場合を除きます。 スクリプトの目的に応じて、スクリプトに依存すると、スクリプトの推論が難しくなる可能性があります。さらに、 cd
コマンドは成功しますが、 cp
コマンドが失敗すると、結果のエラーメッセージが完全に点灯しない場合があります。代わりに、 cd
の手法について説明します。 インタラクティブに役立つパターンであるため、ソースディレクトリに移動します。 シェルの使用。
(Hannuが指摘したように、(
内には任意の数のコマンドをまとめることができます )コード> それらをサブシェルで実行し、
cd
の効果を含むシェル環境に変更します 、コマンドの実行後は持続しません。これは広く有用な手法であり、私が言及しなかったのはかなりの省略でした。ただし、これによって destination
の相対パスを持つことに関連する問題が軽減されるわけではないことに注意してください。 。)
cd
の場合は注意してください コマンドが失敗しても、他のコマンドは通常実行されます。これにより、コピーしたくない別のファイルがコピーされたり(スクリプトの実行元のディレクトリに同じ名前の他のファイルがある場合)、紛らわしいエラーメッセージが表示されたりする可能性があります。だからあなたは好むかもしれません:
cd directory && cp file1 file2 destination
&&
最初のコマンドが成功した場合にのみ、2番目のコマンドを実行します。それでも、最初のコマンドを実行した場合の効果は元に戻らないことに注意してください。すべてが実行された後も、ディレクトリ
にいます。 、(
を使用してサブシェルで実行した場合を除きます )コード> 。