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


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow