GNU/Linux >> Linux Esercitazione >  >> Linux

I Bash Test sono così esigenti riguardo agli spazi bianchi?

Come programmatore principalmente Java, trovo bash ifthen costruire abbastanza confuso, specialmente per quanto riguarda gli spazi bianchi. Qualcuno può spiegare perché il primo funziona, ma non il secondo o il terzo?

#works
if [ -n $1 ]; then echo "parameterized"; fi

#output: ./links: Zeile 1: [-n: Kommando nicht gefunden.
if [-n $1 ]; then echo "parameterized"; fi

#output: ./links: Zeile 1: [: Fehlende `]'
if [ -n $1]; then echo "parameterized"; fi

Risposta accettata:

L'incoerenza è in gran parte dovuta a ragioni storiche.

L'uso delle parentesi come comando condizionale è arrivato dopo l'uso delle parentesi nei modelli di caratteri jolly. Quindi al momento [ -n foo ] è entrato in scena, [foo] già significava “un file il cui nome è f o o ”. Mentre pochi usi dell'operatore parentesi nella pratica sarebbero stati in conflitto con usi realistici delle parentesi nei caratteri jolly, gli autori hanno scelto di non rischiare di rompere gli script esistenti cambiando la sintassi. Questa scelta progettuale ha anche semplificato l'implementazione:inizialmente [ è stato implementato come comando esterno, cosa che non sarebbe stata possibile se fosse stato inserito lo spazio dopo [ era stato facoltativo. (I sistemi moderni hanno ancora [ come comando esterno, ma quasi tutte le shell moderne lo hanno anche integrato.)

Per ragioni simili, il tuo codice "funzionante" è effettivamente errato nella maggior parte dei casi. $1 non significa “il valore del parametro 1”:significa “prendere il valore del parametro 1, dividerlo in parole separate in uno spazio bianco (o qualunque sia il valore di IFS è) e interpreta ogni parola come un modello glob”. Il modo per scrivere "il valore del parametro 1" richiede virgolette:"$1" . Vedere Quando è necessaria la doppia virgoletta? per il nocciolo della questione. Non è necessario capirlo; tutto ciò che devi ricordare è:metti sempre virgolette tra le sostituzioni delle variabili "$foo" e sostituzioni di comandi "$(foo)" . Quindi:

if [ -n "$1" ]; then …

In bash, ksh e zsh, ma non in sh normale, puoi anche usare parentesi doppie. Parentesi singole [ … ] vengono analizzati come un normale comando (e infatti [ è un comando ordinario, sebbene di solito integrato). Le doppie parentesi sono un costrutto sintattico separato e puoi omettere le doppie virgolette la maggior parte delle volte.

if [[ -n $1 ]]; then …

Tuttavia, c'è un'eccezione:[[ "$foo" = "$bar" ]] per verificare se le due variabili hanno lo stesso valore sono necessarie virgolette intorno a $bar , altrimenti $bar viene interpretato come un modello di caratteri jolly. Ancora una volta, invece di ricordare i dettagli, potresti anche usare sempre le virgolette doppie.

Correlati:A partire da bash:argomenti -lt e -gt?
Linux
  1. Parentesi in condizione if:perché ricevo errori di sintassi senza spazi bianchi?

  2. Differenza tra variabili Shell che vengono esportate e quelle che non sono in Bash?

  3. Quali caratteristiche ci sono in Zsh e mancano da Bash o viceversa?

  4. Quali sono i separatori di parole Readline?

  5. Le stringhe mancano dopo aver concatenato due o più stringhe variabili in Bash?

Bash Shebang

Cos'è ZFS? Perché le persone ne vanno pazze?

Cosa devono sapere gli amministratori di sistema sull'utilizzo di Bash

Dichiarazioni di Bash If-Else:tutto ciò che devi sapere

Utili comandi Bash di cui potresti non essere a conoscenza

Comprendere come gli input vengono inviati alle pipe in Bash