Perché non riesco a eseguire il cd su una tilde tra virgolette ('~')?


33

Scrivere il mio primo copione quindi sono sicuro che questa è una domanda di base, ma qualcuno può spiegarmi perché posso:

cd ~
cd bin
cd ~/bin
cd 'bin'

Ma no

cd '~'
cd '~/bin'

Ho bisogno di cdun percorso di directory con uno spazio in uno dei nomi di directory, quindi ho bisogno delle virgolette (è Windows Program Filessotto vino). Posso aggirarlo con due cdcomandi, ma perché non riesco a mettere ~tra virgolette?

Se scrivo cd '~'(o cd "~") ottengo:

bash: cd: ~: No such file or directory

29
Chiediti questo: se non funzionasse in questo modo, come entreresti cdin una directory chiamata ~?
Jörg W Mittag,

2
Come sidenote, se stai scrivendo una sceneggiatura dovresti piuttosto usare percorsi assoluti ed evitare del tutto cd. Usa le variabili per memorizzare i percorsi che non vuoi digitare più volte, ad espf=~/.wine/drive_c/Program\ Files/; cp /path/to/file "$pf"
Dessert

8
@jamesqf: Perché un sistema sensibile dovrebbe presumere di sapere meglio di me come desidero nominare i miei file e le mie directory? Inoltre, non ho mai capito perché Unix sia andato con la segnalazione magica in banda di separatori di componenti di percorso e terminatori di percorso. Cosa c'è di sbagliato in un file / directory chiamato /o NUL?
Jörg W Mittag,

3
@ JörgWMittag presumibilmentecd ./~
k_g

2
@jamesqf Giusto per notare che storicamente, i filesystem Unix consentivano qualsiasi carattere in un nome file tranne '/' (separatore di percorso) e '\ 0' (NUL - carattere di terminazione stringa) - come nota Jorg. Nessuna altra limitazione. Ci sono state molte implementazioni di filesystem Unix, quindi l'introduzione di restrizioni in ognuna di esse avrebbe rotto la compatibilità e una maggiore complessità - e sarebbe stata vista come "strana"! E l'espansione '~' è stata introdotta relativamente di recente solo in csh e più ampiamente in bash, i file / dirs con '~' caratteri non sono sconosciuti (ad esempio myfile ~ come backup per myfile).
SusanW

Risposte:


79

Come ha notato @karel nella sua risposta, ~è un personaggio speciale ed espanso da Bash nella home directory dell'utente corrente. Vedi il manuale di Bash su "Tilde Expansion" o cerca il titolo "Tilde Expansion" nella pagina man ( man bash).

Qualsiasi tipo di citazione intorno al ~impedisce questa espansione della tilde.


Per rispondere alla tua domanda su come è ancora possibile utilizzarlo cdin una directory con spazi nel suo nome, ci sono alcune alternative:

  • Ometti le virgolette e fuggi invece dagli spazi con le barre rovesciate:

    cd ~/foo/spaces\ are\ cool/bar
  • Cita il resto del percorso, ma omettili attorno alla tilde e alla prima barra:

    cd ~/"foo/spaces are cool/bar"

    Come vedi, puoi concatenare stringhe quotate e non quotate in Bash semplicemente scrivendole una accanto all'altra senza spazi nel mezzo.

  • Usa la variabile d'ambiente $HOMEinvece della tilde, che viene comunque espansa all'interno di "virgolette doppie" (ma non di "virgolette singole"):

    cd "$HOME/foo/spaces are cool/bar"

3
@rexkogitans ~'/...'non funzionerà e non è quello che ha questa risposta. ~/'...'o ~/"..."funzionerà.
hvd,

tld; dr: perché è la sintassi della shell
Sergiy Kolodyazhnyy

@hvd grazie. Errore di battitura fisso. Questa è la risposta più completa e spiega anche come risolvere ciò che l'OP vuole fare. ~/'path'è la strada da percorrere.
rexkogitans,

