Python Tkinter and Subprocess Running multiple command lines from a file - python

I am trying to write a script that opens a text file that contains specific lines which can be entered into the command window. Instead of having the user copy and paste these lines, I am trying to use subprocess to automatically make the commands run.
Currently my code is this:
import sys
from Tkinter import *
import tkFileDialog
import subprocess
master = Tk()
master.withdraw()
file_path = tkFileDialog.askopenfilename(title="Open command file")
print file_path
with open (file_path,"r") as infile:
cmd1 = infile.readline()
cmd2 = infile.readline()
cmd3 = infile.readline()
cmd4 = infile.readline()
p=subprocess.Popen("{}; {}; {}; {}".format(cmd1, cmd2, cmd3, cmd4), stdout=subprocess.PIPE)
for line in p.stdout:
print line
p.wait()
print p.returncode
print 'complete'
The text file that the user selects has four commands which are all similar to the following:
program.exe commanduniquetoprogram "C:\\...." "C:\\...."
I don't know how the command line works, but if run in a command window, it does as it should without even opening the program. As it is now, when I run my program the only thing that seems to work is the first part program.exe as it opens up the program then throws a strange error. Instead, if the line is pasted into the command window, the program does not open up at all and does its job, which leads me to believe that subprocess doesn't like the spaces in the command line.
Any help is appreciated as I have no experience with the subprocess module!

Related

Run command in CMD via python and extract the data

I am trying to use the below code to run a command and extract the data from the cmd.
the file with the commands and data is a txt file. (let me know if I should change it or use an excel if better).
the commands look something like this: ping "host name" which would result in some data in the cmd.there is list of these in the file. so it would ping "hostname1" then line two ping "hostname2"..etc
THE QUESTION: I want it to run every line individually and extract the results from the cmd and store them in a txt file or excel file - Ideally I want all the results in the same file. is this possible? and how?
here is the code so far:
root_dir = pathlib.Path(r"path to file here")
cmds_file = root_dir.joinpath('actual file here with commands and data')
#fail = []
cmds = cmds_file.read_text().splitlines()
try:
for cmd in cmds:
args = cmd.split()
print(f"\nRunning: {args[0]}")
output = subprocess.check_output(args)
print(output.decode("utf-8"))
out_file = root_dir.joinpath(f"Name of file where I want results printed in")
out_file.write_text(output.decode("utf-8"))
except:
pass
You can use a module called subprocess import subprocess
Then you can define a variable like this
run = subprocess.run(command_to_execute, capture_output=True)
After that you can do print(run.stdout) to print the command output.
If you want to write it to a file you can do this after you run the above code
with open("PATH TO YOUR FILE", "w") as file:
file.write(run.stdout)
This should write a file which contains the output of your command
After that close the file using file.close() and reopen it but in "a" mode
with open("PATH TO YOUR FILE", "a") as file:
file.write(\n + run.stdout)
This should append data to your file.
Remember to close the file just for best practice, I have some bad memorys about not closing the file after I opened it :D
My plan is simple:
Open input, output file
Read input file line by line
Execute the command and direct the output to the output file
#!/usr/bin/env python3
import pathlib
import shlex
import subprocess
cmds_file = pathlib.Path(__file__).with_name("cmds.txt")
output_file = pathlib.Path(__file__).with_name("out.txt")
with open(cmds_file, encoding="utf-8") as commands, open(output_file, "w", encoding="utf-8") as output:
for command in commands:
command = shlex.split(command)
output.write(f"\n# {shlex.join(command)}\n")
output.flush()
subprocess.run(command, stdout=output, stderr=subprocess.STDOUT, encoding="utf-8")
Notes
Use shlex.split() to simulate the bash shell's command split
The line output.write(...) is optional. You can remove it
With subprocess.run(...), the stdout=output will redirect the command's output to the file. You don't have to do anything.
Update
I updated the subprocess.run line to redirect stderr to stdout, so error will show.

How do you use a python variable in popen()?

