Search code examples
pythonmacosterminalsubprocesstcpdump

subprocess syntaxerr on try to tpcdump with python


#old version of setting the command
#command = 'sudo tcpdump "type mgt subtype beacon and ether src '+ bssid.get() +'" -I -c 1 -i en0 -w beacon.cap'
#command = command.split()

#improved but error still exists
command = ['sudo', 'tcpdump', '"type mgt subtype beacon and ether src ' + bssid.get() + '"', '-I', '-c', '1', '-i', 'en0', '-w', 'beacon.cap']

cmd1 = subprocess.Popen(['echo',sudo_password], stdout=subprocess.PIPE)
cmd2 = subprocess.Popen(['sudo','-S'] + command, stdin=cmd1.stdout, stdout=subprocess.PIPE)
output = cmd2.stdout.read().decode() 
print("Task2completed: " + output + "2END")

Hello stackoverflow,

I have a question about subprocess, in the previous code snippet is the problem, that I only get an syntax error:

tcpdump: can't parse filter expression: syntax error

I cannot reproduce why this error occurs, I tried typing it manually in the terminal, then it works. I also tried set $BSSID and use it in the command instead of

'+ bssid.get() +'

but that also DIDNT worked...

Im pretty sure there is also no problem with bssid.get(), because if I print the command out and then use it in the command line it works... I thought of some kinda' error while splitting the command?? But correct me if im wrong!

Thanks very much for your help ! 🙏


Solution

  • Don't try to mix and match list-style Popen parameters and strings; just using all strings is safer and more convenient.

    You can also use a io.BytesIO() for sending the password to sudo:

    import subprocess
    
    command = [
        "tcpdump",
        f"type mgt subtype beacon and ether src '{bssid.get()}'",
        "-I",
        "-c",
        "1",
        "-i",
        "en0",
        "-w",
        "beacon.cap",
    ]
    
    cmd = subprocess.Popen(
        ["sudo", "-S"] + command,
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
    )
    # Write the password to the subprocess's stdin.
    cmd.stdin.write((f"{sudo_password}\n").encode("utf-8"))
    output = cmd.stdout.read().decode()
    print("Task2completed: " + output + "2END")