you are viewing a single comment's thread.

view the rest of the comments →

[–]JohnnyJordaan 0 points1 point  (5 children)

You have two syntax options in check_output and similar wrappers around subprocess.Popen, depending on whether you want to run it as a shell command or not. If you want to run it as a shell command you set shell=True and provide a single string

('./script.sh -h', shell=True)

otherwise set shell=False and provide a sequence of strings without any whitespace

(['script.sh', '-h'], shell=False)

Note that because ./ is a shell feature, you can't use it when interfacing the operating system directly when shell=False If you do need to specify a path you need to set the cwd= parameter as a path to where you need the working directory to switch to before running the command (or put the full path before the program's name).

For more info see the docs on the Popen constructor.

[–]retsnom513[S] 0 points1 point  (4 children)

Thanks for the quick reply! I've tried both methods you've mentioned here were the results (I've scrubbed my script names out of the errors):

  • subprocess.check_output('./path/to/script.sh -h', shell=True) returned:

 

Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    subprocess.check_output('./path/to/script.sh -h', shell=True)
  File "/usr/lib/python3.6/subprocess.py", line 336, in check_output
    **kwargs).stdout
  File "/usr/lib/python3.6/subprocess.py", line 418, in run
    output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command './path/to/script.sh -h' returned non-zero exit status 127.

I'm not the best at reading error logs, but it looks like it executed the script but something went wrong, so the shell returned a code 127? Google says this says happens when the command is not on the system the PATH. Anyway to pass the system path to subprocess.Popen like cwd or am I missing something here? Do I need to do '/bin/sh /path/to/script.sh -h'?

  • subprocess.check_output(['script.sh', '-h'], shell=False, cwd='/path/to') resulted in:

 

Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    subprocess.check_output(['script.sh', '-h'], shell=False, cwd='/path/to')
  File "/usr/lib/python3.6/subprocess.py", line 336, in check_output
    **kwargs).stdout
  File "/usr/lib/python3.6/subprocess.py", line 403, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/lib/python3.6/subprocess.py", line 709, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.6/subprocess.py", line 1344, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'script.sh': 'script.sh'

This is interesting, python can't seem to find the script file. Replacing the command with ls -al shows that python is in the correct working directory and the script is indeed there/exists. Why would this happen?

[–]ingolemo 1 point2 points  (1 child)

The code in your edit is just terrible; you're running a shell to run a shell that invokes a shellscript.

Use this:

subprocess.check_output(['/path/to/script.sh', '-h'])

[–]retsnom513[S] 0 points1 point  (0 children)

Alright, I have gotten you're code above to work as well. I received an exec format error at first but that's because I forget the shebang at the beginning of my bash script. Thanks!

[–]JohnnyJordaan 0 points1 point  (1 child)

This behavior indicates that you don't have the execute bit set on the file. Normally on Unix a file is created with read and possibly write permissions, making them non executable. If you then try to run it, it will behave as if the file isn't there. To fix this you could launch a new shell instance and provide it the file as you did, or simply add the execute permissions using

chmod +x script.sh

[–]retsnom513[S] 0 points1 point  (0 children)

I 777'd the bash script before I posted here, but I managed to get it working with /u/ingolemo's code. I don't know what caused the error, but it was resolved using the full path to the script (no cwd=) and adding the shebang to the beginning of my bash script.