This question already has answers here:
Store output of subprocess.Popen call in a string [duplicate]
(15 answers)
Closed 5 months ago.
I am trying to use Popen to scp a file from my laptop to a device on my network. The process is pretty straight foward...I can get the file to transfer but I cant get the output from the command to display. I am specificlly looking for the percentage complete. Here is what I have:
from subprocess import Popen, STDOUT, PIPE
scp_command = 'scp -i c:<local_key> <filepath to local file> <user>#<destination_device>:\path'
local_scp_command = Popen(scp_command, text=True, stout=PIPE)
output = local_scp_transfer.communicate
print(output)
I have tried a number of different combinations of stdout and printing the output. I cant even remember all the ways I have tried this. I imagine that there is something kind of easy that I am missing. I am pretty new at programming so even the easy things are compliacted for me.
Thank you so much for all your help!
Use poll() to determine whether or not the process has finished and read a line:
from subprocess import Popen, STDOUT, PIPE
import shlex
scp_command = 'scp -i c:<local_key> <filepath to local file> <user>#<destination_device>:\path'
local_scp_command = Popen(shlex.split(scp_command), text=True, stdout=PIPE)
while local_scp_command.poll() is None and line := local_scp_command.stdout.readline():
print(line)
I added a shlex.split because that's the proper format for Popen.
Related
This question already has answers here:
TypeError: can't use a string pattern on a bytes-like object in re.findall()
(3 answers)
Closed 1 year ago.
I have a problem, I need the output of the command in python and exactly get the download speed from the wget command. My code is :
#!/usr/bin/python3
import os
import re
import subprocess
command = "wget ftp://ftp:password#172.17.1.129:1111/test.bin -p -nv "
process = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True)
ftp_result = re.findall(('\d+.\d+'),process)
print (ftp_result)
TypeError: cannot use a string pattern on a bytes-like object
What I'm doing wrong?
On Python 3, subprocess returns bytes unless you explicitly request decoding.
Also, you generally want to avoid shell=True if you are not actually using the shell for anything.
#!/usr/bin/python3
# import os # not used
import re
import subprocess
process = subprocess.check_output(
["wget", "ftp://ftp:password#172.17.1.129:1111/test.bin", "-p", "-nv"],
text=True) # this is the beef
ftp_result = re.findall(('\d+.\d+'),process)
print (ftp_result)
Notice also how check_output already defaults to capturing the output, so you don't need to explicitly direct stdout to a subprocess.PIPE, either.
Perhaps a more robust solution would be to switch to curl, which allows you to separately retrieve just the download speed using a format specifier.
This question already has answers here:
Get java version number from python
(6 answers)
Closed 5 years ago.
I'm new in this, I want to write the output of java version in a file text.
I used this from another post I saw:
import subprocess
with open('C:\Python27\ping.txt','w') as out:
out.write(subprocess.check_output("ping www.google.com"))
And that worked, wrote the output of "ping www.google.com" to a text file.
I thought that if I just change the "ping www.google.com" to "java -version" everything would be solved.
Like this:
import subprocess
with open('C:\Python27\java.txt','w') as out:
out.write(subprocess.check_output("java -version"))
But this did not work me, this just print the output of "java -version" to console, and didn't write it in the text file.
Can anyone help me?
You could try to use stderr:
from subprocess import Popen, PIPE, STDOUT
with open('C:\Python27\java.txt','w') as out:
cmd = 'java -version'
p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
out.write(p.stderr.read())
This question already has answers here:
Pipe subprocess standard output to a variable [duplicate]
(3 answers)
Closed 6 years ago.
Good evening/morning,
I have been passing a lot of commands to the terminal in a python program and was wondering if there was a way of passing a command and immediately saving the printed information without having to first save it to a file and then read that file in?
For example, this is what I have been doing:
os.system("lspci -tv > results")
if Addresses[i-1] in open('results').read():
Is there a way to just store the results from lspci -tv to a variable in my program so my program isn't dependent on another file and cluttering my computer with files every time I need to use this method?
Thanks in advance.
Yes you can, according with this question:
import subprocess
proc = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE)
output = proc.stdout.read()
print output
Or if you want an array with the results:
import subprocess
proc = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE)
output = proc.stdout.read()
array = output.split("\n")[:-1]
for i in range(len(array)):
print str(i) + " : " + array[i]
Docs here.
I'm trying to get the output of a command's STDOUT with the HandBrakeCLI program when encoding a video. I can't seem to get python to handle its output on the standard output stream. I've tried the following codes:
import subprocess
import sys
encode = subprocess.check_output("HandBrakeCLI -i video.mkv -o out.mp4", shell=True, stderr=subprocess.STDOUT, universal_newlines=True)
print(encode)
This printed nothing as well as this which I also tried:
import subprocess
import sys
encode = subprocess.Popen("HandBrakeCLI -i video.mkv -o out.mp4", stdout=subprocess.PIPE, stderr = subprocess.PIPE, shell=True, universal_newlines=True)
print(encode.stdout.read())
As stated before, both will result in no output. This application is the type that will update text on a single line in bash as it's encoding. I'm not sure if that type of data stream creates a problem with python or not.
It seems HandBrakeCLI changes its output depending on whether it prints to a terminal. Either specify a command-line flag to force the necessary output or you could trick it by providing a pseudo-tty (if your system supports it) using pexpect or pty module directly.
Code examples on how to get output from a subprocess using pexpect, pty modules:
Last unbuffered line can't be read
Python subprocess readlines() hangs
This question already has answers here:
How to just call a command and not get its output [duplicate]
(4 answers)
Closed 5 years ago.
For the following command:
subprocess.call(shlex.split(
"""/usr/local/itms/bin/iTMSTransporter -m lookupMetadata
-apple_id %s -destination %s"""%(self.apple_id, self.destination))
It prints the entire output into the Terminal window. How would I suppress ALL output here? I tried doing subprocess.call(shlex.split(<command> > /dev/null 2&1)), but it didn't produce the required results. How would I do this here?
You can use the stdout= and stderr= parameters to subprocess.call() to direct stdout or stderr to a file descriptor of your choice. So maybe something like this:
import os
devnull = open(os.devnull, 'w')
subprocess.call(shlex.split(
'/usr/local/itms/bin/iTMSTransporter -m lookupMetadata '
'-apple_id %s -destination %s' % (self,apple_id, self.destination)),
stdout=devnull, stderr=devnull)
Using subprocess.PIPE, if you're not reading from the pipe, could cause your program to block if it generates a lot of output.
Update
As #yanlend mentions in a comment, newer (3.x) versions of Python include subprocess.DEVNULL to solve this problem in a more convenient and portable fashion. In that case, the code would look like:
subprocess.call(shlex.split(
'/usr/local/itms/bin/iTMSTransporter -m lookupMetadata '
'-apple_id %s -destination %s' % (self,apple_id, self.destination)),
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
What worked for me is appending 2>/dev/null at the end of the command.