Read/write same variable in batch and python scripts - python

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 . . .

Related

python subprocess.call() doesn't work with multiline shell commands

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)

Run arbitrary Python after 'py' command

Suppose I have the following Fowershell function:
function test {
py
print('hello world')
}
when run, it opens Python in Powershell, but it doesn't execute the code following the 'py' command. how can I make it do that WITHOUT creating a file?
Edit: after quitting python, it outputs Unable to initialize device PRN. I think it's executing print() after py closes
You can use Python's -c command line flag:
python -c "print('hello world');print('Second line')"
>> hello world
>> Second line

the bash scripts returns status -13

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"

Open new gnome-terminal and run command

I'm trying to write a script that opens a new terminal then runs a separate python script from that terminal.
I've tried:
os.system("gnome-terminal 'python f.py'")
and
p = Popen("/usr/bin/gnome-terminal", stdin=PIPE)
p.communicate("python f.py")
but both methods only open a new terminal and do not run f.py. How would I go about opening the terminal AND running a separate script?
Edit:
I would like to open a new terminal window because f.py is a simply server that is running serve_forever(). I'd like the original terminal window to stay "free" to run other commands.
Like most terminals, gnome terminal needs options to execute commands:
gnome-terminal [-e, --command=STRING] [-x, --execute]
You probably need to add -x option:
x, --execute
Execute the remainder of the command line inside the terminal.
so:
os.system("gnome-terminal -x python f.py")
That would not run your process in the background unless you add & to your command line BTW.
The communicate attempt would need a newline for your input but should work too, but complex processes like terminals don't "like" being redirected. It seems like using an interactive tool backwards.
And again, that would block until termination. What could work would be to use p.stdin.write("python f.py\n") to give control to the python script. But in that case it's unlikely to work.
So it seems that you don't even need python do to what you want. You just need to run
python f.py &
in a shell.
As of GNOME Terminal 3.24.2 Using VTE version 0.48.4 +GNUTLS -PCRE2
Option “-x” is deprecated and might be removed in a later version of gnome-terminal.
Use “-- ” to terminate the options and put the command line to execute after it.
Thus the preferred syntax appears to be
gnome-terminal -- echo hello
rather than
gnome-terminal -x echo hello
Here is a complete example of how you would call a executable python file with subprocess.call Using argparse to properly parse the input.
the target process will print your given input.
Your python file to be called:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--file", help="Just A test", dest='myfile')
args = parser.parse_args()
print args.myfile
Your calling python file:
from subprocess import call
#call(["python","/users/dev/python/sandboxArgParse.py", "--file", "abcd.txt"])
call(["gnome-terminal", "-e", "python /users/dev/python/sandboxArgParse.py --file abcd.txt"])
Just for information:
You probably don't need python calling another python script to run a terminal window with a process, but could do as follows:
gnome-terminal -e "python /yourfile.py -f yourTestfile.txt"
The following code will open a new terminal and execute the process:
process = subprocess.Popen(
"sudo gnome-terminal -x python f.py",
stdout=subprocess.PIPE,
stderr=None,
shell=True
)
I am running a uWS server with this.In my case Popen didn't help(Even though it run the executable, still it couldn't communicate with a client -: socket connection is broken).This is working.Also now they recommends to use "--" instead of "-e".
subprocess.call(['gnome-terminal', "--", "python3", "server_deployment.py"])
#server_deployment.py
def run():
execution_cmd = "./my_executable arg1 arg2 dll_1 dll_2"
os.system(execution_cmd)
run()

Pass argument from shell script to Python script without having to specify argument on command line

I want to execute a shell script without having to specify any additional arguments on the command line itself. Instead I would like to hard code the arguments, e.g. input file name and file path, in the shell script.
Toy shell script:
#!/bin/bash
time python3 path/to/pyscript/graph.py \
--input-file-path=path/to/file/myfile.tsv
So, when I run $ ./script.sh, the script should pass the input file information to the py script.
Can this be done? I invariably get the error "no such directory or file" ...
Note, I will deal with the arguments on the python script side using argparse.
EDIT
It turns out that the issue was caused by something I had omitted from my toy script above because I didn't think that it could be the cause. In fact I had a line commented out and it was this line which prevented the script from running.
Toy shell script Full Version:
#!/bin/bash
time python3 path/to/pyscript/graph.py \
# this commented out line prevents the script from running
--input-file-path=path/to/file/myfile.tsv
I suspect your script is correct but the file path is wrong. Maybe you forgot a leading forward slash. Anyway, make sure that path/to/pyscript/graph.py and path/to/file/myfile.tsv are correct.
A dummy example of how to call a python script with hard-coded arguments from a BASH script:
$ cat dummy_script.py
import argparse
import os
import time
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--input-file-path")
args = parser.parse_args()
if os.path.isfile(args.input_file_path):
print args.input_file_path, "is a file"
print "sleeping a second"
time.sleep(1)
$ cat time_python_script.sh
time python dummy_script.py --input-file-path=/etc/passwd
$ /bin/bash time_python_script.sh
/etc/passwd is a file
sleeping a second
real 0m1.047s
user 0m0.028s
sys 0m0.016s

Categories

Resources