Cosa significa $$ nella shell?


143

Una volta ho letto che un modo per ottenere un nome file univoco in una shell per i file temporanei era usare un doppio simbolo del dollaro ( $$). Questo produce un numero che varia di volta in volta ... ma se lo chiami ripetutamente, restituisce lo stesso numero. (La soluzione è usare solo il tempo.)

Sono curioso di sapere cosa sia $$effettivamente, e perché sarebbe suggerito come un modo per generare nomi di file unici.

Risposte:


102

In Bash $$è l'ID del processo, come indicato nei commenti, non è sicuro da usare come nome file temporaneo per una serie di motivi.

Per i nomi di file temporanei, utilizzare il mktempcomando


35
Per le persone che cercano solo la risposta migliore, $$ non va bene nemmeno per un singolo file se si scrive in una directory scrivibile pubblicamente (ad esempio, / tmp). È facile sporcare / tmp con collegamenti simbolici che potrebbero rendere indesiderabile la scrittura del tuo script. mktemp è molto meglio.
Chris Jester-Young,

4
Sì, l'uso di $$ causerà una brutta buca di sicurezza. Non farlo
emk,

7
Oppure la persona che ha posto la domanda dovrebbe impostare la risposta più votata di seguito come risposta accettata ...
jtimberman,

6
Aggiungo "dollaro" per il SEO.
Antoine,

1
Se $$ genera solo il pid, come può essere "non sicuro"? La falla di sicurezza è creata in virtù del design scadente e non dell'uso del PID nel nome del file tmp ... Se ti preoccupi dell'integrità dell'output che va così tanto in tmp, forse non dovresti nemmeno metterlo lì in primo luogo? $$ non causerà falle nella sicurezza, la mancanza di lungimiranza lo farà
niken il

113

$$è l'ID di processo (PID) in bash. L'uso $$è una cattiva idea, perché di solito crea una condizione di competizione e consente al tuo script di shell di essere sovvertito da un attaccante. Vedi, ad esempio, tutte queste persone che hanno creato file temporanei non sicuri e hanno dovuto rilasciare avvisi di sicurezza.

Invece, usa mktemp. La pagina man di Linux per mktemp è eccellente. Ecco un esempio di codice da esso:

tempfoo=`basename $0`
TMPFILE=`mktemp -t ${tempfoo}` || exit 1
echo "program output" >> $TMPFILE

3
Grazie. L' mktempopzione -tè ora obsoleta (penso a causa di problemi con il carattere -). Usa mktemp ${tempfoo}.XXXXXXquesti giorni . Mi prendo la libertà di aggiornare il tuo post.
Sebastian

1
Si noti inoltre che il backtick è obsoleto , quindi utilizzare TMPFILE=$(mktemp)invece.
Michael Kopp,


7

Ogni processo in un sistema operativo come UNIX ha un identificatore univoco (temporaneamente), il PID. Non ci sono due processi in esecuzione contemporaneamente possono avere lo stesso PID e $$ fa riferimento al PID dell'istanza bash che esegue lo script.

Questo è molto non è un idenifier unico, nel senso che non potrà mai essere riutilizzata (anzi, PID vengono riutilizzati in costante). Ciò che ti dà è un numero tale che, se un'altra persona esegue la tua sceneggiatura, otterrà un identificatore diverso mentre il tuo è ancora in esecuzione. Una volta che il tuo è morto, il PID potrebbe essere riciclato e qualcun altro potrebbe eseguire il tuo script, ottenere lo stesso PID e quindi ottenere lo stesso nome file.

In quanto tale, è davvero sensato dire "$$ dà un nome file tale che se qualcun altro esegue lo stesso script mentre la mia istanza è ancora in esecuzione, avranno un nome diverso".


5

$$ è il tuo PID. In realtà non genera un nome file univoco, a meno che tu non stia attento e nessun altro lo fa esattamente allo stesso modo.

In genere si crea qualcosa come / tmp / myprogramname $$

Esistono molti modi per risolverlo, e se stai scrivendo in posizioni in cui altre persone possono scrivere non è troppo difficile su molti sistemi operativi prevedere quale PID avrai e rovinare - immagina di essere in esecuzione come root e creo / tmp / yourprogname13395 come un link simbolico che punta a / etc / passwd - e ci scrivete dentro.

Questa è una brutta cosa da fare in uno script di shell. Se hai intenzione di usare un file temporaneo per qualcosa, dovresti usare una lingua migliore che ti permetterà almeno di aggiungere il flag "esclusivo" per aprire (creare) il file. Quindi puoi essere sicuro di non ostruire qualcos'altro.


3

$$ è il pid dell'attuale processo di shell. Non è un buon modo per generare nomi di file univoci.


3

$$ è il pid (ID processo) dell'interprete della shell che esegue lo script. Al momento è diverso per ogni processo in esecuzione su un sistema, ma col passare del tempo il pid si avvolge e, alla fine, ci sarà un altro processo con lo stesso pid. Finché stai eseguendo, il pid è unico per te.

Dalla definizione sopra dovrebbe essere ovvio che non importa quante volte usi $$ in uno script, restituirà lo stesso numero.

Puoi usare, ad esempio /tmp/myscript.scratch.$$ come file temporaneo per cose che non devono essere estremamente affidabili o sicure. È buona norma eliminare tali file temporanei alla fine dello script, utilizzando, ad esempio, il comando trap:

trap "echo 'Cleanup in progress'; rm -r $TMP_DIR" EXIT

2

È l'ID del processo bash. Nessun processo simultaneo avrà mai lo stesso PID.


2

$$ è l'id di processo della shell in cui è in esecuzione lo script. Per maggiori dettagli, consultare la pagina man per sh o bash. Le pagine man possono essere trovate usando una riga di comando "man sh" o cercando "manpage shell" sul web


2

Consentitemi di rispondere al secondo emk: non usare $$ da solo come qualcosa di "unico". Per i file, utilizzare mktemp. Per altri ID all'interno dello stesso script bash, usa "$$$ (data +% s% N)" per una ragionevole ragionevole possibilità di unicità.

 -k

0

Inoltre, puoi prendere il nome utente di accesso tramite questo comando. Per esempio.

echo $(</proc/$$/login id). After that, you need to use getent command.
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.