raccourcis de répertoire bash

29

Lorsque je tape cd ~foo, j'aimerais que bash m'emmène vers un répertoire foocomme raccourci pour taper le chemin complet du répertoire de foo. et j'aimerais pouvoir cp ~foo/bar.txt ~/bar.txtcopier un fichier du /foo/répertoire vers le répertoire personnel ... Donc, fondamentalement, je veux quelque chose qui fonctionne exactement comme le ~/fait, mais où je précise ce que le répertoire doit être. [Je suis sûr que je devrais jfgi, mais je ne sais pas quoi fg]

Seamus
la source
zsh a un support intégré pour cela. Cela s'appelle " répertoires nommés "
Sildoreth
Je cherchais depuis trop longtemps un outil de bookmarking shell, et finalement je me suis retrouvé avec ma propre solution (basée sur la recherche floue) que j'aime beaucoup plus que tout ce que j'ai vu auparavant. Cochez cette réponse: unix.stackexchange.com/a/209892/46011
Dmitry Frank

Réponses:

40

La façon dont j'ai l'habitude de le faire est de créer un répertoire qui contient des liens symboliques vers les répertoires que vous souhaitez utiliser et d'ajouter ce répertoire à votre CDPATH. CDPATH contrôle où cdva chercher lorsque vous changez de répertoire, donc si ce répertoire de liens symboliques est dans votre CDPATH, vous pouvez cdaccéder instantanément à l'un des répertoires de liens symboliques :

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

L'inconvénient est bien sûr que cela ne fonctionnera pas s'il y a un répertoire dans votre répertoire actuel nommé "b" - qui a priorité sur le CDPATH


Je n'aime normalement pas les réponses qui disent "vous devez d'abord changer de shell", mais cette fonctionnalité exacte existe dans ZSH , si vous êtes prêt à l'utiliser à la place; cela s'appelle des répertoires nommés . Vous exportez une variable foo, et lorsque vous vous y référez, ~fooelle se résout à la valeur de $foo. Ceci est particulièrement pratique car il fonctionne en plus des commandes cd:

echo hi > /tmp/test
export t=/tmp
cat ~t/test   # Outputs "hi"
Michael Mrozek
la source
2
En quoi cette fonctionnalité ZSH diffère-t-elle de: echo hi> / tmp / test, export t = / tmp; cat $ t / test Au moins sur ma machine, cela fonctionne très bien. La seule différence est le caractère que vous devez taper.
Steven D
référencer l'op à zsh est la bonne chose à faire. je n'ai pas manqué cette fonctionnalité une fois en 15 ans. semble être le genre de chose dont certaines personnes sont vraiment obsédées alors que d'autres s'en moquent. c'est pourquoi il y a plus d'un shell.
2
@Steven C'est assez similaire, mais ZSH sait que c'est un répertoire nommé dans ce cas, donc il peut le traiter spécialement dans les extensions rapides et les commandes intégrées au shell
Michael Mrozek
[Je ferais surtout cela en utilisant le shell emacs Mx (puisque c'est à ce moment que j'utilise le terminal), je suppose que cela exclut les solutions ZSH] ...
Seamus
1
Je l'ai ajouté à mon .zshrc et cela a fonctionné.
Seamus
10

Vous pouvez écrire une fonction wrapper pour cdet l'appeler "cd" (finalement la fonction appellera builtin cd- en utilisant le builtinmot - clé). Vous pouvez utiliser un préfixe que Bash ne développera pas sur la ligne de commande avant que votre fonction ne le voit et il est peu probable qu'il apparaisse comme caractère initial dans les noms de votre répertoire, peut-être ":". Vous voudriez le rendre plus robuste, mais voici un aperçu simple:

# 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
En pause jusqu'à nouvel ordre.
la source
1
C'est une très bonne idée
Michael Mrozek
Merci pour cette suggestion - j'ai fait ma solution vraiment simple par-dessus: aaverin.github.io/unix/macox/2014/05/26/bash-named-folders
AAverin
7

avec bash:

~fooest réservé au répertoire personnel de l'utilisateur foo. Je ne recommanderais pas de créer des utilisateurs uniquement pour cette commodité.

Vous pouvez vous rendre la vie plus facile (ou plus difficile) lorsque vous changez de répertoire en définissant la CDPATHvariable d'environnement (recherchez-la dans bash(1)).

En dehors de cela, la seule façon de penser serait de définir des variables d'environnement pour les répertoires que vous souhaitez abréger.

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

la source
2

Les variables Bash peuvent être utilisées pour créer un système de signets. Les variables fonctionneront avec n'importe quelle commande et bash complètera le nom de la variable par tabulation. Dans les versions plus récentes de bash, si un / est ajouté au nom de la variable, le chemin que contient la variable peut également être complété par des tabulations.

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

Pour la persistance, les déclarations de variables peuvent être conservées dans un fichier provenant de .bashrc. Étant donné que ce fichier est un script bash, il peut contenir des déclarations qui font référence à d'autres variables, telles que aur="${HOME}/AUR", ou qui ne s'exécutent que sur certains hôtes if [[ $HOSTNAME == foo ]]; then bar=baz; fi, ce qui est utile si vous réutilisez des fichiers de configuration sur plusieurs hôtes et utilisateurs.

La fonction bash suivante (à ajouter à .bashrc ou à partir de celle-ci) permet aux signets d'être ajoutés et supprimés du fichier de signets. Il est assez récent et n'est pas garanti sans bogues.

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
}
varactyle
la source
0

Une façon serait de créer un alias pour cd qui remplace ~cle chemin voulu. Ou utilisez simplement zsh;)

krissi
la source
2
Oui, j'ai pensé à faire ça, comme alias ~ c = "cd / daten / cvs / plugin_root" mais cela n'aide que pour cd, tandis que les répertoires nommés peuvent être utilisés avec chaque commande.
fschmitt
0

Pour changer de répertoire, vous pouvez utiliser wcd: Whereever Change Directory

Avec ça, ce sera comme wcd plugin_root.

alex
la source
Je voulais quelque chose qui fonctionne avec des commandes autres que cd...
Seamus
0

J'ai la fonction ci-dessous qui créera un alias à la volée,

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
}

Lorsque je veux ajouter un répertoire à mes favoris, je tape simplement s dirName. Cela crée un alias comme alias dirName="cd /my/current/directory/;pwd". donc je peux revenir à ce répertoire en tapant simplement dirName. J'ai une version qui l'enregistre également dans bash_aliases. Cela fonctionne dans n'importe quel shell.

balki
la source