La cosa importante da capire è che l' ~
espansione è una caratteristica della shell (di alcune shell), non è un personaggio magico che significa la tua home directory ovunque venga usata.
Viene espanso (dalla shell, che è un'applicazione utilizzata per interpretare le righe di comando), come $var
viene espanso al suo valore in alcune condizioni se utilizzato in una riga di comando della shell prima dell'esecuzione del comando.
Quella funzionalità apparve per la prima volta nella shell C alla fine degli anni '70 (la shell Bourne non ce l'aveva, né il suo predecessore la shell Thompson), fu successivamente aggiunta alla shell Korn (una shell più recente costruita sulla shell Bourne nella anni 80). Alla fine è stato standardizzato da POSIX ed è ora disponibile nella maggior parte delle shell, incluse quelle non POSIX come fish
.
Dato che è molto diffuso nelle shell, alcune applicazioni non shell lo riconoscono anche come home directory. Questo è il caso di molte applicazioni nelle loro file di configurazione o la loro propria linea di comando ( mutt
, slrn
, vim
...).
bash
in particolare (che è il guscio del progetto GNU e ampiamente utilizzati in molti sistemi operativi basati su Linux), quando invocata sh
, segue lo più le regole POSIX circa ~
espansione, e in aree non indicate da POSIX, si comporta principalmente come shell Korn (di di cui è un clone parziale).
Mentre $var
viene espanso nella maggior parte dei luoghi (tranne all'interno di virgolette singole), l' ~
espansione, essendo un ripensamento viene espansa solo in alcune condizioni specifiche.
Si espande quando è sul proprio argomento in contesti di elenchi, in contesti in cui è prevista una stringa.
Ecco alcuni esempi di dove è espanso bash
:
cmd arg ~ other arg
var=~
var=x:~:x
(richiesto da POSIX, utilizzato per variabili come PATH
, MANPATH
...)
for i in ~
[[ ~ = text ]]
[[ text = ~ ]]
(l'espansione ~
dell'essere preso come modello in AT&T ksh
ma non bash
dalla 4.0).
case ~ in ~) ...
${var#~}
(anche se non in altre conchiglie)
cmd foo=~
(anche se non quando viene invocato come sh
, e solo quando ciò che è a sinistra del =
è a forma di non quotatobash
nome di variabile )
cmd ~/x
(richiesto ovviamente da POSIX)
cmd ~:x
(ma non x:~:x
ox-~-x
)
a[~]=foo; echo "${a[~]} $((a[~]))"
(non in alcune altre conchiglie)
Ecco alcuni esempi in cui non è espanso:
echo "~" '~'
echo ~@ ~~
(nota anche che ~u
è destinato ad espandersi nella home directory dell'utente u
).
echo @~
(( HOME == ~ ))
, $(( var + ~ ))
- con
extglob
: case $var in @(~|other))...
(sebbenecase $var in ~|other)
sia OK).
./configure --prefix=~
(poiché --prefix
non è un nome di variabile valido)
cmd "foo"=~
(nel bash
, a causa delle virgolette).
- Quando invocato come
sh
: export "foo"=~
,env JAVA_HOME=~ cmd
...
Per quanto riguarda ciò che si espande a: ~
da solo si espande nel contenuto della HOME
variabile, o quando non è impostato, nella directory home dell'utente corrente nel database degli account (come estensione poiché POSIX lascia quel comportamento indefinito).
Va notato che in ksh88 e nelle bash
versioni precedenti alla 4.0, l'espansione tilde è stata sottoposta a globbing (generazione del nome file) in contesti di elenco:
$ bash -c 'echo "$HOME"'
/home/***stephane***
$ bash -c 'echo ~'
/home/***stephane*** /home/stephane
$ bash -c 'echo "~"'
~
Questo non dovrebbe essere un problema nei soliti casi.
Si noti che, poiché è espanso, lo stesso avviso si applica ad altre forme di espansioni.
cd ~
Non funziona se $HOME
inizia con -
o contiene ..
componenti. Quindi, anche se è molto improbabile che faccia alcuna differenza, a rigor di termini, si dovrebbe scrivere:
cd -P -- ~
O anche:
case ~ in
(/*) cd -P ~;;
(*) d=~; cd -P "./$d";;
esac
(per coprire valori $HOME
come -
, +2
...) o semplicemente:
cd
(come cd
ti porta alla tua home directory senza alcun argomento)
Altre shell hanno ~
espansioni più avanzate . Ad esempio, inzsh
, abbiamo:
~4
, ~-
,~-2
(Con il completamento) utilizzato per espandere le directory nel vostro stack delle directory (i luoghi che hai cd
a prima).
- directory con nome dinamico . È possibile definire il proprio meccanismo per decidere come
~something
viene espanso.
~
che sarà equivalente a$HOME
in qualsiasi ambiente POSIX; Ma potrei sbagliarmi.