Wie funktioniert die Verwendung der Tilde als Verknüpfung zu meinem Ausgangsverzeichnis?


30

Ich war verwirrt, als ich versuchte, einige Dateien von einem PC auf einen anderen zu kopieren. Ich habe es herausgefunden, aber die Syntax ist für mich immer noch verwirrend. Das funktioniert:

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

was Volenteer.pngin den Ordner legt /home/j0h/b. Dies funktioniert jedoch nicht:

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

Dies schlägt ebenfalls fehl und gibt eine Exit-Status-1-Datei an, die nicht gefunden wurde:

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

Wie geht das:

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

Also klar, es gibt einen Unterschied zwischen ~und ~/ Dieser Unterschied ist die Gegenwart von/

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

Also warum in scp, löst das ~auf ~/? Das ist eine Vermutung, ich kann nicht bestätigen, dass es das ist, was passiert. Aber es scheint inkonsistent und daher verwirrend. Ist das ein Fehler in SCP? oder fehlt mir etwas an tilde?


2
Nur eine Randnotiz hier, es ist "Freiwilliger" geschrieben, mit einem "u" anstelle eines "e" :)
VRE

2
Ich bin ein liberaler Zauberer.
07.08.15 Uhr

Antworten:


68

~ ist Ihr Heimatverzeichnis.

~fooist das Ausgangsverzeichnis des Benutzers foo, wenn ein solcher Benutzer vorhanden ist, oder nur ein Verzeichnis mit dem Namen ~foo, wenn dieser Benutzer nicht vorhanden ist.


Daher in:

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

~Desktopwird zum Ausgangsverzeichnis des Benutzers erweitert Desktop, wenn ein solcher Benutzer vorhanden ist (und dies normalerweise nicht der Fall ist) oder nur ~Desktop(ein Pfad, der normalerweise auch nicht vorhanden ist).


Im:

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

~/j0hwird zu einem Verzeichnis mit dem Namen j0him Ausgangsverzeichnis erweitert jay, das ebenfalls wahrscheinlich nicht vorhanden ist.


Es ist nicht ~und ~/wo der Unterschied auftritt, sondern in ~und ~foo.


Darüber hinaus ~kann auch für Verzeichnis Geschichte Navigation verwendet werden:

  • ~-ist das vorherige Arbeitsverzeichnis (like $OLDPWD)
  • ~+ist das aktuelle Arbeitsverzeichnis (like $PWD)

Dies gilt nicht für scp, da Sie nicht während eines scpVorgangs die Verzeichnisse wechseln müssen .

Und wenn Sie pushdund verwendenpopd , um einen Verzeichnisstapel zu pflegen, und das th-Verzeichnis im Verzeichnisstapel wäre, wie in der Ausgabe von zu sehen . wäre das th-Verzeichnis vom Ende (in beiden Fällen von Null an gezählt). Beispielsweise:~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

Anschließend kann auf die Verzeichnisse im Stapel zugegriffen werden, indem Folgendes verwendet wird:

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

Ist das ~+also immer gleichbedeutend mit dem ., was? Scheint überflüssig.
Wildcard

1
@Wildcard naja, nicht genau. ~+und ~-benutze die Werte von $PWDund $OLDPWD, die absolute Pfade sind. .ist immer ein relativer Pfad. Wenn es also einen Befehl gibt, der beim Ausführen das aktuelle Arbeitsverzeichnis ändert, wird der neue Pfad für angezeigt ., wobei der Pfad, um den erweitert wurde ~-, der gleiche bleibt. tar -Cist ein Beispiel, obwohl ich zugebe, dass ich mir keine gute Verwendung für vorstellen kann ~+. $PWDwäre genauso gut, außer dass Sie nicht zitieren müssen, ~+/foo/barwenn $PWDLeerzeichen enthält.
muru

1
Danke, das macht es klar. Tatsächlich ist dies ein gutes Beispiel für einen Anwendungsfall: Einige Befehle lehnen es aus Sicherheitsgründen ab, auf relativen Pfaden zu arbeiten. Mit solchen Befehlen können Sie nicht verwenden ./filename, können aber "$PWD/filename"oder einfacher verwenden ~+/filename. (Und einige Befehle funktionieren bei relativen Pfadnamen, aber es gibt einen funktionalen Unterschied, wie z. B. lnoder tar.)
Wildcard

21

Lesen Sie sich die GNU-Dokumentation für Bash Tilde Expansion durch (wie ich es vor meiner ersten Iteration dieser Antwort hätte tun sollen).

