Shell script called using Python subprocess call() takes no effect - python

I am having problems executing a shell script using subprocess.call() and I made this test in Python console to try to figure out which is the problem:
import subprocess
subprocess.call(["touch", "/tmp/out.txt"])
This works and creates the file in tmp folder. However, none of these two calls work:
subprocess.call(["sh", "/tmp/test.sh"])
subprocess.call(["/tmp/test.sh"])
/tmp/test.sh:
#!/bin/bash
touch out.txt
exit 0
Basically, executing an script from subprocess.call() is not producing any output. I gave full permissions to files and folders to avoid any problem. It seems the problem may be related to the user executing the script, but it is the same user as in the first case, which is working.
Any idea what the problem could be?
BTW, I am using Ubuntu 12.04 LTS, Python 2.7.4.
Thanks in advance.

Your script is executed correctly. The problem is with your bash script.
You have to understand that this script inherits working directory of the parent script. Therefore out.txt will be created in the directory where you run the python script which makes use of subprocess.call.

Related

Run terminal script in python?

I am using python and I am trying to run a shell script that is located in another folder I am trying
subprocess.call(['source','../Apps/appName/run'])
Where 'run' is a shell script I wrote and made an executable. But it keeps giving errors such as
No such file or directory or **No such file or directory: "source"
I have also tried the following
subprocess.call(['source','../Apps/appName/run'])
subprocess.call(['source ../Apps/appName/run'])
subprocess.call(['.','../Apps/appName/run'])
I am trying to run the script and leave it alone (as in I do not want any return value or to see what the output of the shell script is.
Thank you in advance
source is a shell builtin that reads a file and interprets the commands in the current shell instance. It's similar to C #include or Python import. You should not be using it to run shell scripts.
The correct way to run a script is to add a shebang like #!/bin/bash to the first line, and chmod +x yourscriptfile. The OS will then consider it a real executable, which can be executed robustly from any context. In Python, you would do:
subprocess.call(['../Apps/appName/run'])
If for whichever reason this is not an option, you can instead explicitly invoke bash on the file, since this is similar to what would happen if you're in bash and type source:
subprocess.call(['bash', '../Apps/appName/run'])

Unable to call bash script using os.system() on Windows

I have a very simple bash script test.sh as shown below
#!/usr/bin/env bash
mkdir "/c/AAA"
I want to execute this code in python. When I call os.system(r"Y:\test.sh") in python, a window pops up and asks me which program I want to open the test.sh with. Then python will end with output 0 and no folder is created in my C drive. I can't find any solution online. Any help will be appreciated. :)
os.system() will invoke your command the same as windows cmd would, in this case, the windows doesn't know how to execute *.sh files, so it opens it's default dialog so you can pick one program that you know can ran it.
The same will happen if you open windows terminal and try to invoke such file.
If your windows have a bash interpreter try invoking it like this:
os.system("bash Y:\test.sh")
Instead of running this with a native-Windows Python interpreter, run it with a Cygwin copy of Python, which has an os.system() that will be invoked with the Cygwin /bin/sh.

How to retrieve a filename and file created using a shell script that was called from a python script?

I have a python script that calls a shell script. The shell script captures an image, names the image using a timestamp, and then saves the image to directory. When the shell script finishes, I would like to access the image from the python script that called the shell script.
Here is my shell script capture.sh:
DATE=$(date +"%Y-%m-%d_%H%M%S")
fswebcam -r 1280x720 --no-banner /home/pi/app/images/$DATE.jpg
exit 0
This shell script is called from capture.py:
import os
import subprocess
# call script
subprocess.call(['/home/pi/app/capture.sh'])
#?how to retrieve and process image: /home/pi/app/images/$DATE.jpg
Any advice would be welcome! Thank you!
You can send the name of the file created by the bash script to standardout and capture that in the python script. Here is a similar SO question that I think will lead you in the right direction.
As the top answer to this question points out, it will depend on what version of python you're doing this work in. It looks like you're using subprocess.call. In terms of the current python docs for subprocess, that is the old API call. You can now use subprocess.run in versions 3.5 and newer, which is the recommended way to invoke child processes.
Running shell command and capturing the output

python executing in IDLE, but not in termnal

I have a python script on a Raspberry Pi reading the temperature and humidity from a sensor. It works fine when started in IDLE, but when I try starting it in a terminal I get the message:sudo: unable to execute .thermostaatgui.py: No such file or directory. The first line in the script is: #! /usr/bin/python, the same as in other scripts that run without problems and the script is made executable with chmod +x.
In the script Adafruit_DHT, datetime and time are imported, other scripts that work do the same.
+1 on the above solution.
To Debug
try this
Type "pwd" on your terminal. This will tell you where you are in the shell.
Then type "ls -lah" and look for your script. if you can not find it, then you need to "cd" to the directory where the script exists and then execute the script
Looks like you might have just made a typo:
sudo .thermostaatgui.py
should probably be
sudo ./thermostaatgui.py
assuming that you're in the directory containing your script, and that it's called thermostaatgui.py.
Well, still a little puzzled why it happened, but anyway this solved the problem:
As a workaround, I copied the contents of "thermostaatgui.py" over the contents of a working script ("mysimpletest.py"), saved it and it runs OK.

Writing a line to CMD in python

I am very new to Python and I have been trying to find a way to write in cmd with python.
I tried os.system and subprocess too. But I am not sure how to use subprocess.
While using os.system(), I got an error saying that the file specified cannot be found.
This is what I am trying to write in cmd os.system('cd '+path+'tesseract '+'a.png out')
I have tried searching Google but still I don't understand how to use subprocess.
EDIT:
It's not a problem with python anymore, I have figured out. Here is my code now.
os.system("cd C:\\Users\\User\\Desktop\\Folder\\data\\")
os.system("tesseract a.png out")
Now it says the file cannot be open. But if I open the cmd separately and write the above code, it successfully creates a file in the folder\data.
Each call to os.system is a separate instance of the shell. The cd you issued only had effect in the first instance of the shell. The second call to os.system was a new shell instance that started in the Python program's current working directory, which was not affected by the first cd invocation.
Some ways to do what you want:
1 -- put all the relevant commands in a single bash file and execute that via os.system
2 -- skip the cd call; just invoke your tesseract command using a full path to the file
3 -- change the directory for the Python program as a whole using os.chdir but this is probably not the right way -- your Python program as a whole (especially if running in a web app framework like Django or web2py) may have strong feelings about the current working directory.
The main takeaway is, os.system calls don't change the execution environment of the current Python program. It's equivalent to what would happen if you created a sub-shell at the command line, issued one command then exited. Some commands (like creating files or directories) have permanent effect. Others (like changing directories or setting environment variables) don't.

Categories