Bash-Verzeichnis-Verknüpfungen

28

Wenn ich tippe cd ~foo, möchte ich, dass bash mich zu einem Verzeichnis bringt, das fooals Abkürzung für die Eingabe des vollständigen Verzeichnispfads von dient foo. und ich möchte in der Lage sein, cp ~foo/bar.txt ~/bar.txteine Datei aus dem /foo/Verzeichnis in das Ausgangsverzeichnis zu kopieren ... Also im Grunde möchte ich etwas, das genau so ~/funktioniert, aber wo ich spezifiziere, was das Verzeichnis sein soll. [Ich bin sicher, ich sollte jfgi, aber ich weiß nicht, was ich fg]

Seamus
quelle
zsh hat dafür eine eingebaute Unterstützung. Es heißt "
Named
Ich habe zu lange nach einem Shell-Lesezeichen gesucht und schließlich eine eigene (auf der Fuzzy-Suche basierende) Lösung gefunden, die mir viel besser gefällt als alles andere, was ich bisher gesehen habe. Überprüfen Sie diese Antwort: unix.stackexchange.com/a/209892/46011
Dmitry Frank

Antworten:

39

Zu diesem Zweck habe ich ein Verzeichnis erstellt, das Symlinks zu den Verzeichnissen enthält, die Verknüpfungen enthalten sollen, und dieses Verzeichnis zu Ihrem CDPATH hinzugefügt. CDPATH steuert, wo cdgesucht wird, wenn Sie zwischen Verzeichnissen wechseln. cdBefindet sich dieses Verzeichnis mit Symlinks in Ihrem CDPATH, können Sie sofort auf eines der mit Symlinks verknüpften Verzeichnisse zugreifen:

mkdir ~/symlinks
ln -s /usr/bin ~/symlinks/b
export CDPATH=~/symlinks
cd b   # Switches to /usr/bin

Der Nachteil ist natürlich, dass es nicht funktioniert, wenn sich in Ihrem aktuellen Verzeichnis ein Verzeichnis mit dem Namen "b" befindet, das Vorrang vor dem CDPATH hat


Normalerweise mag ich keine Antworten mit der Aufschrift "Zuerst muss man die Muschel wechseln", aber genau diese Funktion gibt es in ZSH , wenn Sie bereit sind, sie stattdessen zu verwenden. Es heißt benannte Verzeichnisse . Sie exportieren eine Variable foound wenn Sie auf ~foosie verweisen, wird sie in den Wert von aufgelöst $foo. Dies ist besonders praktisch, da es auch in folgenden Befehlen funktioniert cd:

echo hi > /tmp/test
export t=/tmp
cat ~t/test   # Outputs "hi"
Michael Mrozek
quelle
2
Inwiefern unterscheidet sich diese ZSH-Funktion von der folgenden: echo hi> / tmp / test; export t = / tmp; cat $ t / test Zumindest auf meinem Computer funktioniert dies einwandfrei. Der einzige Unterschied ist das Zeichen, das Sie eingeben müssen.
Steven D
Es ist richtig, die Operation auf zsh zu verweisen. Ich habe dieses Feature nicht ein einziges Mal in 15 Jahren verpasst. Es scheint so, als ob manche Leute wirklich besessen davon sind, während es anderen egal ist. Deshalb gibt es mehr als eine Shell.
2
@Steven Es ist ziemlich ähnlich, aber ZSH weiß, dass es sich in diesem Fall um ein benanntes Verzeichnis handelt, sodass es speziell für Eingabeaufforderungserweiterungen und in die Shell integrierte Befehle verwendet werden kann
Michael Mrozek
[Ich würde das meistens mit der emacs Mx-Shell machen (da ich dann das Terminal benutze), ich schätze, das schließt ZSH-Lösungen aus] ...
Seamus
1
Fügte es meinem .zshrc hinzu und das funktionierte.
Seamus
10

Sie könnten eine Wrapper-Funktion für schreiben cdund sie "cd" nennen (letztendlich ruft die Funktion builtin cd- unter Verwendung des builtinSchlüsselworts - auf). Sie können ein Präfix-Zeichen verwenden, das Bash in der Befehlszeile nicht erweitert, bevor Ihre Funktion es sieht. Es ist unwahrscheinlich, dass es als Anfangszeichen in Ihren Verzeichnisnamen erscheint, z. B. ":". Sie möchten es robuster machen, aber hier ist eine einfache Übersicht:

# format: [semicolon] shortcut colon destination [semicolon] ...
export CDDATA='foo:/path/to/foo;bar:/path/to/bar;baz:/path/to/baz'

cd () {
    local dest=$1
    if [[ $dest == :* ]]
    then
        [[ $CDDATA =~ (^|;)${dest:1}:([^;]*)(;|$) ]]
        dest=${BASH_REMATCH[2]}
    fi
    if [[ -z $dest ]]
    then
        cd
    else
        builtin cd "$dest"
    fi
}

cd :bar    # pwd is now /path/to/bar
Bis auf weiteres angehalten.
quelle
1
Das ist eine wirklich gute Idee
Michael Mrozek
Vielen Dank für diesen Vorschlag - meine wirklich einfache Lösung darauf gesetzt: aaverin.github.io/unix/macox/2014/05/26/bash-named-folders
AAverin
7

