PRP PRP - 1 year ago 45
Bash Question

call function not working with cd command

I am trying to execute some shell commands using python :

The command is

cd /home/n1603031f/Desktop/parsec/wd/

It works fine through the shell, but when executed through python it does not work :

path_to_wd = "/home/n1603031f/Desktop/parsec/wd/"

Error :

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/", line 522, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.7/", line 710, in __init__
errread, errwrite)
File "/usr/lib/python2.7/", line 1327, in _execute_child
raise child_exception

I need this command to work as the original command I want to execute is :

cd ./parsec/wd/ && tar -cf ../abcd.tar *

which works correctly only when you change directories to not create the top-level folders in the .tar file

Answer Source

Even if you had the right call to change directories it wouldn't accomplish what you want because each creates a separate process.

What you really need is the cwd argument to subprocess.Popen to say what directory you want to work in. Additionally you need to use os.listdir since the subprocess call won't go through a shell to expand the * glob. This is the right way to do what you're trying to do:

d = './parsec/wd'
subprocess.Popen(['tar', '-cf', '../abcd.tar'] + os.listdir(d), cwd=d).wait()

However, os.listdir will list hidden files as well, if you want to you can filter them out beforehand:

files = [f for f in os.listdir(d) if not f.startswith('.')]

If you really need to (and you don't,) you can use shell=True to get this to work with *. Though unless you're working with trusted input shell=True is widely considered a security vulnerability.

subprocess.Popen('tar -cf ../abcd.tar *', shell=True, cwd='./parsec/wd').wait()

If you need your python process to change it's current working directory, use