2009-04-24 14 views
240

Używając powłoki Linux, jak uruchomić program z innym katalogiem roboczym z bieżącego katalogu roboczego?Jak uruchomić program z innym katalogiem roboczym niż bieżący, z powłoki systemu Linux?

Na przykład mam plik binarny helloworld, który tworzy plik hello-world.txt w bieżącym katalogu. Ten plik znajduje się w katalogu /a. Obecnie jestem w katalogu /b. Chcę uruchomić program pod numerem ../a/helloworld i pobrać hello-world.txt gdzieś w trzecim katalogu /c.

+4

odkryłem na własnej skórze, że ' su' resetuje katalog roboczy do katalogu domowego użytkownika określonego przed uruchomieniem jakichkolwiek komend '-c'. To mi bardzo pomogło. –

Odpowiedz

406

połączeń program tak:

(cd /c; /a/helloworld) 

Nawiasy spowodować sub-shell się zrodził. Ta podrzędna skorupa zmienia katalog roboczy na /c, a następnie wykonuje helloworld z /a. Po wyjściu programu kończy się podrzędna powłoka, zwracając cię do monitu o powłokę nadrzędną w katalogu, z którego zacząłeś.

Obsługa błędów: Aby uniknąć uruchamiania programu bez zmiany katalogu, np. kiedy po błędnie /c uzależnić wykonanie helloworld Warunkowo:

(cd /c && /a/helloworld) 

Zmniejszenie zużycia pamięci: Aby uniknąć pamięć odpadów powłoki w tle podczas hello world uruchamia, zadzwoń helloworld poprzez exec:

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

[ Dzięki Josh and Juliano za wskazówki dotyczące poprawy tej odpowiedzi!]

+1

Jakikolwiek sposób przekazywania argumentów do tej powłoki? Jak w 1 $ i 2 $? – finiteloop

+1

@segfault: Podpozycja ma pełny dostęp do otaczającego zakresu. –

+0

Wygląda na to, że jest tymczasowo w tym katalogu, prawda? – dhein

1

Jeśli zawsze chcesz, aby przejść do/C, użyj bezwzględnej ścieżki podczas pisania pliku.

3

Jednym ze sposobów jest utworzenie skryptu powłoki opakowania.

Skrypt powłoki zmieni bieżący katalog na/c, a następnie uruchom/a/helloworld. Po wyjściu skryptu powłoki bieżący katalog powraca do/b.

Oto przykład skrypt powłoki bash:

#!/bin/bash 
cd /c 
/a/helloworld 
14
sh -c 'cd /c && ../a/helloworld' 
+1

Użyto tego dla jexec FreeBSD, aby wykonać polecenie wewnątrz więzienia w określonym katalogu roboczym. –

+0

Wow, masz szczęście, że pozwolili ci nawet użyć komputera w więzieniu –

+0

@MattWilde https://www.freebsd.org/cgi/man.cgi?jail – mihi

77

podobne do odpowiedzi David Schmitt „s, plus sugestia Josha, ale nie pozostawia zakonczeniu powłoki:

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

Ten sposób jest bardziej podobny do tego, jak zwykle uruchamianie komend na powłoce. Aby zobaczyć praktyczną różnicę, musisz uruchomić ps ef z innej powłoki z każdym rozwiązaniem.

+0

[Bash manual builtins ** exec **] (https: // www .gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html # Bourne-Shell-Builtins) –

1

Jeśli chcesz wykonać to wewnątrz programu to chciałbym zrobić coś takiego:

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

    // rest of your program... 

} 
+0

Chce to zrobić w skrypcie powłoki, a nie w C. Również byłoby okropny pomysł podprocesowania pliku binarnego. –

9

zawsze myślę narzędzia UNIX powinno być napisane jak filtry, odczytać dane wejściowe z stdin i zapisywać dane wyjściowe do stdout. Jeśli to możliwe, możesz zmienić plik binarny helloworld, aby zapisać zawartość pliku tekstowego na standardowe wyjście zamiast konkretnego pliku. W ten sposób możesz użyć powłoki do napisania swojego pliku w dowolnym miejscu.

$ cd ~/b

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

+5

+1 za bycie prawym, chociaż odpowiedź jest tylko obwodowo odpowiedzią. –

1

dlaczego nie keep it simple

cd SOME_PATH && run_some_command && cd -

ostatni ' Polecenie cd 'przeniesie cię z powrotem do ostatniego katalogu pwd. Powinno to działać na wszystkich systemach * nix.

+0

Nie spowoduje to powrotu, jeśli run_some_command nie powiedzie się. –

+0

Piszecie @mezhaka, powinniście to rozważyć :) – Sahil

7

opcja, która nie wymaga podpowłoce i jest zbudowany w bash

(pushd SOME_PATH && run_stuff; popd) 

Demo:

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

Podobna sugestia została przedstawiona poniżej przez Sahila. Nie działa, jeśli polecenie się nie powiedzie. Rozważmy 'pushd SOME_PATH && run_stuff && popd' - jeśli run_stuff się nie powiedzie, to popd nie zostanie wykonany. –

+0

Późna odpowiedź, która zależy od ustawień pliku bash. Bash może kontynuować wykonywanie poleceń nawet po nieudanym poleceniu (w przeciwieństwie do używania &&), ale można go ustawić, aby nie robił tego za pomocą '' set -e'' w pliku, a następnie nie powiedzie się '' popd''. – Loren

+1

Nadal myślę, że 'pushd" $ {SOME_PATH} "&& run_stuff; popd' jest lepszy niż obecna odpowiedź, ponieważ semantyka pushd/popd została specjalnie zaprojektowana dla tej sytuacji przejścia do jakiegoś katalogu, a następnie powrotu do pierwotnego. –

4

Wystarczy zmienić ostatni "& &" w ";" i będzie cd kopii bez względu na to polecenie nie powiedzie się lub udaje:

cd SOME_PATH && run_some_command ; cd - 
-1

z bieżącego katalogu podać pełną ścieżkę do katalogu skryptu, aby wykonać polecenie

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

To wcale nie zmienia katalogu roboczego - myślę, że odpowiadasz na inne pytanie niż to, które zostało zadane. –

Powiązane problemy