Unterschied zwischen $ HOME und ~

31

$HOMEund ~beziehen sich normalerweise auf die gleiche Sache. Das heißt, sie sind der Pfad zum Home-Verzeichnis des Benutzers, das die allgemeine Form "/ home / userName" hat.

Wann, wenn überhaupt, beziehen sich diese nicht auf dasselbe Verzeichnis?

H2ONaCl
quelle
11
Das ~ist shellabhängig, $ HOME nicht.
Kulfy,
Sehr ähnlich unix.stackexchange.com/a/400715/85039
Sergiy Kolodyazhnyy

Antworten:

45

Beide $HOMEund ~zeigen auf denselben Ordner, den Basisordner des aktuellen Benutzers, aber beide sind sehr unterschiedlich.

  • $HOMEist eine Umgebungsvariable , die den Basisordner des aktuellen Benutzers enthält.
  • ~ist ein Shell-Erweiterungssymbol , dh eines der Symbole, die verarbeitet werden, bevor der eigentliche Befehl ausgeführt wird. ~Alleine wird auf den Wert von $ HOME erweitert. ~nemowird zum Home-Verzeichnis des Benutzers erweitert nemo. Ein Shell-Erweiterungssymbol ist ein Zeichen (oder ein Zeichenpaar), das von der Shell verarbeitet / interpretiert wird, um den eigentlichen Befehl zu erstellen. Ein weiteres Beispiel für ein Shell-Erweiterungssymbol ist *, das zum Erweitern von Dateinamen verwendet wird.
Vanadium
quelle
1
~wird unter Windows auf $ HOME oder% APPDATA% erweitert. Wenn sie nicht definiert sind, wird nach dem Pfad in der "Kennwortdatenbank" gesucht (was normalerweise bedeutet /etc/passwd, aber möglicherweise LDAP oder eine andere Datenquelle ist). Vor ungefähr 20 Jahren hätte man Sie warnen können, dass $ HOME auf einigen Rechnern möglicherweise nicht gesetzt ist, während ~es garantiert auf etwas erweitert wurde.
Mirek Długosz
Dieser Unterschied macht sich in Programmen wie make bemerkbar, wenn Sie wissen müssen, welches der beiden Programme Sie benötigen
D. Ben Knoble,
3
@ MirekDługosz Zumindest auf Git Bash unter Windows, ~erweitert sich auf $HOME(gleich $HOMEPATH), nicht $APPDATA. Und auf cmd.exe, ~nicht erweitert.
Hyde
1
@vanadium HOMEist eine Umgebungsvariable (ein O Konzept, in sh Schalen zum Beispiel Set mit exportoder declare -x), nicht einem Shell - Variable (Definition, welche ausschließlich auf Schale abhängt, sondern in sh Schalen wird in der Regel mit eingestellt foo=valueoder mit setoder in einigen anderen Wege).
Hyde
1
@hyde Ich habe das falsch formuliert. Bash sucht nach $ HOME, wenn es nicht gesetzt ist, sucht es nach% APPDATA%, aber nur unter Windows. Ist dies nicht der Fall, wird "die Passwortdatenbank" nachgeschlagen. Siehe git.savannah.gnu.org/cgit/bash.git/tree/lib/readline/…
Mirek Długosz
17

Ein Unterschied besteht darin, wie die Bash-Shell sie konvertiert, wenn sie in "Anführungszeichen eingeschlossen sind.

Wenn Sie echowie folgt verwenden, ohne Anführungszeichen, dann ~und $HOMEhaben den gleichen Effekt:

$ echo ~
/home/elias
$ echo $HOME
/home/elias

Mit "Anführungszeichen unterscheidet sich das Ergebnis jedoch:

$ echo "~"
~
$ echo "$HOME"
/home/elias
Elias
quelle
13

~Erweitert sich nur als Teil eines Tilde-Präfixes, das per Definition am Wortanfang beginnen muss. Da es früher Teil von Globbing-Mustern war, ~funktioniert es auch nicht in doppelten Anführungszeichen. Also, "~"oder a~bwird zu einem wörtlichen Wert der ~Erhaltung führen.

