How can I specify quotes(" ") in my string text in Python? - python

The command I want to run from my python script is:
tool-manager-cli -a "somexml.xml" -c "another.xml"
My python code is:
command1 = """ tool-manager-cli -a "somexml.xml" -c "another.xml" """
subprocess.Popen(command1)
However when I run my py script, I get SyntaxError: invalid syntax as my error for this line.
How can I specify quotes(" ") in my string text without closing it or invalid syntax?

Try using single quotes to differentiate like so
command1 = """ tool-manager-cli -a 'somexml.xml' -c 'another.xml' """

You can use format method to structure your command:
command1= "{} {} {} {} {}".format("tool-managel-cli","-a", "somexml.xml","-c","another.xml")
subprocess.Popen(command1)
You can also concat by + , but its tedious ofcourse
command1 ="tool-manager-cli"+" -a"+ " somexml.xml" + " -c "+" another.xml"

Related

subprocess.check_output returns non-zero exit status 1 [duplicate]

I'm trying to call ffmpeg command using subprocess.call() on linux, but I'm unable to get the arguments right. Before hand, I used os.system and it worked, but this method is not recommended.
Using arguments with a dash such as "-i" gets me this error
Unrecognized option 'i "rtsp://192.168.0.253:554/user=XXX&password=XXX&channel=0&stream=0.sdp?real_stream"'.
Error splitting the argument list: Option not found
Using arguments without dash like "i" gets me this error
[NULL # 0x7680a8b0] Unable to find a suitable output format for 'i rtsp://192.168.0.253:554/user=admin&password=&channel=0&stream=0.sdp?real_stream'
i rtsp://192.168.0.253:554/user=XXX&password=XXX&channel=0&stream=0.sdp?real_stream: Invalid argument
Here's the code
class IPCamera(Camera):
"""
IP Camera implementation
"""
def __init__(self,
path='\"rtsp://192.168.0.253:554/'
'user=XXX&password=XXX&channel=0&stream=0.sdp?real_stream\"'):
"""
Constructor
"""
self.path = path
def __ffmpeg(self, nb_frames=1, filename='capture%003.jpg'):
"""
"""
ffm_input = "-i " + self.path
ffm_rate = "-r 5"
ffm_nb_frames = "-vframes " + str(nb_frames)
ffm_filename = filename
if platform.system() == 'Linux':
ffm_path = 'ffmpeg'
ffm_format = '-f v4l2'
else:
ffm_path = 'C:/Program Files/iSpy/ffmpeg.exe'
ffm_format = '-f image2'
command = [ffm_path, ffm_input, ffm_rate, ffm_format, ffm_nb_frames, ffm_filename]
subprocess.call(command)
print(command)
BTW, I'm running this command on a MT7688.
Thanks
You have to split the options:
command = [ffm_path, '-i', ffm_input, '-r', ffm_rate, '-f', ffm_format, '-vframes', ffm_nb_frames, ffm_filename]
The ffm_input, ffm_rate, ffm_format should only contain the value:
ffm_input = self.path
ffm_rate = '5'
ffm_nd_frames = str(nb_frames)
ffm_format = 'v412' if platform.system() == 'Linux' else 'image2'
When you pass a list no parsing is done so -r 5 is taken as a single argument but the program expects you to provide two separate arguments -r followed by 5.
Basically if you put them as a single element in the list it's as if you quoted them on the command line:
$ echo "-n hello"
-n hello
$ echo -n hello
hello$
In the first example echo sees a single argument -n hello. Since it does not match any option it just prints it. In the second case echo sees two arguments -n and hello, the first is the valid option to suppress end of line and as you can see the prompt is printed right after hello and not on its own line.

Shell - New line seperator in python script output

How do I specify a new line in python output? Because the code below is not working.
Already tried 'os.linesep'.
LOGS=$(echo "$RESPONSE" | python -c "
import sys, json, os;
res=json.load(sys.stdin);
result=''
for x in range(len(res['hits']['hits'])):
result += res['hits']['hits'][x]['_source']['message'] + '\n'
print result
")
echo -e $LOGS
The problem is that you need to echo the variable $LOG in quotes to expand any carriage returns. The last line should therefore be:
echo -e "$LOGS"

How to call a python script on a new shell window from python code?

I'm trying to execute 10 python scripts from python code and open each of them in a new shell window.
My code :
for i in range(10):
name_of_file = "myscript"+str(i)+".py"
cmd = "python " + name_of_file
os.system("gnome-terminal -e 'bash -c " + cmd + "'")
But each script file are not executing, I get only the live interpreter of python in the new terminal...
Thank you guys
I would suggest using the subprocess module (https://docs.python.org/2/library/subprocess.html).
In this way, you'll write something like the following:
import subprocess
cmd = ['gnome-terminal', '-x', 'bash', '-c']
for i in range(10):
name_of_file = "myscript"+str(i)+".py"
your_proc = subprocess.Popen(cmd + ['python %s' % (name_of_file)])
# or if you want to use the "modern" way of formatting string you can write
# your_proc = subprocess.Popen(cmd + ['python {}'.format(name_of_file)])
...
and you have more control over the processes you start.
If you want to keep using os.system(), build your command string first, then pass it to the function. In your case would be:
cmd = 'gnome-terminal -x bash -c "python {}"'.format(name_of_file)
os.system(cmd)
something along these lines.
Thanks to #anishsane for some suggestions!
I think that it is to do with the string quoting of the argument to os.system. Try this:
os.system("""gnome-terminal -e 'bash -c "{}"'""".format(cmd))

Bash doesn't think string is properly quoted?

I'm attempting to execute a command over SSH, but bash on the other end doesn't think it's escaped properly.
Here, self._client is a paramiko.SSHClient object; args is a list of arguments, the command to execute.
def run(self, args, stdin=None, capture_stdout=False):
"""Runs a command.
On success, returns the output, if requested, or None.
On failure, raises CommandError, with stderr and, if captured, stdout,
as well as the exit code.
"""
command = ' '.join(_shell_escape(arg) for arg in args)
print('About to run command:\n {}'.format(command))
print('About to run command:\n {!r}'.format(command))
channel = self._client.get_transport().open_session()
channel.exec_command(command)
_shell_escape:
_SHELL_SAFE = _re.compile(r'^[-A-Za-z0-9_./]+$')
def _shell_escape(s):
if _SHELL_SAFE.match(s):
return s
return '\'{}\''.format(s.replace('\'', '\'\\\'\''))
I'm attempt to run some Python through this. On stderr, I get back:
bash: -c: line 5: unexpected EOF while looking for matching `''
bash: -c: line 6: syntax error: unexpected end of file
The output from the two print statements:
About to run command:
python -c 'import os, sys
path = sys.argv[1]
if sys.version_info.major == 2:
path = path.decode('\''utf-8'\'')
entries = os.listdir(path)
out = b'\'''\''.join(e.encode('\''utf-8'\'') + b'\'''\'' for e in entries)
sys.stdout.write(out)
' .
About to run command:
"python -c 'import os, sys\npath = sys.argv[1]\nif sys.version_info.major == 2:\n path = path.decode('\\''utf-8'\\'')\nentries = os.listdir(path)\nout = b'\\'''\\''.join(e.encode('\\''utf-8'\\'') + b'\\''\x00'\\'' for e in entries)\nsys.stdout.write(out)\n' ."
If I copy and paste the output of command, and paste it into bash, it executes, so it really does appear to be properly escaped. My current understanding is that SSH, on the other end, will take command, and run [my_shell, '-c', command].
Why is bash erroring on that command?
The input contains an embedded nul character, which bash appears to treat as the end of the string. (I'm not sure there's any way it couldn't!). This is visible in my question, where I output command:
About to run command:
"python -c 'import os, sys [SNIP…] + b'\\''\x00'\\'' for [SNIP…]"
That's a repr output, but notice the single slash before the x in \x00: that's an actual \x00 that made it through. My original code has this Python embedded as a snippet, which I didn't include (I didn't believe it was relevant):
_LS_CODE = """\
import os, sys
path = sys.argv[1]
if sys.version_info.major == 2:
path = path.decode('utf-8')
entries = os.listdir(path)
out = b''.join(e.encode('utf-8') + b'\x00' for e in entries)
sys.stdout.write(out)
"""
Here, Python's """ is still processing \ as an escape character. I need to double up, or look into raw strings (r""")
You need to escape newlines as well. A better option is to put the program text in a here document.
Make the output of "About to run command:" to look like
python -c << EOF
import os, sys
path = sys.argv[1]
if sys.version_info.major == 2:
path = path.decode('\''utf-8'\'')
entries = os.listdir(path)
out = b'\'''\''.join(e.encode('\''utf-8'\'') + b'\'''\'' for e in entries)
sys.stdout.write(out)
.
EOF
Maybe you wouldn't need to escape anything at all.

Python string formatting

I'm building up several command strings to pass to os.system. I want to group the common stuff into a string then add the specific stuff as needed. For example:
CMD = "python app.py %s -o %s > /dev/null"
option1 = "-i 192.169.0.1"
option2 = "results-file"
cmd = CMD, (option1, option2) #doesn't work
os.system(cmd)
I know cmd is a tuple. How do I get cmd to be the command string I want?
You use the % operator.
cmd = CMD % (option1, option2)
See also: Python documentation on string formatting
You could do it this way using the string format() method which processes Format String Syntax:
CMD = "python app.py {} -o {} > /dev/null"
option1 = "-i 192.169.0.1"
option2 = "results-file"
os.system(CMD.format(option1, option2))
cmd = CMD % (option1, option2)
This is explained here.

Categories