Im trying to record docker stats for every file in the mydata directory. For example if one of the files is names piano.txt I would like the output file to be piano_stuff.txt. This is what I have so far:
import subprocess
import signal
import os
for file_name in os.listdir('mydata'):
data_txt = "./" + file_name.split(".")[0] + "_stuff.txt"
dockerStats = subprocess.Popen("docker stats --format {{.MemUsage}} >> ${data_txt}", shell=True)
os.killpg(os.getpgid(dockerStats.pid), signal.SIGTERM)
Don't use shell=True. Open the file locally, and pass the file object as the stdout argument. You can also use the --no-stream option to have the command exit after producing one line of output, rather than asynchronously trying to kill the process as soon as possible. (You might get multiple lines of output, or you might get none, depending on when the OS schedules the Docker process to run.)
with open(data_txt, "a") as f:
subprocess.run(["docker", "stats", "--format", "{{.MemUsage}}", "--no-stream"], stdout=f)

How do I run another file in python?

So I know how to write in a file or read a file but how do I RUN another file?
for example in a file I have this:
a = 1
print(a)
How do I run this using another file?
file_path = "<path_to_your_python_file>"
using subprocess standard lib
import subprocess
subprocess.call(["python3", file_path])
or using os standard lib
import os
os.system(f"python3 {file_path}")
or extract python code from the file and run it inside your script:
with open(file_path, "r+", encoding="utf-8") as another_file:
python_code = another_file.read()
# running the code inside the file
exec(python_code)
exec is a function that runs python strings exactly how python interpreter runs python files.
IN ADDITION
if you want to see the output of the python file:
import subprocess
p = subprocess.Popen(
["python3", file_path],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
err, output = p.communicate()
print(err)
print(output)
EXTRA
for people who are using python2:
execfile(file_path)
exec_file documentation

Autorun python script save output to txt file raspberry pi

I have a issue with my raspberry pi that starts up a python script.How do I save the printed output to a file when it is running on boot? I found script below on the internet but it doesn't seem to write the printed text,it creates the file but the content is empty.
sudo python /home/pi/python.py > /home/pi/output.log
It does write its output to the file but you cannot see it until the python file has finished executing due to buffer never flushed.
If you change the output to a file within your python script you can periodicity call flush in your code to push the output through to the file as and when you wish, something like this.
import sys
import time
outputFile = "output.txt";
with open(outputFile, "w+") as sys.stdout:
while True:
print("some output")
sys.stdout.flush() # force buffer content out to file
time.sleep(5) # wait 5 seconds
if you want to set the output back to the terminal, you may want to save a reference to the original stdout like this
import time
outputFile = "output.txt";
original_stdout = sys.stdout
with open(outputFile, "w+") as sys.stdout:
print("some output in file")
sys.stdout.flush()
time.sleep(5)
sys.stdout = original_stdout
print("back in terminal")

Redirecting exe generated cmd prompt data to text file

I have prepared an exe file using IEXPRESS on Windows 7 to run a Python script in cmd which copies some data to a product through ftp.
When the exe file is run, the command prompt opens and displays text describing the process. This works fine. But now I want to redirect all the cmd data to a text file.
Example: I run a file "se.exe". It opens cmd and displays "This is stackoverflow.com.", and closes. I want this text to be redirected to a text file.
Is there any way I can do this without having to modify the Python script?
Any suggestions would be appreciable.
import os
import sys
import string
import time
from ftplib import FTP
import filecmp
#Check for Ethernet connection
try:
ftp = FTP('192.168.2.10','FACTORY','Factory','\0',3)
except:
print 'Communication cannot be established...'
print 'Check Ethernet connection or IP address and retry.'
os.system('pause')
sys.exit()
ftp.close();
time.sleep(3)
sys.exit()
You should run exe file from cmd like this:
se.exe 2 > log.txt
log.txt will contain the output of the program, including handle 2 (that is, STDERR) (link for details).

Categories