Como executo um programa com um diretório de trabalho diferente do atual, do shell Linux?


352

Usando um shell Linux , como inicio um programa com um diretório de trabalho diferente do diretório de trabalho atual?

Por exemplo, eu tenho um arquivo binário helloworldque cria o arquivo hello-world.txtno diretório atual .

Este arquivo está dentro do diretório /a.

Atualmente, estou no diretório /b. Quero iniciar meu programa em execução ../a/helloworlde obter o hello-world.txtlugar em um terceiro diretório /c.


5
Eu descobri da maneira mais difícil que suredefine o diretório de trabalho para o diretório inicial do usuário especificado antes de executar qualquer -ccomando. Isso foi muito útil para mim.
Patrick M

Respostas:


561

Chame o programa assim:

(cd /c; /a/helloworld)

Os parênteses fazem com que um sub-shell seja gerado. Esse sub-shell altera seu diretório de trabalho para /ce executa a helloworldpartir de /a. Após a saída do programa, o sub-shell é finalizado, retornando ao prompt do shell pai, no diretório em que você iniciou.

Tratamento de erros: Para evitar a execução do programa sem ter alterado o diretório, por exemplo, ao escrever incorretamente /c, torne a execução helloworldcondicional:

(cd /c && /a/helloworld)

Reduzindo o uso de memória: Para evitar que o subshell desperdice memória enquanto o hello world é executado, chame helloworldvia exec:

(cd /c && exec /a/helloworld)

[Obrigado a Josh e Juliano por dar dicas sobre como melhorar esta resposta!]


11
Alguma maneira de passar argumentos para esse shell? Como em $ 1 e $ 2?
Finiteloop 22/05

2
@segfault: o subshell tem acesso completo ao escopo ao redor.
David Schmitt

Parece que está temporariamente nesse diretório de qualquer maneira, não é?
dhein

11
Você pode passar todos os argumentos, fazendo $ *, $ @ ou "$ @" (se você quiser argumentos para respeitar aspas)
Marcel Valdez Orozco

11
Funcionará se eu adicionar esta linha ao /etc/rc.d/rc.local?
Pratik Patil

95

Semelhante à resposta de David Schmitt , mais a sugestão de Josh, mas não deixa um processo de shell em execução:

(cd /c && exec /a/helloworld)

Dessa forma, é mais parecido com o modo como você geralmente executa comandos no shell. Para ver a diferença prática, você deve executar a ps efpartir de outro shell com cada solução.



25

Uma opção que não requer um subshell e é incorporada ao bash

(pushd SOME_PATH && run_stuff; popd)

Demo:

$ pwd
/home/abhijit
$ pushd /tmp # directory changed
$ pwd
/tmp
$ popd
$ pwd
/home/abhijit

11
Uma sugestão semelhante foi feita abaixo por Sahil. Não funciona se o comando falhar. Considere pushd SOME_PATH && run_stuff && popd- se run_stuff falhar, o popd não será executado.
Anton Daneyko

Resposta tardia, isso depende das configurações do arquivo bash. O Bash pode continuar executando comandos mesmo depois de um comando com falha (diferente de usar &&), mas pode ser configurado para não fazer isso usando set -eo arquivo e, em seguida, falharia popd.
Loren

8
Ainda assim, acho que pushd "${SOME_PATH}" && run_stuff; popdé melhor que a resposta atual, uma vez que a semântica pushd / popd foi projetada especificamente para essa situação de entrar em algum diretório e depois voltar ao original.
Marcel Valdez Orozco

Como funciona como definido como alias e preciso passar um parâmetro?
DRB

Eu acho que você precisaria escrever um script de shell para o qual passaria o parâmetro que executaria a série de comandos, pois você não pode passar um parâmetro no meio de um alias. Se você precisar de ajuda para escrever isso, faça uma pergunta separada e faça referência a esta. Depois de ter o script de shell, você pode escrever um alias para chamar seu novo script.
Loren

19
sh -c 'cd /c && ../a/helloworld'

11
Utilizado para o jexec do FreeBSD para executar um comando dentro da prisão no diretório de trabalho especificado.
Marián Černý

11

Eu sempre acho que as ferramentas UNIX devem ser escritas como filtros, ler a entrada do stdin e gravar a saída no stdout. Se possível, você pode alterar o binário do helloworld para gravar o conteúdo do arquivo de texto em stdout, em vez de um arquivo específico. Dessa forma, você pode usar o shell para gravar seu arquivo em qualquer lugar.

$ cd ~ / b

$ ~ / a / helloworld> ~ / c / helloworld.txt


6
+1 por estar certo, embora a resposta seja apenas periférica.
25410 David Schmitt

8

Basta alterar o último "&&" para ";" e ele retornará o CD, não importa se o comando falhar ou for bem-sucedido:

cd SOME_PATH && run_some_command ; cd -

4

Uma maneira de fazer isso é criar um script de shell wrapper.

O script do shell alteraria o diretório atual para / c, depois executaria / a / helloworld. Depois que o script do shell sai, o diretório atual é revertido para / b.

Aqui está um exemplo de script do shell bash:

#!/bin/bash
cd /c
/a/helloworld

2

por que não simplificar

cd SOME_PATH && run_some_command && cd -

o último comando 'cd' o levará de volta ao último diretório pwd. Isso deve funcionar em todos os sistemas * nix.


Está escrita @mezhaka, deveria ter considerado que :)
Sahil

11
Aviso: Se run_some_commandfalhar, cd -não será executado.
starbeamrainbowlabs 12/03

1

Se você sempre deseja que ele vá para / C, use um caminho absoluto ao escrever o arquivo.


0

Se você deseja executar isso dentro do seu programa, eu faria algo como:

#include <unistd.h>
int main()
{
  if(chdir("/c") < 0 )  
  {
     printf("Failed\n");
     return -1 ;
  }

  // rest of your program...

}

Ele quer fazer isso em um shell-script, e não em um C. Além disso, seria uma idéia horrível subprocessar o arquivo binário.

-1

do diretório atual forneça o caminho completo para o diretório de scripts para executar o comando

/root/server/user/home/bin/script.sh

11
Isso não muda o diretório de trabalho - acho que você está respondendo a uma pergunta diferente daquela que foi solicitada.
Toby Speight

Veio aqui para encontrar uma resposta para a pergunta que você respondeu. Obrigado! lol
kfrncs
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.