I'm trying to invoke a shell script shell_script.sh from a python script (python_script.py) using the call command. The shell_script.sh invokes a executable that requires root access to execute.
The python_script.py invokes shell_script.sh using subprocess.call().
See below:
subprocess.call(['/complete_path/shell_script.sh', 'param1', 'param2',
'param3'], shell=True)
When I try to execute the python script python_script.py it gives me permission denied.
I've tried different ways.
a) Invoke python with sudo - sudo python python_script.py
b) Invoke sudo into inside the call method - subprocess.call(['sudo' '/complete_path/shell_script.sh', 'param1', 'param2',
'param3'], shell=True)
What's the best way to resolve this.
Thanks.
I'd put logic in the python_script.py to check its UID and fail if is not executed as root. if os.getuid() != 0:. That will ensure it only runs as root, ether by a root login, or sudo.
If you're getting permission denied when trying to execute the python_script.py, you need to set the execute bit on it. chmod +x python_script.py
Related
I want to invoke a bash script with name myScript.sh in a newly created lambda function.
Step 1: I created a lambda function with name myLambda.py and the source code like:
import subprocess
print("start")
subprocess.call("./myScript.sh")"
Step 2: Create a bash script with name myScript.sh under the same path with myLambda.py
Step 3: Click the test button and got the response:
{
"errorMessage": "[Errno 13] Permission denied: './myScript.sh'"
}
Anybody knows how to deal with the permission denied issue in aws lambda function env?
Since the files are added as the guideline in https://docs.aws.amazon.com/lambda/latest/dg/code-editor.html, it's not helpful to use linux command "chmod +x " to change the file permission.
It's resolved by move myScript.sh to /tmp folder and add permission change command:
subprocess.run(["chmod", "+x", "/tmp/myScript.sh"])
You can't execute scripts that don't have execute permission. You can supply execute permissions using some variant of:
chmod +x /somepath/myScript.sh
You can run this using your current subprocess approach. Run chmod before you run myScript.sh.
I'm attempting to create a .sh file to batch a number of runs of a neural network on Python whilst on holidays.
At the moment I have been calling this from the command line:
python neural_network_trainer.py [args]
I now have a .sh script written:
#!/bin/bash
python neural_network_trainer.py [args]
# Repeated with varied args
That I am attempting to call in the same terminal as the original command line was running:
./august_hols.sh
I get the following error:
File "/data/Python-3.6.9/lib/python3.6/site.py", line 177
file=sys.stderr)
^
SyntaxError: invalid syntax
Where the Python install is in /data (for reasons).
Running which on the command line reports the correct Python directory set via an alias in ~/.bashrc:
alias python=/data/Python-3.6.9/bin/python3
But running which between the Bash shebang and the first python call reports /bin/python.
I've attempted to set the alias again at the start of the .sh script to no avail. I'm scratching my head as this is exact process I have used elsewhere, albeit not on this precise PC. I can copy the exact command from the top of the bash file into the terminal and it runs fine, try and call ./august_hols.sh and get the above Python error.
Where is Bash getting that path from, and why is it not using my expected route through ~/.bashrc?
Bash sub-shell does not inherit alias in the main shell
You can source the script (run in the main shell), instead of execute it (run in the sub-shell)
source script.sh
EDIT:
Solution 2:
Run bash as the login shell so ~/.bashrc is executed, so your alias is loaded before your script.
The subshell needs to be interactive to enable alias, because alias is enabled by default only for interactive shell, but script is non-interactive by default.
bash --login -i script.sh
Solution 3:
Similar to above, except alias is enabled explicitly
bash --login -O expand_aliases script.sh
Have you tried:
python=/data/Python-3.6.9/bin/python3 ./[your_bash].sh
In your .sh
Do this
#!/usr/bin/env bash
export PATH=/data/Python-3.6.9/bin:$PATH
exec python neural_network_trainer.py "$#"
Aliases are tricky.
A maybe more nasty solution
mapfile < <(declare -p | grep -m 1 BASH_ALIASES) && bash script.sh "${MAPFILE[#]}"
within your script you will need
shopt -s expand_aliases
eval $1
echo ${BASH_ALIASES[python]}
python --version
How about this:
#!/bin/bash
/data/Python-3.6.9/bin/python3 neural_network_trainer.py [args]
# Repeated with varied args
When a command is executed via subprocess.run, what permissions is the command executed with? Is it the permissions of the enclosing python file? Is it user permissions?
For example, if a python file were run with sudo:
sudo python3 file.py
and file.py contained the line
subprocess.run([ 'chmod', '+x', 'file.sh' ])
Would chmod be run with super user permissions?
Intuitively, it should, because, through sudo, you are giving the script itself superuser permissions - this means that the commands it runs would be effectively performed by the superuser.
However, to verify, let's do a little experiment.
test.py
import subprocess
subprocess.run('whoami')
(Now, on the terminal)
$ sudo python test.py
root
$
So, chmod will run with superuser permissions, yes.
Using ubuntu's 16.04 crontab and #reboot to run python3 script. The script runs properly on reboot as I see the logged output. However, my script's os.system command is not running. It runs fine if ran outside of crontab. My scripts are all executable.
crontab -l output:
SHELL=/bin/bash
#reboot nohup /usr/bin/python3 -u /home/path/scheduler.py >> /path/log.out &
scheduler.py code:
#...(check if web server is running...if not restart)
os.system('nohup /usr/bin/python3 -u /path/webserver/main.py &')
print('this function ran')
When I logged the output of the os.system command , there was no output.
As a side note, I am running python schedule commands to check the general health of a webserver. crontab doesn't seem to be the right tool for this so I just use crontab to start my python scheduler on reboot.
I am using flask as the webserver, and would use gunicorn and systemctrl if I could get it to work... but it didn't so this is my workaround.
The point is that, the command called by os.system is not in default path.
For example, tcpdump is not in /usr/bin/.
So, you can solve the problem by adding the full path of the command.
I was facing the same issue when we try to run python script directly in crontab it just by passes the os.system() commands.
Make launcher.sh:
#!bin/bash
cd /home/pi/
sudo python example.py
Then, make your script executable:
chmod 755 launcher.sh
And at last, add your script to crontab:
crontab -e
and add this line at the end:
#reboot sh /home/pi/launcher.sh
(I set the program to run at each reboot)
I am creating a cron job to execute a python script
hello.py
a = 'a cron job was executed here'
text_file = open('output_hello.txt', 'w')
text_file.write(a)
text_file.close()
Works fine if I execute via terminal, I am on ubuntu 15.10.
My cron job file is:
* * * * * /usr/bin/python /home/rohit/hello.py
(excluding the #)
I am a root user and creating the job in /var/spool/cron
The issue is that it is not executing the script. I don't know why.
One does not simply modify the crontab, you run the command:
crontab -e
and edit from there. Execute the above command using sudo if you want it to run as root.
Assuming your paths are correct, your script may not have the right environment or it may not be executable. Ensure your script starts with:
#!/usr/bin/python
And also that you then give execute permission to that script:
chmod a+x hello.py
Ensure you use crontab -e and if you have any doubts about your syntax, you can find more info here:
https://help.ubuntu.com/community/CronHowto