atajos de directorio bash

29

Cuando escribo cd ~foo, me gustaría que bash me lleve a algún directorio foocomo acceso directo para escribir la ruta completa del directorio foo. y me gustaría poder cp ~foo/bar.txt ~/bar.txtcopiar un archivo desde el /foo/directorio al directorio de inicio ... Entonces, básicamente, quiero algo que funcione exactamente como ~/funciona, pero donde especifique cuál debería ser el directorio. [Estoy seguro de que debería jfgi, pero no sé qué hacer]

Seamus
fuente
zsh tiene soporte incorporado para esto. Se llama " directorios con nombre "
Sildoreth
Estuve buscando una herramienta de marcadores de shell durante demasiado tiempo, y finalmente terminé con mi propia solución (basada en búsqueda difusa) que me gusta mucho más que cualquier otra cosa que haya visto antes. Verifique esta respuesta: unix.stackexchange.com/a/209892/46011
Dmitry Frank

Respuestas:

40

La forma en que solía hacer esto es crear un directorio que contenga enlaces simbólicos a los directorios que desea que hagan los accesos directos y agregar ese directorio a su CDPATH. CDPATH controla dónde cdbuscará cuando cambie de directorio, por lo que si ese directorio de enlaces simbólicos está en su CDPATH, puede acceder cda cualquiera de los directorios enlazados al instante:

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

La desventaja, por supuesto, es que no funcionará si hay un directorio en su directorio actual llamado "b", que tiene prioridad sobre el CDPATH


Normalmente no me gustan las respuestas que dicen "primero necesitas cambiar los shells", pero esta característica exacta existe en ZSH , si estás dispuesto a usarla en su lugar; se llama directorios con nombre . Exporta una variable fooy, cuando se refiere a ~fooella, se resuelve en el valor de $foo. Esto es especialmente conveniente porque funciona en comandos además de cd:

echo hi > /tmp/test
export t=/tmp
cat ~t/test   # Outputs "hi"
Michael Mrozek
fuente
2
¿En qué se diferencia esta función de ZSH de hacer: echo hi> / tmp / test; export t = / tmp; cat $ t / test Al menos en mi máquina, esto funciona bien. La única diferencia es el carácter que tienes que escribir.
Steven D
referir el op a zsh es lo correcto. No me he perdido esa característica una vez cada 15 años. parece el tipo de cosas por las que algunas personas se obsesionan realmente mientras que a otras no les importa Por eso hay más de un caparazón.
2
@Steven Es bastante similar, pero ZSH sabe que es un directorio con nombre en este caso, por lo que puede tratarlo especialmente en expansiones rápidas y comandos integrados de shell
Michael Mrozek
[En su mayoría estaría haciendo esto usando emacs Mx shell (ya que es cuando uso el terminal), supongo que eso descarta las soluciones ZSH] ...
Seamus
1
Lo agregué a mi .zshrc y funcionó.
Seamus
10

Puede escribir una función de contenedor para cdy llamarla "cd" (en última instancia, la función llamará builtin cd, utilizando la builtinpalabra clave). Puede usar un carácter de prefijo que Bash no expandirá en la línea de comando antes de que su función lo vea y es poco probable que aparezca como el carácter inicial en los nombres de su directorio, tal vez ":". Desea hacerlo más robusto, pero aquí hay un esquema 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
Pausado hasta nuevo aviso.
fuente
1
Esta es una muy buena idea
Michael Mrozek
Gracias por esta sugerencia: hice mi solución realmente simple: aaverin.github.io/unix/macox/2014/05/26/bash-named-folders
AAverin
7

con golpe:

~fooestá reservado para el directorio de inicio del usuario foo. No recomendaría crear usuarios solo por esa conveniencia.

Puede hacer su vida más fácil (o más difícil) al cambiar de directorio configurando la CDPATHvariable de entorno (búsquela en bash(1)).

Aparte de eso, la única forma de pensar sería establecer variables de entorno para los directorios que desea abreviar.

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

fuente
2

Las variables Bash se pueden usar para crear un sistema de marcadores. Las variables funcionarán con cualquier comando y bash completará con pestañas el nombre de la variable. En las versiones más nuevas de bash, si se agrega un / al nombre de la variable, la ruta que contiene la variable también se puede completar con pestañas.

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

Por persistencia, las declaraciones de variables se pueden guardar en un archivo que se obtiene de .bashrc. Dado que este archivo es un script bash, puede contener declaraciones que hacen referencia a otras variables, como aur="${HOME}/AUR", o que solo se ejecutan en ciertos hosts if [[ $HOSTNAME == foo ]]; then bar=baz; fi, lo que es útil si reutiliza archivos de configuración en varios hosts y usuarios.

La siguiente función bash (que se agregará a .bashrc o se obtendrá de ella) permite agregar y eliminar marcadores del archivo de marcadores. Es bastante nuevo y no se garantiza que esté libre de errores.

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
fuente
0

Una forma sería crear un alias para cd que reemplace ~ca la ruta deseada. O simplemente use zsh;)

krissi
fuente
2
Sí, pensé en hacer eso, como alias ~ c = "cd / daten / cvs / plugin_root", pero eso solo ayuda con cd, mientras que los directorios con nombre se pueden usar con cada comando.
fschmitt
0

Para cambiar directorios, puede usar wcd: Wherever Change Directory

Con eso, será como wcd plugin_root.

alex
fuente
Quería algo que funcione con comandos que no sean cdtambién ...
Seamus
0

Tengo la siguiente función que creará un alias sobre la marcha,

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
}

Cuando quiero marcar un directorio, simplemente escribo s dirName. Esto crea un alias como alias dirName="cd /my/current/directory/;pwd". para que pueda volver a este directorio simplemente escribiendo dirName. Tengo una versión que también lo guarda en bash_aliases. Esto funciona en cualquier shell.

balki
fuente