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.