Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python bash globbing子流程_Python_Bash - Fatal编程技术网

Python bash globbing子流程

Python bash globbing子流程,python,bash,Python,Bash,如果我有一个目录,我想删除除一个文件以外的所有文件,我可以在bash中执行此操作: cd /tmp/a rm -rf !(specialfile) cd - 将其转换为最明显的Python代码对我来说是失败的: >>> subprocess.Popen( 'cd /tmp/a; rm -rf !(specialfile); cd -', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicat

如果我有一个目录,我想删除除一个文件以外的所有文件,我可以在bash中执行此操作:

cd /tmp/a
rm -rf !(specialfile)
cd -
将其转换为最明显的Python代码对我来说是失败的:

>>> subprocess.Popen( 'cd /tmp/a; rm -rf !(specialfile); cd -', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
谨此致辞:

('', "/bin/sh: -c: line 0: syntax error near unexpected token `('\n/bin/sh: -c: line 0: `cd /tmp/a; rm -rf !(specialfile); cd -'\n")
Python中第二个最好的东西似乎是:

p = '/tmp/a'
    for i in os.listdir( p ):
    if i != 'specialfile':
        os.remove( os.path.join( p, i ) )

当然,这并不能很好地处理文件和子目录。有更好的方法吗?

Update:正如@isedev和OP@JohnSchmitt在评论中指出的,
subprocess.Popen
调用
sh
,而不是
bash
(和
sh
可能是也可能不是
bash
,取决于平台),但使用扩展模式匹配操作符
!(…)
需要(a)
bash
(b)启用
extglob
选项(背景信息请参见下文)

因此,答案是:

  • 使用通过
    -c
    命令行选项传递的命令字符串显式调用
    bash
  • 通过
    -O
    命令行选项打开
    extglob
    shell选项(如果没有它,glob
    !(specialfile)
    会触发OP遇到的语法错误)
借用@JohnSchmitt自己的评论,我们得到:

subprocess.Popen("bash -O extglob -c 'cd /tmp/a; rm -rf !(file2); cd -'",
  stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
(不那么优雅的替代方法是在
rm
命令之前,将
shopt-s extglob;
添加到bash命令字符串中。)

背景


!(specialfile)
是扩展模式匹配操作符的一个实例(请参见
man bash
,部分
模式匹配
);默认情况下,这些扩展运算符未启用
shopt-s extglob
启用它们(
shopt-u extglob
禁用它们)。

更新:正如@isedev和OP@JohnSchmitt在评论中指出的那样,
子流程.Popen
调用
sh
,而不是
bash
(并且
sh
可能是也可能不是
bash
,取决于平台),但是使用扩展模式匹配操作符
!(…)
需要(a)
bash
(b)启用
extglob
选项(背景信息请参见下文)

因此,答案是:

  • 使用通过
    -c
    命令行选项传递的命令字符串显式调用
    bash
  • 通过
    -O
    命令行选项打开
    extglob
    shell选项(如果没有它,glob
    !(specialfile)
    会触发OP遇到的语法错误)
借用@JohnSchmitt自己的评论,我们得到:

subprocess.Popen("bash -O extglob -c 'cd /tmp/a; rm -rf !(file2); cd -'",
  stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
(不那么优雅的替代方法是在
rm
命令之前,将
shopt-s extglob;
添加到bash命令字符串中。)

背景


!(specialfile)
是扩展模式匹配操作符的一个实例(请参见
man bash
,部分
模式匹配
);默认情况下,这些扩展运算符未启用
shopt-s extglob
启用它们(
shopt-u extglob
禁用它们)。

更新:正如@isedev和OP@JohnSchmitt在评论中指出的那样,
子流程.Popen
调用
sh
,而不是
bash
(并且
sh
可能是也可能不是
bash
,取决于平台),但是使用扩展模式匹配操作符
!(…)
需要(a)
bash
(b)启用
extglob
选项(背景信息请参见下文)

因此,答案是:

  • 使用通过
    -c
    命令行选项传递的命令字符串显式调用
    bash
  • 通过
    -O
    命令行选项打开
    extglob
    shell选项(如果没有它,glob
    !(specialfile)
    会触发OP遇到的语法错误)
借用@JohnSchmitt自己的评论,我们得到:

subprocess.Popen("bash -O extglob -c 'cd /tmp/a; rm -rf !(file2); cd -'",
  stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
(不那么优雅的替代方法是在
rm
命令之前,将
shopt-s extglob;
添加到bash命令字符串中。)

背景


!(specialfile)
是扩展模式匹配操作符的一个实例(请参见
man bash
,部分
模式匹配
);默认情况下,这些扩展运算符未启用
shopt-s extglob
启用它们(
shopt-u extglob
禁用它们)。

更新:正如@isedev和OP@JohnSchmitt在评论中指出的那样,
子流程.Popen
调用
sh
,而不是
bash
(并且
sh
可能是也可能不是
bash
,取决于平台),但是使用扩展模式匹配操作符
!(…)
需要(a)
bash
(b)启用
extglob
选项(背景信息请参见下文)

因此,答案是:

  • 使用通过
    -c
    命令行选项传递的命令字符串显式调用
    bash
  • 通过
    -O
    命令行选项打开
    extglob
    shell选项(如果没有它,glob
    !(specialfile)
    会触发OP遇到的语法错误)
借用@JohnSchmitt自己的评论,我们得到:

subprocess.Popen("bash -O extglob -c 'cd /tmp/a; rm -rf !(file2); cd -'",
  stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
(不那么优雅的替代方法是在
rm
命令之前,将
shopt-s extglob;
添加到bash命令字符串中。)

背景


!(specialfile)
是扩展模式匹配操作符的一个实例(请参见
man bash
,部分
模式匹配
);默认情况下,这些扩展运算符未启用
shopt-s extglob
启用它们(
shopt-u extglob
禁用它们)。

您可以使用@Bakuriu提到的os.walk。非常重要的是从下到上遍历目录树,以便始终有空目录,但包含“specialfile”的目录除外。这就是为什么在
os.rmdir
命令中需要
try
子句的原因

import os
for root, dirs, files in os.walk(top, topdown=False):
    for name in files:
        if name != 'specialfile':
            os.remove(os.path.join(root, name))
    for name in dirs:
        try:
            os.rmdir(os.path.join(root, name))
        except:
            pass
你可以