Podkatalog zmiany katalogu

Chcę wykonać skrypt wewnątrz podkatalogu / superkatalogu(najpierw muszę być w tym podkatalogu / superkatalogu). Nie mogę dostać subprocess do mojego podkatalogu:

tducin@localhost:~/Projekty/tests/ve$ python
Python 2.7.4 (default, Sep 26 2013, 03:20:26) 
[GCC 4.7.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> import os
>>> os.getcwd()
'/home/tducin/Projekty/tests/ve'
>>> subprocess.call(['cd ..'])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/subprocess.py", line 524, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib/python2.7/subprocess.py", line 711, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1308, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

Python rzuca OSError i nie wiem dlaczego. Nie ma znaczenia, czy próbuję wejść do istniejącego podkatalogu, czy wejść do jednego katalogu w górę ( jak wyżej) - zawsze kończę z tym samym błędem.

Author: GG., 2014-01-28

5 answers

Twój kod próbuje wywołać program o nazwie cd ... To, co chcesz, to wywołać komendę o nazwie cd.

Ale cd jest skorupą wewnętrzną. Więc możesz go nazywać tylko

subprocess.call('cd ..', shell=True) # pointless code! See text below.

Ale to nie ma sensu. ponieważ żaden proces nie może zmienić katalogu roboczego innego procesu (przynajmniej na UNIKSOPODOBNYM systemie operacyjnym, ale także na Windows), To wywołanie spowoduje, że subshell zmieni swój katalog i natychmiast zakończy działanie.

To, co chcesz, można osiągnąć za pomocą os.chdir() lub za pomocą parametr subprocess o nazwie cwd, który zmienia katalog roboczy bezpośrednio przed wykonaniem podprocesu.

Na przykład, aby wykonać ls w katalogu głównym, możesz wykonać

wd = os.getcwd()
os.chdir("/")
subprocess.Popen("ls")
os.chdir(wd)

Lub po prostu

subprocess.Popen("ls", cwd="/")
 71
Author: glglgl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-28 12:18:13

Aby uruchomić your_command jako podproces w innym katalogu, podaj parametr cwd, jak zasugerowano w odpowiedzi @ wim :

import subprocess

subprocess.check_call(['your_command', 'arg 1', 'arg 2'], cwd=working_dir)

Proces potomny nie może zmienić katalogu roboczego rodzica (normalnie ). Uruchomienie cd .. w podrzędnym procesie powłoki przy użyciu podprocesu nie zmieni katalogu roboczego skryptu Pythona, tzn. przykład kodu w odpowiedzi @glglgl jest błędny . cd jest wbudowaną powłoką (nie osobnym programem wykonywalnym), może zmieniać Katalog tylko w ten sam proces.

 27
Author: jfs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:31

Chcesz użyć bezwzględnej ścieżki do pliku wykonywalnego i użyć cwd kwarg z Popen do Ustawienia katalogu roboczego. Zobacz docs .

Jeśli cwd nie jest None, bieżący katalog dziecka zostanie zmieniony na cwd przed jego wykonaniem. Zauważ, że ten katalog nie jest brany pod uwagę podczas przeszukiwania pliku wykonywalnego, więc nie można określić ścieżki programu w stosunku do cwd.

 23
Author: wim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-28 13:33:21

Inna opcja oparta na tej odpowiedzi: https://stackoverflow.com/a/29269316/451710

Pozwala to na wykonywanie wielu poleceń (np. cd) w tym samym procesie.

import subprocess

commands = '''
pwd
cd some-directory
pwd
cd another-directory
pwd
'''

process = subprocess.Popen('/bin/bash', stdin=subprocess.PIPE, stdout=subprocess.PIPE)
out, err = process.communicate(commands.encode('utf-8'))
print(out.decode('utf-8'))
 7
Author: Eyal Levin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:26

subprocess.call Inne metody w module subprocess mają parametr cwd.

Ten parametr określa katalog roboczy, w którym chcesz wykonać proces.

Więc możesz zrobić coś takiego:

subprocess.call('ls', shell=True, cwd='path/to/wanted/dir/')

Sprawdź podproces docs .popen-konstruktor

 5
Author: l__flex__l,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-08 15:18:00