mit bash:

~fooist für das Home-Verzeichnis des Benutzers foo reserviert. Ich würde nicht empfehlen, Benutzer nur zu diesem Zweck zu erstellen.

Sie können Ihr Leben leichter (oder schwerer) machen, wenn Sie Verzeichnisse wechseln, indem Sie die CDPATHUmgebungsvariable setzen (suchen Sie sie in bash(1)).

Abgesehen davon besteht die einzige Möglichkeit darin, Umgebungsvariablen für die Verzeichnisse festzulegen, die Sie abkürzen möchten.

$ FOODIR=/var/lib/misc
$ cp ~/bar.txt $FOODIR

quelle
2

Bash-Variablen können zum Erstellen eines Lesezeichen-Systems verwendet werden. Variablen funktionieren mit jedem Befehl und Bash vervollständigt den Variablennamen. Wenn in neueren Versionen von bash ein / an den Variablennamen angehängt wird, kann der Pfad, den die Variable enthält, ebenfalls mit einem Tabulator vervollständigt werden.

mydir=/home/chris/dir
ls $my         # Tab completion works on variable name.
ls $mydir/     # Tab completion is equivalent to that with ls /home/chris/dir/
               # (doesn't work in older versions of bash).

Aus Gründen der Persistenz können Variablendeklarationen in einer Datei gespeichert werden, die von .bashrc stammt. Da es sich bei dieser Datei um ein Bash-Skript handelt, kann sie Deklarationen enthalten, die auf andere Variablen verweisen, z. B. auf aur="${HOME}/AUR"oder nur auf bestimmten Hosts. Dies if [[ $HOSTNAME == foo ]]; then bar=baz; fiist hilfreich, wenn Sie Konfigurationsdateien auf mehreren Hosts und Benutzern wiederverwenden.

Mit der folgenden Bash-Funktion (die zu .bashrc hinzugefügt oder von dort bezogen wird) können Lesezeichen zur Lesezeichen-Datei hinzugefügt und daraus entfernt werden. Es ist ziemlich neu und garantiert nicht fehlerfrei.

bookmark_file=~/.bookmarks
source "$bookmark_file"

bm() {
usage='Usage:
bm add <name> <path>           Create a bookmark for path.
bm add <name>                  Create a bookmark for the current directory.
bm update                      Source the bookmark file.
bm remove <name>               Remove a bookmark'              

case $1 in
    add)
        local path
        if [[ $# -eq 2 ]]; then
            path=.
        elif [[ $# -eq 3 ]]; then
            if [[ -e $3 ]]; then
                path="$3"
            else
                echo "bm: ${3}: No such file or directory."
                return 1
            fi               
        else
            echo "$usage"
            return 1
        fi

        if declare | grep "^${2}=" > /dev/null; then
            echo "bm: The name $2 is in use."
            return 1
        fi
        path=$(readlink -f "$path")
        echo ${2}=\""$path"\" >> "$bookmark_file"
        eval ${2}=\""$path"\"
        return 0
        ;;
    update)
        if [[ $# -eq 1 ]]; then
            source "$bookmark_file"
            return 0
        fi
        ;;
    remove)
        if [[ $# -eq 2 ]]; then
            unset $2
            local contents=$(grep -v "^${2}=" "$bookmark_file")
            echo "$contents" > "${bookmark_file}.tmp"
            rm -f "$bookmark_file"
            mv "${bookmark_file}.tmp" "$bookmark_file"
            return 0
        fi
        ;;
esac

echo "$usage"
return 1
}
Varactyl
quelle
0

Ein Weg wäre, einen Alias ​​für CD zu erstellen ~c, der den gewünschten Pfad ersetzt. Oder benutze einfach zsh;)

krissi
quelle
2
Ja, ich habe darüber nachgedacht, wie bei alias ~ c = "cd / daten / cvs / plugin_root", aber das hilft nur bei cd, während benannte Verzeichnisse mit jedem Befehl verwendet werden können.
Fschmitt
0

Zum Ändern von Verzeichnissen können Sie wcd: Wherever Change Directory verwenden

Damit wird es so sein wcd plugin_root.

Alex
quelle
Ich wollte etwas, das mit anderen Befehlen cdals auch funktioniert ...
Seamus
0

Ich habe die folgende Funktion, die Alias ​​im laufenden Betrieb erstellen wird,

s () {
    if [[ "x$1" != "x" ]]
    then
        alias $1="cd $PWD;pwd"
        echo "alias $1=\"cd $PWD;pwd\""
    else
        echo "Usage: s[s] <directory bookmark name>"
        return 1
    fi
}

Wenn ich ein Verzeichnis mit einem Lesezeichen versehen möchte, gebe ich einfach Folgendes ein s dirName. Dies erzeugt einen Alias ​​wie alias dirName="cd /my/current/directory/;pwd". Ich kann also durch einfaches Eingeben in dieses Verzeichnis zurückkehren dirName. Ich habe eine Version, die es auch in bash_aliases speichert. Dies funktioniert in jeder Shell.

balki
quelle