Jag har ett bash-skript med följande:
#!/bin/bash -e egrep "^username" /etc/passwd >/dev/null if[ $? -eq 0 ] then echo "doesn"t exist" fi
Detta skript kommer inte springa utan -e. Vad gör -e
för detta skript? Vad gör $?
också i detta sammanhang?
Kommentarer
Svar
Ditt inlägg innehåller faktiskt två frågor.
-
-e
-flaggan instruerar manuset att avsluta vid fel. Fler flaggorOm det finns ett fel kommer det att avslutas direkt.
-
$?
är utgångsstatus för det senaste kommandot. I Linux betyder en utgångsstatus0
att kommandot lyckades. Alla andra status skulle innebära att ett fel inträffade.
För att tillämpa dessa svar på ditt skript:
egrep "^username" /etc/passwd >/dev/null
skulle leta efter username
i /etc/passwd
-filen.
-
Om den hittar den då kommer utgångsstatus
$?
att vara lika med0
. -
Om det inte ”t finner att utgångsstatusen kommer att vara något annat (inte
0
). Här vill du köraecho "doesn"t exist"
delen av kod.
Tyvärr finns det ett fel i ditt skript, och du skulle köra den koden om användaren existerar – ändra raden till
if [ $? -ne 0 ]
för att få logiken rätt.
Men om användaren inte ”t existerar, egrep
returnerar ett fel c ode och på grund av alternativet -e
kommer skalet omedelbart att avslutas efter den raden, så att du aldrig når den delen av koden.
Kommentarer
- Dessutom kan du få skriptet att fungera korrekt utan -e genom att ersätta de två första raderna med
if egrep "^username" /etc/passwd >/dev/null
. - Varför krävs ingen
set
? : – / - @pst: Eftersom
-e
ges till bash som ett kommandoradsargument. Alla alternativ som listas underset
accepteras också av bash i kommandoraden – notera första meningen i avsnitt Alternativ i handboken sida.
Svar
Alla bash-kommandoradsomkopplare är dokumenterade i man bash
.
-e Exit immediately if a pipeline (which may consist of a single simple command), a subshell command enclosed in parentheses, or one of the commands executed as part of a command list enclosed by braces (see SHELL GRAMMAR above) exits with a non-zero status. The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test following the if or elif reserved words, part of any command executed in a && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command"s return value is being inverted with !. A trap on ERR, if set, is executed before the shell exits. This option applies to the shell environment and each subshell envi- ronment separately (see COMMAND EXECUTION ENVIRONMENT above), and may cause subshells to exit before executing all the commands in the subshell.
Kommentarer
- Ahh. Jag letade efter det hos mannen, men efter att ha hittat -e i filtesterna och nej -e under huvudargumenten gav jag upp. Trevligt utdrag. Varför krävs dock ingen
set
? : – /
Svar
Ditt skript är felaktigt, eftersom
egrep "^username" /etc/passwd >/dev/null if[ $? -eq 0 ] then #echo "doesn"t exist" # WRONG echo "the USER EXISTS" fi
exit status 0 – medelvärde – allt är OK, i fallet med grep betyder” OK, hittade strängen ”. exit status! = 0 menar att något är fel, i fallet med grep 1 betyder ”inte hittat”, 2 betyder ”kan inte öppna ingång” …
-e
på mansidan (jag vill verkligen se ett svar adressera det här).$?
innehåller den sista utgångskoden (den föregrep
-processen som skapats ovan).-e
dokumenteras underset
.if egrep -q "^username" /etc/passwd ; then echo "doesn't exist" ; fi
if
och[
. Detta skript vann ' t arbete med-e
, för omgrep
hittar inte ' något under-e
skriptet avslutas där. Utan-e
har du ' fått meddelandet bakåt: en status ($?
) 0 betyder att grep hittade användaren. Observera att detta bör vara `grep ' ^ användarnamn: ', förresten (vad händer om det finns ' är en annan användare med ett längre namn?).#/bin/bash -e
att ha samma effekt som#/bin/bash
på rad # 1 ochset -e
på rad # 2?