Risposte:
In Bash, teste [sono integrati nella shell.
La parentesi doppia , che è una parola chiave shell, consente funzionalità aggiuntive. Ad esempio, è possibile utilizzare &&e ||invece di -ae -oe c'è un regolare operatore di espressione di corrispondenza =~.
Inoltre, in un semplice test, le parentesi quadre doppie sembrano valutare molto più velocemente di quelle singole.
$ time for ((i=0; i<10000000; i++)); do [[ "$i" = 1000 ]]; done
real 0m24.548s
user 0m24.337s
sys 0m0.036s
$ time for ((i=0; i<10000000; i++)); do [ "$i" = 1000 ]; done
real 0m33.478s
user 0m33.478s
sys 0m0.000s
Le parentesi graffe, oltre a delimitare un nome di variabile, vengono utilizzate per l' espansione dei parametri in modo da poter fare cose come:
Tronca il contenuto di una variabile
$ var="abcde"; echo ${var%d*}
abc
Rendi le sostituzioni simili a sed
$ var="abcde"; echo ${var/de/12}
abc12
Usa un valore predefinito
$ default="hello"; unset var; echo ${var:-$default}
hello
e molti altri ancora
Inoltre, le espansioni di controvento creano elenchi di stringhe che sono in genere ripetute nei loop:
$ echo f{oo,ee,a}d
food feed fad
$ mv error.log{,.OLD}
(error.log is renamed to error.log.OLD because the brace expression
expands to "mv error.log error.log.OLD")
$ for num in {000..2}; do echo "$num"; done
000
001
002
$ echo {00..8..2}
00 02 04 06 08
$ echo {D..T..4}
D H L P T
Si noti che le funzioni di zero e incremento iniziali non erano disponibili prima di Bash 4.
Grazie a gboffi per avermi ricordato le espansioni del tutore.
Le doppie parentesi vengono utilizzate per le operazioni aritmetiche :
((a++))
((meaning = 42))
for ((i=0; i<10; i++))
echo $((a + b + (14 * c)))
e consentono di omettere i segni del dollaro sulle variabili intere e array e includere spazi attorno agli operatori per la leggibilità.
Le parentesi singole vengono utilizzate anche per gli indici di array :
array[4]="hello"
element=${array[index]}
Sono richiesti parentesi graffe per (quasi / tutti?) I riferimenti di matrice sul lato destro.
Il commento di ephemient mi ha ricordato che le parentesi sono usate anche per i subshells. E che sono usati per creare array.
array=(1 2 3)
echo ${array[1]}
2
:.
$[expression]:; questa è la sintassi dell'espressione aritmetica obsoleta e deprecata per la sintassi più nuova e preferita:$((expression))
bashè la creazione di sequenze, come indicato di seguito sotto ( stackoverflow.com/a/8552128/2749397 ). Mi sto prendendo la libertà di usare la risposta più votata come veicolo ... Due esempi di letterali di sequenza: echo {01..12}-> 01 02 03 04 05 06 07 08 09 10 11 12(nota lo zero iniziale); echo {C..Q}-> C D E F G H I J K L M N O P Q. Il suo uso principale è nei loop, ad es. for cnt in {01..12} ; do ... ${cnt} ... ; done
echo {01..12..2}-> "01 03 05 07 09 11". Grazie per il promemoria sulle sequenze. Lo aggiungerò alla mia risposta.
Una singola parentesi ( [) di solito in realtà chiama un programma chiamato [; man testo man [per maggiori informazioni. Esempio:
$ VARIABLE=abcdef
$ if [ $VARIABLE == abcdef ] ; then echo yes ; else echo no ; fi
yes
La doppia parentesi ( [[) fa la stessa cosa (fondamentalmente) di una singola parentesi, ma è un built-in bash.
$ VARIABLE=abcdef
$ if [[ $VARIABLE == 123456 ]] ; then echo yes ; else echo no ; fi
no
Le parentesi ( ()) vengono utilizzate per creare una subshell. Per esempio:
$ pwd
/home/user
$ (cd /tmp; pwd)
/tmp
$ pwd
/home/user
Come puoi vedere, la subshell ti ha permesso di eseguire operazioni senza influire sull'ambiente della shell corrente.
(a) Le parentesi graffe ( {}) vengono utilizzate per identificare in modo univoco le variabili. Esempio:
$ VARIABLE=abcdef
$ echo Variable: $VARIABLE
Variable: abcdef
$ echo Variable: $VARIABLE123456
Variable:
$ echo Variable: ${VARIABLE}123456
Variable: abcdef123456
(b) Le parentesi graffe vengono anche utilizzate per eseguire una sequenza di comandi nel contesto della shell corrente , ad es
$ { date; top -b -n1 | head ; } >logfile
# 'date' and 'top' output are concatenated,
# could be useful sometimes to hunt for a top loader )
$ { date; make 2>&1; date; } | tee logfile
# now we can calculate the duration of a build from the logfile
Vi è tuttavia una sottile differenza sintattica ( )(vedi riferimento bash ); essenzialmente, una virgola ;dopo l'ultimo comando tra parentesi graffe è un must, e le bretelle {, } deve essere circondato da spazi.
[realtà è un builtin in Bash, ma dovrebbe agire come /bin/[al contrario del [[builtin. [[ha caratteristiche diverse, come più operazioni logiche e ruoli di quotazione diversi. Inoltre: le parentesi singole vengono utilizzate anche per array, sostituzione di processo e globi estesi; le doppie parentesi sono usate per l'aritmetica; le parentesi graffe {}vengono utilizzate per il raggruppamento dei comandi o una moltitudine di tipi di espansione dei parametri o espansione delle parentesi graffe o espansione della sequenza. Sono sicuro di aver perso anche altri usi ...
if [ $VARIABLE == abcdef ]è un basismo che, sebbene funzioni, dovrebbe probabilmente essere evitato; utilizzare esplicitamente bash ( if [[ ...==...]]) o chiarire che si sta utilizzando il condizionale più tradizionale ( if [ "$VARIABLE" = "abcdef" ]). Probabilmente, gli script dovrebbero iniziare nel modo più semplice e portatile possibile, fino a quando non hanno davvero bisogno di funzionalità specifiche per bash (per una ragione o per l'altra). Ma in ogni caso, l'intento dovrebbe essere chiaro; "=" e "==" e "[[" e "[" funzionano in modo diverso e il loro utilizzo deve essere coerente.
[ "$var" = ".."]invece di ==, mentre in C assegnerebbe invece di test (ed è una causa abbastanza comune di bug) ... perché 't testutilizzare ==al posto di =? qualcuno lo sa?
/usr/bin/[non è un link simbolico a /usr/bin/test, e altro ancora: questi programmi hanno anche dimensioni diverse!
)fa parte della casesintassi dell'istruzione per terminare una riga del caso. Non ha una parentesi aperta. Questo mi ha gettato via la prima volta che l'ho visto.
Parentesi
if [ CONDITION ] Test construct
if [[ CONDITION ]] Extended test construct
Array[1]=element1 Array initialization
[a-z] Range of characters within a Regular Expression
$[ expression ] A non-standard & obsolete version of $(( expression )) [1]
[1] http://wiki.bash-hackers.org/scripting/obsolete
Parentesi graffe
${variable} Parameter substitution
${!variable} Indirect variable reference
{ command1; command2; . . . commandN; } Block of code
{string1,string2,string3,...} Brace expansion
{a..z} Extended brace expansion
{} Text replacement, after find and xargs
parentesi
( command1; command2 ) Command group executed within a subshell
Array=(element1 element2 element3) Array initialization
result=$(COMMAND) Command substitution, new style
>(COMMAND) Process substitution
<(COMMAND) Process substitution
Parentesi doppie
(( var = 78 )) Integer arithmetic
var=$(( 20 + 5 )) Integer arithmetic, with variable assignment
(( var++ )) C-style variable increment
(( var-- )) C-style variable decrement
(( var0 = var1<98?9:21 )) C-style ternary operation
Volevo solo aggiungere questi da TLDP :
~:$ echo $SHELL
/bin/bash
~:$ echo ${#SHELL}
9
~:$ ARRAY=(one two three)
~:$ echo ${#ARRAY}
3
~:$ echo ${TEST:-test}
test
~:$ echo $TEST
~:$ export TEST=a_string
~:$ echo ${TEST:-test}
a_string
~:$ echo ${TEST2:-$TEST}
a_string
~:$ echo $TEST2
~:$ echo ${TEST2:=$TEST}
a_string
~:$ echo $TEST2
a_string
~:$ export STRING="thisisaverylongname"
~:$ echo ${STRING:4}
isaverylongname
~:$ echo ${STRING:6:5}
avery
~:$ echo ${ARRAY[*]}
one two one three one four
~:$ echo ${ARRAY[*]#one}
two three four
~:$ echo ${ARRAY[*]#t}
one wo one hree one four
~:$ echo ${ARRAY[*]#t*}
one wo one hree one four
~:$ echo ${ARRAY[*]##t*}
one one one four
~:$ echo $STRING
thisisaverylongname
~:$ echo ${STRING%name}
thisisaverylong
~:$ echo ${STRING/name/string}
thisisaverylongstring
echo ${#ARRAY}mostra tre, a causa del primo elemento del ARRAYcontiene tre caratteri, non perché contiene tre elementi! Per stampare il numero di elementi utilizzare echo ${#ARRAY[@]}.
${TEST:-test}uguale $TESTse la variabile TESTesiste, altrimenti restituisce semplicemente la stringa "test". Esiste un'altra versione che fa ancora di più: ${TEST:=test}--- che equivale anche a $TESTse TEST esiste, ma ogni volta che non lo fa, crea la variabile TESTe assegna un valore "test" e diventa anche il valore dell'intera espressione.
La differenza tra test , [ e [[ è spiegata in dettaglio nel BashFAQ .
Per farla breve: test implementa la vecchia sintassi portatile del comando. In quasi tutte le shell (le più vecchie shell Bourne sono l'eccezione), [è sinonimo di test (ma richiede un argomento finale di]). Sebbene tutte le shell moderne abbiano implementazioni integrate di [, di solito esiste ancora un eseguibile esterno con quel nome, ad esempio / bin / [.
[[ne è una nuova versione migliorata, che è una parola chiave, non un programma. Ciò ha effetti benefici sulla facilità d'uso, come mostrato di seguito. [[è compreso da KornShell e BASH (ad es. 2.03), ma non da POSIX o BourneShell precedenti.
E la conclusione:
Quando dovrebbe essere usato il nuovo comando test [[e quando quello vecchio [? Se la portabilità su BourneShell è un problema, è necessario utilizzare la vecchia sintassi. Se invece lo script richiede BASH o KornShell, la nuova sintassi è molto più flessibile.
Le parentesi ()vengono utilizzate nella definizione della funzione:
function_name () { command1 ; command2 ; }
Questo è il motivo per cui devi sfuggire alle parentesi anche nei parametri di comando:
$ echo (
bash: syntax error near unexpected token `newline'
$ echo \(
(
$ echo () { command echo The command echo was redefined. ; }
$ echo anything
The command echo was redefined.
unset -f echo. Vedere help unset.
Truncate the contents of a variable
$ var="abcde"; echo ${var%d*}
abc
Make substitutions similar to sed
$ var="abcde"; echo ${var/de/12}
abc12
Use a default value
$ default="hello"; unset var; echo ${var:-$default}
hello