Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python subprocess sends backslash before a quote

I have a string, which is a framed command that should be executed by in command line

cmdToExecute = "TRAPTOOL -a STRING "ABC" -o STRING 'XYZ'"

I am considering the string to have the entire command that should be triggered from command prompt. If you take a closer look at the string cmdToExecute, you can see the option o with value XYZ enclosed in SINGLE QUOTE. There is a reason that this needs to be given in single quote orelse my tool TRAPTOOL will not be able to process the command.

I am using subprocess.Popen to execute the entire command. Before executing my command in a shell, I am printing the content

print "Cmd to be exectued: %r" % cmdToExecute
 myProcess = subprocess.Popen(cmdToExecute, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
(stdOut, stdErr) = myProcess.communicate()

The output of the above command is, Cmd to be executed: TRAPTOOL -a STRING "ABC" -o \'XYZ\'.

You can see that the output shows a BACKWARD SLASH added automatically while printing. Actually, the \ is not there in the string, which I tested using a regex. But, when the script is run on my box, the TRAPTOOL truncates the part of the string XYZ on the receiving server. I manually copy pasted the print output and tried sending it, I saw the same error on the receiving server. However, when I removed the backward slash, it sent the trap without any truncation.

  1. Can anyone say why this happens?
  2. Is there anyway where we can see what command is actually executed in subprocess.Popen?
  3. Is there any other way I can execute my command other that subprocess.Popen that might solve this problem?
like image 816
ASANT Avatar asked Mar 21 '23 01:03

ASANT


2 Answers

Try using shlex to split your command string:

>>> import shlex
>>> argv = shlex.split("TRAPTOOL -a STRING \"ABC\" -o STRING 'XYZ'")
>>> myProcess = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
>>> (stdOut, stdErr) = myProcess.communicate()

The first parameter to the Popen constructor can be an argument list for your shell command or a string, but an argument list might be easier to work with because of all the quotes involved. (See the Python subprocess documentation.)

If you want to see the commands being written, you could probably do something like:

>>> argv = shlex.split("bash -x -c 'TRAPTOOL -a STRING \"ABC\" -o STRING \'XYZ\''")

This makes bash echo the commands to the shell by means of the -x option.

like image 116
Alex Smith Avatar answered Apr 02 '23 03:04

Alex Smith


You asked for the repr representation of the string, not the str representation. Basically, what would you have to type at the Python interactive interpreter to get the same output? That's what %r displays. Change that to %s to see the value as it's actually stored:

print "Cmd to be exectued: %s" % cmdToExecute
like image 34
Kirk Strauser Avatar answered Apr 02 '23 03:04

Kirk Strauser