Quali sono gli operatori di controllo e reindirizzamento della shell?


246

Vedo spesso tutorial online che collegano vari comandi con simboli diversi. Per esempio:

command1 |  command2
command1 &  command2
command1 || command2    
command1 && command2

Altri sembrano collegare comandi ai file:

command1  > file1
command1  >> file1

Cosa sono queste cose? Come si chiamano? Cosa fanno? Ce ne sono altri?


Meta thread su questa domanda. .

Risposte:


340

Questi sono chiamati operatori di shell e sì, ce ne sono altri. Darò una breve panoramica delle più comuni tra le due classi principali, gli operatori di controllo e gli operatori di reindirizzamento e come funzionano rispetto alla shell bash.

A. Operatori di controllo

Nel linguaggio dei comandi della shell, un token che esegue una funzione di controllo.
È uno dei seguenti simboli:

&   &&   (   )   ;   ;;   <newline>   |   ||

E |&in bash.

A non! è un operatore di controllo ma una parola riservata . Diventa un NOT logico [operatore di negazione] all'interno delle espressioni aritmetiche e all'interno dei costrutti di test (pur richiedendo ancora un delimitatore di spazio).

A.1 Elenco terminatori

  • ; : Eseguirà un comando dopo che un altro è terminato, indipendentemente dal risultato del primo.

    command1 ; command2

    Il primo command1viene eseguito, in primo piano e, una volta terminato, command2verrà eseguito.

    Una nuova riga che non è in una stringa letterale o dopo determinate parole chiave non è equivalente all'operatore punto e virgola. Un elenco di ;comandi semplici delimitati è ancora un elenco , poiché nel parser della shell deve continuare a leggere nei comandi semplici che seguono un ;comando semplice delimitato prima dell'esecuzione, mentre una nuova riga può delimitare un intero elenco di comandi o un elenco di elenchi. La differenza è sottile, ma complicata: dato che la shell non ha un imperativo precedente per leggere i dati seguendo una nuova riga, la nuova riga segna un punto in cui la shell può iniziare a valutare i semplici comandi in cui ha già letto, mentre un punto ;e virgola lo fa non.

  • & : Questo eseguirà un comando in background, che consente di continuare a lavorare nella stessa shell.

     command1 & command2

    Qui, command1viene avviato in background e command2inizia a essere eseguito in primo piano immediatamente, senza attendere command1l'uscita.

    Un newline dopo command1è facoltativo.

A.2 Operatori logici

  • && : Utilizzato per creare elenchi AND, consente di eseguire un comando solo se un altro è uscito correttamente.

     command1 && command2

    Qui, command2verrà eseguito dopo che command1è terminato e solo se ha command1avuto esito positivo (se il suo codice di uscita era 0). Entrambi i comandi vengono eseguiti in primo piano.

    Questo comando può anche essere scritto

    if command1
    then command2
    else false
    fi

    o semplicemente if command1; then command2; fise lo stato di ritorno viene ignorato.

  • || : Utilizzato per creare elenchi OR, consente di eseguire un comando solo se un altro è uscito senza successo.

     command1 || command2

    Qui, command2verrà eseguito solo in caso di command1errore (se ha restituito uno stato di uscita diverso da 0). Entrambi i comandi vengono eseguiti in primo piano.

    Questo comando può anche essere scritto

    if command1
    then true
    else command2
    fi

    o in modo più breve if ! command1; then command2; fi.

    Si noti che &&e ||sono associativi di sinistra; vedi Precedenza degli operatori logici della shell &&, || per maggiori informazioni.

  • !: Questa è una parola riservata che funge da operatore "non" (ma deve avere un delimitatore), utilizzata per negare lo stato di ritorno di un comando - restituisce 0 se il comando restituisce uno stato diverso da zero, restituisce 1 se restituisce lo stato 0 Anche un NOT logico per l' testutilità.

    ! command1
    
    [ ! a = a ]

    E un vero operatore NOT nelle espressioni aritmetiche:

    $ echo $((!0)) $((!23))
    1 0

A.3 Operatore di tubi

  • |: L'operatore pipe, passa l'output di un comando come input a un altro. Un comando creato dall'operatore pipe viene chiamato pipeline .

     command1 | command2

    Qualsiasi output stampato da command1viene passato come input a command2.

  • |&: Questa è una scorciatoia per 2>&1 |in bash e zsh. Passa sia l'output standard sia l'errore standard di un comando come input a un altro.

    command1 |& command2

