aliasing cd para pushd - é uma boa ideia?

33

É uma boa ideia usar o seguinte alias:

cd() {
    pushd $1;
}

no bash?

Acho que isso seria muito útil, pois posso usar uma série de popd s em vez de apenas cd - uma vez.

Existe algum caso em que isso possa ser um problema?

    
por Lazer 23.11.2010 / 18:42

4 respostas

36

Pessoalmente, eu tenho estes no meu bashrc e usá-los o tempo todo:

pushd()
{
  if [ $# -eq 0 ]; then
    DIR="${HOME}"
  else
    DIR="$1"
  fi

  builtin pushd "${DIR}" > /dev/null
  echo -n "DIRSTACK: "
  dirs
}

pushd_builtin()
{
  builtin pushd > /dev/null
  echo -n "DIRSTACK: "
  dirs
}

popd()
{
  builtin popd > /dev/null
  echo -n "DIRSTACK: "
  dirs
}

alias cd='pushd'
alias back='popd'
alias flip='pushd_builtin'

Você pode navegar na linha de comando um pouco como um navegador. cd altera o diretório. back vai para o diretório anterior do qual você foi cd ed. E o flip se moverá entre os diretórios atual e anterior sem estourá-los da pilha de diretórios. No geral, funciona muito bem.

O único problema real de que estou ciente é o fato de que é um conjunto de comandos que eu estou completamente acostumado, mas não existem na máquina de outra pessoa. Então, se eu tiver que usar a máquina de outra pessoa, isso pode ser um pouco frustrante. Se você está acostumado a usar apenas pushd e popd diretamente, você não tem esse problema. E se você apenas alias cd colocar não popd , você não terá o problema de back não existir, você ainda terá o problema que cd não faz exatamente o que você espera em outro máquinas.

Eu observaria, no entanto, que sua implementação específica de cd não funciona como cd em que o cd normal por si só irá para seu diretório pessoal, mas o seu não. A versão que tenho aqui não tem esse problema. O meu também acrescenta DIRSTACK na frente da impressão de dirs , mas isso é mais uma questão de gosto pessoal, mais do que qualquer coisa.

Então, como eu disse, eu uso esses aliases o tempo todo e não tenho problemas com eles. É só que pode ser um pouco frustrante ter que usar outra máquina e depois encontrá-las lá (o que não deveria ser surpreendente, mas elas são uma daquelas coisas que você usa com tanta frequência que você não pensa nelas , então tê-los funcionando como você está acostumado ainda pode ser surpreendente).

    
por 23.11.2010 / 19:25
7

Esta não é uma resposta direta para a pergunta, mas eu me apaixonei pela janela do histórico do diretório no 4DOS. Tanto é assim que eu escrevi minha própria versão para Linux (e Cygwin). Eu nunca cheguei a fazer dele um utilitário fácil de instalar, mas se você souber como contornar um prompt do Bash, não deve ser difícil de ser executado. Sua pergunta me inspirou a colocá-lo em um repositório do Git e enviá-lo para o GitHub: dirhistory .

Basicamente, é um daemon que coleta mudanças de diretório de todos os seus shells, e um programa de Cdk que exibe o histórico e permite que você escolha qualquer diretório para mudar (assim você não está limitado a uma pilha). Eu acho realmente útil, e tenho que estar ligado ao Ctrl-PageUp, assim como o 4DOS fez. (Eu até atualizei o PuTTY para que ele enviasse o Ctrl-PageUp para o Bash).

    
por 24.11.2010 / 09:10
0

Para mim, o pushd / popd / dirs é quase útil, mas falta. Então, criei um 'wrapper' em torno desses chamados 'navd', implementado como essencialmente um conjunto de 20 aliases. (Um deles é uma função, na verdade.) O código está abaixo, mas aqui está uma breve explicação primeiro. (Uma coisa legal sobre o "navd" e trabalhar nas máquinas de outras pessoas: Existe uma forma "no-install" de executá-lo: Como uma opção de instalação, você pode simplesmente colar os comandos que implementam "navd" no bash-prompt , e para a duração da sessão de bash para que a máquina navd funcione.Isso dá zero footprint no sistema de arquivos, ainda é uma instalação temporária.Posicione esses comandos em .bashrc para uma instalação "real", de claro.)

Recursos:

navd <path>;   -- will make that path the current dir AND will add it to the stack
                         AS A BONUS: If a relative path is used, this command is added to history
                         with an absolute path instead. This improves navigation even when only
                         using history ... because very often relative-path commands in history
                         are useless if the command changes the current directory. (After all, you
                         would have to be in the directory the command was originally issued
                         from in order for such a command to work correctly.)
navd           -- shows the stack, with index numbers for convenience
navd0          -- makes the first entry on the stack (read left-to-right) **the current dir**
navd1          -- makes the second entry on the stack (read left-to-right) **the current dir**
.
.
.
navd9          -- makes the tenth entry on the stack (read left-to-right) **the current dir**
navd-1         -- makes the first entry on the stack WHEN READ RIGHT-to-LEFT(!) **the current dir**
.                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
.
.
navd-9         -- makes the 9th entry on the stack WHEN READ RIGHT-to-LEFT(!) **the current dir**

Qualquer um dos dezenove navd < N > comandos gira a pilha para que o diretório que se torna atual também agora seja exibido na frente da pilha. Positivo < N > valores encontram um dir contando a partir da esquerda, com indexação começando em zero. Negativo < N > valores encontram um dir contando a partir da DIREITA, com indexação começando em -1.     (Isso segue a convenção de como os índices de array podem ser usados em Java e outras linguagens.)

Nota: Qualquer comando "navd" exibe a mesma pilha que "pushd" e "dirs" usa - mas exibe-o SEM o entrada mais à esquerda que "dirs" seria exibida (desde que essa entrada não está realmente na pilha - é o diretório atual e com "dirs" que a entrada mais à esquerda muda se um comando cd for digitado). (O comando "cd < path >" não afeta nenhum comportamento de navd embora certamente afete o comportamento de pushd / dirs / popd. Também ... Eu adoro usar "cd -" para "voltar" uma vez para um diretório que acabei de navegar, e "cd -" também não afeta o comportamento do navd.)

Bônus: pode haver mais 19 aliases que NÃO rotacionam a pilha, mas apenas mudam dir para o local indicado na pilha.

 nav0 ... nav9   and   nav-1  ... nav-9

2º bônus: "navh" mostra navd < path > comandos do histórico, para carregar facilmente a pilha com o cut-n-paste. (Cada um é listado apenas uma vez, mesmo que esteja no histórico várias vezes, e a lista esteja classificada. Além disso, as entradas podem ser colocadas em um arquivo $ HOME / .navhignore para evitar que essas entradas exatas apareçam na lista de navh.)

 navh

Três comportamentos principais:

  1. Se você limpar a pilha e repetir uma "navegação < caminho >" específica comando, esse caminho vai na pilha. Isso é o que eu quero e espero ... mas o pushd não faz isso - ele coloca o diretório atual no qual você está navegando AWAY FROM - então o efeito na pilha é variável (parece imprevisível) quando você repete o comando .

  2. "navegação < caminho >" não colocará o mesmo caminho na pilha duas vezes.

  3. "navegação < caminho >" coloca-se no histórico de comandos com o caminho absoluto mesmo que o caminho relativo tenha sido digitado para o comando.

Para mim, os três últimos comportamentos descritos usam o uso de "navd < path >" comando do histórico muito mais útil do que usar um "pushd < path >" da história. Eu realmente posso reutilizar o histórico para ir a lugares. E quando faço isso, não "estrago" minha pilha.

Se você puder e quiser envolver seu cérebro, você pode alternar entre o uso de navd e pushd / dirs / popd. Ambos usam a mesma pilha; apenas com um estilo diferente. Por exemplo, use "popd" para remover coisas da pilha "navd" ou use "dirs -c" para limpar a pilha navd.

Pense em pushd / dirs / popd como "como faço para refazer meus passos?".
Pense no navd como "como eu mantenho um conjunto de diretórios favoritos e alterno facilmente entre eles?".

Cole o seguinte em uma janela de terminal e você pode começar a usar o navd imediatamente durante a sessão de terminal. Este é todo o código que existe para esse recurso.

# Add 1 function and many related aliases for something like "pushd", called "navd". http://unix.stackexchange.com/a/229161
# Think of pushd/dirs/popd as "how do I retrace my steps?".
# Think of navd as "how do I hold on to a set of favorite directories, and easily switch between them?".
# Pseudo-code to explain each part of the "navd" bash function just below:
#              If no arguments to the 'navd' command:
#                  If stack has entries, then print the stack one-line-per-dir with each line numbered.
#                  Else, if stack is empty, automatically run the equivalent of the navh command.
#              Else (there **are** arguments to the 'navd' command):
#                  If arg is '--help' or '/?' then show help.
#                  Else    (arg is assumed to be a path to a directory)
#                      Remember the directory we are starting at
#                      Change to dir given as argument (the "arg-dir"), and do a few chores:
#                      Do not use arg-dir literally ... instead, magically put the **absolute** path we arrived at into history.
#                      Set a flag if the arg-dir is already in the stack.
#                      If the flag is set then just show the stack (on one line), else ADD to stack, ROTATE to end-of-stack, and show the stack.
#                      Change to dir we started at and then back to the arg-dir. This allows "cd -" to go back to dir we started at.
#                  End-If
#              End-If
navd () {
    if [[ $1 == '' ]]; then                             #--no arguments to the 'navd' command
        if dirs +1 >/dev/null 2>&1; then                #------stack has entries
            dirs -p | perl -ne 'print (-1+$cn++); print "$_"' | grep -v "^-1";
        else                                            #------stack is empty
            echo "The navd stack is empty. Now running 'navh' in case that's helpful. navd --help works."
            if [[ ! -f $HOME/.navhignore ]]; then echo -n ''>>$HOME/.navhignore;fi;diff --new-line-format="" --unchanged-line-format="" <(history | perl -ne "if (m/^\s*\d+\s+navd [\"~.\/]/) {s/^\s*\d+\s+/  /;s/\/$//;print}" | sort -u) <(cat $HOME/.navhignore | sort -u);echo "cat $HOME/.navhignore # (Has "'grep -c . <(sort -u $HOME/.navhignore)'" unique lines.)"
        fi
    else                                                #--(there **are** arguments to the 'navd' command)
        if [[ $1 == '--help' || $1 == '/?' ]]; then     #------arg is '--help' or '/?'
            echo "The 'navd' functionality is nothing but one bash function and a set of aliases."
            echo "It offers a different style of handy directory navigation than pushd/popd."
            echo "It uses the same 'stack' as pushd. Look in the .bashrc file for details."
            echo "    (Think of pushd/dirs/popd as 'how do I retrace my steps?'."
            echo "     Think of navd as 'how do I remember a set of favorite directories,"
            echo "     and easily switch between them?'.)"
            echo "As of 10/2015, this link has more info: http://unix.stackexchange.com/a/229161"
            echo "Here is the set of navd-related aliases. None need any parameter:"
            alias | grep 'alias nav' | cut -d= -f1 | grep -v '-' | grep -v 'navh'
            alias | grep 'alias nav' | cut -d= -f1 | grep '-'
            echo "alias navh  # The 'navh' alias has nothing to display until a 'navd <path>' is run. Short for nav-history."
            echo "---- To get started, simpy type navd followed by your favorite path. ----"
            echo "---- navd with no param shows stack. nav0 navigates to first on stack. ----"
        else                                            #------(arg is assumed to be a path to a directory)
            mypwd="$PWD"
            cd "$1" >/dev/null;
            history -s 'echo "$PWD" | perl -pe 's/$ENV{'HOME'}/~/;s/ /\\ /g;s/^/navd /''
            myflag='dirs -p | perl -pe 's/\n/:/' | perl -ne '@a=split(":");$pwd=shift(@a);$flag=0;foreach (@a) {if ($_ eq $pwd) {$flag=1}};print $flag''
            if [[ $myflag == 1 ]]; then dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"; else pushd .>/dev/null; pushd +1>/dev/null; dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"; fi
            cd "$mypwd"; cd "'dirs -l -0'"
        fi
    fi
};
# Aliases for navigating and rotating the "pushd" stack in the style of "navd":
alias navd0='cd "'dirs -l +1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"' # "-l" is dash-L, and expands "~" to denote the home dir. Needed inside back-ticks.
alias navd1='cd "'dirs -l +1'";pushd -n +1;cd "'dirs -l +1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd2='myd=$PWD;cd "'dirs -l +1'";for i in {1..2};do pushd -n +1>/dev/null;cd "'dirs -l +1'";done;cd "$myd";cd "'dirs -l +1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd3='myd=$PWD;cd "'dirs -l +1'";for i in {1..3};do pushd -n +1>/dev/null;cd "'dirs -l +1'";done;cd "$myd";cd "'dirs -l +1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd4='myd=$PWD;cd "'dirs -l +1'";for i in {1..4};do pushd -n +1>/dev/null;cd "'dirs -l +1'";done;cd "$myd";cd "'dirs -l +1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd5='myd=$PWD;cd "'dirs -l +1'";for i in {1..5};do pushd -n +1>/dev/null;cd "'dirs -l +1'";done;cd "$myd";cd "'dirs -l +1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd6='myd=$PWD;cd "'dirs -l +1'";for i in {1..6};do pushd -n +1>/dev/null;cd "'dirs -l +1'";done;cd "$myd";cd "'dirs -l +1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd7='myd=$PWD;cd "'dirs -l +1'";for i in {1..7};do pushd -n +1>/dev/null;cd "'dirs -l +1'";done;cd "$myd";cd "'dirs -l +1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd8='myd=$PWD;cd "'dirs -l +1'";for i in {1..8};do pushd -n +1>/dev/null;cd "'dirs -l +1'";done;cd "$myd";cd "'dirs -l +1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd9='myd=$PWD;cd "'dirs -l +1'";for i in {1..9};do pushd -n +1>/dev/null;cd "'dirs -l +1'";done;cd "$myd";cd "'dirs -l +1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-1='cd "'dirs -l -0'";pushd -n -0>/dev/null; dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-2='myd=$PWD;cd "'dirs -l -0'";pushd -n -0>/dev/null;cd "'dirs -l -0'";pushd -n -0>/dev/null;cd "$myd";cd "'dirs -l +1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-3='myd=$PWD;cd "'dirs -l -0'";for i in {1..3};do pushd -n -0>/dev/null;cd "'dirs -l -0'";done;cd "$myd";cd "'dirs -l +1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-4='myd=$PWD;cd "'dirs -l -0'";for i in {1..4};do pushd -n -0>/dev/null;cd "'dirs -l -0'";done;cd "$myd";cd "'dirs -l +1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-5='myd=$PWD;cd "'dirs -l -0'";for i in {1..5};do pushd -n -0>/dev/null;cd "'dirs -l -0'";done;cd "$myd";cd "'dirs -l +1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-6='myd=$PWD;cd "'dirs -l -0'";for i in {1..6};do pushd -n -0>/dev/null;cd "'dirs -l -0'";done;cd "$myd";cd "'dirs -l +1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-7='myd=$PWD;cd "'dirs -l -0'";for i in {1..7};do pushd -n -0>/dev/null;cd "'dirs -l -0'";done;cd "$myd";cd "'dirs -l +1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-8='myd=$PWD;cd "'dirs -l -0'";for i in {1..8};do pushd -n -0>/dev/null;cd "'dirs -l -0'";done;cd "$myd";cd "'dirs -l +1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias navd-9='myd=$PWD;cd "'dirs -l -0'";for i in {1..9};do pushd -n -0>/dev/null;cd "'dirs -l -0'";done;cd "$myd";cd "'dirs -l +1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
# BONUS commands (beyond the 20). Aliases for navigating but NOT rotating the "navd" stack:
#      Help in remembering: "navd<#>" does more since it both changes the PWD and rotates the stack, whereas "nav<#>" does less
#            (and has one letter less) since "nav<#>" only changes the PWD. Also "navd<#>" acts like the pushd-related command: dirs
#      There is no "nav" command (with no number) so that there will be no conflict if any program called "nav" is used.
alias nav0='cd "'dirs -l +1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav1='cd "'dirs -l +2'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav2='cd "'dirs -l +3'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav3='cd "'dirs -l +4'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav4='cd "'dirs -l +5'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav5='cd "'dirs -l +6'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav6='cd "'dirs -l +7'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav7='cd "'dirs -l +8'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav8='cd "'dirs -l +9'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav9='cd "'dirs -l +10'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-1='cd "'dirs -l -0'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-2='cd "'dirs -l -1'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-3='cd "'dirs -l -2'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-4='cd "'dirs -l -3'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-5='cd "'dirs -l -4'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-6='cd "'dirs -l -5'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-7='cd "'dirs -l -6'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-8='cd "'dirs -l -7'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
alias nav-9='cd "'dirs -l -8'";dirs -p | perl -ne "chomp;s/$/ /;print unless ++\$cn==1"'
# BONUS command (beyond the 20). Alias for showing 'history' of all navd commands that add to the stack.
#                Can be used in a new terminal session to quickly add recently used dirs to the navd stack.
alias navh='if [[ ! -f $HOME/.navhignore ]]; then echo -n ''>>$HOME/.navhignore;fi;diff --new-line-format="" --unchanged-line-format="" <(history | perl -ne "if (m/^\s*\d+\s+navd [\"~.\/]/) {s/^\s*\d+\s+/  /;s/\/$//;print}" | sort -u) <(cat $HOME/.navhignore | sort -u);echo "cat $HOME/.navhignore # (Has "'grep -c . <(sort -u $HOME/.navhignore)'" unique lines.)"'
# Note: When 'navd <relative-path>' is used, then by bash-magic the navd command puts 'navd <absolute-path>' into history,
#       instead. This allows the output of "navh" to be useful regardless of the directory that is current when it is run.
#
# BONUS commands (beyond the 20). An even shorter alias for navd. An even shorter alias for navh.
alias nd='navd'
alias nh='if [[ ! -f $HOME/.navhignore ]]; then echo -n "">>$HOME/.navhignore;fi;diff --new-line-format="" --unchanged-line-format="" <(history | perl -ne "if (m/^\s*\d+\s+navd [\"~.\/]/) {s/^\s*\d+\s+/  /;s/\/$//;print}" | sort -u) <(cat $HOME/.navhignore | sort -u);echo "cat $HOME/.navhignore # (Has "'grep -c . <(sort -u $HOME/.navhignore)'" unique lines.)"'

Esses aliases são baseados em comandos "bash". Um cuidado especial é tomado para preservar o comportamento normal de "cd -". (A maior parte do tempo eu uso "cd -" em vez de incomodar com pushd ou navd - porque "cd -" é muito útil para voltar ao último "lugar" que você estava, ou alternar entre apenas 2 lugares, e funciona em qualquer lugar sem instalação.

Esses comandos podem, é claro, ser colocados no arquivo .bashrc para uma instalação mais permanente deles.

    
por 11.09.2015 / 23:38
0

Aqui está outra solução que você pode gostar. Eu escrevi isso depois de brincar com a solução por @cjm. Ele usa o comando de diálogo para criar um menu do tipo ncurses a partir da saída de dirs. A seleção de um item trará esse diretório para o topo da pilha e fará o cd nele. Isto tem o benefício sobre o dirhistory de dar a cada emulador de terminal seu próprio buffer de histórico de diretório, e é um pouco mais fácil de instalar.

Para instalar: Depois de ter aliased cd para pushd, instale a caixa de diálogo, em seguida, basta colocar esta função em seu bashrc:

dirmenu(){
    dirIter=$(dialog --backtitle 'dirmenu' --clear --cancel-label "Exit" --menu "Please select:" 0 0 0 $(dirs) 3>&2 2>&1 1>&3)
    cmd="builtin cd ~$dirIter"
    eval $cmd
}

Eu gosto disso um pouco melhor do que executar o dirs -v, em seguida, executar outro comando para pop ou cd para o diretório que eu quero. Os menus de diálogo também podem ser altamente personalizados através de seu dialogrc.

Então, para responder à sua pergunta, sim, acho que aliasing pushd to cd é uma ótima ideia. É improvável que você tenha problemas de estouro de buffer se estiver reinicializando sua máquina regularmente, pelo menos para atualizações. Embora eu tenha cuidado ao usar o cd ao criar scripts; cd em um loop while pode causar problemas de estouro de buffer. Não tenho certeza do que controla o tamanho do buffer dirs / pushd.

    
por 12.12.2016 / 16:37