Bash
Villkorliga uttryck
Sök…
Syntax
- [[-OP $ filnamn]]
- [[$ fil1 -OP $ fil2]]
- [[-z $ string]]
- [[-n $ string]]
- [["$ string1" == "$ string2"]]
- [["$ string1" == $ mönster]]
Anmärkningar
Syntaxen [[ … ]]
omger bash-inbyggda villkorliga uttryck. Observera att utrymmen krävs på vardera sidan av konsolerna.
Villkorliga uttryck kan använda unära och binära operatörer för att testa egenskaper för strängar, heltal och filer. De kan också använda de logiska operatörerna &&
, ||
och !
.
Filjämförelse
if [[ $file1 -ef $file2 ]]; then
echo "$file1 and $file2 are the same file"
fi
"Samma fil" betyder att ändra en av filerna på plats påverkar den andra. Två filer kan vara desamma även om de har olika namn, till exempel om de är hårda länkar, eller om de är symboliska länkar med samma mål, eller om den ena är en symbolisk länk som pekar mot den andra.
Om två filer har samma innehåll, men de är distinkta filer (så att ändra den ena inte påverkar den andra), rapporterar -ef
dem som olika. Om du vill jämföra två filer byte för byte använder du cmp
verktyget.
if cmp -s -- "$file1" "$file2"; then
echo "$file1 and $file2 have identical contents"
else
echo "$file1 and $file2 differ"
fi
diff
verktyget för att skapa en lista över människor som kan läsas av skillnader mellan textfiler.
if diff -u "$file1" "$file2"; then
echo "$file1 and $file2 have identical contents"
else
: # the differences between the files have been listed
fi
Test av filåtkomst
if [[ -r $filename ]]; then
echo "$filename is a readable file"
fi
if [[ -w $filename ]]; then
echo "$filename is a writable file"
fi
if [[ -x $filename ]]; then
echo "$filename is an executable file"
fi
Dessa test tar hänsyn till behörigheter och äganderätt för att avgöra om skriptet (eller programmen som startats från skriptet) har åtkomst till filen.
Akta dig för tävlingsförhållanden (TOCTOU) : bara för att testet lyckas nu betyder det inte att det fortfarande är giltigt på nästa rad. Det är vanligtvis bättre att försöka få åtkomst till en fil och hantera felet i stället för att testa först och sedan måste hantera felet ändå om filen har ändrats under tiden.
Numeriska jämförelser
Numeriska jämförelser använder -eq
operatörer och vänner
if [[ $num1 -eq $num2 ]]; then
echo "$num1 == $num2"
fi
if [[ $num1 -le $num2 ]]; then
echo "$num1 <= $num2"
fi
Det finns sex numeriska operatörer:
-
-eq
-
-ne
inte lika -
-le
mindre eller lika -
-lt
mindre än -
-ge
större eller lika -
-gt
större än
Observera att <
och >
operatörerna i [[ … ]]
jämför strängar, inte siffror.
if [[ 9 -lt 10 ]]; then
echo "9 is before 10 in numeric order"
fi
if [[ 9 > 10 ]]; then
echo "9 is after 10 in lexicographic order"
fi
De två sidorna måste vara siffror skrivna i decimal (eller i oktal med en ledande noll). Alternativt kan du använda den ((…))
aritmetiska uttryckssyntaxen, som utför heltalberäkningar i en C / Java / ... -liknande syntax.
x=2
if ((2*x == 4)); then
echo "2 times 2 is 4"
fi
((x += 1))
echo "2 plus 1 is $x"
Strängen jämförelse och matchning
Strängen jämförelse använder ==
operatören mellan citerade strängar. Operatören !=
Negerar jämförelsen.
if [[ "$string1" == "$string2" ]]; then
echo "\$string1 and \$string2 are identical"
fi
if [[ "$string1" != "$string2" ]]; then
echo "\$string1 and \$string2 are not identical"
fi
Om den högra sidan inte citeras är det ett jokerteckenmönster som $string1
matchas mot.
string='abc'
pattern1='a*'
pattern2='x*'
if [[ "$string" == $pattern1 ]]; then
# the test is true
echo "The string $string matches the pattern $pattern"
fi
if [[ "$string" != $pattern2 ]]; then
# the test is false
echo "The string $string does not match the pattern $pattern"
fi
Operatörerna <
och >
jämför strängarna i lexikografisk ordning (det finns inga mindre eller lika eller större eller lika operatörer för strängar).
Det finns unära tester för den tomma strängen.
if [[ -n "$string" ]]; then
echo "$string is non-empty"
fi
if [[ -z "${string// }" ]]; then
echo "$string is empty or contains only spaces"
fi
if [[ -z "$string" ]]; then
echo "$string is empty"
fi
Ovanför kan -z
kontrollen innebära att $string
-strängen är inställd, eller den är inställd på en tom sträng. För att skilja mellan tom och ouppsatt använder du:
if [[ -n "${string+x}" ]]; then
echo "$string is set, possibly to the empty string"
fi
if [[ -n "${string-x}" ]]; then
echo "$string is either unset or set to a non-empty string"
fi
if [[ -z "${string+x}" ]]; then
echo "$string is unset"
fi
if [[ -z "${string-x}" ]]; then
echo "$string is set to an empty string"
fi
där x
är godtyckligt. Eller i tabellform :
+-------+-------+-----------+
$string is: | unset | empty | non-empty |
+-----------------------+-------+-------+-----------+
| [[ -z ${string} ]] | true | true | false |
| [[ -z ${string+x} ]] | true | false | false |
| [[ -z ${string-x} ]] | false | true | false |
| [[ -n ${string} ]] | false | false | true |
| [[ -n ${string+x} ]] | false | true | true |
| [[ -n ${string-x} ]] | true | false | true |
+-----------------------+-------+-------+-----------+
Alternativt kan staten kontrolleras i ett ärendeuttalande:
case ${var+x$var} in
(x) echo empty;;
("") echo unset;;
(x*[![:blank:]]*) echo non-blank;;
(*) echo blank
esac
Där [:blank:]
är språkspecifika horisontella avståndstecken (flik, mellanslag, etc).
Test av filtyp
De -e
villkorliga operatörs testar om en fil finns (inklusive alla filtyper: kataloger, etc.).
if [[ -e $filename ]]; then
echo "$filename exists"
fi
Det finns tester för specifika filtyper också.
if [[ -f $filename ]]; then
echo "$filename is a regular file"
elif [[ -d $filename ]]; then
echo "$filename is a directory"
elif [[ -p $filename ]]; then
echo "$filename is a named pipe"
elif [[ -S $filename ]]; then
echo "$filename is a named socket"
elif [[ -b $filename ]]; then
echo "$filename is a block device"
elif [[ -c $filename ]]; then
echo "$filename is a character device"
fi
if [[ -L $filename ]]; then
echo "$filename is a symbolic link (to any file type)"
fi
För en symbolisk länk, förutom -L
, gäller dessa test för målet och returnerar falskt för en trasig länk.
if [[ -L $filename || -e $filename ]]; then
echo "$filename exists (but may be a broken symbolic link)"
fi
if [[ -L $filename && ! -e $filename ]]; then
echo "$filename is a broken symbolic link"
fi
Testa på utgångsstatus för ett kommando
Avsluta status 0: framgång
Utgångsstatus annan än 0: misslyckande
Så här testar du ett utgångsstatus för ett kommando:
if command;then
echo 'success'
else
echo 'failure'
fi
Ett fodertest
Du kan göra saker som detta:
[[ $s = 'something' ]] && echo 'matched' || echo "didn't match"
[[ $s == 'something' ]] && echo 'matched' || echo "didn't match"
[[ $s != 'something' ]] && echo "didn't match" || echo "matched"
[[ $s -eq 10 ]] && echo 'equal' || echo "not equal"
(( $s == 10 )) && echo 'equal' || echo 'not equal'
Ett fodertest för utgångsstatus:
command && echo 'exited with 0' || echo 'non 0 exit'
cmd && cmd1 && echo 'previous cmds were successful' || echo 'one of them failed'
cmd || cmd1 #If cmd fails try cmd1