Inizializzazione delle variabili di Bash: è richiesta, consigliata o definita man mano che procedi


9

C'è qualche vantaggio / svantaggio di inizializzare il valore di una variabile bash nello script, prima del codice principale o delle variabili locali in una funzione prima di assegnare ad esso il valore effettivo?

Devo fare qualcosa del genere:

init()
{
    name=""
    name=$1
}

init "Mark"

Esiste il rischio che le variabili vengano inizializzate con valori di immondizia (se non inizializzati) e che abbiano un effetto negativo sui valori delle variabili?


2
Dove hai preso questa idea?

6
@DoritoStyle Bene, se uno è abituato a linguaggi di livello inferiore, come C, allora questa è una cosa perfettamente valida di cui preoccuparsi.
Kusalananda

@Kusalananda Non è l'equivalente C di quel codice name = ""; name = argv[1];? E non è altrettanto inutile?
Joseph Sible: ripristina Monica il

1
@ JosephSible-ReinstateMonica Sì. Il codice C che hai pubblicato è inutile. In C, invece, a differenza della shell, le variabili non inizializzate non hanno un valore ben definito. Ciò significa che l'inizializzazione di variabili in linguaggi come C ha senso in molte circostanze. Non è necessario farlo nella shell. Inizializzare una variabile in C solo per impostarla immediatamente su un altro valore non ha senso, come fai notare.
Kusalananda

Risposte:


22

Non vi è alcun vantaggio nell'assegnare una stringa vuota a una variabile e quindi nell'assegnare immediatamente un'altra stringa di variabile. Un'assegnazione di un valore a una variabile di shell sovrascriverà completamente il suo valore precedente.

Per quanto ne sappia, non esiste alcuna raccomandazione che affermi che è necessario inizializzare esplicitamente le variabili in stringhe vuote. In effetti, farlo potrebbe mascherare errori in alcune circostanze (errori che sarebbero altrimenti evidenti se in esecuzione sotto set -u, vedi sotto).

Una variabile non impostata, non utilizzata dall'inizio di uno script o non esplicitamente eseguita eseguendo il unsetcomando su di essa, non avrà alcun valore. Il valore di tale variabile non sarà nulla. Se usato come "$myvariable", otterrai l'equivalente di ""e non otterrai mai "dati inutili".

Se l'opzione della shell nounsetè impostata con uno dei due set -o nounseto set -u, quindi facendo riferimento a una variabile non impostata, la shell produrrà un errore (e una shell non interattiva terminerebbe):

$ set -u
$ echo "$myvariable"
/bin/sh: myvariable: parameter not set

o, in bash:

$ set -u
$ echo "$myvariable"
bash: myvariable: unbound variable

Le variabili di shell verranno inizializzate dall'ambiente se il nome della variabile corrisponde a una variabile di ambiente esistente.

Se ti aspetti di utilizzare una variabile che può essere inizializzata dall'ambiente in questo modo (e se è indesiderata), puoi disinserirla esplicitamente prima della parte principale dello script:

unset myvariable    # unset so that it doesn't inherit a value from the environment

che lo rimuoverà anche come variabile d'ambiente, oppure potresti semplicemente ignorare il suo valore iniziale e sovrascriverlo semplicemente con un'assegnazione (che farebbe cambiare anche il valore della variabile d'ambiente).

Non vedresti mai immondizia non inizializzata in una variabile shell (a meno che, come indicato, quell'immondizia esistesse già in una variabile d'ambiente con lo stesso nome).


3
Sebbene non vi sia alcun valore per impostare una variabile su un valore vuoto e quindi impostarla immediatamente come letteralmente OP, esiste un valore nell'impostazione di un valore vuoto (o unsetting) prima di eseguire un tipo di foro whileciclo per impostarlo su un valore calcolato valore se esiste la possibilità che il loop non venga effettivamente eseguito a causa del mancato rispetto delle condizioni; e la variabile potrebbe essere stata impostata su qualche altro valore nell'ambiente ereditato dallo script. Ma è probabilmente meglio mettere tutto in a main()e definire le variabili come local.
Monty Harder,

È inoltre possibile rilevare le variabili non impostate utilizzando gli operatori di espansione dei parametri, omettendo :, ad esempio${myvariable-defaultvalue}
Barmar

3

Modifica : Whoops, apparentemente la dichiarazione è diversa dall'inizializzazione. Lascio questo qui comunque in modo che programmatori principianti come me possano imparare dal mio errore.


Il vantaggio di dichiarare variabili locali in una funzione è che puoi facilmente copiare il codice.

Ad esempio, supponiamo che io abbia una funzione:

foo(){
    local name
    name="$1"
    echo "$name"
}

Se voglio trasformarlo in uno script, ignoro semplicemente l' localaffermazione e copio tutto il resto:

#!/bin/bash
name="$1"
echo "$name"

Se la dichiarazione e l'assegnazione fossero nella stessa riga, dovrei modificare manualmente la localparte prima di poterla trasformare in uno script:

foo(){
    local name="$1"
    echo "$name"
}

In questo esempio non è un grosso problema, ma se hai a che fare con funzioni più grandi e complesse, può diventare più doloroso.


1
La domanda non riguardava la combinazione della dichiarazione e l'inizializzazione. Si trattava di inizializzare con un valore vuoto prima di assegnare un valore reale.
Barmar,

@Barmar Oh, ho appena cercato "inizializzazione". Pensavo fosse sinonimo di "dichiarazione" ...
wjandrea,
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.