Come funziona l'uso della tilde come collegamento alla mia directory home?


30

Ero confuso, cercando di copiare alcuni file da un PC a un altro. L'ho capito, ma la sintassi mi confonde ancora. Questo funziona:

scp ~/Desktop/Volenteer.png jay@server.ip:~j0h/b

che mette Volenteer.pngnella cartella /home/j0h/b. Tuttavia, questo non funziona:

scp ~Desktop/Volenteer.png     jay@server.ip:~j0h/b

Anche questo non riesce, dando un file con stato di uscita 1 non trovato:

scp ~/Desktop/Volenteer.png     jay@server.ip:~/j0h/b

Come fa questo:

scp ~Desktop/Volenteer.png     jay@server.ip:~j0h/b

Quindi, chiaramente, c'è qualche differenza tra ~e ~/ Quella differenza è la presenza di/

$~/
bash: /home/j0h/: Is a directory
$ ~
bash: /home/j0h: Is a directory

Quindi, perché in SCP, la ~risoluzione lo fa ~/? Questa è una supposizione, non posso verificare che sia ciò che sta accadendo. Ma sembra incoerente e quindi confuso. È un bug in SCP? o c'è qualcosa di tilde che mi manca?


2
Solo una nota a margine qui, è scritto "volontario", con una "u" invece di una "e" :)
AER

2
Sono uno speller liberale.
j0h

Risposte:


68

~ è la tua home directory.

~fooè la directory home dell'utente foo, se esiste tale utente, o solo una directory denominata ~foo, se l'utente non esiste.


Quindi, in:

scp ~Desktop/Volenteer.png     jay@server.ip:~j0h/b

~Desktopsi espanderà nella home directory dell'utente Desktop, se tale utente esiste (e di solito non lo è), o sarà solo ~Desktop(un percorso che di solito non esiste).


Nel:

scp ~/Desktop/Volenteer.png     jay@server.ip:~/j0h/b

~/j0hsi espanderà in una directory denominata j0hnella jayhome directory, che, di nuovo, è improbabile che esista.


Non è ~e ~/dove si verifica la differenza, ma in ~e ~foo.


Inoltre, ~può essere utilizzato anche per la navigazione della cronologia delle directory:

  • ~-è la directory di lavoro precedente (come $OLDPWD)
  • ~+è la directory di lavoro corrente (come $PWD)

Questo non è applicabile a scp, poiché non è possibile cambiare directory durante scpun'operazione.

E se usi pushdepopd per mantenere uno stack di directory, e sarebbe la directory th nello stack di directory, come si vede nell'output di . sarebbe la th directory dalla fine (contando da zero, in entrambi i casi). Per esempio:~N~+NNdirs~-NN

$ for i in etc usr var tmp; do pushd /$i; done
/etc ~/.vim
/usr /etc ~/.vim
/var /usr /etc ~/.vim
/tmp /var /usr /etc ~/.vim

$ dirs
/tmp /var /usr /etc ~/.vim

Quindi, è possibile accedere alle directory nello stack utilizzando:

/tmp /var /usr /etc ~/.vim
  ~0   ~1   ~2   ~3     ~4
 ~+0  ~+1  ~+2  ~+3    ~+4
 ~-4  ~-3  ~-2  ~-1    ~-0 
  ~+   ~-

Quindi, ~+è sempre equivalente a .allora, giusto? Sembra ridondante.
Wildcard

1
@Wildcard bene, non esattamente. ~+e ~-usa i valori di $PWDe $OLDPWD, che sono percorsi assoluti. .è sempre un percorso relativo. Quindi, se c'è un comando che cambia l'attuale directory di lavoro durante l'esecuzione, vedrà il nuovo percorso per ., in cui il percorso espanso ~-rimarrà lo stesso. tar -Cè un esempio, anche se ammetto che non riesco a pensare a un buon uso per ~+. $PWDsarebbe altrettanto buono, tranne per il fatto che non è necessario citare ~+/foo/barse $PWDcontiene spazi.
muru,

1
Grazie, questo lo chiarisce. In realtà è un buon esempio di caso d'uso proprio lì: alcuni comandi rifiutano di operare su percorsi relativi per motivi di sicurezza; con tali comandi non puoi usare ./filenamema puoi usare "$PWD/filename"o più semplicemente ~+/filename. (E alcuni comandi funzioneranno su percorsi relativi ma c'è una differenza funzionale, come lno tar.)
Carattere jolly

21

