シェルで1行で複数のコマンドを実行する


388

たとえば、ファイルが/templates/appleあり、

  1. それを2つの異なる場所に置いてから
  2. オリジナルを削除します。

なので、AND /templates/appleにコピーしてから 元を削除したいと思います。/templates/used/templates/inuse

cpこれを行うための最良の方法は次のとおりrmですか?それとももっと良い方法がありますか?

私はそれをすべて1行で実行したいので、次のようになると思います。

cp /templates/apple /templates/used | cp /templates/apple /templates/inuse | rm /templates/apple

これは正しい構文ですか?

回答:


792

|コマンドの出力を別のコマンドに送るために(パイプ)を使用しています。あなたが探しているのは&&、前のコマンドが成功した場合にのみ次のコマンドを実行する演算子です:

cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apple

または

cp /templates/apple /templates/used && mv /templates/apple /templates/inuse

(非網羅的に)bashのコマンドオペレーター/セパレーターを要約するには:

  • |stdoutあるコマンドの標準出力()を別のコマンドの標準入力にパイプ(パイプライン)します。stderr何があっても、デフォルトの宛先に移動することに注意してください。
  • |&stdoutstderr1つのコマンドの両方を別のコマンドの標準入力にパイプします。非常に便利で、bashバージョン4以降で使用できます。
  • &&&&前のコマンドが成功した場合にのみ、右側のコマンドを実行します。
  • ||||以前のコマンドが失敗した場合にのみ、右側のコマンドを実行します。
  • ;;前のコマンドが成功したか失敗したかに関係なく、常に右側のコマンドを実行します。ない限りは、set -e以前に発生した、呼び出されたbashエラーで失敗します。

6
賛成。公式ドキュメントgnu.org/software/bash/manual/bash.html#Lists
flow2k

78

なぜcpロケーション1に、次にmvロケーション2にしないのですか。これにより、オリジナルが「削除」されます。

そして、いいえ、それは正しい構文ではありません。|1つのプログラムからの出力を「パイプ」して、次のプログラムの入力に変換するために使用されます。必要なのは;、複数のコマンドを分離することです。

cp file1 file2 ; cp file1 file3 ; rm file1

次のコマンドを開始する前に個々のコマンドを成功させる必要がある場合は、&&代わりに次のコマンドを使用します。

cp file1 file2 && cp file1 file3 && rm file1

このように、いずれかのcpコマンドが失敗した場合、はrm実行されません。


10

それcp A B; rm Aは正確mv A Bです。実際にバイトをコピーする必要がないので(宛先が同じファイルシステムにあると仮定して)、ファイルの名前を変更するだけで、速度も速くなります。あなたが望んでいるのはcp A B; mv A C


7

別のオプションはCtrl+V Ctrl+J、各コマンドの最後に入力することです。

例(置き換え#Ctrl+V Ctrl+J):

$ echo 1#
echo 2#
echo 3

出力:

1
2
3

これにより、前のコマンドが失敗したかどうかに関係なく、コマンドが実行されます。

と同じ: echo 1; echo 2; echo 3

失敗したコマンドの実行を停止する場合&&は、最後の行を除いて各行の終わりに追加します。

例(置き換え#Ctrl+V Ctrl+J):

$ echo 1 &&#
failed-command &&#
echo 2

出力:

1
failed-command: command not found

でまたは代わりにzsh使用することもできますAlt+EnterEsc+EnterCtrl+V Ctrl+J


3

これを試して..

cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apple


2

パイプを使うのは奇妙に思えます。とにかく、論理andBash演算子を使用する必要があります。

$ cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apples

場合はcpコマンドが失敗し、rm実行されません。

または、forループとを使用して、より複雑なコマンドラインを作成できますcmp

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.