Quali sono alcuni casi in cui il numero di spazi è importante negli script bash (o altra shell)


14

Mi è stato detto che gli spazi sono importanti in basho altri script di shell e non dovrei cambiare l'esistenza degli spazi se non so cosa sto facendo. "Cambiando l'esistenza" intendo o inserire uno spazio tra due caratteri non spaziali o rimuovere uno spazio tra due caratteri non spaziali, ad esempio cambiando var="$val"in var ="$val"o viceversa. voglio chiedere

Ci sono casi in cui l'uso di un singolo spazio o l'utilizzo di più spazi consecutivi in ​​uno script di shell fa la differenza? .

(Naturalmente, inserire / eliminare uno spazio tra virgolette fa la differenza, come passare da echo "a b"a echo "a b"o viceversa. Sto cercando esempi diversi da questo esempio banale.)

Mi sono imbattuto in questa domanda, ma quella riguarda l'aggiunta e la rimozione di spazi tra due caratteri non spaziali per i quali conosco molti esempi che farebbero la differenza.

Qualsiasi aiuto sarebbe apprezzato. Includi più varietà di conchiglie, se possibile.

Risposte:


19

Al di fuori delle virgolette, la shell usa spazi bianchi (spazi, tabulazioni, nuova riga, ritorno a capo, ecc.) Come separatore di parole / token. Questo significa:

  • Le cose non separate da spazi bianchi sono considerate come una "parola".
  • Le cose separate da uno o più caratteri di spazi bianchi sono considerate come due (o più) parole.

Il numero effettivo di caratteri di spazio tra ogni "cosa" non ha importanza, purché ce ne sia almeno uno.


Grazie. Non riesco a trovare alcun contro esempio da solo. Voglio solo essere sicuro.
Weijun Zhou,

2
Bash considera anche i feed di modulo e le schede verticali come spazi bianchi.
fpmurphy,

vero. originariamente ho scritto "... newline, ecc" e poi l'ho modificato per aggiungere esplicitamente ritorni a capo. lasciato cadere accidentalmente il 'etc'.
Cas

Cosa succede se il numero di spazi è così grande, che il programma non può adattarsi alla memoria?
Worse_Username

7
@Worse_Username Lo spazio bianco non deve rientrare nella memoria. Ho appena creato uno script da 48 GB su una macchina con 8 GB di RAM e 20 GB di swap. Funzionava bene. Ci sono voluti 3 minuti per sgretolare tutto quello spazio bianco, ma alla fine ha eseguito con successo un echocomando con tanto spazio bianco tra il comando e l'argomento.
Kasperd,

23

Questo è probabilmente un imbroglio, ma questo:

rm foo\ bar         # "delete the file named 'foo bar'"

è diverso da questo:

rm foo\  bar        # "delete the files named 'foo ' and 'bar'"

anche se gli spazi non sono tra virgolette. ;-)

Più confusamente, questo:

rm \
    foo          # "delete the file named 'foo'"

è diverso da questo:

rm \ 
    foo          # "delete the file named ' ', then run the command 'foo'"

anche se sembrano identici!


Anche se gli spazi non sono tra virgolette, la barra rovesciata è funzionalmente simile alla forma di virgolette e la metterei nella stessa categoria del "banale esempio" della domanda. (È interessante però.)
David Z,

12

Se noi non parliamo del carattere di spazio ( U+0020), ma qualsiasi carattere di spazio ( U+0020, \n, \t, etc.), poi un caso particolare mi vengono in mente: Qui-Documenti.

Questo codice (usando gli spazi):

cat <<- 'EOF'
<space><space>foo
EOF

Stampa:

  foo

Ma questo codice (usando le schede):

cat <<- 'EOF'
<tab><tab>foo
EOF

Stampa:

foo

Questo perché ( come afferma POSIX ):

Se l'operatore di reindirizzamento lo è <<-, tutti i caratteri <tab> iniziali devono essere rimossi dalle righe di input e dalla riga contenente il delimitatore finale.


1
È interessante. Ho pensato ai documenti qui, ma non conoscevo l' <<-operatore. Grazie mille.
Weijun Zhou,

qui i documenti sono una forma di testo tra virgolette, non un codice shell. la suddivisione delle parole della shell non si applica.
Cas

2

Ha anche un effetto quando si scrivono le dichiarazioni di assegnazione. Come se dico FOO=xyzche creerà una variabile d'ambiente chiamata FOOcon valore xyz, ma se separo gli uguali con uno spazio, penserà che sto invocando un programma chiamato FOOcon l'arg =xyz. Quindi importa quando si tratta di una certa sintassi.


Generalmente FOO=xyzcrea una variabile di shell interna ma non una variabile di ambiente. Ne hai bisogno set -ao export FOO=xyzper quello (cioè renderlo parte dell'ambiente di sottoprocessi non subshell).
Hauke ​​Laging,
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.