Jak uruchomić program z innym katalogiem roboczym niż bieżący, z powłoki Linux?


351

Używać powłoki Linux , jak uruchomić program z innym katalogiem roboczym niż bieżący katalog roboczy?

Na przykład mam plik binarny, helloworldktóry tworzy plik hello-world.txtw bieżącym katalogu .

Ten plik znajduje się w katalogu /a.

Obecnie jestem w katalogu /b. Chcę uruchomić mój program ../a/helloworldi znaleźć hello-world.txtgdzieś w trzecim katalogu /c.


5
Odkryłem twardy sposób, który suresetuje katalog roboczy do katalogu domowego użytkownika określonego przed uruchomieniem jakichkolwiek -cpoleceń. To było dla mnie bardzo pomocne.
Patrick M

Odpowiedzi:


560

Wywołaj program w następujący sposób:

(cd /c; /a/helloworld)

Nawiasy powodują odrodzenie podpowłoki. Ta podpowłoka następnie zmienia katalog roboczy na /c, a następnie wykonuje helloworldz /a. Po wyjściu z programu podpowłoka kończy działanie, co powoduje powrót do monitu powłoki nadrzędnej w katalogu, w którym został uruchomiony.

Obsługa błędów: Aby uniknąć uruchamiania programu bez zmiany katalogu, np. W przypadku błędnej pisowni /c, wykonaj helloworldwarunek:

(cd /c && /a/helloworld)

Zmniejszenie zużycia pamięci: aby uniknąć marnowania pamięci podpowłoki podczas wykonywania hello world, zadzwoń helloworldprzez exec:

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

[Podziękowania dla Josha i Juliano za udzielenie wskazówek na temat poprawy tej odpowiedzi!]


1
Jakiś sposób przekazać argumenty do tej powłoki? Jak w 1 $ i 2 $?
finiteloop

2
@segfault: podpowłoka ma pełny dostęp do otaczającego zakresu.
David Schmitt

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

1
Możesz przekazać wszystkie argumenty, wykonując $ *, $ @ lub „$ @” (jeśli chcesz, aby argumenty szanowały podwójne cudzysłowy)
Marcel Valdez Orozco

1
Czy to zadziała, jeśli dodam tę linię do /etc/rc.d/rc.local?
Pratik Patil


25

Opcja, która nie wymaga podpowłoki i jest wbudowana w bash

(pushd SOME_PATH && run_stuff; popd)

Próbny:

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

1
Podobną sugestię przedstawił poniżej Sahil. Nie działa, jeśli polecenie się nie powiedzie. Zastanów się pushd SOME_PATH && run_stuff && popd- jeśli run_stuff zawiedzie, to popd nie zostanie wykonany.
Anton Daneyko,

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 ustawić, aby nie robił tego przy użyciu set -epliku, a wtedy nie będzie popd.
Loren,

8
Mimo to myślę, że pushd "${SOME_PATH}" && run_stuff; popdjest lepsza niż obecna odpowiedź, ponieważ semantyka pushd / popd została zaprojektowana specjalnie do tej sytuacji, gdy wchodzę do jakiegoś katalogu, a potem wracam do pierwotnego.
Marcel Valdez Orozco

Jak to działa jako zdefiniowane jako alias i muszę przekazać parametr?
DrB.

Myślę, że musisz napisać skrypt powłoki, do którego przekazałeś parametr, który wykonałby serię poleceń, ponieważ nie możesz przekazać parametru w środku aliasu. Jeśli potrzebujesz pomocy w napisaniu tego, powinieneś zadać osobne pytanie i odnieść się do tego. Po utworzeniu skryptu powłoki możesz napisać alias, aby wywołać nowy skrypt.
Loren

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

1
Wykorzystano to dla jexec FreeBSD w celu wykonania polecenia w więzieniu w określonym katalogu roboczym.
Marián Černý

11

Zawsze uważam, że narzędzia UNIX powinny być zapisywane jako filtry, czytać dane wejściowe ze standardowego wejścia i zapisywać dane wyjściowe na standardowe wyjście. Jeśli to możliwe, możesz zmienić swój plik binarny helloworld, aby zapisywał zawartość pliku tekstowego na standardowe wyjście, a nie na określony plik. W ten sposób możesz użyć powłoki, aby zapisać plik w dowolnym miejscu.

$ cd ~ / b

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


6
+1 za rację, chociaż odpowiedź jest tylko peryferyjną odpowiedzią.
David Schmitt

8

Po prostu zmień ostatnie „&&” na „;” i odeśle CD bez względu na to, czy polecenie zakończy się niepowodzeniem, czy pomyślnie:

cd SOME_PATH && run_some_command ; cd -

4

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

Skrypt powłoki zmieniłby bieżący katalog na / c, a następnie uruchomił / a / helloworld. Po zakończeniu skryptu powłoki bieżący katalog powraca do / b.

Oto przykładowy skrypt powłoki bash:

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

2

dlaczego nie uprościć tego

cd SOME_PATH && run_some_command && cd -

ostatnia komenda „cd” zabierze cię z powrotem do ostatniego katalogu pwd. Powinno to działać na wszystkich systemach * nix.


Piszesz @mezhaka, powinienem był to wziąć pod uwagę :)
Sahil

1
Ostrzeżenie: jeśli run_some_commandzawiedzie, cd -nie zostanie wykonane.
starbeamrainbowlabs

1

Jeśli zawsze chcesz, aby przechodził do / C, użyj bezwzględnej ścieżki podczas zapisywania pliku.


0

Jeśli chcesz to zrobić w swoim programie, zrobiłbym coś takiego:

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

  // rest of your program...

}

On chce to zrobić w skrypcie powłoki, a nie w C. Także przerobienie pliku binarnego byłoby okropnym pomysłem.

-1

z bieżącego katalogu podaj pełną ścieżkę do katalogu skryptów, aby wykonać polecenie

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

1
To wcale nie zmienia katalogu roboczego - myślę, że odpowiadasz na inne pytanie niż zadane.
Toby Speight,

Przyszedł tutaj, aby znaleźć odpowiedź na pytanie, na które odpowiedziałeś. Dzięki! lol
kfrncs
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.