~/Desktopund ~j0hmachen grundsätzlich andere Dinge, was erklärt, warum ~Desktopnicht funktioniert:

  • Die ~aktuelle $HOMEUmgebungsvariable wird durch eine Ebene ersetzt , die beim Anmelden festgelegt wird. Also ~beschließt /home/olifür mich, und ~/Desktopliest als /home/oli/Desktop. Hier sehen Sie die Tilda, die am häufigsten verwendet wird.

  • ~usernamewird in das Haus dieses Benutzers aufgelöst , wie in festgelegt /etc/passwd. So ~oliEntschlüssen zu /home/oli, ~j0hlösen könnte , /home/j0haber nicht notwendigerweise, kann Ihr homedir überall sein.

  • ~not-a-usernamelöst sich nicht auf. Weil Desktopkein Benutzer ist, ~Desktopwird nicht ersetzt. Es wird wörtlich als eine Datei oder ein Pfad mit dem Namen ~Desktop(der hier nicht existiert) verstanden.

Und natürlich geschieht dies alles aus der Ferne (es wäre nutzlos, scpwenn es durch lokale Werte ersetzt würde). Dies funktioniert, weil Bash nichts ersetzt, ~...wenn ihm nur Leerzeichen vorangestellt sind.


Was getent passwd binheißt das?
muru

2
"bin" ist ein Systembenutzer auf den meisten Linux-Rechnern mit einem Ausgangsverzeichnis von / bin.
5.

1
Der Fehler beim Erweitern ~dirsteht im Einklang mit den GNU-Dokumenten: "... die Zeichen im Tilde-Präfix, die auf die Tilde folgen, werden als möglicher Anmeldename behandelt ... Wenn der Anmeldename ungültig ist oder die Tilde-Erweiterung fehlschlägt, das Wort bleibt unverändert. " Ist dirhier nicht der Name eines Benutzers auf diesem System, so bleibt er unverändert.
Apsillers

Vielen Dank an alle. Ich sollte wahrscheinlich die Links lesen, die ich poste :)
Oli

4

Das Symbol ~wird als Abkürzung für /home/userin verwendet bash, ist also in diesem Fall ~/Desktop/Volenteer.pngeine Abkürzung für /home/user/Desktop/Volenteer.png.

Wie Sie sehen /, zeigt das wie immer eine neue Ebene in der Dateisystemhierarchie.


3
nur zur Hälfte richtig, es ist eine Abkürzung für die Umgebungsvariable $ HOME. ~{user}/Dies kann ein beliebiger Pfad sein, wie er in der Datenbankdatei passwd (5) festgelegt ist. Während ja, die filesytem.org-Standards reguläre Benutzer in / home platzieren, ist dies nicht bei jedem Benutzer der Fall (dh root in / root und Dienste in / var / ... oder älteren Unixies, die / usr anstelle von / home verwenden).
Dwight Spencer

DwightSpencer ist richtig. Ich verwalte mehrere Server, auf denen sich die Benutzer in / usr / {CLIENTNAME} / home / befinden und die auf mehreren internen und Remote-Systemen (alle verweisen auf dieses Verzeichnis) gemeinsam genutzt werden, sodass nur 1 System verwaltet werden muss. Und ~ zeigt auf dieses Verzeichnis;)
Rinzwind

3
@ Rinzwind eek. Ich muss gegen diesen gotteslästerlichen Missbrauch von protestieren /usr.
muru

@muru hey es war nicht MEIN Anruf>: - D Es war ein
Überbleibsel

1
Ehrlich gesagt mochte ich die Verwendung von / usr für alle Benutzer, da dies ursprünglich bedeutete. Was ich heutzutage finde, ist der gotteslästerlichere Missbrauch von / usr / bin als einheitlicher Speicherort aller Binärdateien (sys, user, sysop) außerhalb der Basis-Binutils. Nachdem alle / usr als alle Dinge gedacht waren, auf die Benutzer von einem nfs-Mount zugreifen können, war / usr / local der lokale Benutzerbereich mit / sbin als Sysop-Binärdateien und / bin-System-Binärdateien. Ich verstehe, dass / home eine andere Partition sein kann, aber / usr / home / ... behält sie in / usr als Benutzernamensraum bei, sowohl in Bezug auf Richtlinien, Implementierung als auch in Bezug auf die Einstellung.
Dwight Spencer

3

~ist eine Abkürzung für die Umgebungsvariable $HOMEauf den meisten C-Shell-Derivaten / unterstützenden POSIX-kompatiblen Shells. Die gebräuchlichste Verwendung ~ist, wenn Sie auf Ihr eigenes Heimverzeichnis oder das eines anderen Benutzers verweisen:

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

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

Um das Home-Verzeichnis für einen lokalen Benutzer auf einem POSIX-System (UNIX, Linux, OS X, BSD) zu finden, das die passwd (5) -Datenbank verwendet, führen Sie awk on folgendermaßen aus /etc/passwd:

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

Dies listet jeden lokalen Benutzer und sein Ausgangsverzeichnis auf.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.