This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: shlex.quote incorrectly quotes ampersants, pipes
Type: behavior Stage: resolved
Components: Versions: Python 3.4
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: klo.uo, r.david.murray, xiang.zhang
Priority: normal Keywords:

Created on 2016-07-05 15:50 by klo.uo, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (5)
msg269830 - (view) Author: klo uo (klo.uo) Date: 2016-07-05 15:50
Example code:

========================================
Python 3.4.3 (default, Oct 14 2015, 20:28:29)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import shlex
>>> cmd = ["pwd", "&&", "ls"]
>>> ' '.join(shlex.quote(arg) for arg in cmd)
"pwd '&&' ls"
>>>
========================================

Double ampersants is quoted, and if this command string is passed to Popen or pasted in shell it would fail.


OTOH, Windows so-so compatible list2cmdline:

========================================
Python 3.5.1 (v3.5.1:37a07cee5969, Dec  6 2015, 01:54:25) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> cmd = ["cd", "&&", "dir"]
>>> subprocess.list2cmdline(cmd)
'cd && dir'
>>>
========================================

behaves correctly.
msg269833 - (view) Author: Xiang Zhang (xiang.zhang) * (Python committer) Date: 2016-07-05 16:08
Doesn't this the expected behaviour of shlex.quote, return a shell-escaped version of the string s? If && is not quoted, how about "pwd && rm -rf ~"? I think in your case there is no need to use shlex.quote.
msg269835 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2016-07-05 16:14
Yes, the point of shlex.quote is to get something that is *not* special to the shell, and therefore safe to pass to the shell.  If you *want* an & in your command, just pass it, don't quote it.  quote is for *untrusted* data, like filenames received from a user.

Or better, don't use shell=True all.

(list2cmdline has a different purpose, unique to windows)
msg269842 - (view) Author: klo uo (klo.uo) Date: 2016-07-05 16:38
So there is no reliable way for converting chained command line sequence to string on *nix, when I have to to use string as shell=True?
msg269843 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2016-07-05 16:59
If you use shell=True you can do almost anything you can do in the shell, but making it safe is up to you.  We provide shlex.quote to help you with that, but only you can know what parts of the expression need quoting and what don't.

It sounds like you might find the stdlib 'pipes' module interesting.
History
Date User Action Args
2022-04-11 14:58:33adminsetgithub: 71644
2016-07-05 16:59:14r.david.murraysetmessages: + msg269843
2016-07-05 16:38:37klo.uosetmessages: + msg269842
2016-07-05 16:14:27r.david.murraysetstatus: open -> closed

nosy: + r.david.murray
messages: + msg269835

resolution: not a bug
stage: resolved
2016-07-05 16:08:19xiang.zhangsetnosy: + xiang.zhang
messages: + msg269833
2016-07-05 15:50:26klo.uocreate