Menjalankan banyak perintah dalam satu baris dalam shell

388

Katakanlah saya punya file /templates/appledan saya mau

  1. letakkan di dua tempat berbeda lalu
  2. hapus yang asli.

Jadi, /templates/appleakan disalin ke /templates/usedDAN /templates/inuse dan kemudian setelah itu saya ingin menghapus yang asli.

Apakah cpcara terbaik untuk melakukan ini, diikuti oleh rm? Atau ada cara yang lebih baik?

Saya ingin melakukan semuanya dalam satu baris jadi saya pikir akan terlihat seperti:

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

Apakah ini sintaks yang benar?

John Redyns
sumber

Jawaban:

792

Anda menggunakan |(pipa) untuk mengarahkan output dari suatu perintah ke perintah lain. Apa yang Anda cari adalah &&operator untuk menjalankan perintah berikutnya hanya jika yang sebelumnya berhasil:

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

Atau

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

Untuk meringkas (tidak lengkap) operator perintah / pemisah bash:

  • |pipa (pipeline) output standar ( stdout) dari satu perintah ke input standar yang lain. Perhatikan bahwa stderrmasih masuk ke tujuan default, apa pun itu terjadi.
  • |&pipa keduanya stdoutdan stderrdari satu perintah ke input standar dari yang lain. Sangat berguna, tersedia dalam versi bash 4 ke atas.
  • &&menjalankan perintah kanan &&hanya jika yang sebelumnya berhasil.
  • ||mengeksekusi perintah kanan ||hanya itu yang sebelumnya gagal.
  • ;mengeksekusi perintah kanan ;selalu terlepas apakah perintah sebelumnya berhasil atau gagal. Kecuali set -esebelumnya dipanggil, yang menyebabkan bashkegagalan pada kesalahan.
Maxim Egorushkin
sumber
6
Terpilih. Dokumentasi resmi gnu.org/software/bash/manual/bash.html#Lists
flow2k
78

Mengapa tidak cpke lokasi 1, lalu mvke lokasi 2. Ini menangani "menghapus" aslinya.

Dan tidak, itu bukan sintaks yang benar. |digunakan untuk "menyalurkan" output dari satu program dan mengubahnya menjadi input untuk program selanjutnya. Yang Anda inginkan adalah ;, yang memisahkan banyak perintah.

cp file1 file2 ; cp file1 file3 ; rm file1

Jika Anda mengharuskan perintah individu HARUS berhasil sebelum yang berikutnya dapat dimulai, maka Anda akan menggunakan &&sebagai berikut:

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

Dengan begitu, jika salah satu dari cpperintah gagal, rmtidak akan berjalan.

Marc B
sumber
10

Perhatikan cp A B; rm Apersis mv A B. Ini akan lebih cepat juga, karena Anda tidak harus benar-benar menyalin byte (dengan asumsi tujuan berada pada sistem file yang sama), cukup ganti nama filenya. Jadi kamu maucp A B; mv A C

glenn jackman
sumber
7

Opsi lain adalah mengetik Ctrl+V Ctrl+Jdi akhir setiap perintah.

Contoh (ganti #dengan Ctrl+V Ctrl+J):

$ echo 1#
echo 2#
echo 3

Keluaran:

1
2
3

Ini akan menjalankan perintah terlepas dari yang sebelumnya gagal.

Sama dengan: echo 1; echo 2; echo 3

Jika Anda ingin menghentikan eksekusi pada perintah yang gagal, tambahkan &&di akhir setiap baris kecuali yang terakhir.

Contoh (ganti #dengan Ctrl+V Ctrl+J):

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

Keluaran:

1
failed-command: command not found

Di dalam zshAnda juga dapat menggunakan Alt+Enteratau Esc+EnterbukanCtrl+V Ctrl+J

Eyal Levin
sumber
3

Coba ini..

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

Peter
sumber
2

Menggunakan pipa terasa aneh bagi saya. Pokoknya Anda harus menggunakan andoperator Bash logis :

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

Jika cpperintah gagal, maka rmtidak akan dieksekusi.

Atau, Anda dapat membuat baris perintah yang lebih rumit menggunakan forloop dan cmp.

Renaud
sumber