A.4 Punteggiatura di altri elenchi

;;viene utilizzato esclusivamente per contrassegnare la fine di un'istruzione case . Ksh, bash e zsh supportano anche il ;&passaggio al caso successivo e ;;&(non in ATT ksh) per andare avanti e testare i casi successivi.

(e )vengono utilizzati per raggruppare i comandi e avviarli in una subshell. {e }anche raggruppare i comandi, ma non avviarli in una subshell. Vedi questa risposta per una discussione sui vari tipi di parentesi, parentesi e parentesi graffe nella sintassi della shell.

B. Operatori di reindirizzamento

Operatore di reindirizzamento

Nel linguaggio dei comandi della shell, un token che esegue una funzione di reindirizzamento. È uno dei seguenti simboli:

<     >     >|     <<     >>     <&     >&     <<-     <>

Questi ti consentono di controllare l'input e l'output dei tuoi comandi. Possono apparire ovunque all'interno di un semplice comando o possono seguire un comando. I reindirizzamenti vengono elaborati nell'ordine in cui appaiono, da sinistra a destra.

  • < : Fornisce input a un comando.

    command < file.txt

    Quanto sopra verrà eseguito commandsul contenuto di file.txt.

  • <>: come sopra, ma il file è aperto in modalità lettura + scrittura anziché in sola lettura :

    command <> file.txt

    Se il file non esiste, verrà creato.

    Quell'operatore viene usato raramente perché i comandi generalmente leggono solo dal loro stdin, anche se può tornare utile in diverse situazioni specifiche .

  • > : Dirige l'output di un comando in un file.

    command > out.txt

    Quanto sopra salverà l'output di commandas out.txt. Se il file esiste, il suo contenuto verrà sovrascritto e se non esiste verrà creato.

    Questo operatore viene spesso utilizzato anche per scegliere se stampare qualcosa su errore standard o output standard :

    command >out.txt 2>error.txt

    Nell'esempio sopra, >reindirizzerà l'output standard e 2>reindirizzerà l'errore standard. L'output può anche essere reindirizzato utilizzando 1>ma, poiché questo è il valore predefinito, 1viene solitamente omesso e viene scritto semplicemente come >.

    Così, a correre commandsu file.txte salvare la sua uscita nel out.txte eventuali messaggi di errore in error.txtsi correrebbe:

    command < file.txt > out.txt 2> error.txt
  • >|: Funziona come >, ma sovrascriverà la destinazione, anche se la shell è stata configurata per rifiutare la sovrascrittura (con set -Co set -o noclobber).

    command >| out.txt

    Se out.txtesiste, l'output di commandsostituirà il suo contenuto. Se non esiste verrà creato.

  • >>: Equivale a >, tranne che se esiste il file di destinazione, i nuovi dati vengono aggiunti.

    command >> out.txt

    Se out.txtesiste, l'output di commandverrà aggiunto ad esso, dopo tutto ciò che è già in esso. Se non esiste verrà creato.

  • &>, >&, >>&E &>>: (non standard). Reindirizzare rispettivamente l'errore standard e l'output standard, sostituendo o aggiungendo.

    command &> out.txt

    commandVerranno salvati sia l'errore standard sia l'output standard di out.txt, sovrascrivendone il contenuto o creandolo se non esiste.

    command &>> out.txt

    Come sopra, tranne che se out.txtesiste, l'output e l'errore di commandverranno aggiunti ad esso.

    La &>variante ha origine in bash, mentre la >&variante proviene da csh (decenni prima). Entrambi sono in conflitto con altri operatori shell POSIX e non devono essere utilizzati negli shscript portatili .

  • <<: Un documento qui. Viene spesso utilizzato per stampare stringhe su più righe.

     command << WORD
         Text
     WORD

    Qui, commandprenderà tutto fino a quando non trova la prossima occorrenza di WORD, Textnell'esempio sopra, come input. Sebbene WORDsia spesso EoFo sue variazioni, può essere qualsiasi stringa alfanumerica (e non solo) che ti piace. Quando WORDviene citato, il testo nel documento qui viene trattato alla lettera e non vengono eseguite espansioni (ad esempio sulle variabili). Se non è quotato, le variabili verranno espanse. Per maggiori dettagli, consultare il manuale di bash .

    Se si desidera reindirizzare l'output di command << WORD ... WORDdirettamente in un altro comando o comandi, è necessario posizionare la pipe sulla stessa riga di << WORD, non è possibile inserirla dopo la WORD di terminazione o sulla riga seguente. Per esempio:

     command << WORD | command2 | command3...
         Text
     WORD
  • <<<: Stringhe qui, simili ai documenti qui, ma intese per una singola riga. Esistono solo nella porta Unix o rc (dove ha avuto origine), zsh, alcune implementazioni di ksh, yash e bash.

    command <<< WORD

    Tutto ciò che viene dato WORDviene espanso e il suo valore viene passato come input a command. Questo è spesso usato per passare il contenuto delle variabili come input a un comando. Per esempio:

     $ foo="bar"
     $ sed 's/a/A/' <<< "$foo"
     bAr
     # as a short-cut for the standard:
     $ printf '%s\n' "$foo" | sed 's/a/A/'
     bAr
     # or
     sed 's/a/A/' << EOF
     $foo
     EOF

