Cosa significa la sostituzione $ {! Var_name + x}?


Risposte:


17

Nella bashshell, ${!var}è una indiretta variabile. Si espande al valore della variabile di cui viene mantenuto il nome $var.

L'espansione della variabile ${var+value}è un'espansione POSIX che si espande a valuese la variabile varè impostata (indipendentemente dal fatto che il suo valore sia vuoto o meno).

Combinando questi, ${!var+x}si espanderebbe xse la variabile il cui nome è mantenuto $varè impostata.

Esempio:

$ foo=hello
$ var=foo
$ echo "${!var+$var is set, its value is ${!var}}"
foo is set, its value is hello
$ unset foo
$ echo "${!var+$var is set, its value is ${!var}}"

(riga vuota come output)


La funzione nella domanda potrebbe essere abbreviata in

check_if_variable_is_set () { [ -n "${!1+x}" ]; }

o anche:

check_if_variable_is_set () { [ -v "$1" ]; }

o anche:

check_if_variable_is_set()[[ -v $1 ]]

Dov'è -vun bashtest su un nome di variabile che sarà vero se la variabile nominata è impostata, e falso altrimenti.


POSIXly, potrebbe essere scritto:

check_if_variable_is_set() { eval '[ -n "${'"$1"'+x}" ]'; }

Si noti che tutte queste sono potenziali vulnerabilità nell'iniezione di comandi se l'argomento di tale funzione potrebbe finire per essere sotto il controllo di un utente malintenzionato. Prova ad esempio con check_if_variable_is_set 'a[$(id>&2)]'.

Per evitare ciò, è possibile verificare prima che l'argomento sia un nome di variabile valido. Per le variabili:

check_if_variable_is_set() {
  case $1 in
    ("" | *[![:alnum:]_]* | [![:alpha:]_]*) false;;
    (*)  eval '[ -n "${'"$1"'+x}" ]'
  esac
}

(nota che [[:alpha:]]controllerà i caratteri alfabetici nelle tue impostazioni locali mentre alcune shell accettano solo i caratteri alfabetici dal set di caratteri portatile nella loro variabile)


Non c'è nulla al mondo più completo di questo. Ti meriti un cookie per questo.
Karim Manaouil,

@KarimManaouil Un terzo di quel biscotto va a Stéphane però :-)
Kusalananda
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.