使用Python发送带有转义字符的子进程命令

时间:2018-04-23 23:44:19

标签: python replace terminal subprocess escaping

我正在使用python脚本,它使用子进程将命令传递给终端。我传递的命令的一部分涉及包含括号的路径。 Python处理带括号的字符串很好,但当然终端不处理没有转义字符的字符串。

我正在尝试通过将字符串输入到子进程中来将变量传递给命令行程序,但这是重现错误的简单示例:

import subprocess

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

这给了我这个错误:

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)'

当我使用转义字符将其直接写入终端时,效果很好。

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

但是在Python中我尝试在调用subprocess之前向字符串添加转义字符:

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

我得到了和以前一样的错误,因为与print不同,子进程字符串添加了第二个转义字符,它将传递给终端。

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\\)'

有没有办法解决这个特殊错误?通过replacesubprocess.run执行不同的操作? (我不是在寻找一种更好的删除目录的方法。)谢谢。

2 个答案:

答案 0 :(得分:1)

不要使用子进程,也不必担心shell转义。使用stdlib的shutil

中提供的高级文件操作API
import shutil
shutil.rmtree('/home/user/Desktop/directory(2018)')

答案 1 :(得分:1)

Python实现rmrmdir,因此无需调用进程。通常,如果要在subprocess中的命令上跳过shell处理,请不要使用shell。

import subprocess

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

shell将命令行分成参数列表。您可以自己构建该列表并完全跳过shell。