Saya perlu menjalankan sejumlah perintah shell yang disalurkan dari skrip non-BASH (yaitu skrip PHP) seperti ini:
command1 | command2 | command3
sehingga, jika command1
gagal dengan kode keluar bukan nol, setiap perintah lainnya juga gagal. Sejauh ini, yang saya pikirkan adalah:
set -o pipefail && command1 | command2 | command3
Tetapi meskipun berjalan dengan baik dari terminal, ia menghasilkan ini jika dieksekusi dari skrip:
sh: 1: set: Opsi ilegal -o pipefail
linux
command-line
shell
pipe
Desmond Hume
sumber
sumber
/bin/sh
tidak sukaset -o pipefail
. Apakah itu sebenarnyabash
dalam penyamaran, atau apakah itu shell yang berbeda? Kapanbash
dijalankan sebagai/bin/sh
, apakah ia menerimaset -o pipefail
?/bin/sh set -o pipefail
mengatakan/bin/sh: 0: Can't open set
(hal yang sama dengansudo
). Semoga saya mengujinya dengan benar. Sistemnya adalah Ubuntu 12./bin/sh -c "set -o pipefail"
; seolah-olah, shell sedang mencoba untuk mengeksekusi skrip di direktori saat ini dipanggilset
dan tidak menemukannya./bin/sh -c "set -o pipefail"
tidak berfungsi, namunbash -c "set -o pipefail"
tidak./bin/sh
yang tidak dikenaliset -o pipefail
. Karenanya, Anda harus memastikan bahwa skrip dijalankan oleh/bin/bash
alih-alih/bin/sh
. Atau, jika Anda percaya diri, berani - dan mungkin bodoh - ubah/bin/sh
menjadi tautan, atau salinan,/bin/bash
alih-alih shell mana pun yang saat ini ditautkan atau salinannya. Jika Anda sedang yakin bahwa/bin/sh
adalahbash
, maka Anda menggunakan perilaku yangbash
tidak mengekspos ketika dijalankan sebagai/bin/sh
; gunakanbash
sebagaibash
.Jawaban:
Dari baris perintah Bash Anda perlu mengaktifkan subkulit untuk menghindari
pipefail
ditetapkan setelahnya:Ini akan membatasi efek
pipefail
opsi ke subkulit yang dibuat oleh tanda kurung(...)
.Contoh nyata:
Jika Anda menggunakan panggilan shell eksplisit dengan
-c
opsi Anda tidak perlu subkulit, baik denganbash
atau dengansh
alias untukbash
:Karena Anda
sh
tidak menerimapipefail
opsi, saya harus berasumsi bahwa itu adalah beberapa versi yang lebih tua atau yang dimodifikasibash
- atau itu sebenarnya beberapa shell lain sepenuhnya.sumber
$
di bagian pertama bagian dari perintah itu hanya prompt shell? Mencoba dua arah, tidak benar-benar berhasil. Thebash -c
cara selalu bekerja, tidak terlalu elegan tho ..Tidak yakin mengapa itu tidak disebutkan di atas, tetapi dimungkinkan untuk menghapus secara eksplisit
pipefail
, menggunakanset +o pipefail
.Jika Anda menjalankan fragmen, dan tidak yakin tentang
pipefail
set yang sudah ditetapkan, Anda dapat menggunakan ini dengan subkulit seperti yang disarankan sebelumnya:sumber
Anda dapat menggunakan $ (command1) yang dikombinasikan dengan $? :
Mencetak "abc"
Cetakan "".
"[$? -eq 0] &&" berarti bahwa perintah berikut dijalankan hanya jika yang sebelumnya berhasil.
Itu dosen tidak menjawab pertanyaan Anda, tetapi itu adalah solusi untuk masalah Anda.
sumber
command1 && command2 && command3