Cannot perform subprocess.run inside a snap - python

In my snap (coded in python), I try to perform some sudo commands but it didn’t work. Here is an example of a command that didn’t work:
command = "sudo netmgr -i country_code set:" + countryCode
subprocess.run([command])
And when I run the snap in my device it won’t work and I got this error:
> Traceback (most recent call last): File
> “/snap/iotr-configuration/x17/bin/iotr-configuration”, line 11, in
> load_entry_point(‘iotr-configure==0.0.3’, ‘console_scripts’,
> ‘iotr-configuration’)() File
> “/snap/iotr-configuration/x17/lib/python3.5/site-packages/src/app.py”,
> line 53, in main configuration_program() File
> “/snap/iotr-configuration/x17/lib/python3.5/site-packages/src/app.py”,
> line 37, in configuration_program
> confNIC.set_nic_settings(“fd05:a40b:b47d:7340::4”, “1250”) File
> “/snap/iotr-configuration/x17/lib/python3.5/site-packages/src/configureNic.py”,
> line 16, in set_nic_settings subprocess.run([command]) File
> “/snap/iotr-configuration/x17/usr/lib/python3.5/subprocess.py”, line
> 693, in run with Popen(*popenargs, **kwargs) as process: File
> “/snap/iotr-configuration/x17/usr/lib/python3.5/subprocess.py”, line
> 947, in init restore_signals, start_new_session) File
> “/snap/iotr-configuration/x17/usr/lib/python3.5/subprocess.py”, line
> 1551, in _execute_child raise child_exception_type(errno_num, err_msg)
> FileNotFoundError: [Errno 2] No such file or directory: ‘sudo netmgr
> -i country_code set:1250’
This function exist because when I type it directly in the terminal, it works…
Can you help me on this issue ?

You're calling subprocess.run in the wrong way. You should either pass it a the command as a single string (like you're doing here) but then set shell=True, or break the command into several arguments, as in:
command = ["sudo", "netmgr", "-i", "country_code", "set:" + countryside]
subprocess.run(command)
See the FAQ part of the documentation:
args is required for all calls and should be a string, or a sequence of program arguments. Providing a sequence of arguments is generally preferred, as it allows the module to take care of any required escaping and quoting of arguments (e.g. to permit spaces in file names). If passing a single string, either shell must be True (see below) or else the string must simply name the program to be executed without specifying any arguments.

Related

Python can't access file on Windows

I'm trying to run my code in Python through Windows 10 cmd like this:
python3 flir_image_extractor.py -avg -i 'C:\\Users\\Daniel\\Desktop\\example.jpg'
The first thing it does is checking if the input path it's a file:
if not os.path.isfile(flir_img_filename):
raise ValueError("Input file does not exist or this user don't have permission on this file")
And that error is exactly what I'm getting when running the cmd command. My file exists and is located at the given path ("this pc" and "desktop", respectivelly), and explorer's set to show file extension:
I tried many other ways to input the path, as:
'C:\Users\Daniel\Desktop\example.jpg'
'C:/Users/Daniel/Desktop/example.jpg'
r'C:\Users\Daniel\Desktop\example.jpg'
Nothing worked so far.
This code works perfectly on Ubuntu, but I need to make sure it works on Windows in order to use PyInstaller for this OS. I'm using Python 3.9.5
You can check the complete code I'm using at https://github.com/Nervengift/read_thermal.py?fbclid=IwAR3FDfsIgSF5k-EKWSrAbnWO1oM-vWiBgDPrL3iOSSfUSexhlP1_BeVTUz4
. I added only the -avg option to match the use I want, but mimicking the other ones.
I thank you in advance.
EDIT:
I "coppyed as path" the file as sugested, and now there's the output:
C:\Users\Daniel\Desktop\venv_holder>python3 flir_image_extractor.py -avg -i "C:\Users\Daniel\Desktop\example.jpg"
Traceback (most recent call last):
File "C:\Users\Daniel\Desktop\venv_holder\flir_image_extractor.py", line 232, in <module>
fie.process_image(args.input)
File "C:\Users\Daniel\Desktop\venv_holder\flir_image_extractor.py", line 53, in process_image
if self.get_image_type().upper().strip() == "TIFF":
File "C:\Users\Daniel\Desktop\venv_holder\flir_image_extractor.py", line 66, in get_image_type
meta_json = subprocess.check_output(
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.1520.0_x64__qbz5n2kfra8p0\lib\subprocess.py", line 424, in check_output
return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.1520.0_x64__qbz5n2kfra8p0\lib\subprocess.py", line 505, in run
with Popen(*popenargs, **kwargs) as process:
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.1520.0_x64__qbz5n2kfra8p0\lib\subprocess.py", line 951, in __init__
self._execute_child(args, executable, preexec_fn, close_fds,
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.1520.0_x64__qbz5n2kfra8p0\lib\subprocess.py", line 1420, in _execute_child
hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
FileNotFoundError: [WinError 2] O sistema não pode encontrar o arquivo especificado
Last line reads "System can't find the specified file"
If you're on windows, do not enclose your command line arguments in single quotes, they are passed as literals to your application. Either use doube quotes, or - if your path does not contain spaces - don't use quotes at all.
You probably could have figured that out yourself if you'd print out the filename as part of the error message.
Also: single quotes will not prevent a command line argument from being split if it contains spaces.

Python Subprocess Call with variables [duplicate]

This question already has answers here:
"OSError: [Errno 2] No such file or directory" while using python subprocess with command and arguments
(3 answers)
Closed 7 years ago.
I am currently writing a script for a customer.
This script reads from a config file.
Some of these infos are then stores in variables.
Afterwards I want to use subprocess.call to execute a mount command
So I am using these variables to build the mount command
call("mount -t cifs //%s/%s %s -o username=%s" % (shareServer, cifsShare, mountPoint, shareUser))
However this does not work
Traceback (most recent call last):
File "mount_execute.py", line 50, in <module>
main()
File "mount_execute.py", line 47, in main
call("mount -t cifs //%s/%s %s -o username=%s" % (shareServer, cifsShare, mountPoint, shareUser))
File "/usr/lib64/python2.6/subprocess.py", line 470, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib64/python2.6/subprocess.py", line 623, in __init__
errread, errwrite)
File "/usr/lib64/python2.6/subprocess.py", line 1141, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
buidling the command first with
mountCommand = 'mount -t cifs //%s/%s %s -o username=%s' % (shareServer, cifsShare, mountPoint, shareUser)
call(mountCommand)
also results in the same error.
Your current invocation is written for use with shell=True, but doesn't actually use it. If you really want to use a string that needs to be parsed with a shell, use call(yourCommandString, shell=True).
The better approach is to pass an explicit argument list -- using shell=True makes the command-line parsing dependent on the details of the data, whereas passing an explicit list means you're making the parsing decisions yourself (which you, as a human who understands the command you're running, are better-suited to do).
call(['mount',
'-t', 'cifs',
'//%s/%s' % (shareServer, cifsShare),
mountPoint,
'-o', 'username=%s' % shareUser])

Subprocess in Python: File Name too long

I try to call a shellscript via the subprocess module in Python 2.6.
import subprocess
shellFile = open("linksNetCdf.txt", "r")
for row in shellFile:
subprocess.call([str(row)])
My filenames have a length ranging between 400 and 430 characters.
When calling the script I get the error:
File "/usr/lib64/python2.6/subprocess.py", line 444, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib64/python2.6/subprocess.py", line 595, in __init__
errread, errwrite)
File "/usr/lib64/python2.6/subprocess.py", line 1106, in _execute_child
raise child_exception
OSError: [Errno 36] File name too long
An example of the lines within linksNetCdf.txt is
./ShellScript 'Title' 'Sometehing else' 'InfoInfo' 'MoreInformation' inputfiile outputfile.txt 3 2
Any ideas how to still run the script?
subprocess.call can take the command to run in two ways - either a single string like you'd type into a shell, or a list of the executable name followed by the arguments.
You want the first, but were using the second
import subprocess
shellFile = open("linksNetCdf.txt", "r")
for row in shellFile:
subprocess.call(row, shell=True)
By converting your row into a list containing a single string, you're saying something like "Run the command named echo these were supposed to be arguments with no arguments"
You need to tell subprocess to execute the line as full command including arguments, not just one program.
This is done by passing shell=True to call
import subprocess
cmd = "ls " + "/tmp/ " * 30
subprocess.call(cmd, shell=True)

