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
user232103
fonte

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.

Kusalananda
fonte
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'
Nikolas
fonte
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.)

Gilles 'SO- parar de ser mau'
fonte
-1

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

alias do_something='cd /tmp; ls'
John Elliot V
fonte
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