Running OpenSSL System Call - python

New to Python and can't get this to work. I need to spawn an openSSL process. Here is what I have:
from subprocess import call
cmd = "openssl aes-128-cbc -d -in ciphertext -base64 -pass pass:test123"
decrypted = call(cmd)
print (decrypted)
This won't even compile. I get TypeError: 'function' object is not subscriptable
Can anyone tell me how I can do this? Thanks.
By the way, when I just type my cmd string into a terminal, it works fine.
EDIT: I changed the line decrypted = call[cmd] to decrypted = call(cmd). When I do that, I get this sequence of errors:
Traceback (most recent call last):
..., line 14, in <module>
plaintext = call(cmd)
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/subprocess.py", line 523, in call
with Popen(*popenargs, **kwargs) as p:
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/subprocess.py", line 817, in __init__
restore_signals, start_new_session)
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/subprocess.py", line 1441, in _execute_child
raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2] No such file or directory: 'openssl aes-128-cbc -d -in test.enc -base64 -pass pass:hello'

you use paranthesis instead of square brackets
i.e.:
decrypted = call(cmd)
More generally, you use parenthesis to wrap the arguments in a function call in python (as well as in most other main-stream languages).
Also, by default call treats the first argument as the executable to run, without any argument. You either need to pass shell=True as well, or split the command up into an array and pass that.
decrypted = call(cmd, shell=True) #execute command with the shell
# or
decrypted = call(['openssl', 'aes-128-cbc', '-d', '-in', 'ciphertext', '-base64', '-pass', 'pass:test123'])
In general the latter is preferred because it takes care of escaping for you, and is more portable between different shells.

Related

Cannot perform subprocess.run inside a snap

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.

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

Can't rm -r directory using python subprocess.call

Welp, I need to remove some huge temporary directories from python and I can't seem to use rm -r. I'm working thought a big dataset (on s3) I don't have the disc space to leave them around.
The usual way I would call a command from python is
import subprocess
subprocess.call('rm','-r','/home/nathan/emptytest')
That gives me
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/subprocess.py", line 493, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.7/subprocess.py", line 629, in __init__
raise TypeError("bufsize must be an integer")
TypeError: bufsize must be an integer
What's this all about?
You're calling it the wrong way. The first argument should be a list:
import subprocess
subprocess.call(['rm','-r','/home/nathan/emptytest'])
You might also just want to try and use shutitl.rmtree
According to the documentation,
>> In [3]: subprocess.call?
Type: function
Base Class: <type 'function'>
String Form: <function call at 0x01AE79F0>
Namespace: Interactive
File: c:\python26\lib\subprocess.py
Definition: subprocess.call(*popenargs, **kwargs)
Docstring:
Run command with arguments. Wait for command to complete, then
return the returncode attribute.
The arguments are the same as for the Popen constructor. Example:
retcode = call(["ls", "-l"])
So try:
subprocess.call(['rm','-r','/home/nathan/emptytest'])

Popen error: "[Errno 2] No such file or directory" when calling shell function

I have some custom commands.
This works:
subprocess.Popen(['python'], stdout=subprocess.PIPE)
But if I have my own system commands like deactivate, I get that error
Traceback (most recent call last):
File "runner2.py", line 21, in <module>
main()
File "runner2.py", line 18, in main
subprocess.Popen(['deactivate',], stdout=subprocess.PIPE)
File "/usr/lib/python2.6/subprocess.py", line 633, in __init__
errread, errwrite)
File "/usr/lib/python2.6/subprocess.py", line 1139, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Let alone I need to execute this under my sandbox virtualenv.
Try add an extra parameter shell=True to the Popen call.
Just a note. shell=True was likely the correct solution to the o.p., since they did not make the following mistake, but you can also get the "No such file or directory" error if you do not split up your executable from its arguments.
import subprocess as sp, shlex
sp.Popen(['echo 1']) # FAILS with "No such file or directory"
sp.Popen(['echo', '1']) # SUCCEEDS
sp.Popen(['echo 1'], shell=True) # SUCCEEDS, but extra overhead
sp.Popen(shlex.split('echo 1')) # SUCCEEDS, equivalent to #2
Without shell=True, Popen expects the executable to be the first element of args, which is why it fails, there is no "echo 1" executable. Adding shell=True invokes your system shell and passes the first element of args to the shell. i.e. for linux, Popen(['echo 1'], shell=True) is equivalent to Popen('/bin/sh', '-c', 'echo 1') which is more overhead than you may need. See Popen() documentation for cases when shell=True is actually useful.
You have to give the full path to your program deactivate and then it the subprocess module should be able to find it.
I'm spawning subprocesses like that:
SHUTDOWN_CMD = os.path.sep.join(["c:", "windows", "system32", "shutdown.exe"])
def abortShutdown():
os.spawnv(os.P_NOWAIT, SHUTDOWN_CMD,
[SHUTDOWN_CMD, '/A'])
time.sleep(3)
I'm not using subprocess since Python 2.5 does not support it. I had to use use the FULL path to have it working and I guess you also have to use the full path to your custom commands.

Categories

Resources