scorciatoie della directory bash


29

Quando scrivo cd ~foo, vorrei che bash mi portasse in qualche directory foocome scorciatoia per digitare il percorso completo della directory di foo. e vorrei essere in grado di cp ~foo/bar.txt ~/bar.txtcopiare un file dalla /foo/directory alla home directory ... Quindi, in sostanza, voglio qualcosa che funzioni esattamente come ~/fa, ma dove specifica quale dovrebbe essere la directory. [Sono sicuro che dovrei jfgi, ma non so cosa fg]


zsh ha il supporto integrato per questo. Si chiama " directory nominate "
Sildoreth,

Stavo cercando uno strumento di bookmarking della shell da troppo tempo, e finalmente sono finito con la mia soluzione (basata sulla ricerca fuzzy) che mi piace molto di più di qualsiasi altra cosa che abbia mai visto prima. Controlla questa risposta: unix.stackexchange.com/a/209892/46011
Dmitry Frank

Risposte:


40

Il modo in cui lo facevo in precedenza è creare una directory che contenga collegamenti simbolici alle directory che si desidera utilizzare le scorciatoie e aggiungere quella directory al proprio CDPATH. CDPATH controlla dove cdcercare quando cambi directory, quindi se quella directory di symlink è nel tuo CDPATH, puoi immediatamente cduna delle directory symlink:

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

Il rovescio della medaglia ovviamente non funzionerà se c'è una directory nella tua directory attuale chiamata "b" - che ha la precedenza sul CDPATH


Di solito non mi piacciono le risposte che dicono "per prima cosa devi cambiare shell", ma questa funzionalità esatta esiste in ZSH , se invece sei disposto a usarla; si chiama directory denominate . Esporti una variabile fooe quando ti riferisci ad ~fooessa si risolve nel valore di $foo. Questo è particolarmente utile perché funziona con comandi oltre a cd:

echo hi > /tmp/test
export t=/tmp
cat ~t/test   # Outputs "hi"

2
In che modo questa funzione ZSH differisce dal fare: echo hi> / tmp / test; export t = / tmp; cat $ t / test Almeno sulla mia macchina, funziona perfettamente. L'unica differenza è il personaggio che devi digitare.
Steven D

riferire l'op a zsh è la cosa giusta da fare. non ho perso questa funzione una volta ogni 15 anni. sembra il tipo di cose di cui alcune persone sono veramente ossessionate mentre ad altri non importa. ecco perché c'è più di una shell.

2
@Steven È abbastanza simile, ma ZSH sa che in questo caso è una directory denominata, quindi può trattarla specialmente in proroghe espansioni e comandi incorporati nella shell
Michael Mrozek

[Lo farei principalmente usando la shell emacs Mx (dato che è quando uso il terminale), immagino che escluda le soluzioni ZSH] ...
Seamus

1
L'ho aggiunto al mio .zshrc e ha funzionato.
Seamus,

10

Puoi scrivere una funzione wrapper cde chiamarla "cd" (alla fine la funzione chiamerà builtin cd- usando la builtinparola chiave). Potresti usare un prefisso che Bash non si espanderà sulla riga di comando prima che la tua funzione lo veda e che è improbabile che appaia come il carattere iniziale nei nomi delle tue directory, forse ":". Vorresti renderlo più robusto, ma ecco un semplice schema:

# 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

1
Questa è davvero una buona idea
Michael Mrozek

Grazie per questo suggerimento - ci ha reso la mia soluzione davvero semplice: aaverin.github.io/unix/macox/2014/05/26/bash-named-folders
AAverin

7

con bash:

~fooè riservato per la home directory dell'utente foo. Non consiglierei di creare utenti solo per quella comodità.

Puoi rendere la tua vita più semplice (o più difficile) quando cambi directory impostando la CDPATHvariabile d'ambiente (cercala in bash(1)).

A parte questo, l'unico modo di pensare sarebbe quello di impostare le variabili di ambiente per quelle directory che si desidera abbreviare.

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

2

Le variabili Bash possono essere utilizzate per creare un sistema di bookmarking. Le variabili funzioneranno con qualsiasi comando e bash tab completerà il nome della variabile. Nelle versioni più recenti di bash, se a / viene aggiunto al nome della variabile, anche il percorso che contiene la variabile può essere completato con la scheda.

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).

Per persistenza, le dichiarazioni delle variabili possono essere conservate in un file proveniente da .bashrc. Poiché questo file è uno script bash, può contenere dichiarazioni che fanno riferimento ad altre variabili, come aur="${HOME}/AUR", o che vengono eseguite solo su determinati host if [[ $HOSTNAME == foo ]]; then bar=baz; fi, il che è utile se riutilizzi i file di configurazione su più host e utenti.

La seguente funzione bash (da aggiungere a .bashrc o proveniente da essa) consente di aggiungere e rimuovere i segnalibri dal file dei segnalibri. È abbastanza nuovo e non è garantito che sia privo di bug.

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
}

0

Un modo sarebbe creare un alias per cd che sostituisca ~cil percorso desiderato. O semplicemente usa zsh;)


2
Sì, ho pensato di farlo, come alias ~ c = "cd / daten / cvs / plugin_root" ma questo aiuta solo con cd, mentre le directory nominate possono essere utilizzate con ogni comando.
fschmitt,


0

Ho la seguente funzione che creerà alias al volo,

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
}

Quando voglio aggiungere un segnalibro a una directory, scrivo e basta s dirName. Questo crea un alias simile alias dirName="cd /my/current/directory/;pwd". così posso tornare in questa directory semplicemente digitando dirName. Ho una versione che la salva anche in bash_aliases. Funziona con qualsiasi shell.

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.