subprocess.check_output(): OSError file not found in Python

Executing following command and its variations always results in an error, which I just cannot figure out:
command = "/bin/dd if=/dev/sda8 count=100 skip=$(expr 19868431049 / 512)"
print subprocess.check_output([command])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/subprocess.py", line 566, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
WHich file it is referring to ? other commands like ls,wc are running correctly though, the command is also running well on terminal but not python script.
Your command is a list with one element. Imagine if you tried to run this at the shell:
/bin/'dd if='/dev/'sda8 count=100 skip=$(expr 19868431049 '/' 512)'
That's effectively what you're doing. There's almost certainly no directory named dd if= in your bin directory, and there's even more almost certainly no dev directory under that with an sd8 count=100 skip=$(expr 19868431049 directory with a program named 512 in it.
What you want is a list where each argument is its own element:
command = ['/bin/dd', 'if=/dev/sda8', 'count=100', 'skip=$(expr 19868431049 / 512)']
print subprocess.check_output(command) # notice no []
But that brings us to your second problem: $(expr 19868431049 / 512) isn't going to be parsed by Python or by dd; that's bash syntax. You can, of course, just do the same thing in Python instead of in bash:
command = ['/bin/dd', 'if=/dev/sda8', 'count=100',
'skip={}'.format(19868431049 // 512)]
print subprocess.check_output(command)
Or, if you really want to use bash for no good reason, pass a string, rather than a list, and use shell=True:
command = "/bin/dd if=/dev/sda8 count=100 skip=$(expr 19868431049 / 512)"
print subprocess.check_output(command, shell=True) # still no []
Although that still isn't going to work portably, because the default shell is /bin/sh, which may not know how to handle bashisms like $(…) (and expr, although I think POSIX requires that expr exist as a separate process…). So:
command = "/bin/dd if=/dev/sda8 count=100 skip=$(expr 19868431049 / 512)"
print subprocess.check_output(command, shell=True, executable='/bin/bash')
This worked for me using subprocess.popen
command = "echo $JAVA_HOME"
proc = subprocess.Popen(command,stdout=subprocess.PIPE,shell=True)

Using Python's subprocess.call to kill firefox process

I am trying to kill any firefox processes running on my system as part of a python script, using the script below:
if subprocess.call( [ "killall -9 firefox-bin" ] ) is not 0:
self._logger.debug( 'Firefox cleanup - FAILURE!' )
else:
self._logger.debug( 'Firefox cleanup - SUCCESS!' )
I am encountering the following error as shown below, however 'killall -9 firefox-bin' works whenever I use it directly in the terminal without any errors.
Traceback (most recent call last):
File "./pythonfile", line 109, in __runMethod
if subprocess.call( [ "killall -9 firefox-bin" ] ) is not 0:
File "/usr/lib/python2.6/subprocess.py", line 478, in call
p = Popen(*popenargs, **kwargs)
File "/usr/lib/python2.6/subprocess.py", line 639, in __init__
errread, errwrite)
File "/usr/lib/python2.6/subprocess.py", line 1228, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Am I missing something or should I be trying to use a different python module altogether?
You need to separate the arguments when using subprocess.call:
if subprocess.call( [ "killall", "-9", "firefox-bin" ] ) > 0:
self._logger.debug( 'Firefox cleanup - FAILURE!' )
else:
self._logger.debug( 'Firefox cleanup - SUCCESS!' )
call() normally does not treat your command like the shell does, and it won't parse it out into the separate arguments. See frequently used arguments for the full explanation.
If you must rely on shell parsing of your command, set the shell keyword argument to True:
if subprocess.call( "killall -9 firefox-bin", shell=True ) > 0:
self._logger.debug( 'Firefox cleanup - FAILURE!' )
else:
self._logger.debug( 'Firefox cleanup - SUCCESS!' )
Note that I changed your test to > 0 to be clearer about the possible return values. The is test happens to work for small integers due to an implementation detail in the Python interpreter, but is not the correct way to test for integer equality.

Categories

Resources