Vilket är mer idiomatiskt i ett bash-skript: `|| true` eller `|| : `?

Jag gör inte väldigt mycket skalskript, så jag blev lite förvånad när jag läste dokumentationen för git submodule och jag såg syntaxen som de använde i den här dokumentationen:

A icke-noll avkastning från kommandot i någon undermodul får bearbetningen att avslutas. Detta kan åsidosättas genom att lägga till || : i slutet av kommandot.

Jag var tvungen att leta upp att || : var en förkortning för att tvinga ett kommando att avsluta framgångsrikt. Varje gång jag måste göra ett kommandoutgång , Jag använde || true. Anses || : för att vara mer idiomatisk?

Kommentarer

  • Det ' är värt att notera att ||: (utan utrymme) också är giltigt i bash. Det gör samma sak som || : eller || true.

Svar

true byggdes inte in i Bourne-skalet. : var alltid (det var sättet att skriva in kommentarer innan # infördes).

Det, och därför det är kortare att skriva är förmodligen den främsta anledningen till att folk föredrar : framför true.

Notera en annan skillnad i POSIX-skal (för bash, endast i POSIX-läge): medan true är ett vanligt inbyggt (behöver inte ens byggas in) , : är en special inbyggd. Det har några konsekvenser, varav de flesta är osannolika att ha någon inverkan i detta specifika fall:

  • Om ett : -kommando misslyckas, inklusive på grund av en misslyckad omdirigering, som får skalet att gå ut. I praktiken kommer det förmodligen inte att göra skillnad om du inte skickar omdirigeringar till :

    $ sh -c ": > / ; echo HERE" sh: 1: cannot create /: Is a directory $ sh -c "true > /; echo HERE" sh: 1: cannot create /: Is a directory HERE 
  • i var=value :, var förblir inställd på value efter : returnerar, inte i fallet med true:

    $ var=1; var=2 : ; echo "$var" 2 $ var=1; var=2 true; echo "$var" 1 

Observera också att || true fungerar i skal av rc och csh familjer men inte || : (men inte för att avbryta set -e i csh).

|| : är inte samma som :. Det betyder eller kör : annars (det vill säga om föregående pipeline misslyckas).

set -e false 

Skulle att skalet skulle gå ut på grund av set -e (aka errexit alternativet) och har utgångsstatus som inte är noll (fel). set -e -effekten avbryts om kommandot som returnerar en utgångsstatus som inte är noll används som villkor som i:

if false; then ... while false; do ... false && : ... false || : ... 

false && : avbryter endast set -e. false || : avbryter effekten av set -e och sätter utgångsstatus till 0 så är det mer idiomatiskt att säga att vi vill ignorera en felkod för kommandot. De flesta skulle hävda att || true är mer läsbart (förmedlar avsikten tydligare).

Kommentarer

  • && : är lysande, finns det några dokument eller ytterligare läsning om detta? Google saknar mig för att försöka hitta den här typen av nyckelord …

Svar

De flesta av dessa svar misslyckas med att ta itu med den vanligaste användningen av :.

För det första är denna diskussion inte relaterad till något skal som inte är Bourne-skal (sh) derivat. Som sagt, alla Bourne-derivatskal ser true och : som samma sak. Tidigare uppmuntrades programmerare att använda : istället för true, eftersom : alltid är en inbyggd medan det tidigare fanns fall där true inte alltid var en inbyggd.

: har två användningsområden. Det är inte en synonym för #, men det har en annan funktion. När du felsöker ditt skript under en set -x tappas rader där # används av tolkaren och ignoreras helt, medan rader med : analyseras och utvärderas. Detta är verkligen användbart vid felsökning eftersom under -x dessa rader visas och deras värde efter utvärdering visas.Det är som att sätta print uttalanden i din kod som bara visas under -x -läge. Var försiktig med värdena efter : eftersom de är riktig kod och biverkningarna kan påverka ditt program.

Kommentarer

  • Vad är den andra användningen?

Svar

Generellt, i bash, är kolon : och true är ekvivalent.

Är | | : anses vara mer idiomatisk?

Jag tror att den baseras på -kontext .

Om du vill ha en return value, eller en condition är alltid sant , bör du använda true nyckelord, det kommer att göra din kod tydligare och låta tittarna veta att du vill betona värdet true , dvs.:

while true; do something 

eller

<commnad> RETURN_VALUE= $? || true 

Och om du vill gör ingenting , eller NOP i skal ska du använda kolon :

if condition then : # DO NOTHING HERE else do something fi 

eller

while conditon do : # DO NOTHING HERE done 

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *