Return full error message from subprocess - python

I would like to get a full, descriptive error message from failed Python script executed with subprocess module.
I have a following script sub_script.py which fails and produces IndexError: pop from empty list error when executed on it's own:
# sub_script.py
empty_list = []
empty_list.pop()
I am calling sub_script.py from sub_test.py as follows:
# sub_test.py
import subprocess
import sys
print(str(subprocess.run([sys.executable, 'sub_script.py'],
check=True,
capture_output=True)))
However I am only getting subprocess.CalledProcessError error.
Traceback (most recent call last):
File "/Users/my_user/Desktop/my_dir/sub_test.py", line 4, in <module>
print(str(subprocess.run([sys.executable, 'sub_script.py'],
File "/usr/local/Cellar/python#3.9/3.9.5/Frameworks/Python.framework/Versions/3.9/lib/python3.9/subprocess.py", line 528, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['/usr/local/opt/python#3.9/bin/python3.9', 'sub_script.py']' returned non-zero exit status 1.
I would like to see a full description of the error returned from sub_script.py (IndexError: pop from empty list) when it's executed with a subprocess in sub_test.py.
Is it possible to get full error when script executes and fails within subprocess.run?

Keep the return value of the subprocess.run call instead of immediately converting it to a str, and do not have check=True.
# main.py
import subprocess
import sys
command = [sys.executable, 'task.py']
outcome = subprocess.run(command, check=False, capture_output=True)
print(f"returncode = {outcome.returncode}")
if outcome.returncode != 0:
# there was an error, we assume the traceback was printed to stderr
print("there was an error :\n")
print(outcome.stderr.decode("utf-8"))
# task.py
empty_list = []
empty_list.pop()
output :
returncode = 1
there was an error :
Traceback (most recent call last):
File "task.py", line 2, in <module>
empty_list.pop()
IndexError: pop from empty list

Related

how to create logic to run python code in self made code editor properly like python shell

I have create run function to run python script but when i use input() code it shows error
error is
Enter any numberTraceback (most recent call last):
File "C:\Users\USER\Downloads\N1.py", line 1, in <module>
a = int(input("Enter any number"))
EOFError: EOF when reading a line
command = f"python {self.file}"
run_file = subprocess.Popen(command, stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
Output, error = run_file.communicate()
self.text.output_area.insert(END,f"{self.file}>>\n")
self.text.output_area.insert(END,Output)
self.text.output_area.insert(END,error)
what modification I have to do in my run function ?????

ResourceWarning: subprocess 47013 is still running Exception ignored in: <_io.FileIO name=5 mode='rb' closefd=True>

I got trouble to face the error, could you help me?.
Please take a look at my code!
code in file tools.py
from action import Action
import typer
from rich.table import Table
from rich.console import Console
from model import Command
from shell import Shell
import os
db=Action("localhost","root","","db_cmd")
sh=Shell()
console=Console()
app=typer.Typer()
#app.command(short_help="Untuk melihat data")
def show():
lists=db.show_data()
# print(lists)
console.print("[bold magenta]command alias[/bold magenta]!","💻️")
# print(lists)
table=Table(show_header=True, header_style="bold blue")
table.add_column("No", style="dim", width=6, justify="center")
table.add_column("command", min_width=20, justify="center")
table.add_column("isi command", min_width=12, justify="center")
table.add_column("deskripsi", min_width=12, justify="center")
if len(lists) > 0 :
for i, list in enumerate(lists, start=1):
table.add_row(str(i), list.cmd, list.isi_cmd, list.deskripsi)
else:
table.add_row("-","-","-","-")
console.print(table)
#app.command(short_help="Untuk menambahkan data")
def add(cmd:str=None, isi_cmd:str=None, deskripsi:str=None):
typer.echo(f"Menambahkan command {cmd}")
shell=sh.shellName()
#app.command(short_help="Untuk menghapus data")
def delete(position):
cmd=db.cmd(int(position)-1)
typer.echo(f"deleting command {cmd}")
db.delete_data(int(position)-1)
show()
if __name__=="__main__":
app()
code in file shell.py
import os
import subprocess
import signal
class Shell:
def add(self, cmd, isi_cmd, shell):
if shell == "zsh":
os.system(f"printf 'alias {cmd}=\"{isi_cmd}\"\n' >> /home/$USER/.zshrc")
elif shell == "bash":
os.system(f"printf 'alias {cmd}=\"{isi_cmd}\"\n' >> /home/$USER/.bashrc")
elif shell == "fish":
os.system(f"printf 'alias {cmd}=\"{isi_cmd}\"\n' >> /home/$USER/.fzf.bash")
def delete(self):
pass
def shellName(self):
result=subprocess.Popen("echo $SHELL", shell=True, stdout=subprocess.PIPE)
arr=str(result.stdout.read()).split("/")
shell=arr[3].replace("\\n'","")
return shell
shell=Shell()
print(shell.shellName())
When I run the file named shell.py and called the method sh.shellName(), the program was running well
$python3 shell.py
zsh
But when I run the file named tools.py, and sh.shellName() method, it show me error like this
$python3 tools.py add --cmd="ls" --isi-cmd="ls -lah" --deskripsi="Untuk melihat isi file beserta ukurannya"
Exception ignored in: <function Popen.__del__ at 0x7fa7c6d36550>
Traceback (most recent call last):
File "/usr/lib/python3.8/subprocess.py", line 946, in __del__
_warn("subprocess %s is still running" % self.pid,
ResourceWarning: subprocess 48516 is still running
Exception ignored in: <_io.FileIO name=4 mode='rb' closefd=True>
Traceback (most recent call last):
File "/home/fajar/Documents/python/tools_alias_cmd/shell.py", line 24, in <module>
print(shell.shellName())
ResourceWarning: unclosed file <_io.BufferedReader name=4>
zsh
Menambahkan command ls
Exception ignored in: <function Popen.__del__ at 0x7fa7c6d36550>
Traceback (most recent call last):
File "/usr/lib/python3.8/subprocess.py", line 946, in __del__
_warn("subprocess %s is still running" % self.pid,
ResourceWarning: subprocess 48517 is still running
Exception ignored in: <_io.FileIO name=5 mode='rb' closefd=True>
Traceback (most recent call last):
File "tools.py", line 38, in add
shell=sh.shellName()
ResourceWarning: unclosed file <_io.BufferedReader name=5>
I'v been searching all the solutions on google, youtube, and forum, but I got nothing, it doesn't work for my problems. Thanks

How to use Python subprocess.run when the command contains a hyphen?

I'm trying to run the following command using subprocess.run, but I think the hyphen in the command ir-keytable, is confusing the parser. What's the best way to solve this?
ir-keytable -t -s rc0
The error:
stdout:
stderr: Traceback (most recent call last):
File "<string>", line 1, in <module>
NameError: name 'ir' is not defined
My code:
import subprocess
import sys
result = subprocess.run(
[sys.executable, "-c", "ir-keytable('-t -s rc0')"], capture_output=True, text=True
)
print("stdout:", result.stdout)
print("stderr:", result.stderr)
Your Syntax is giving error for any command, you should just try this :
import subprocess
# If you just want to run command then this :
result=subprocess.run("<>")
# But if you want to get result of your command the this:
result=subprocess.check_output("<>")
print(result.decode("utf-8")) # It returns byte type data, so we are converting that into utf-8

How to run a blob data transfer through .py

I have tried to create a program to run in my VM to make it so I can do a transfer of data from a directory to my azure blob storage account. Whenever I run the command outside of the program (On the command line) it works, however, if I run the program that contains a subprocess that runs the command, it does not work.
Here is what I send over the command line that works:
sudo ./azcopy cp "/directory/subdirectory" "https://myblob.blob.core.windows.net/container[SAS]" --recursive=true
This completes the data transfer.
When I put it into a program, I ran into many issues.
Current code:
import subprocess
import os
import sys
try:
key = ('SAS')
file_path = ('/directory/subdirectory')
full_link = ('"https://myblob.blob.core.windows.net/' + key + '"')
transfer = subprocess.check_output(['azcopy', 'cp', file_path,
full_link,
'--recursive=true'], stderr=subprocess.STDOUT)
print('Transfer Complete.')
# except subprocess.CalledProcessError as e:
# raise RuntimeError("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
except EOFError as error:
#Output for EOF error, would be caused by missing SAS
print('Error with SAS')
except Exception as e:
#When an unexpected error has occured.
print(str(e) + 'Unknown error has occured')
exit(0)
Output:
Command '['azcopy', 'cp', '/directory/subdirectory', '"https://myblob.blob.core.windows.net/[SAS]"', '--recursive=true']'
returned non-zero exit status 1Unknown error has occured
If I re-add the except statement I have in the code that is currently commented out, I get this error:
Traceback (most recent call last):
File "data_transfer.py", line 11, in <module>
'--recursive=true'], stderr=subprocess.STDOUT)
File "/usr/lib/python3.5/subprocess.py", line 626, in check_output
**kwargs).stdout
File "/usr/lib/python3.5/subprocess.py", line 708, in run
output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '['azcopy', 'cp', 'datadrive/peeled-images', '"https://myblob.blob.core.windows.net[SAS]"', '--recursive=true']' returned non-zero exit status 1
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "data_transfer.py", line 14, in <module>
raise RuntimeError("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
RuntimeError: command '['azcopy', 'cp', '/directory/subdirectory', '"https://myblob.blob.core.windows.net/[SAS]"', '--recursive=true']' return with error (code 1): b'\nfailed to parse user input due to error: the inferred source/destination combination is currently not supported. Please post an issue on Github if support for this scenario is desired\n'
All help is much appreciated
The answer to this was to change the following line:
subprocess.check_output(['azcopy', 'cp', '/directory/subdirectory',
full_link, '--recursive=true'], stderr=subprocess.STDOUT)
The change needed was:
subprocess.call(['azcopy', 'cp', '/directory/subdirectory',
full_link, '--recursive=true'], stderr=subprocess.STDOUT)
This is because this was meant to run and execute a program, not necessarily provide a specific output.

Popen subprocess exception

Sorry if this is a simple question and has been answered before, but I couldn't find it anywhere.
I'm trying to listen to UDP packets and if they are certain packets, run different batch scripts. I have this working correctly, but I have found that if the Popen command doesn't find the file it triggers an exception and the script stops running. Ideally, I want this to print a message and then continue listening for other packets and act upon them, just giving us a message for debugging. Here is the code I have used, how could I do this?
if rxdata == "Camera 1":
from subprocess import Popen
try:
p = Popen("Camera 1.bat", cwd=r"C:\xxx")
stdout, stderr = p.communicate()
except FileNotFoundError():
print('Camera 1.bat not found')
elif rxdata == "Camera 2":
from subprocess import Popen
p = Popen("Camera 2.bat", cwd=r"C:\xxx")
stdout, stderr = p.communicate()
In both examples, I receive the following and the script closes.
Traceback (most recent call last):
File "C:\UDP Listener.py", line 42, in <module>
p = Popen("Camera 1.bat", cwd=r"C:\xxx")
File "C:\Python34\lib\subprocess.py", line 858, in __init__
restore_signals, start_new_session)
File "C:\Python34\lib\subprocess.py", line 1111, in _execute_child
startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified
Thanks in advance
Matt
You must not use the brackets behind the FileNotFoundError (don't call it, just "name" it). Test (with Python 2):
try:
b = a
except NameError():
print "NameError caught."
Execution:
Traceback (most recent call last):
File "test.py", line 2, in <module>
b = a
NameError: name 'a' is not defined
For instance, OSError is a type, whereas OSError() creates an instance of this type:
>>> type(OSError)
<type 'type'>
>>> type(OSError())
<type 'exceptions.OSError'>
Strangely, after re-installing python on my PC everything is now working correctly. Not sure what went wrong but when I run the code now and an exception is found then the code prints as expected.
Thanks for your help!

Categories

Resources