atalhos do diretório bash

28

Quando digito cd ~foo, gostaria que o bash me levasse a algum diretório foocomo um atalho para digitar o caminho completo do diretório foo. e gostaria de poder cp ~foo/bar.txt ~/bar.txtcopiar um arquivo do /foo/diretório para o diretório pessoal ... Então, basicamente, quero algo que funcione exatamente como o ~/faz, mas onde especifique qual deve ser o diretório. [Tenho certeza que devo jfgi, mas não sei o que fazer]

Seamus
fonte
O zsh possui suporte embutido para isso. É chamado de " diretórios nomeados "
Sildoreth
Eu estava procurando por alguma ferramenta de bookmarking por muito tempo e, finalmente, acabei com minha própria solução (baseada em pesquisa difusa) que gosto muito mais do que qualquer outra coisa que já vi antes. Verifique esta resposta: unix.stackexchange.com/a/209892/46011
Dmitry Frank

Respostas:

39

O jeito que eu costumava fazer isso é criar um diretório que contenha links simbólicos para os diretórios que você deseja que os atalhos e adicionar esse diretório ao seu CDPATH. O CDPATH controla onde cda pesquisa será realizada quando você alternar os diretórios; portanto, se esse diretório de links simbólicos estiver no seu CDPATH, você poderá cdacessar instantaneamente qualquer um dos diretórios com links simbólicos:

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

A desvantagem, claro, é que não funcionará se houver um diretório em seu diretório atual chamado "b" - que tenha precedência sobre o CDPATH


Normalmente não gosto de respostas que digam "primeiro é necessário trocar de concha", mas esse recurso exato existe no ZSH , se você estiver disposto a usá-lo; é chamado de diretórios nomeados . Você exporta uma variável fooe, quando se refere a ~fooela, resolve o valor de $foo. Isso é especialmente conveniente porque funciona em comandos além de cd:

echo hi > /tmp/test
export t=/tmp
cat ~t/test   # Outputs "hi"
Michael Mrozek
fonte
2
De que maneiras esse recurso ZSH difere de fazer: echo hi> / tmp / test; export t = / tmp; cat $ t / test Pelo menos na minha máquina, isso funciona muito bem. A única diferença é o personagem que você precisa digitar.
Steven D
referir o op ao zsh é a coisa certa a se fazer. eu não perdi esse recurso uma vez em 15 anos. parece o tipo de coisa que algumas pessoas ficam realmente obcecadas, enquanto outras não se importam. é por isso que há mais de um shell.
2
@ Steven É muito semelhante, mas ZSH sabe que é um diretório chamado neste caso para que ele possa tratá-lo especialmente em expansões imediatas e shell built-in comandos
Michael Mrozek
[Eu estaria fazendo isso principalmente usando o emacs Mx shell (já que é nesse momento que uso o terminal), acho que isso exclui as soluções ZSH] ...
Seamus
11
Adicionei-o ao meu .zshrc e funcionou.
Seamus
10

Você pode escrever uma função de invólucro cde chamá-la de "cd" (finalmente a função chamará builtin cd- usando a builtinpalavra - chave). Você pode usar um caractere de prefixo que o Bash não expandirá na linha de comando antes que sua função o veja e é improvável que apareça como o caractere inicial nos nomes dos diretórios, talvez ":". Você gostaria de torná-lo mais robusto, mas aqui está um esboço simples:

# 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 até novo aviso.
fonte
11
Esta é realmente uma boa idéia
Michael Mrozek
Obrigado por esta sugestão - fez o meu realmente simples solução em cima dela: aaverin.github.io/unix/macox/2014/05/26/bash-named-folders
AAverin
7

com bash:

~fooestá reservado para o diretório inicial do usuário foo. Eu não recomendaria a criação de usuários apenas para essa conveniência.

Você pode tornar sua vida mais fácil (ou mais difícil) ao alterar diretórios , configurando a CDPATHvariável de ambiente (consulte-a bash(1)).

Além disso, a única maneira de pensar seria definir variáveis ​​de ambiente para os diretórios que você deseja abreviar.

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

fonte
2

As variáveis ​​bash podem ser usadas para criar um sistema de favoritos. As variáveis ​​funcionarão com qualquer comando e o bash completará o nome da variável na guia. Nas versões mais recentes do bash, se a / for anexado ao nome da variável, o caminho que a variável contém também pode ser preenchido com tabulação.

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

Para persistência, as declarações de variáveis ​​podem ser mantidas em um arquivo originário de .bashrc. Como esse arquivo é um script bash, ele pode conter declarações que referenciam outras variáveis, como aur="${HOME}/AUR"ou que são executadas apenas em determinados hosts if [[ $HOSTNAME == foo ]]; then bar=baz; fi, o que é útil se você reutilizar arquivos de configuração em vários hosts e usuários.

A seguinte função bash (a ser adicionada ao .bashrc ou originada dele) permite que os indicadores sejam adicionados e removidos do arquivo de indicadores. É relativamente novo e não é garantido que esteja livre de erros.

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
}
varactil
fonte
0

Uma maneira seria criar um alias para cd, que substitui ~co caminho desejado. Ou apenas use zsh;)

krissi
fonte
2
Sim, pensei em fazer isso, como alias ~ c = "cd / daten / cvs / plugin_root", mas isso só ajuda no cd, enquanto diretórios nomeados podem ser usados ​​com todos os comandos.
fschmitt 22/09
0

Para alterar diretórios, você pode usar o wcd: Wherever Change Directory

Com isso, será como wcd plugin_root.

alex
fonte
Eu queria algo que funciona com comandos que não seja cdassim ...
Seamus
0

Eu tenho a função abaixo, que irá criar alias em tempo real,

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 quero marcar um diretório, apenas digito s dirName. Isso cria um apelido como alias dirName="cd /my/current/directory/;pwd". para que eu possa voltar a esse diretório apenas digitando dirName. Eu tenho uma versão que a salva em bash_aliases também. Isso funciona em qualquer shell.

balki
fonte