Alcuni altri operatori ( >&-, x>&y x<&y) possono essere utilizzati per chiudere o duplicare i descrittori di file. Per i dettagli, consultare la relativa sezione del manuale della shell ( qui ad esempio per bash).

Questo riguarda solo gli operatori più comuni di shell tipo Bourne. Alcune shell hanno alcuni operatori di reindirizzamento aggiuntivi propri.

Ksh, bash e zsh hanno anche costrutti <(…), >(…)e =(…)(quest'ultimo uno in zshsolo). Non si tratta di reindirizzamenti, ma di sostituzione del processo .


2
Probabilmente varrebbe la pena notare che non tutte le shell sono uguali, e in particolare evidenziare le funzionalità specifiche di bash.
Greg Hewgill,

1
@GregHewgill sì, me ne sono liberato dicendo che sto discutendo riguardo a bash. Questo viene elaborato come una domanda e risposta canonica per chiudere le varie domande "Cosa fa questo strano coso" e la maggior parte di esse proviene da utenti di bash. Spero che qualcun altro lanci e risponda per shell non bash, ma evidenziare quelle specifiche per bash ha molto senso. Dovrò comunque controllare, non so quali siano al di sopra della mia testa.
terdon

&>, >>>e <<<sono tutti non-posix come è il riferimento a non solo caratteri non alfanici nel nome di un documento. Questa risposta discute anche molto poco di come funzionano - per esempio, è quasi peggio che inutile parlare di un semplice comando e di un comando senza spiegare cosa sono e come decide la shell.
Mikeserv,

@mikeserv grazie. Lavorano su bash e zsh però. Non so cosa, se non altro, sia veramente specifico per bash in quell'elenco. Dovrei passare attraverso questo e aggiungere le shell in cui funziona ciascuna, ma ciò implicherebbe scoprirlo prima.
terdon

1
@ Arc676 No, non valutano vero o falso, è un contesto completamente diverso. Questo significa solo che un valore di uscita diverso da 0 indica un problema (non false) e un codice di uscita 0 indica successo (non true). È sempre stato così ed è abbastanza standard. Un codice di uscita diverso da 0 indica un errore in ogni ambiente che conosco.
Terdon

61

Avvertenza relativa a ">"

I principianti di Unix che hanno appena appreso il reindirizzamento I / O ( <e >) spesso provano cose del genere

comando ... input_file > the_same_file

o

comando ... < file      > the_same_file

o, quasi equivalentemente,

file cat | comando ...> the_same_file

( grep, sed, cut, sort, E spellsono esempi di comandi che le persone sono tentati di utilizzare in costrutti come questi.) Gli utenti sono sorpresi di scoprire che questi scenari il risultato nel file di diventare vuoto.

Una sfumatura che non sembra essere menzionata nell'altra risposta può essere trovata in agguato nella prima frase della sezione Reindirizzamento di bash (1) :

Prima dell'esecuzione di un comando, l'input e l'output possono essere reindirizzati utilizzando una notazione speciale interpretata dalla shell.

Le prime cinque parole dovrebbero essere in grassetto, corsivo, sottolineato, ingrandito, lampeggiante, colorato di rosso e contrassegnato da punto esclamativo nel triangolo rossoun'icona, per sottolineare il fatto che la shell esegue i reindirizzamenti richiesti prima dell'esecuzione del comando . E ricorda anche

Il reindirizzamento dell'output provoca l'apertura del file ... per la scrittura ... Se il file non esiste, viene creato; se esiste, viene troncato a dimensione zero.

  1. Quindi, in questo esempio:

    sort roster > roster

    la shell apre il rosterfile per la scrittura, troncandolo (ovvero scartando tutto il suo contenuto), prima che il sortprogramma inizi a funzionare. Naturalmente, non è possibile fare nulla per recuperare i dati.

  2. Si potrebbe ingenuamente aspettarselo

    tr "[:upper:]" "[:lower:]" < poem > poem

    potrebbe essere migliore. Poiché la shell gestisce i reindirizzamenti da sinistra a destra, si apre poemper la lettura (per trinput standard) prima di aprirla per la scrittura (per output standard). Ma non aiuta. Anche se questa sequenza di operazioni produce due handle di file, entrambi puntano allo stesso file. Quando la shell apre il file per la lettura, i contenuti sono ancora lì, ma vengono comunque bloccati prima dell'esecuzione del programma. 

Quindi, cosa fare al riguardo?

Le soluzioni includono:

  • Controlla se il programma che stai eseguendo ha una propria capacità interna per specificare dove va l'output. Questo è spesso indicato da un -o(o --output=) token. In particolare,

    sort roster -o roster

    è approssimativamente equivalente a

    sort roster > roster

    tranne, nel primo caso, il sortprogramma apre il file di output. Ed è abbastanza intelligente da non aprire il file di output fino a quando non ha letto tutti i file di input.

    Allo stesso modo, almeno alcune versioni di sedhanno un'opzione -i(modifica i n place) che può essere utilizzata per riscrivere l'output nel file di input (di nuovo, dopo aver letto tutto l'input). Editor come ed/ ex, emacs, pico, e vi/ vim consentono all'utente di modificare un file di testo e salvare il testo modificato nel file originale. Si noti che ed(almeno) può essere utilizzato in modo non interattivo.

    • viha una funzione correlata. Se digiti , scriverà il contenuto del buffer di modifica in , leggerà l'output e lo inserirà nel buffer (sostituendo il contenuto originale).:%!commandEntercommand
  • Semplice ma efficace:

    comando ... input_file > temp_file   && mv temp_file  input_file

    Questo ha lo svantaggio che, se input_fileè un collegamento, sarà (probabilmente) sostituito da un file separato. Inoltre, il nuovo file sarà di tua proprietà, con protezioni predefinite. In particolare, ciò comporta il rischio che il file finisca per essere leggibile in tutto il mondo, anche se l'originale input_filenon lo era.

    variazioni:

    • commandinput_file > temp_file && cp temp_file input_file && rm temp_file
      che lascerà comunque (potenzialmente) temp_fileleggibile il mondo. Anche meglio:
    • cp input_file temp_file && commandtemp_file > input_file && rm temp_file
      Ciò preserva lo stato del collegamento, il proprietario e la modalità (protezione) del file, potenzialmente a un costo pari al doppio degli I / O. (Potrebbe essere necessario utilizzare un'opzione come -ao -pon cp per dirle di preservare gli attributi.)
    • commandinput_file > temp_file &&
      cp --attributes-only --preserve=all input_file temp_file &&
      mv temp_file input_file
      (suddiviso in righe separate solo per leggibilità) Ciò preserva la modalità del file (e, se sei root, il proprietario), ma lo rende di tua proprietà (se non sei root) e lo rende un nuovo, file separato.
  • Questo blog (modifica "sul posto" dei file) suggerisce e spiega

    {rm input_file   &&   command …> input_file ; } < file_input

    Ciò richiede che commandsia in grado di elaborare l'input standard (ma quasi tutti i filtri possono farlo). Il blog stesso lo definisce un kludge rischioso e scoraggia il suo utilizzo. E questo creerà anche un nuovo file separato (non collegato a nulla), di proprietà dell'utente e con autorizzazioni predefinite.

  • Il pacchetto moreutils ha un comando chiamato sponge:

    comando ... input_file | sponge the_same_file

    Vedi questa risposta per maggiori informazioni.

Ecco qualcosa che mi ha sorpreso completamente: syntaxerror dice :

[La maggior parte di queste soluzioni] fallirà su un file system di sola lettura, dove “sola lettura” significa che il tuo $HOME sarà scrivibile, ma /tmpsarà di sola lettura (per impostazione predefinita). Ad esempio, se hai Ubuntu e hai avviato la Console di ripristino di emergenza, questo è comunemente il caso. Inoltre, anche l'operatore del documento qui <<<non funzionerà lì, poiché richiede /tmpdi essere letto / scritto perché scriverà anche un file temporaneo.
(cfr. questa domanda include un strace'd output)

In questo caso potrebbe funzionare:

  • Solo per utenti esperti: se il tuo comando è garantito per produrre la stessa quantità di dati di output quanti sono gli input (ad es. sort, O tr senza l' opzione -do -s), puoi provare
    comando ... input_file | dd of = the_same_file conv = notrunc
    Vedi questa risposta e questa risposta per ulteriori informazioni, inclusa una spiegazione di quanto sopra, e alternative che funzionano se il tuo comando è garantito per produrre la stessa quantità di dati di output quanti sono gli input o meno (es. grep, O cut). Queste risposte hanno il vantaggio di non richiedere spazio libero (o richiedono pochissimo). Le risposte sopra del modulo richiedono chiaramente che ci sia abbastanza spazio libero affinché il sistema sia in grado di contenere l'intero file di input (vecchio) e output (nuovo) contemporaneamente; questo non è ovviamente vero per la maggior parte delle altre soluzioni (ad esempio, e ). Eccezione: probabilmente richiederà molto spazio libero, perchécommandinput_file > temp_file && …sed -ispongesort … | dd …sort deve leggere tutti i suoi input prima di poter scrivere qualsiasi output, e probabilmente buffererà la maggior parte se non tutti quei dati in un file temporaneo.
  • Solo per utenti esperti:
    comando ... input_file 1 <> the_same_file
    può essere equivalente alla ddrisposta sopra. La sintassi apre il file indicato sul descrittore di file sia per l'input che per l'output , senza troncarlo - una specie di combinazione di e . Nota: alcuni programmi (ad esempio, e ) potrebbero rifiutarsi di essere eseguiti in questo scenario perché possono rilevare che l'input e l'output sono lo stesso file. Vedi questa risposta per una discussione di cui sopra e uno script che faccia funzionare questa risposta se il tuo comando è garantito per produrre la stessa quantità di dati di output quanti sono gli input o meno . Avvertenza: non ho testato la sceneggiatura di Peter, quindi non lo garantisco.n<> filen n<n>catgrep

Allora, qual era la domanda?

Questo è stato un argomento popolare su U&L; è affrontato nelle seguenti domande:

... e questo non conta Super User o Ask Ubuntu. Ho incorporato molte informazioni dalle risposte alle domande precedenti qui in questa risposta, ma non tutte. (Vale a dire, per ulteriori informazioni, leggi le domande sopra elencate e le loro risposte.)

PS Non ho alcuna affiliazione con il blog che ho citato, sopra.


Poiché questa domanda continua a sorgere, ho pensato di provare a scrivere una "risposta canonica". Dovrei pubblicarlo qui (e forse collegarlo ad alcune delle altre domande più pesantemente trafficate) o dovrei spostarlo su una delle domande che solleva effettivamente questo problema? Inoltre, questa è forse una situazione in cui le domande dovrebbero essere unite?
Scott,

/ tmp Una directory resa disponibile per le applicazioni che necessitano di un posto per creare file temporanei. Le applicazioni devono poter creare file in questa directory, ma non devono presumere che tali file vengano conservati tra le invocazioni dell'applicazione.
Mikeserv,

@mikeserv: Sì, (1) sto citando syntaxerror e (2) ho detto che ero sorpreso. Ho pensato che, se qualcosa fosse stato letto-scritto, lo sarebbe /tmp.
Scott,

Bene, la cosa che @syntaxerror ha detto è doppiamente strana perché, come penso, dashsarebbe la shell di ripristino predefinita su Ubuntu e non solo non capisce un <<<herestring, ma ottiene anche pipe anonime per i documenti <<ereditari e non si scherza con ${TMPDIR:-/tmp}quello scopo a tutti. Vedi questo o questo per le demo sulla gestione dei documenti qui. Anche perché la stessa quantità di output o meno avviso?
Mikeserv,

@mikeserv: Bene, dd … conv=notrunce le 1<>risposte non troncano mai il file di output, quindi, se l'output del comando è inferiore all'input (es., grep), alla fine del file rimarranno alcuni byte dell'originale. E, se l'uscita è più grande l'ingresso (per esempio, cat -n, nl, o (potenzialmente) grep -n), c'è un rischio di sovrascrivere i vecchi dati prima hai letto.
Scott,

29

Ulteriori osservazioni su ;, &, (e)

  • Nota che alcuni dei comandi nella risposta di terdon potrebbero essere nulli. Ad esempio, puoi dire

    command1 ;

    (con no command2). Questo equivale a

    command1

    (vale a dire, gira semplicemente command1in primo piano e attende che si completi. Comparativamente,

    command1 &

    (senza command2) verrà avviato command1in background e quindi emetterà immediatamente un altro prompt della shell.

  • Al contrario, command1 &&, command1 ||, e command1 |non ha alcun senso. Se si digita uno di questi, la shell supporrà (probabilmente) che il comando continui su un'altra riga. Verrà visualizzato il prompt della shell secondario (continuazione), che è normalmente impostato su >, e continuerà a leggere. In uno script di shell, leggerà solo la riga successiva e la aggiungerà a ciò che ha già letto. (Attenzione: questo potrebbe non essere quello che vuoi che accada.)

    Nota: alcune versioni di alcune shell possono trattare tali comandi incompleti come errori. In tali casi (o, in effetti, in ogni caso in cui hai un comando lungo), puoi mettere una barra rovesciata ( \) alla fine di una riga per dire alla shell di continuare a leggere il comando su un'altra riga:

    command1  &&  \
    command2

    o

    find starting-directory -mindepth 3 -maxdepth 5 -iname "*.some_extension" -type f \
                            -newer some_existing_file -user fred -readable -print
  • Come dice terdon, (e )può essere usato per raggruppare i comandi. L'affermazione che "non sono veramente rilevanti" per quella discussione è discutibile. Alcuni dei comandi nella risposta di terdon potrebbero essere gruppi di comandi . Per esempio,

    ( command1 ; command2 )  &&  ( command3; command4 )

    fa questo:

    • Corri command1e aspetta che finisca.
    • Quindi, indipendentemente dal risultato dell'esecuzione di quel primo comando, esegui command2e attendi che finisca.
    • Quindi, se è command2riuscito,

      • Corri command3e aspetta che finisca.
      • Quindi, indipendentemente dal risultato dell'esecuzione di quel comando, esegui command4e attendi che finisca.

      In caso command2contrario, interrompere l'elaborazione della riga di comando.

  • Tra parentesi esterne, si |lega molto strettamente, quindi

    command1 | command2 || command3

    è equivalente a

    ( command1 | command2 )  ||  command3

    ed &&e ||legare più stretto di ;, in modo da

    command1 && command2 ; command3

    è equivalente a

    ( command1 && command2 ) ;  command3

    cioè, command3verrà eseguito indipendentemente dallo stato di uscita di command1e / o command2.


Perfetto, +1! Ho detto che non erano rilevanti perché non volevo entrare nei dettagli. Volevo una risposta che potesse funzionare come un rapido cheatheet per i neofiti che si chiedono quali siano tutti gli strani squiggles alla fine dei vari comandi. Non intendevo implicare che non fossero utili. Grazie per aver aggiunto tutto questo.
terdon

1
Sono preoccupato per il problema della "massa critica": se pubblichiamo tutto ciò che potremmo dire sulle shell, finiremo con la nostra versione TL; DR del Manuale di riferimento di Bash.
G-Man,

Vale anche la pena ricordare: a differenza dei linguaggi della famiglia C, di ;per sé (o senza un comando che lo precede) è un errore di sintassi e non un'istruzione vuota. Quindi ; ;è un errore. (Una trappola comune per i nuovi utenti, IMHO). Inoltre: ;;è un delimitatore speciale, per le casedichiarazioni.
muru,

1
@muru: buon punto, ma generalizziamolo. Qualsiasi degli operatori di controllo che possono apparire tra i comandi: ;, &&, ||, &, e |, sono errori se appaiono con nulla li precede. Inoltre, Terdon si è rivolto ;;(brevemente) nella sua risposta.
G-Man,

1
@Wildcard: OK, vedo da dove vieni. La parola chiave è "può"; tutto quello che stavo dicendo era che non garantisco che tutte le shell accetteranno tali costrutti (cioè YMMV). Ovviamente l'ho scritto prima di sapere dell'uso del linebreaktoken nella grammatica della shell POSIX. Quindi forse è sicuro affermare che tutte le shell conformi a POSIX le accetteranno. Attendo la mia dichiarazione come disclaimer generale; se trovi una shell pre-POSIX abbastanza vecchia, come una vera shell Bourne o precedente, tutte le scommesse sono disattivate.
G-Man,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.