Jeg laver heltalssammenligning i bash (forsøger at se om brugeren kører som root), og jeg fandt to forskellige måder at gøre det på:
Dobbelt svarer til:
if [ $UID == 0 ] then fi
-eq
if [ $UID -eq 0 ] then fi
Jeg forstår, at der “s no> = eller < = i bash, kun -ge og -le, så hvorfor er der en ==
hvis der er “sa -eq
?
Er der forskel på, hvordan den sammenligner begge sider?
Kommentarer
Svar
==
er en bash
-specifikt alias for =
, der udfører en streng (leksikalsk) sammenligning i stedet for -eq
numerisk sammenligning. (Det er bagud fra Perl: ordstiloperatorerne er numeriske, de symbolske er leksikale.)
Kommentarer
- Betyder det, at hvis begge sider er heltal, det konverterer begge sider til strenge og sammenligner dem derefter?
- Mere præcist er det ' omvendt: alt er en streng,
-eq
fortællerbash
at fortolke strengene som heltal (der producerer0
uden en advarsel, hvis en streng isn ' t numerisk). - @tjameson For at give et eksempel:
[ 01 -eq 1 ]
men[ 01 != 1 ]
. - Bemærk at mens
==
som[
operatør er ikke-standard og bør ikke bruges, det er ikke bash-specifikt . Det blev introduceret af ksh og understøttes også af zsh (selvom den første=
skal citeres) , yash og GNU[
hjælpeprogrammet ( og sådanne værktøjer implementeret som ksh-scripts på nogle systemer) i det mindste). - @geekosaur Jeg får en advarsel fra bash v4.3.42, hvis min streng ikke er ' t numerisk:
$ if [ "hello" -eq 0 ]; then echo true; fi
bash: [: hej: heltal udtryk forventes
Svar
For at uddybe bollovans svar …
Der er ingen >=
eller <=
sammenligningsoperator for strenge. Men du kan bruge dem med ((...))
aritmetisk kommando til at sammenligne heltal.
Du kan også bruge de andre strengesammenligningsoperatorer (==
, !=
, <
, >
, men ikke =
) for at sammenligne heltal, hvis du bruger dem inden for ((...))
.
Eksempler
- Både
[[ 01 -eq 1 ]]
og(( 01 == 1 ))
gør heltal sammenligninger. Begge er sande. - Både
[[ 01 == 1 ]]
og[ 01 = 1 ]
foretager strengesammenligninger. Begge er falske. - Både
(( 01 -eq 1 ))
og(( 01 = 1 ))
returnerer en fejl.
Bemærk: Syntaks med dobbelt parentes [[...]]
og syntaks med dobbelt parentes ((...))
understøttes ikke af alle skaller.
Kommentarer
- Bemærk, at (undtagen
mksh
/zsh
(undtagen i POSIX-tilstand (skønt at ' ikke er en POSIX-funktion))), ville(( 010 == 10 ))
returnere falsk, fordi010
ville blive behandlet som et oktalt tal (8 i decimal). - Bemærk at mens de fleste
test
/[
implementeringer har ' t har>=
/<=
operatorer (yash
' s[
har dog),expr
har sådanne operatører, selvom det vil gøre ar matematisk sammenligning, hvis argumenterne genkendes som tal (expr 01 '>=' 1
returnerer true,expr X01 '>=' X1
returnerer false).
Svar
Hvis du vil foretage heltalssammenligning, vil du bedre bruge (()), hvor du også kan bruge> = osv.
Eksempel:
if (( $UID == 0 )); then echo "You are root" else echo "You are not root" fi
Kommentarer
- Eller
(( UID == 0 ))
eller(( ! UID ))
for det der betyder noget. Bemærk, at((...))
ikke er standard (enksh
-funktion, der også understøttes afbash
ogzsh
med variationer).
[ $UID -eq 0 ]
, ikke[ $UID -eq 0]
.