通配符在使用 shlex 的子进程调用中不起作用 [英] Wildcard not working in subprocess call using shlex

查看:33
本文介绍了通配符在使用 shlex 的子进程调用中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

语言:Python v2.6.2

Language: Python v2.6.2

操作系统:AIX 5.3

OS: AIX 5.3

我正在使用 Python 将一些文件从备份恢复到测试系统 - 所有命令都以下面的方式调用,但有些只是不想工作.

I'm using Python to restore some files from a backup to a test system - all commands are called in the manner below, however some just plain don't want to work.

#!/usr/bin/python
import subprocess, shlex

cmd = 'sudo rm -rf /work/TEST/*'
arg = shlex.split(cmd)

# This does not work
p = subprocess.Popen(arg)

# This, however, works just fine
p = subprocess.Popen(cmd, shell=True)

如果我从命令中删除 * 的,它们就可以正常工作(好吧,它们可以在没有通配符的情况下正常工作,不幸的是,这不是我想要的).

If I remove the *'s from the commands they work fine (well, they work as they should without the wildcards, which is unfortauntely not what I want).

出于明显的安全原因,我真的不想使用 shell=True,但是还有一些其他命令基本上可以做同样的事情.如果命令中有一个通配符,它​​就不会工作——它执行没有错误,只是什么都不做.

I really do not want to use shell=True for obvious security reasons, however there are a couple of other commands that basically do the same thing. If there is a wildcard in the command it just won't work - it executes without error, just doesn't do anything.

有趣的是以下命令(通过shlex解析):

Interestingly the following command (parsed through shlex):

sudo mv /work/testrestore/production/* /work/TESTC

产生以下内容:

mv:0653-401 无法将/work/testrestore/production/* 重命名为/work/TESTC/*:路径名中的文件或目录不存在.

mv: 0653-401 Cannot rename /work/testrestore/production/* to /work/TESTC/*: A file or directory in the path name does not exist.

就好像 unix 现在试图移动一个名为 * 的文件,而不是使用 * 作为通配符.这是 shlex 的典型行为吗?

It's as if unix is now trying to move a file named * rather then using * as a wildcard. Is this typical behaviour of shlex?

我试过用 \ 转义 *,也试过从单引号改为双引号.

I have tried escaping the * with a \, also tried changing from single quotes to double.. not that I expected that to do anything.

推荐答案

要将 * 替换为它的含义,您要么需要 shell,要么需要 glob模块.所以最简单的方法是 shell=True(如果命令是不变的,我看不到任何安全漏洞).

For replacing the * with what it means, you either need the shell or you need the glob module. So the easiest way would be shell=True (if the command is constant, I do not see any security holes).

另一种方法是

#!/usr/bin/python
import subprocess
import shlex
import glob

cmd = 'sudo rm -rf /work/TEST/*'
arg = shlex.split(cmd)
arg = arg[:-1] + glob.glob(arg[-1])

# This should work now
p = subprocess.Popen(arg)

或者,如果您仍然要自己附加路径,

or, if you would nevertheless append the path by yourself,

cmd = 'sudo rm -rf'
basearg = shlex.split(cmd)
arg = basearg + glob.glob(path+"/*")

这篇关于通配符在使用 shlex 的子进程调用中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