How to use double quotes in a python application by running a subprocess

Asked

Viewed 146 times

6

I’m trying to add a new wifi network via command line in a Raspberry Pi, however when I pass the string containing the data of the Wifi network the quotes that should be between the login name and password if lost, I would like to understand how could pass the data without losing the quotes. Below I will provide part of the codes for a better understanding of my problem.

Code:

cmd="echo \"network={ \n    ssid=\"" + ssdi_usr + "\""+"\n    psk=\"" + psk_usr + "\"\n    key_mgmt=WPA-PSK\n}\" >> /etc/wpa_supplicant/wpa_supplicant.conf"
subprocess.Popen(cmd, shell=True)

Output:

Insira nome da rede: jimi
Insira a senha: yay
echo "network={ 
    ssid="jimi"
    psk="yay"
    key_mgmt=WPA-PSK
}" >> /etc/wpa_supplicant/wpa_supplicant.conf

As it is in the file /etc/wpa_supplicant/wpa_supplicant.conf:

network={ 
    ssid=jimi
    psk=yay
    key_mgmt=WPA-PSK
}
  • I’ve tried to put: \"\"\" but it didn’t work either.

3 answers

7


Your string cmd contains this:

echo "network={ 
    ssid="jimi"
    psk="yay"
    key_mgmt=WPA-PSK
}" >> /etc/wpa_supplicant/wpa_supplicant.conf

And when you run this command, the quotes are ignored. For example, test this command:

echo "abc"def"xyz"

The exit will be abcdefxyz. That’s because the quotes are interpreted by shell before being passed to echo. So much so that echo abc and echo "abc" produce the same result (read here for more information).

So that the echo print the quotes, you have to escape them with \ - that is to say, echo \"abc\" prints "abc", but echo "abc" prints only abc.

Only in a Python string, the character \ should be written as \\. And to have the quotes in the string itself, you would have to use \" (or exchange double quotes for single quotes). Then it would look like this:

cmd = 'echo "network={ \n    ssid=\\"' + ssdi_usr + '\\"\n    psk=\\"' + psk_usr + '\\"\n    key_mgmt=WPA-PSK\n}" >> /etc/wpa_supplicant/wpa_supplicant.conf'

The quotation marks around network i kept for line breaks to be considered. But the quotes corresponding to the ssid and psk has to be escapes with \. With this, the generated command will be:

echo "network={ 
    ssid=\"jimi\"
    psk=\"yay\"
    key_mgmt=WPA-PSK
}" >> /etc/wpa_supplicant/wpa_supplicant.conf

And with that, the quotation marks will be written in the file, which will look like this:

network={
    ssid="jimi"
    psk="yay"
    key_mgmt=WPA-PSK
}

If you are using Python >= 3.6 you can swap the concatenation for f-string:

cmd = f'echo \"network={{ \n    ssid=\\"{ssdi_usr}\\"\n    psk=\\"{psk_usr}\\"\n    key_mgmt=WPA-PSK\n}}" >> /etc/wpa_supplicant/wpa_supplicant.conf'

The difference is that the variables ssdi_usr and psk_usr are placed between brackets, and their values are placed directly in the string. The "boring" part is that the brackets themselves have to be written as {{ and }}.


That said, instead of calling a shell command, it is no longer easy to use Python itself to write to the file?

with open('/etc/wpa_supplicant/wpa_supplicant.conf', 'a') as arq:
    arq.write(f"""echo network={{
    ssid="{ssdi_usr}"
    psk="{psk_usr}"
    key_mgmt=WPA-PSK
}}""")

So you’re not depending on the "nested" escape rules - because in your code you need to worry about the rules of how to write the \ and the quotes in Python, so that they follow Bash’s escape rules, already using only Python, is one less "layer" to worry about.

1

I was having problems because the information, such network name and password were entries provided by the user, I was able to find a medium for the solution:

cmd="echo 'ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev\nupdate_confg=1\ncountry=BR\nnetwork={ \n    ssid=" + '"' + ssdi_usr + '"' + "\n    psk=" + '"' + psk_usr + '"' + "\n    key_mgmt=WPA-PSK\n}' > /etc/wpa_supplicant/wpa_supplicant.conf"

subprocess.Popen(cmd, shell=True)

0

To escape the double quotes wrap the entire content with single quotes. For example:

Insira nome da rede: jimi
Insira a senha: yay
echo 'network={ 
    ssid="jimi"
    psk="yay"
    key_mgmt=WPA-PSK
}' 

Another method would be to use \ before each double quote you want to escape, for example:

Insira nome da rede: jimi
Insira a senha: yay
echo "network={ 
    ssid=\"jimi\"
    psk=\"yay\"
    key_mgmt=WPA-PSK
}"
  • I tried to do this, but it didn’t work either, when I write the contents in the file using this command echo "conteudo" >> /etc/destino quotes get lost

Browser other questions tagged

You are not signed in. Login or sign up in order to post.