Hogyan írhatok egy shell parancsfájlt, amely kilép, ha annak egyik része nem sikerül? Például, ha a következő kódrészlet nem sikerül, akkor a parancsfájlnak ki kell lépnie.
n=0 until [ $n -ge 5 ] do gksu *command* && break n=$[$n+1] sleep 3
Válasz
Az egyik megközelítés a set -e
hozzáadása a szkript elejéhez. Ez azt jelenti (help set
-től):
-e Exit immediately if a command exits with a non-zero status.
Tehát, ha bármelyik parancs meghiúsul, a parancsfájl kilép.
Alternatív megoldásként hozzáadhat explicit exit
utasításokat a lehetséges hibapontokhoz:
command || exit 1
Megjegyzések
. Az OP 5 sikertelen kísérlet után futtatni akarja a parancsfájlt.
set -e
módon tudom megtenni. set -e
sleep
(break
speciális beépítettség miatt a parancsfájl a legtöbb kagyló hibájából kilép, a if
vagy a &&
bal oldalán nem érinti a set -e
, n=...
nem sikerülhet, ha a n
csak olvasható, de ez kilépne a szkriptből set -e
nélkül is, tehát az értelmezés elég valószínűtlennek hangzik. Egyetértek azzal, hogy a kérdés rosszul van megfogalmazva. Válasz
A szkriptből bárhol kiléphet a kulcsszó használatával exit
. Megadhat egy kilépési kódot is annak érdekében, hogy más programoknak jelezze, hogy a szkript hogyan vagy hogyan sikertelen, pl. exit 1
vagy exit 2
stb. (Megállapodás szerint a 0 kilépési kód a siker, a 0-nál nagyobb érték pedig kudarcot jelent; azonban egyezmény szerint is , a 127 feletti kilépési kódok rendellenes lezárásra vannak fenntartva (pl. jelzéssel)).
A hiba esetén kilépő általános konstrukció
if [ failure condition ]; then exit n fi
megfelelő failure condition
és n
De bizonyos esetekben másképp járhat el. Most az Ön esetére értelmezem azt a kérdését, hogy ha a gksu
öt meghívása közül bármelyik meghiúsul, akkor kilépni akar. Az egyik mód az ilyen funkció használata
function try_command { for i in 1 2 3 4 5 ; do if gksu command ; then return 0 fi fi exit 1 }
, majd a ciklus meghívása a következővel: try_command
.
A kérdés megválaszolásához (több) fejlett vagy kifinomult módszer létezik. A fenti megoldás azonban hozzáférhetőbb a kezdők számára, mint mondjuk Stephane megoldása.
Válasz
attempt=0 until gksu command; do attempt=$((attempt + 1)) if [ "$attempt" -gt 5 ]; then exit 1 fi done
exit
kilép a szkriptből, hacsak nem hívják alhéjba. Ha a szkriptnek ez a része alhéjban van, például azért, mert “div
vagy $(...)
vagy csővezeték része , akkor csak akkor lép ki abból az alhéjból .
Ebben az esetben, ha azt szeretné, hogy a parancsfájl az alhéjon kívül kilépjen, akkor ” Fel kell hívnom a következőt: exit
, amikor az alhéj kilép.
Például itt 2 beágyazott alhéjszinttel:
( life=hard output=$( echo blah [ "$life" = easy ] || exit 1 # exit subshell echo blih not run ) || exit # if the subshell exits with a non-zero exit status, # exit as well with the same exit status echo not run either ) || exit # if the subshell exits with a non-zero exit status, # exit as well with the same exit status
Bonyolultabbá válhat, ha az alhéj egy csővezeték része. A bash
speciális $PIPESTATUS
tömbje van, hasonló a zsh
“s $pipestatus
amely itt segíthet:
{ echo foo exit 1 echo bar } | wc -c subshell_ret=${PIPESTATUS[0]} if [ "$subshell_ret" -ne 0 ]; then exit "$subshell_ret" fi
Válasz
A csapda egy jel fogadásakor végrehajt egy műveletet.
trap "echo EXIT; exit" 0 trap "echo HUP; exit" 1 trap "echo CTL-C; exit" 2 trap "echo QUIT; exit" 3 trap "echo ERR; exit" ERR n=0 until [ $n -ge 5 ] do n=$[$n+1] echo $n sleep 3 done
Futtassa ezt, és hagyja, hogy normálisan kilépjen. Csapdába ejti a 0. jelet.
EXIT
Futtassa újra, és szakítsa meg a ^ C gombbal. A 2. és a 0. jelre egyaránt csapdába esik.
CTL-C EXIT
A nullától eltérő kilépési állapot csapdába esik az ERR-en
ERR EXIT
Válasz
pass_to_functio() { echo "command exited with status $1" } ( exec <Any Command > & child_pid=$! wait $child_pid pass_to_function $? )&
set -e
funkciót használná. Ez azonban nem igaz div div