Quando è `_` una variabile d'ambiente di una shell bash?


10

Bash Manual dice (manpage, la mia enfasi):

Quando Bash invoca un comando esterno, la variabile $_viene impostata sul percorso completo del comando e passata a quel comando nel suo ambiente.

E ( parametri speciali ):

_

( $_, un trattino basso). All'avvio della shell, impostare sul percorso assoluto usato per invocare la shell o lo script della shell in esecuzione come passato nell'ambiente o nell'elenco degli argomenti. Successivamente, si espande all'ultimo argomento al comando precedente, dopo l'espansione. Impostato anche sul percorso completo utilizzato per richiamare ciascun comando eseguito e inserito nell'ambiente esportato in quel comando. Quando si controlla la posta, questo parametro contiene il nome del file di posta.

  1. In una shell bash, corro:

    $ bash
    $ export | grep '_=' 
    

    Secondo il manuale, _dovrebbe essere una variabile d'ambiente della nuova shell bash. exportdovrebbe generare tutte le variabili d'ambiente della nuova shell bash, ma non produce _. Quindi mi chiedo se _sia una variabile d'ambiente della nuova shell bash?

  2. In realtà in qualsiasi shell bash, succede la stessa cosa

    $ export | grep '_='

    non genera nulla. Quindi mi chiedo se _c'è mai una variabile d'ambiente di una shell bash?

  3. Per confronto:

    $ dash
    $ export  | grep '_='        
    export _='/bin/dash'
    

Il mio post è ispirato al commento di Mike e alla risposta di Stephane .


1
È una variabile shell ed è passata all'ambiente del comando ; non è necessariamente esportato nell'ambiente della shell . exportè integrato, ma se lo usi printenv _ti mostrerà come è stato invocato: /usr/bin/printenvsu questo sistema.
Toby Speight,

Si noti che bash -c export | grep _=(da Bash), sarà mostrare come la shell genitore invocato il bashcomando, anche se $_non è impostata nel genitore.
Toby Speight,

Risposte:


13

Sì, _è una variabile d'ambiente della nuova shell Bash; puoi vederlo correndo

tr '\0' '\n' < /proc/$$/environ | grep _=

all'interno della shell: mostra il contenuto dell'ambiente iniziale della shell. Non lo vedrai nella prima shell perché non c'era una shell precedente per impostarla prima che iniziasse.

L'espansione $_all'interno di Bash si riferisce al _parametro speciale, che si espande all'ultimo argomento del comando precedente. (Internamente Bash lo gestisce usando una _variabile di shell, che viene aggiornata ogni volta che viene analizzato un comando, ma che in realtà è un dettaglio di implementazione. È “non esportata” ogni volta che viene analizzato un comando. ) exportNon mostra _perché non lo è una variabile contrassegnata come esportata; puoi comunque vederlo nell'output di set.

Nel primo esempio, i nuovi analizza shell Bash ed esegue i comandi nel suoi file di inizializzazione, così quando si esegue explore | grep '-=', _è già stato sovrascritto e contrassegnato come non esportati.

Nel dashesempio, non sembra per eseguire qualsiasi tipo di file di start-up, in modo che stai vedendo la variabile come una variabile d'ambiente che è stato messo da Bash prima di eseguire dash.


Grazie. Nella nuova shell bash, perché non export | grep '_='emette nulla? Nella shell bash originale, perché non tr '\0' '\n' < /proc/$$/environ | grep _=emette nulla?
Tim


9

exportsenza argomenti elenca tutte le variabili esportate . _non è una variabile, ma è elencato come parametro speciale .

Un po 'confuso, _sarebbe anche un nome valido per una variabile , a differenza dei nomi degli altri parametri speciali. Almeno Bash 4.4 consente assegnazioni ad esso, senza lamentele. Non è utile perché l'effetto speciale sovrascrive immediatamente il valore.


2
Divertiti cercando di usare _come variabile però ;-). È effettivamente di sola scrittura e il valore viene perso immediatamente.
Stephen Kitt,

1
Inoltre, internamente Bash tratta _come una variabile, motivo per cui appare nell'output di set. Tuttavia non può essere contrassegnato come esportato per quanto posso determinare.
Stephen Kitt,

2
@StephenKitt, ma Bash 4.4 consente di contrassegnarlo come di sola lettura. O un numero intero. Con risultati un po 'esilaranti.
ilkkachu,

1
Ah, bella scoperta, è piuttosto divertente!
Stephen Kitt,

5

Non tutte le variabili di shell sono contrassegnate come esportate come si può vedere nell'output di declare -p.

Non ha alcun senso bashcontrassegnare $_come esportato perché aggiunge automaticamente questa variabile all'ambiente dei processi figlio ma con un valore diverso da quello che ha nella shell (in quel momento).

Mostrarlo come esportato confonderebbe semplicemente l'utente su ciò che accadrà con l'ambiente dei comandi esterni.

Tutte le "variabili di runtime" BASH*non vengono esportate.

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.