Leggi la documentazione GNU per Bash Tilde Expansion (come avrei dovuto prima della mia prima iterazione di questa risposta).

~/Desktope ~j0hstanno facendo cose sostanzialmente diverse, il che spiega perché ~Desktopnon funziona:

  • Viene ~sostituita una semplice per la $HOMEvariabile di ambiente corrente , impostata al login. Quindi ~risolve /home/oliper me e ~/Desktoplegge come /home/oli/Desktop. Qui è dove vedi la tilda più utilizzata.

  • ~usernamesi risolve a casa dell'utente , come impostato in /etc/passwd. Quindi ~olirisolve /home/oli, ~j0hpotrebbe risolversi, /home/j0hma non necessariamente, il tuo homedir può essere ovunque.

  • ~not-a-usernamenon si risolve. Perché Desktopnon è un utente, ~Desktopnon viene sostituito. Viene preso letteralmente come un file o percorso denominato ~Desktop(che non esiste qui).

E inutile dirlo, tutto sta accadendo da remoto (sarebbe inutile scpse fosse sostituito con valori locali). Questo funziona perché Bash non sostituirà ~...se è preceduto da nient'altro che spazi bianchi.


Cosa getent passwd bindice?
muru,

2
"bin" è un utente di sistema sulla maggior parte delle macchine Linux, con una home directory di / bin.
fNek

1
La mancata espansione ~dirè coerente con i documenti GNU: "... i caratteri nel prefisso tilde che segue la tilde vengono trattati come un possibile nome di accesso ... Se il nome di accesso non è valido o l'espansione della tilde non riesce, la parola rimane invariato. " Qui, dirnon è il nome di un utente su questo sistema, quindi rimane invariato.
apsillers il

Ringrazia tutti. Probabilmente dovrei leggere i link che inserisco :)
Oli

4

Il simbolo ~viene utilizzato come scorciatoia per /home/userin bash, quindi nel caso di ~/Desktop/Volenteer.pngesso è una scorciatoia per /home/user/Desktop/Volenteer.png.

Come puoi vedere /, come sempre, mostra un nuovo livello nella gerarchia del file system.


3
solo a metà, è una scorciatoia per la variabile d'ambiente $ HOME. ~{user}/potrebbe essere qualsiasi percorso casuale impostato dal file di database passwd (5). Anche se sì, gli standard filesytem.org collocano utenti regolari in / home, non è così per tutti gli utenti (ad esempio root in / root e servizi in / var / ... o precedenti unixies che utilizzano / usr anziché / home)
Dwight Spencer,

DwightSpencer è corretto. Mantengo diversi server in cui gli utenti sono in / usr / {CLIENTNAME} / home / e sono condivisi su più sistemi interni e remoti (tutti puntano a quella directory), quindi è necessario mantenere solo 1 sistema. E ~ indica quella directory;)
Rinzwind

3
@Rinzwind eek. Devo protestare per questo sacrilego abuso di /usr.
muru,

@muru hey non è stata la MIA chiamata>: - D Era rimasto da SCO D:
Rinzwind

1
Onestamente mi è piaciuto l'uso di / usr per tutte le cose dell'utente poiché questo era quello che originariamente significava. Quello che trovo in questi giorni è l'uso più sacrilego di / usr / bin come una grande discarica unificata di tutti i binari (sys, user, sysop) al di fuori delle binutils di base. Dopotutto / usr era inteso come tutto ciò a cui gli utenti hanno accesso da un mount nfs mentre / usr / local era lo spazio utente locale con / sbin come binari sysop e binari di sistema / bin. Ho capito che / home può essere una partizione diversa, ma così / usr / home / ... tenerlo in / usr lo mantiene come spazio dei nomi utente sia nella politica, nell'implementazione e nella mentalità.
Dwight Spencer,

3

~è una scorciatoia per la variabile d'ambiente $HOMEsulla maggior parte delle derivate shell c / che supporta shell compatibili POSIX. l'uso più comune ~è quando si fa riferimento alla propria home directory o a quella della home di un altro utente:

cd ~ # ie shell, take me to my home folder

cd ~root # i.e. shell, take me to root's home folder

Per trovare la home directory per qualsiasi utente locale su un sistema POSIX (UNIX, Linux, OS X, BSD) che utilizza il database passwd (5), eseguire awk su in questo /etc/passwdmodo:

awk -F: '{ print $1,$(NF-1) }' /etc/passwd

Questo elencherà ogni utente locale e la loro home directory.

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.