How to call from within Python an application with double quotes around an argument using subprocess? - python-3.x

I'm trying to call certutil from inside python. However I need to use quotation marks and have been unable to do so. My code is as follows:
import subprocess
output= subprocess.Popen(("certutil.exe", "-view", '-restrict "NotAfter <= now+30:00, NotAfter >= now+00:00"' ), stdout=subprocess.PIPE).stdout
for line in output:
print(line)
output.close()
I thought the single quotes would allow me to use double quotes inside the string.
Also I have tried using double quotes with the escape character (\"), however I keep getting the same error:
Unknown arg: -restrict \\NotAfter\r\n'
For some reason it seems to be translating " into \\.
Can anyone give insight as to why and how to fix it?

I do not have Python in any version installed. But according to answer on How do I used 2 quotes in os.system? PYTHON and documentation of subprocess, subprocess handles requirement for double quotes on arguments with space automatically.
So you should need to use simply:
import subprocess
output= subprocess.Popen(("certutil.exe", "-view", "-restrict", "NotAfter <= now+30:00, NotAfter >= now+00:00" ), stdout=subprocess.PIPE).stdout
for line in output:
print(line)
output.close()
And the command line used on calling certutil is:
certutil.exe -view -restrict "NotAfter <= now+30:00, NotAfter >= now+00:00"

output=subprocess.Popen(("certutil.exe -view -restrict \"NotAfter<=now+30:00,NotAfter>=now+00:00\"" ),stdout=subprocess.PIPE).stdout
This is what was needed. I was passing the command as a command with 2 args. What I should have been doing was passing it as one big command with 2 parameters.

Related

How do I pass ">>" or "<<" to my script without the terminal trying to interpret it as me either appending to something or getting stdin?

My python script can take a series of bitwise operators as one of its arguments. They all work fine except for "=<<" which is roll left, and "=>>" which is roll right. I run my script like ./script.py -b +4,-4,=>>10,=<<1, where anything after -b can be any combination of similar operations. As soon as the terminal sees "<<" though, it just drops the cursor to a new line after the command and asks for more input instead of running the script. When it sees ">>", my script doesn't process the arguments correctly. I know it's because bash uses these characters for a specific purpose, but I'd like to get around it while still using "=>>" and "=<<" in my arguments for my script. Is there any way to do it without enclosing the argument in quotation marks?
Thank you for your help.
You should enclose the parameters that contain special symbols into single quotation marks (here, echo represents your script):
> echo '+4,-4,=>>10,=<<1'
+4,-4,=>>10,=<<1
Alternatively, save the parameters to a file (say, params.txt) and read them from the file onto the command line using the backticks:
> echo `cat params.txt`
+4,-4,=>>10,=<<1
Lastly, you can escape some offending symbols:
> echo +4,-4,=\>\>10,=\<\<1
+4,-4,=>>10,=<<1

Subprocess Hexdump Command Returning Bad Format Error

I am utilizing subprocess in order to grab the hexdump for a .tgz file as I require the hex string. The only problem is, hexdump is throwing a bad format error, but only when the command is issues through subprocess. I believe I have escaped everything correctly, but I can't figure out why I am not getting my intended output:
def package_plugin():
plugin_hex = subprocess.run(["hexdump", "-v", "-e", "'1/1 \"\\\\x%%02x\"'", "package.tgz"])
This results in an error: hexdump: "'1/1 "''x%%02x"'": bad format. However, if I just run the command straight in the terminal I receive the expected output of a hexstring with the '\x' separating the hex.
How should I be running this to store the output in a Python variable? Is my command being mangled somehow and hence not executing correctly? Any advice is appreciated.
Thanks
EDIT: I should add that when entering in the terminal the command is hexdump -v -e '1/1 "\\x%02x"' I am not sure why the extra '%' sign is shown in the error as it should be interpreting as a single % sign.
Nevermind. I couldn't figure this out but I solved it with hexlify:
def package_plugin():
plugin_hex = ""
with open('plugin.tgz', 'rb') as f:
for chunk in iter(lambda: f.read(32), b''):
plugin_hex += binascii.hexlify(chunk).decode("utf-8")
formatted_hex = '\\x' + '\\x'.join(plugin_hex[i:i+2] for i in range(0, len(plugin_hex), 2))

Semicolon on command line in linux

i am running my application in linux by providing inputs as command line. My input field contain an argument which contains ";"(semicolon) internally.(For example:123;434;5464).
This will be parsed using UTF8String encode and send.
But when i am using like this, in initial itself i am getting,
bash: 434: command not found
bash: 5464: command not found
And when i capture traffic the output contains only 123 instead 123;434;5464
But if i give without semicolon (Ex:123:434:5464),not getting any problem output coming properly as 123:434:5464
Point me how to give command line input by using semicolon as to come output. Is there any particular syntax to use while doing with semicolon.
I am running like below
./runASR.sh -ip 10.78.242.4 -port 3868 -sce 10.78.241.206 -id 85;167838865;1385433280
where -id field contain that value with issue.
; is treated an end of command character. So 123;456;5464 to bash is in fact 3 commands. To pass such meta-characters escape it with escape character \.
./command 123\;456\;5464
Or Just quote it with single quote (double quote evaluates the inner string) (Thanks Triplee, I forgot to mention this)
./command '123;456;5464'

build bash string containing a variable value surrounded with single quotes

I'm having a nightmare from what should be the most trivial of tasks.
My final goal is issue the following command from a bash script:
sqlite3 my_db.db '.read my_file.sql'
There are two catches here:
1. The single-quotes are obligatory, and can't be replaced by, say, double-quotes
2. my_file.sql is a variable known only at run-time.
So what I need is a way to have bash build a string that on one hand contains a variable value, while on the other hand that value should be surrounded by single quotes.
I would also much prefer a solution not relying on additional tools like AWK, Perl or the like. Maybe sed if it's really necessary.
Thanks.
Thanks Jonathan and Nelson.
I tried all three suggestions, but they all failed.
For simplicity I reduced the problem to the following:
I wrote the following script (tst.sh):
#!/bin/bash
file=/tmp/1
ls "'"$file"'"
ls \'$file\'
ls "'$file'"
Then I isuues the following commands:
$ touch /tmp/1
$ ls '/tmp/1'
/tmp/1
$ ./tst.sh
'/tmp/1': No such file or directory
'/tmp/1': No such file or directory
'/tmp/1': No such file or directory
It seems the quotes were indeed added, but the resulting command was not the same as when entered manually.
Any ideas ?
Single-quotes are not obligatory. All of the following commands run sqlite3 with exactly the same arguments:
sqlite3 my_db.db '.read my_file.sql'
sqlite3 my_db.db ".read my_file.sql"
sqlite3 my_db.db .read\ my_file.sql
sqlfile="my_file.sql"
sqlite3 my_db.db ".read $sqlfile"
In all cases, the quotes (/escape) are parsed and removed before the arguments are passed to sqlite3. This is what you want. You want sqlite3 to get two arguments: my_db.db and .read my_file.sql. You do not want sqlite3 to see the quotes around the command -- that would be the equivalent of:
$ sqlite3 my_db.db
SQLite version 3.7.7 2011-06-25 16:35:41
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> '.read my_file.sql'
...>
...which, as you can see, just confuses sqlite3.
BTW, this is the same as the problem in your ls examples: you're passing single-quotes as part of the argument to ls, so it's looking for a file with single-quotes in the name and not finding it. You want the shell to remove the quotes rather than pass them to the command as part of an argument.
This will do what you say you want to do (getting single quotes to the program), but it uses double quotes:
sqlite3 my_db.db "'".read" "my_file.sql"'"
Avoiding double quotes, you can write:
sqlite3 my_db.db \'.read\ my_file.sql\'
For both of these, the second argument will be seen by sqlite3 as a string containing:
'.read my_file.sql'
If the file name is in a variable (file=my_file.sql), then:
sqlite3 my_db.db "'".read" "$file"'"
sqlite3 my_db.db \'.read\ $file\'
These notations are vulnerable to confusion if the file name contains spaces.
However, I don't think that's likely to be what you really want. The proscription on double quotes is puzzling, and the requirement for single quotes is likewise puzzling.
You can do as follows:
VAR=my_file.sql
VAR2="'.read $VAR'"
sqlite3 my_db.db $VAR2
user1860085, if you check out documentation for sqlite3 command and you will know how shell treats quotes and white spaces, you will probably come to conclusion that you want double quotes for your case.
but if you really want single quotes, here is solution:
eval sqlite3 my_db.db \'.read $VARIABLE\'
which in the fly will change to:
sqlite3 my_db.db '.read my_file.sql'
But I don't see why you could want it...
OK, problem solved !!
All that was missing is adding a little 'eval' command before the line.
So, in the simple example script I gave, changing:
ls "'$file'" to:
eval ls "'$file'"
did the job.
Thanks to all replyers :-)

Passing a node.js script an argument with a space on Windows

I'm running a node script from the command line on Windows and am trying to pass in a folder path that includes a space. When accessing this argument, via require modules or via the process.argv variable I don't seem to get what I would expect. For the following command:
node script.js "C:\path\to\folder\with a space\"
I seem to get the following value:
process.argv[2] = C:\path\to\folder\with a space\"
Notice the trailing " in the string. If the argument is passed without quotes, it obviously passes it as different arguments split on the space.
Am I doing something wrong, or is this a bug? And if it is a bug, is there a possible workaround?
The trailing backslash escapes the quote which is then again implied by the shell (instead of aborting due to lack of a closing quote).
The fix is simply escaping that backslash with another backslash or omitting it altogether:
C:\Users\myself> python -c "import sys; print sys.argv[1]" "foo\bar\"
foo\bar"
C:\Users\myself> python -c "import sys; print sys.argv[1]" "foo\bar\\"
foo\bar\
Note that you may only escape the last backslash this way - any other backslash ins the string will not act as an escape character:
C:\Users\myself> python -c "import sys; print sys.argv[1]" "foo\\bar\\"
foo\\bar\

Resources