Muszę wykonać szereg potokowych poleceń powłoki ze skryptu innego niż BASH (a mianowicie skryptu PHP), takiego jak te:
command1 | command2 | command3
tak, że jeśli command1
nie powiedzie się niezerowy kod wyjścia, każde inne polecenie również zawiedzie. Do tej pory wymyśliłem:
set -o pipefail && command1 | command2 | command3
Ale mimo że działa poprawnie z terminala, generuje to, jeśli jest wykonywany ze skryptu:
sh: 1: set: Niedozwolona opcja -o pipefail
linux
command-line
shell
pipe
Desmond Hume
źródło
źródło
/bin/sh
się nie podobaset -o pipefail
. Czy to rzeczywiściebash
w przebraniu, czy może to inna skorupa? Kiedybash
jest uruchamiany jako/bin/sh
, czy akceptujeset -o pipefail
?/bin/sh set -o pipefail
, mówi/bin/sh: 0: Can't open set
(to samo zsudo
). Mam nadzieję, że dobrze to przetestowałem. System to Ubuntu 12./bin/sh -c "set -o pipefail"
; tak jak było, powłoka próbowała wykonać skrypt w bieżącym katalogu o nazwieset
i nie znalazł go./bin/sh -c "set -o pipefail"
nie działa, jednakbash -c "set -o pipefail"
działa./bin/sh
który nie rozpoznajeset -o pipefail
. W związku z tym musisz upewnić się, że skrypt jest uruchamiany/bin/bash
zamiast/bin/sh
. Lub, jeśli jesteś pewny siebie, odważny - i prawdopodobnie nierozsądny - zmień/bin/sh
się na link do lub kopię/bin/bash
zamiast na jakąkolwiek powłokę, z którą jest obecnie połączona lub kopię. Jeśli masz pewność, że/bin/sh
jestbash
, to używasz zachowania, którebash
nie narażają gdy uruchamiane jako/bin/sh
; użyjbash
jakobash
.Odpowiedzi:
Z linii poleceń Bash trzeba wywołać podpowłokę, aby uniknąć
pipefail
późniejszego ustawienia:Ograniczyłoby to efekt tej
pipefail
opcji do podpowłoki utworzonej przez nawiasy(...)
.Prawdziwy przykład:
Jeśli używasz jawnego wywołania powłoki z
-c
opcją, nie potrzebujesz podpowłoki,bash
zsh
aliasem lub z aliasem, abybash
:Ponieważ
sh
nie akceptujesz tejpipefail
opcji, musiałbym założyć, że jest to jakaś starsza lub zmodyfikowana wersjabash
- lub że w rzeczywistości jest to zupełnie inna powłoka.źródło
$
w pierwszym kawałku jest częścią polecenia, czy to tylko zachęta do powłoki? Próbowałem w obie strony, tak naprawdę nie działało.bash -c
Sposób zawsze działa, nie jest zbyt elegancki tho ..Nie jestem pewien, dlaczego nie wspomniano powyżej, ale możliwe jest jawne rozbrojenie
pipefail
przy użyciuset +o pipefail
.Jeśli wykonujesz fragment i nie
pipefail
masz pewności co do już ustawionego, możesz użyć tego w podpowłoce, jak wcześniej sugerowano:źródło
Możesz użyć $ (polecenie1) w połączeniu z $? :
Drukuje „abc”
Drukuje „”.
„[$? -eq 0] &&” oznacza, że następujące polecenie jest wykonywane tylko wtedy, gdy poprzednie się powiodło.
Ta dawka nie odpowiada na twoje pytanie, ale jest rozwiązaniem twojego problemu.
źródło
command1 && command2 && command3