简体   繁体   中英

using Python to send subprocess commands with escape characters

I'm using a python script which uses subprocess to pass a commmand to the terminal. Part of the command that I'm passing involves paths which contain parentheses. Python handles strings with parentheses fine, but of course terminal does not handle these without escape characters.

I'm trying to pass variables to a command line program by feeding a string into subprocess, but here's simple example to reproduce the error:

import subprocess

path = '/home/user/Desktop/directory(2018)'
command_str =  'rmdir ' + path
print (subprocess.run(command_str))

which gives me this error:

Traceback (most recent call last):
  File "ex.py", line 7, in <module>
    print (subprocess.run(command_str))
  File "/usr/lib/python3.6/subprocess.py", line 403, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/lib/python3.6/subprocess.py", line 709, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.6/subprocess.py", line 1344, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'rmdir /home/user/Desktop/directory(2018)': 'rmdir /home/user/Desktop/directory(2018)'

When I write it directly into the terminal with escape characters it works great.

$ rmdir /home/user/Desktop/directory\(2018\)

But in Python when I try to add escape characters to the strings before calling subprocess:

command_str = command_str.replace('(','\(')
command_str = command_str.replace(')','\)')

I get the same error as before because, unlike print , the subprocess string adds a second escape character which gets passed to the terminal.

Traceback (most recent call last):
  File "ex.py", line 7, in <module>
    print (subprocess.run(command_str))
  File "/usr/lib/python3.6/subprocess.py", line 403, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/lib/python3.6/subprocess.py", line 709, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.6/subprocess.py", line 1344, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'rmdir /home/user/Desktop/directory\\(2018\\)': 'rmdir /home/user/Desktop/directory\\(2018\\)'

Is there a way to fix this particular error? Either by doing something different with replace or subprocess.run ? (I'm not looking for a better way to remove directories.) Thanks.

Do not use subprocess, and you don't have to worry about shell escaping. Use the high-level file operation APIs provided in stdlib's shutil :

import shutil
shutil.rmtree('/home/user/Desktop/directory(2018)')

Python implements rm and rmdir so no need to call a process. In general, if you want to skip shell processing on a command in subprocess , don't use the shell.

import subprocess

path = '/home/user/Desktop/directory(2018)'
command =  ['rmdir', path]
print (subprocess.run(command, shell=False))

The shell breaks a command line into a list of arguments. You can build that list yourself and skip the shell completely.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM