Alias ​​para CD em um diretório e chame um comando


21

Eu tenho um .bash_profilee em que eu tenho um conjunto de aliases. Esses apelidos no momento executam apenas um único comando e foi bastante fácil. No entanto, gostaria de fazer duas coisas com um novo alias que estou tentando criar.

  1. CD em um diretório
  2. Execute um comando desse diretório

Respostas:


26

Para executar um comando com um diretório de trabalho específico, geralmente é necessário

( cd directory && utility )

Os parênteses ao redor do cd ...meio significa que o (s) comando (s) é executado em um subshell. A alteração do diretório de trabalho em um subshell faz com que o diretório de trabalho atual do shell de chamada não seja alterado, ou seja, depois de chamar este comando, você ainda estaria localizado no mesmo diretório em que iniciou.

Exemplo:

( cd / && echo "$PWD" )  # will output "/"
echo "$PWD"              # will output whatever directory you were in at the start

Isso não pode ser transformado em um alias genérico, pois um alias não pode receber nenhum argumento.

Para um diretório e utilitário específicos , pode-se fazer

alias cdrun='( cd "$HOME/somedir" && ./script.sh )'

mas para o caso geral, você precisaria usar uma função shell:

cdrun () {
    ( cd "$1" && shift && command "$@" )
}

ou

cdrun () (
    cd "$1" && shift && command "$@"
)

Substituir os chavetas entre parênteses ao redor do corpo da função faz com que a função seja executada em seu próprio subshell.

Isso seria usado como

$ cdrun "$HOME/somedir" ./script.sh

que executaria o script script.shlocalizado no diretório $HOME/somedir, com $HOME/somediro diretório de trabalho ou

$ cdrun / ls -l

que forneceria uma listagem de diretório em "formato longo" do diretório raiz.

A função shell pega seu primeiro argumento e tenta mudar para esse diretório. Se isso funcionar, ele desativa o nome do diretório dos parâmetros posicionais (a lista de argumentos da linha de comandos) e executa o comando fornecido pelo restante dos argumentos. commandé um comando interno no shell que simplesmente executa seus argumentos como um comando.


Tudo isso é necessário se você deseja executar um comando com um diretório de trabalho alterado . Se você quiser apenas executar um comando localizado em outro lugar, obviamente poderá usar

alias thing='$HOME/somedir/script.sh'

mas isso seria executado script.shlocalizado no $HOME/somedircom o atual diretório como o diretório de trabalho.

Outra maneira de executar um script localizado em outro lugar sem alterar o diretório de trabalho é adicionar o local do script à sua PATHvariável de ambiente, por exemplo

PATH="$PATH:$HOME/somedir"

O Now script.shin $HOME/somedirpoderá ser executado em qualquer lugar usando apenas

$ script.sh

Novamente, isso não altera o diretório de trabalho do comando.


2
Excelente, resposta abrangente. Eu apenas pensei que eu ia mencionar que a definição da função só precisa de um método de agrupamento de comandos e os parênteses para o subnível são suficientes: cdrun () ( cd "$1" && shift && command "$@" ).
Anthony G - Justice para Monica

2
@AnthonyGeoghegan Ah, isso é verdade. Eu sempre uso { ... }para consistência com funções mais longas.
Kusalananda

Esta sessão de perguntas e respostas parece falar da minha situação e pode ser uma melhoria no uso de um ambiente circundante pushde popd(também > /dev/nullse você estiver tentando evitar as mensagens de saída), além de manter o contexto limpo!
Pysis

11
@Pysis Sim, (cd dir && thing)também é muito mais portátil do que usar pushde popd.
Kusalananda

@Kusalananda Realmente? Eu trabalhei com eles em pelo menos vários sistemas.
Pysis

4
alias <name-of-the-alias>='cd <the-directory> && <command>'

Portanto, se você deseja alterar o diretório (cd) para a pasta /var/log/e listar (ls) seus arquivos, você pode anexar ao .bash_profilearquivo o seguinte:

alias logs='cd /var/log/ && ls'

1

Eu uso essa função para executar um único comando em um diretório diferente:

cd1 () {
  if [ $# -eq 1 ]; then
    command cd -- "$1"
  else
    ( command cd -- "$1" && shift && "$@" )
  fi
}

Uma limitação dessa função é que os curingas são concluídos em relação ao diretório original, não em relação ao diretório em que o comando é executado. É possível fazer melhor no zsh .

Essa função age como o comum cdse for chamada com um único argumento; portanto, convém chamá-lo cd. (Esta função não suporta nenhuma opção, mas opções cdraramente são usadas.)


-1

Separe os comandos com ponto e vírgula, por exemplo:

alias do_something='cd /tmp; ls'

8
Se a cdfalha falhar, você obterá a lista de diretórios do diretório errado. É melhor usar em &&vez de ;aqui.
Kusalananda

@Kusalananda está certo. Você pode encontrar mais nesta resposta
Nikolas
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.