Qual è il significato di "_ ="?


29

Dopo aver eseguito il set -a var=99, posso trovare una frase nell'output di set:

...
TERM=xterm
UID=0
USER=root
VIRTUAL_ENV_DISABLE_PROMPT=1
_=var=99
colors=/etc/DIR_COLORS
...

Qualcuno potrebbe dirmi cosa significa "_ ="?

Noto che echo $varnon darà nulla. Se eseguo il set -a, quindi setnon includerà di nuovo questa variabile. Che cosa sta succedendo?


Risposte:


16

Quando esegui set -a var=99, accadono tre cose distinte (legate alla tua domanda):

  1. Un'opzione set ( -a) (indietro facendo set +a) per esportare var.
  2. I parametri posizionali sono "impostati" su ciò che segue le opzioni ( $1impostato su var=99).
  3. La sottolineatura della variabile di shell $_è impostata sull'ultimo parametro (espanso).

impostare -a

L'esecuzione di set -acontrassegna tutte le variabili successive (nuove o modificate) come esportate (in tutte le shell, ad eccezione di cshalcune shell correlate).

$ set -a
$ myvariable=wer
$ env | grep myvariable
myvariable=wer

Per ripristinare da questa impostazione, basta cambiare -in a +:

$ set +a
$ unset myvariable              # to erase it from the environment if it
                                # was exported before the change of set +a
$ myvariable=456544654          # A new value of the variable.
$ env | grep "variable"         # No output means the var does not exist
                                # in the current environment

impostare var = 99

Che dovrebbe effettivamente essere set -- var=99per evitare l'interpretazione di un'opzione (e set ha molto) con valori che iniziano con un trattino ( -).

Imposta l'elenco degli argomenti (l'elenco dei parametri posizionali) su quello dopo il --. Questo è valido in tutte le shell ragionevoli (non in csh et al). Gli argomenti posizionali vengono stampati con "$ @" (o "$ *" simile, non uguale).

$ set -- a=1 b=2 c=3
$ echo "$@"
a=1 b=2 c=3

_ = Last_argument

E il valore della variabile della shell interna _cambia all'ultimo argomento della riga eseguita. Questo NON è vero in quasi tutte le shell (jsh, ash, yash, dash, lksh, mksh, ksh93, attsh e ovviamente csh e tcsh) tranne bash.

$ echo one two last argument
one two last argument

$ echo "$_"
argument

$ echo This is a new: last_argument
This is a new: last_argument

$ echo "$_"
last_argument

Si noti che il valore in $_è il valore dopo l'espansione:

$ a="A New_Argument"
$ echo Something else to test: "$a"
Something else to test: A New_Argument

$ echo "$_"
A New_Argument

Ecco perché quando esegui:

$ set -a myvar=99; set | grep 'myvar'
_=myvar=99

Si ottiene una descrizione della variabile di shell '$ _'. Questo funziona anche:

$  set -a myvar=99; declare -p _
declare -- _="myvar=99"

37

Il trattino basso è in realtà una speciale variabile shell. Quello che vedi qui è la _variabile underscore ( ) con un valore di var=99. È di sola lettura e gestito dalla shell. È:

  • Impostato all'avvio della shell, contenente il nome file assoluto della shell o dello script in esecuzione come passato nell'elenco degli argomenti.
  • Successivamente, si espande fino all'ultimo argomento del comando precedente, dopo l'espansione.
  • Quando si controlla la posta, questo parametro contiene il nome del file di posta.
  • È inoltre impostato sul percorso completo di ciascun comando eseguito e inserito nell'ambiente esportato in quel comando.

Il tuo esempio rientra nella seconda categoria. Hai digitato:

set -a var=99  

Quindi l'ultimo argomento che c'era var=99, e quello era il valore che stavi impostando (non stavi impostando varsu 99). Quindi, è _stato impostato su quello. E questo è ciò che viene segnalato:

_=var=99  

È un po 'confuso, ma il primo =indica l'assegnazione alla variabile _e il secondo fa parte del valore.

Vale anche la pena ricordare che l' -aopzione setcauserà tutte le variabili successivamente definiti da esportare.


16

La risposta giusta dipende dalla shell che stai usando:

  • per bash, qualunque cosa si applichi a @BobEager
  • per zsh, è impostato solo sull'ultimo argomento del comando precedente e sul percorso completo del comando nell'ambiente del comando
  • alcune shell come dashimpostano questa variabile solo quando si esegue una sessione interattiva

Potrebbero esserci altre particolarità anche in altre shell. Come tale, non$_ è definito in POSIX, quindi si dovrebbe essere consapevoli dei potenziali problemi di portabilità quando lo si utilizza.

Nota a margine: se si intende assegnare il valore 99 vare renderlo disponibile nell'ambiente dei sottoprocessi successivi, la sintassi corretta per raggiungere questo obiettivo è:

export var=99

2
Una sintassi anche corretta è unset var;set -a; var=99. Funziona in tutte le shell resonable (non csh et al).
Arrow

1
@Arrow Anche se secondo l'ultima riga della risposta di Bob Eager questo renderebbe tutte le variabili impostate / modificate successivamente esportate, che potrebbe non essere quello che desideri.
TripeHound,

8

E noto echo $varche non darà nulla. ... che succede?

Nella stampa non così fine di bash (1) , troviamo

set[ --abefhkmnptuvxBCEHPT] [ nome-opzione ] [ arg ...]   [ ] [ nome-opzione ] [ arg ...]-o
set+abefhkmnptuvxBCEHPT+o

            ︙
    Quando vengono specificate le opzioni, impostano o annullano gli attributi della shell. Eventuali altri argomenti previa trasformazione opzione vengono trattati come valori per i parametri posizionali e vengono assegnati, in ordine, $1, $2, ... .$n

Ciò significa set -a var=99che non imposta la variabile di ambiente varsu 99; si imposta $1su var=99. Prova echo "$1"o echo "$*"e vedrai.

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.