Jake Horse
Jake Horse

Reputation: 23

When trying to call a bash script in subprocess I am denied permission

I am trying to run a bash script in my python script, I'm sure there is a way to do what my bash script is doing in python instead but I am more focused on getting this working.

Here is the code I am running as root followed by the error:

import subprocess
#variable = subprocess.check_output('dmidecode', shell=True)
#print(variable)
#run program once as root then cron it as root
try :
    file = open("/var/log/serialcontrol/dmidecode.txt", "r")
except FileNotFoundError:
    file = open('/var/tmp/serialcontrol.bash', 'w') 
    file.write("#!/bin/bash/\nif [ ! -d /var/log/serialcontrol/]\nthen\n\tmkdir /var/log/serialcontrol/\nfi");
    file.close()
    subprocess.call("/var/tmp/serialcontrol.bash")

Heres the error

Traceback (most recent call last):
  File "/home/trisimix/serialcontrol/serialcontrol.py", line 6, in <module>
    file = open("/var/log/serialcontrol/dmidecode.txt", "r")
FileNotFoundError: [Errno 2] No such file or directory: '/var/log/serialcontrol/dmidecode.txt'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/trisimix/serialcontrol/serialcontrol.py", line 11, in <module>
    subprocess.call("/var/tmp/serialcontrol.bash")
  File "/usr/lib/python3.5/subprocess.py", line 557, in call
    with Popen(*popenargs, **kwargs) as p:
  File "/usr/lib/python3.5/subprocess.py", line 947, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.5/subprocess.py", line 1551, in _execute_child
    raise child_exception_type(errno_num, err_msg)
PermissionError: [Errno 13] Permission denied

Upvotes: 1

Views: 1598

Answers (1)

janos
janos

Reputation: 124648

The /var/tmp/serialcontrol.bash file that you create while handling the FileNotFoundError is not executable. Make it executable first before trying to execute it with subprocess.

import subprocess
import os
import stat

#variable = subprocess.check_output('dmidecode', shell=True)
#print(variable)
#run program once as root then cron it as root
try :
    file = open("/var/log/serialcontrol/dmidecode.txt", "r")
except FileNotFoundError:
    script = '/var/tmp/serialcontrol.bash'
    with open(script, 'w') as file:
        file.write("#!/usr/bin/env bash/\nif [ ! -d /var/log/serialcontrol/]\nthen\n\tmkdir /var/log/serialcontrol/\nfi");

    st = os.stat(script)
    os.chmod(script, st.st_mode | stat.S_IEXEC)

    subprocess.call(script)

As @anishsane pointed out in a comment, another alternative to chmod-ing the script is to call it like this, and just drop the chmod:

subprocess.call(["/bin/bash", script])

Actually, if we can assume that bash is on PATH, then this would be more portable:

subprocess.call(["bash", script])

Upvotes: 2

Related Questions