1
@hvd solo un po 'di curiosità, perché non dovrebbe ~'/...'funzionare? La barra non è un carattere speciale, quindi sembra che dovrebbe funzionare all'interno o all'esterno delle virgolette.
Kodos Johnson,

6
@KodosJohnson Dai un'occhiata alla sezione manpage di Bash su "Tilde Expansion". Il paragrafo pertinente di questo è anche citato nella risposta del dessert di seguito. TL; DR: l'espansione della tilde ha luogo se il primo carattere di una parola è una tilde non quotata, quindi tutto tra quella tilde e la successiva barra non quotata viene considerato il "prefisso tilde". Se questo prefisso non è una cosa valida come +, -, un numero o un nome utente (neanche le virgolette sono presenti), l'espansione fallisce e ottieni un carattere ~ letterale.
Byte Commander

17

~ è un carattere speciale che viene interpretato dalla shell come directory home dell'utente che ha effettuato l'accesso. '~' viene interpretato dalla shell come un carattere ~ letterale, non come la home directory dell'utente che ha effettuato l'accesso perché racchiudere una stringa all'interno di due caratteri di virgoletta singola comporta che la stringa venga interpretata come una stringa di testo letterale.


~non è un alias nel senso in cui lo bashinterpreta: gli alias consentono a una stringa di essere sostituita con una parola quando viene usata come prima parola di un semplice comando. . Come spiego nella mia risposta di seguito, è piuttosto un'espansione.
dessert

15

Questa è una bashfunzione chiamata Tilde Expansion . Citando man bash:

Se una parola inizia con un carattere tilde non quotato (`~ '), tutti i caratteri che precedono la prima barra non quotata (o tutti i caratteri, se non c'è barra non quotata) sono considerati un prefisso tilde. Se nessuno dei caratteri nel prefisso tilde viene citato, i caratteri nel prefisso tilde che segue la tilde vengono trattati come un possibile nome di accesso. Se questo nome di accesso è la stringa nulla, la tilde viene sostituita con il valore del parametro shell HOME. Se HOME non è impostato, viene invece sostituita la home directory dell'utente che esegue la shell.

Affinché l'espansione funzioni, il carattere tilde ~deve essere citato, altrimenti il ​​carattere viene preso alla lettera e ha cdesito negativo se non vi è alcuna directory denominata ~presente nella directory corrente. Vedi questa risposta intensiva per una spiegazione del preventivobash . Se è necessario citare parte del percorso, è quindi possibile:

  1. citare almeno i caratteri che devono essere citati con virgolette singole, ad es

    ~/dir' 'with' 'spaces/

    o

    ~/'dir with spaces/'
  2. citare almeno i caratteri che devono essere citati con virgolette doppie, ad es

    ~/dir" "with" "spaces/

    o

    ~/"dir with spaces/"
  3. citare solo i caratteri che devono essere citati con barre rovesciate, ad es

    ~/dir\ with\ spaces/

Tilde Expansion ha alcune caratteristiche più interessanti, ad esempio:

  • ~+si espande al valore di PWD, ovvero la directory di lavoro corrente
  • ~-si espande al valore di OLDPWD, ovvero la directory di lavoro precedente
  • ~john si espande nella home directory associata al nome di accesso "john"

Per inciso, va bene anche "citare" le barre rovesciate; ad es $ touch a; cd \a. (Ho pensato che questo potesse avere problemi cd \n, ma la sperimentazione almeno sulla mia versione di bashsuggerisce che funzioni bene.)
LSpice

1

Esplora usando il echocomando

Il modo più semplice per esplorare come funzionano le cose in bash è con il echocomando. In caso di ~utilizzo questo:

$ echo ~
/home/rick
$ echo '~'
~
$ echo "~"
~
$ echo `~`
bash: /home/rick: Is a directory

Come puoi vedere, quando apri una virgoletta singola o usi virgolette doppie ~viene interpretata letteralmente come una stringa e non espansa come variabile. Quando usi i backtick (`) viene eseguito come comando e genera un messaggio di errore.

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.