0

So, I am trying to pass parameters to a bash shell script across a python TCP socket connection. The script being executed in the bash shell always bombs out even though when I print the variable being passed to os.system() or subprocess.call() it looks correct. Any ideas? Small chunk of the code that is giving me issues.

while 1:
    conn, addr = s.accept()
    print 'Connected with ' + addr[0] + ':' + str(addr[1])    
    data = conn.recv(1024)
    if not data:
        break
    data2 = data.rstrip('\n')
    cmd = 'ls ' + data2
    #os.system(cmd)  
    subprocess.call([cmd], shell=True)
    print cmd
3
  • You need to be specific about how it "bombs out". What does happen, exactly? Commented Apr 6, 2015 at 13:42
  • similar question here Commented Apr 6, 2015 at 13:51
  • Hi Brian, The program can locate the binary and runs it successfully in a bash shell however when attempting to add parameters in order to be passed to the bash binary, the binary does not interpret the parameters correctly causing it to return whatever error code that was programed for "invalid parameter" Using "ls" as an example: running "ls" works, passing "-l" to it fails when I print the variable cmd it returns what i would expect to work "ls -l" Commented Apr 6, 2015 at 16:35

1 Answer 1

1

Python's subprocess call (doc) takes a single string to execute or a list of arguments. You're passing a string as a single argument and thus the entire thing is interpreted as the command to execute, which of course cannot be found.

subprocess.call(cmd, shell=True) or subprocess.call(['ls', data2])

The latter is preferred as it means a malicious caller cannot create arbitrary shell actions by passing "foo; rm -rf / &" down the socket.

Note: Better to use call(('ls', data2)) (parentheses instead of brackets) to create a simple Python "tuple" rather than a dynamic list for passing to call(...).

Sign up to request clarification or add additional context in comments.

7 Comments

Hi Bran, Thank you for the thoughts! I will try this out and let you know my results.
Hi Brian, Trying your suggested method subprocess.call(('ls', data2)) leaves me still a bit broken. my output is: Connected with 127.0.0.1:36085 's: invalid option -- ' Try `ls --help' for more information. If I take the socket connection out of the equation and just try and pass the parameters to the script from statically assigned variables, it works great. I am thinking there is something to do with how the variable is created containing the information passed via the socket
What's the value of data2? Does it start with a dash? Also, you wrote "s: invalid option --"... was that supposed to be "ls: invalid option"? Sockets are raw 8-bit connections so as long as you're passing the exact characters that make up the destination filename, you should be fine.
The value of data2 does start with a dash. I have tried sending "-l" for "ls -l" and "--blue" for "blink1-tool --blue". Oddly enough, the error message is exactly how I typed it. Missing its first character.
Perhaps the issue is with how the data is being transferred. I am using telnet as a client. As a test I setup a number of IF statements directly after I receive the data on the server. Basically if data == 1: print data else: print "fail" On the client I sent "1" however it always falls through the first test and prints fail
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.