Existe uma maneira de executar um comando em um diretório diferente sem precisar fazê cd
-lo? Eu sei que eu poderia simplesmente entrar cd
e cd
sair, mas só estou interessado nas possibilidades de renunciar às etapas extras :)
Existe uma maneira de executar um comando em um diretório diferente sem precisar fazê cd
-lo? Eu sei que eu poderia simplesmente entrar cd
e cd
sair, mas só estou interessado nas possibilidades de renunciar às etapas extras :)
Respostas:
Não sei se isso conta, mas você pode fazer um subshell:
$ (cd /var/log && cp -- *.log ~/Desktop)
O diretório é alterado apenas para esse subshell, para evitar o trabalho de precisar cd -
depois.
$ (cd /var/log && cp *.log ~/Desktop)
. Dessa forma, se o diretório não existir, nenhum comando adicional será executado.
Alguns programas têm opções com as quais você pode dizer a eles próprios para chdir (2) (por exemplo, GNU tar 's -C
/ --directory
).
Fora de tais programas, porém, algo terá que chdir . Você pode escrever e usar algum tipo de programa "binário" compilado em vez de fazer com que o shell o faça, mas provavelmente não traria muitos benefícios.
Em um comentário em outra resposta, você deu um exemplo:
execindirectory -d /var/log "cp *.log ~/Desktop"
Como o *.log
padrão é expandido pelo próprio shell (não pelo cp ), algo terá que chdir para o diretório antes de um shell avaliar seu comando.
Se você é apenas interessante para evitar ter que “voltar ao cd”, pode usar um subshell para isolar o efeito do cd da sua instância do shell de trabalho.
(cd /path/to/dir && some command)
Você pode empacotar isso em uma função shell. (Abandonei a -d
opção do seu exemplo de uso, pois há pouco sentido nesse comando se o diretório for realmente opcional.)
runindir() { (cd "$1" && shift && eval "$@"); }
runindir /var/log 'cp *.log ~/Desktop' # your example
runindir /var/log cp \*.log \~/Desktop # eval takes multiple args
runindir /var/log cp \*.log ~/Desktop # it is okay to expand tilde first
Não para minar o valor das respostas dadas por outras pessoas, mas acredito que o que você quer é o seguinte:
(cd /path/to && ./executable [ARGS])
Observe as parênteses a serem invocadas cd
em um subcasca.
Aqui está uma coisa que deve deixar você cd
voltar onde estava (usando o Bash), já que não esquecer disso parece ser o objetivo da pergunta:
# Save where you are and cd to other dir
pushd /path/to/dir/that/needs/to/be/current/dir
run-your-command
# Get back where you were at the beginning.
popd
(EDIT: versão um pouco mais curta, graças a @ Random832)
pushd other-dir
, em vez depushd .; cd other-dir
Infelizmente, seu exemplo:
execindirectory -d /var/log "cp *.log ~/Desktop"
não precisa de uma alteração no diretório, porque
cp /var/log/*.log ~/Desktop
faria o mesmo. Você não pode se aproximar do seu problema real? Porque também podemos conhecer uma solução melhor para isso.
Uma maneira complicada de resolver seu problema, que está longe da elegância da solução Michaels, é o uso de find, que possui uma opção '-execdir' a ser executada no diretório em que um arquivo é encontrado. Mal adotado no seu exemplo:
find /var/log -maxdepth 1 -type f -name "*.log" -execdir echo cp {} ~/Desktop ";"
Talvez seja útil para o seu problema real. -okdir em vez de -execdir solicitará que você confirme todas as chamadas.
-okdir e -execdir podem precisar do gnu-find para serem instalados, o que normalmente é usado no Linux.
Que tal ./your/path/command.sh
?
execindirectory -d /var/log "cp *.log ~/Desktop"
.
echo "#!/bin/bash; cd $1; exec $2" > /usr/local/bin/execindirectory; chmod +x /usr/local/bin/execindirectory
. Pode ser necessário um pouco mais de esforço se você quiser realmente oferecer suporte a "tags" de opções, como-d
outras coisas.