Ein einzelnes ~(oder ein ~gefolgt von einem /) wird zum Haus des aktuellen Benutzers erweitert:

$ echo ~/.ssh
/home/user/.ssh

Ein ~gefolgt von einem Benutzernamen wird zum Basisordner dieses Benutzers erweitert:

$ echo ~root/.ssh
/root/.ssh

Ein ~gefolgt von einem +oder einem -und einer optionalen Zahl wird zu Elementen des Verzeichnisstapels erweitert :

$ cd /etc
$ echo ~+0
/etc

$HOMEist das Äquivalent einer einzelnen ~Variable, die stattdessen den Syntaxregeln für Variablen folgt. Beispielsweise wird es in doppelten Anführungszeichen erweitert, kann deaktiviert werden und Zeichenfolgenmanipulationsoperanden können darauf angewendet werden.

Dmitry Grigoryev
quelle
3

Das hängt sehr davon ab, was die Erweiterung bewirkt. In bash ~ist dies eine bequeme Methode, um das Basisverzeichnis abzurufen, ohne die Dateinamenerweiterung oder die Wortteilung auszulösen, obwohl es nicht in Anführungszeichen gesetzt ist. Beispielsweise:

$ HOME='/*'
$ echo $HOME
/bin /boot /dev /etc /home /lib /lib64 /media /mnt /opt /proc /root /run /sbin /srv /sys /tmp /usr /var
$ echo ~
/*

Oder:

$ HOME='/ a b'
$ printf "|%s|\n" $HOME ~
|/|
|a|
|b|
|/ a b|

Wenn Sie also aus irgendeinem Grund mit Zitaten ringen (in diesem Fall sollten Sie das Ganze wirklich überdenken, es ist einfacher, mit Schweinen zu ringen), ist dies ~möglicherweise praktischer.


An anderer Stelle, zum Beispiel in Python, ~und $HOMEmüssen um verschiedene Funktionen erweitert werden . Einige andere Stellen erlauben Variablen und erlauben keine andere Shell-Syntax wie Platzhalter oder Tilde-Erweiterung (z. B. ~/.pam_environmenteine spezielle Syntax für die Variablenerweiterung). Wieder andere Stellen erlauben eine Tilde-Erweiterung als Ausnahme (z. B. systemd ), fragen jedoch die passwd-Datenbank direkt ab, anstatt sie zu verwenden $HOME.

Homeboy
quelle
Ein weiterer großer Unterschied, den Sie hier zeigen, aber nicht erwähnen, ist, dass Sie den Wert von ändern können $HOME, aber Sie können den Wert von nicht (direkt) ändern ~.
Joe
Also habe ich gefragt, wann auf dasselbe verweisen soll $HOMEund wann ~nicht - normalerweise standardmäßig - und Sie haben der Umgebungsvariablen absichtlich zugewiesen, damit sie nicht auf dasselbe verweisen. Dies ist eine gute Demonstration, aber unnötig verwirrend.
H2ONaCl
1

Es ist wahrscheinlicher, dass $ HOME / in POSIX.2 Bourne / bin / sh funktioniert, da die Tilde-Erweiterung eine Erweiterung von BSD csh tcsh GNU bash und anderen ist.

Wenn Sie Skripte schreiben möchten, die auf busybox oder dash oder BSD sh portierbar sind, investieren Sie in die zusätzlichen Buchstaben, damit Sie nicht mit ~ /: Keine solche Datei oder Verzeichnis auf bestimmten Systemen abstürzen.

Ich finde auch $ HOME / lesbarer.

Roman Czyborra
quelle
In einem Skript sind Lesbarkeit und Sichtbarkeit wichtig. Vielleicht werden meine Skripte deshalb $HOMEnur selten verwendet ~. Mein früheres Ich wusste das wahrscheinlich.
H2ONaCl