Scenario: Below are two scripts where a bash script is invoked by python script.
test.py
import subprocess
p=subprocess.call(['bash','test.sh'])
f = open("demofile2.txt", "a")
f.write(p)
f.close()
test.sh
echo "hello world"
observation:
works fine when the test.py is executed directly.
issue:
when I create demon under /service to run the file. The value of 'p' (return of call) is -13.
Note: The user:group for both script is root. I am using centos8
If anyone has same problem, the answer lies in the resolution of the path.
When I to execute the python script in the command line, it was able to locate the script.
But when the demon tool (even systemd) runs the script it was not able to locate the bash script. When I provided absolute path of the bash script(opt\test\test.sh) in the python script,it worked.
\opt\test\test.py
import subprocess
p=subprocess.call(['bash','opt\test\test.sh'])
f = open("demofile2.txt", "a")
f.write(p)
f.close()
\opt\test\test.sh
echo "hello world"
Related
I would like to run this multiline shell commands:
echo 'a=?'
read a
echo "a=$a"
from a python script, using the subprocess.call() method.
I wrote this, in test.py file:
import shlex, subprocess
args = ["echo", 'a=?',"read", "a", "echo", "a=$a"]
subprocess.call(args)
and when I execute it, I have in terminal this report:
Armonicus#MyMacs-iMac MyNewFolder % python test.py
a=? read a echo a=$a
which is not at least close to what I expect.
Can I have some support from anyone, please?
There are a couple of issues with your approach here.
First, if what you're trying to do is prompt the user for input from the command line, then you can use Python builtins instead of a subprocess:
a = input('a=?')
print(a)
If you do want to call a subprocess with multiple commands, you need to either make separate calls for each command, or invoke a shell and execute the commands within it. For example:
subprocess.call("echo 'a=?'; read a; echo $a", shell=True)
Running on Windows system, I run bash.exe using subprocess.call().
Following is the code
def predict():
os.system('notepad cmnd.txt')
subprocess.call(['C:/Windows/System32/bash.exe'])
print(file_contents)
label = Label(master, text=file_contents)
#subprocess.call(['c:/users/hp/open.py'])
label.pack()
The handle passes to bash,thus not executing a couple of commands.
cd commands that runs on actually entering values return Missing Directory error.
ls command returns 'cannot run binary file' error.
What should I do?
I'm not really sure what you want here, but if you want to run bash commands in a Windows enviorment, you can try using subprocess.check_output():
from subprocess import check_output
bash_commands = ['ls', 'pwd']
for command in bash_commands:
output = check_output(['bash', '-c', command]).decode()
print(output)
Which in this example, lists all files in the current directory and prints out the parent working directory.
I have a simple bash script that runs "apt update" I tried to call it via python like this. It runs although I didn't chmod +x update.sh it.
def updateUsingBash(self):
p = QtCore.QProcess()
p.finished.connect(self.onFinished)
p.start('sh', ['update.sh'])
p.waitForFinished(-1)
def onFinished(self, exit_code, exit_status):
print "script finished with exit code :", exit_code
You did not execute update.sh. You executed sh passing it update.sh as an argument. That made sh interpret update.sh as a shell script.
By the way, note that sh is not exactly like bash.
This is exactly the same as how python foo.py runs foo.py without the latter being marked executable -- it's simply a data file containing script text, and the thing being executed is either python or sh, respectively.
I have 2 scripts. One is .bat and other is python. The python script is triggered by the .bat file. While executing, first I will run .bat with command line arguments but then I need to read the argument into the python script.
What am I doing wrong?
I call the batch script like this:
C:>main.bat c:\temp\text1.txt
main.bat :
#ECHO off
set var1=%~1
call python_script.bat
echo "returned to main"
pause
python_script.bat :
python -x %0 %*
print var1 # Notworking
import sys
var1 = sys.argv ############ Also not working
with open(var1, 'r+') as f:
content = f.read()
f.seek(0)
f.trunca........
I don't know much about bat and windows but doesn't windows support calling a python script with a command line argument from a bat file? If so, wouldn't something like this work?
This works in Linux shell:
call_py.sh:
# do stuff with command line argument 1 here ($1) and pass it on to py
echo "I'm a shell script and i received this cmd line arg: " $1
# pass $1 on to python as a cmd line arg here
python some_script.py $1
echo "shell script still running after python script finished"
The other question I linked to showed us how to call python from bat (although I can't verify it). Couldn't you simply add you var1 after the name of the py script like I did in call_py.sh?
# syntax might be wrong
start C:\python27\python.exe D:\py\some_script.py var1
some_script.py then receives $1/var1 as sys.argv[1]
some_script.py:
import sys
print "I'm a python script called " + sys.argv[0]
print "I received this cmd line arg from shell: " + sys.argv[1]
Output:
$ sh call_py.sh "VARIABLE_GIVEN_TO_SHELL_AND_PASSED_TO_PY"
I'm a shell script and i received this cmd line arg: VARIABLE_GIVEN_TO_SHELL_AND_PASSED_TO_PY
I'm a python script called some_script.py
I received this cmd line arg from shell VARIABLE_GIVEN_TO_SHELL_AND_PASSED_TO_PY
shell script still running after python script finished
Does this work or is Windows weirder than I thought? :)
UPDATE:
I fired up the old malware magnet and tried passing arguments from command line -> batch script -> python. I didn't use your python -x %0 %* syntax that seems to allow running python code in a batch script but simply wrote a separate .py file and called that from the .bat file.
This worked on Windows 7:
call_py.bat:
#ECHO off
set var1=%~1
echo Bat script called with cmdline arg: "%var1%"
echo Passing cmdline arg to python script
call C:\Python27\python.exe C:\Users\bob\Desktop\print_arg1.py %var1%
echo Bat again - continuing...
pause
print_arg1.py:
import sys
try:
print "Python says hi and received this cmdline arg: " + sys.argv[1]
except IndexError:
print "Python says hi but didn't receive any cmdline args :("
Output:
C:\Users\bob\Desktop>call_py.bat I_AM_A_CMDLINE_ARG
Bat script called with cmdline arg: "I_AM_A_CMDLINE_ARG"
Passing cmdline arg to python script
Python says hi and received this cmdline arg: I_AM_A_CMDLINE_ARG
Bat again - continuing...
Press any key to continue . . .
I want to run IDLE3.2 with the argument "-s" so it can read ".pythonstartup" and export relevant modules, change the working directory and etc. Here is what I have tried:
Created a shell script:
/usr/local/bin/idle3.2 -s
this works allright, however running the script from the Finder opens up the Terminal, which is not the desired behavior.
Created an applescript:
do shell script "/bin/bash; cd /usr/local/bin/; ./idle3.2 -s"
this get rids of the terminal however fails to pass "-s" argument to idle3.2 so the configuration file is not loaded.
any suggestions?
EDIT: turns out environment variables are not properly set even though /bin/bash is called. so the following solves the problem:
do shell script "/bin/bash; source ~/.profile; /usr/local/bin/idle3.2 -s"
I think your do shell script "/bin/bash; cd /usr/local/bin; ./idle3.2 -s" is doing extra work, and can probably be done more simply. Try:
do shell script "/usr/local/bin/idle3.2 -s"
thanks to #lain the following applescript solves the problem:
do shell script "source ~/.profile; idle3.2 -s"
where ~/.profile points the shell (in this case /bin/sh) the path for .PYTHONSTARTUP and the path for idle3.2