如何从python子进程调用LC_ALL = C排序[重复]

Posted

技术标签:

【中文标题】如何从python子进程调用LC_ALL = C排序[重复]【英文标题】:How to call LC_ALL=C sort from python subprocess [duplicate] 【发布时间】:2018-12-19 23:12:36 【问题描述】:

如何用pythonsubprocess调用LC_ALL=C sort -k1 file -o file

当我尝试时: subprocess.check_call(["LC_ALL=C sort -k1 -o ".format(file,file)])

出现以下错误: FileNotFoundError: [Errno 2] No such file or directory: 'LC_ALL=C sort -k1 file.txt -o file.txt'

【问题讨论】:

另见***.com/questions/2231227/… 【参考方案1】:

赋值是 shell 语法

当您不设置shell=True 时,没有shell,因此没有任何东西可用于解析和履行分配。


仅设置shell=True 会导致安全漏洞。

如果你的文件名中包含$(rm -rf ~),使用''.format()注入是很危险的。


因此生成一个添加了LC_ALL 的环境,其值为C

sort_env = os.environ.copy()
sort_env['LC_ALL'] = 'C'

subprocess.check_call(['sort', '-k1', file, '-o', file], env=sort_env)

或者使用shell=True,但是在带外传递参数:

当一个列表被传递给shell=True时,第一个元素被当作脚本来解释;在该脚本的上下文中,第二个为$0;第三个为$1,等等。因此:

subprocess.check_call(['LC_ALL=C sort -k1 "$1" -o "$2"', '_', file, file])

【讨论】:

【参考方案2】:

var=value command 语法是设置环境变量和运行命令的 shell 语法。 subprocess 默认情况下不提供外壳(尽管您可以使用 shell=True 获得外壳,但如果可以,您通常应该尽量避免这种情况)。在 Python 中执行此操作的方法是传入带有 env 的变量字典。

myenv = os.environ.copy()
myenv['LC_ALL'] = 'C'
subprocess.check_call(['sort', '-k1', file, '-o', file], env=myenv)

Python 完全能够在内部对一系列行进行排序;完全避免外部过程是一个更好的解决方案。

【讨论】:

感谢您指出这一点;现在编辑以复制 os.environ 这是一种比我使用的更简洁的方法;可能会采用它。 :)【参考方案3】:

将环境变量的字典作为env kwarg 传递给the subprocess invocation。

    Python 2.7.14 (default, Mar 22 2018, 14:43:05)

    In [1]: import subprocess

    In [2]: subprocess.check_call(["env"], env='LC_ALL': 'C')
    LC_ALL=C

【讨论】:

以上是关于如何从python子进程调用LC_ALL = C排序[重复]的主要内容,如果未能解决你的问题,请参考以下文章

从 django 子进程调用 python,mysql not found 错误

从 Python 调用带有“子进程”的 Java 应用程序并读取 Java 应用程序输出

在 C 编程中,如何 fork() 在子进程中运行 N 个函数调用?

使用 Python 子进程调用 cmd 并传递参数

如何使用python子进程调用在命令中使用管道[重复]

如果使用 python 和子进程从 pycharm 调用 gsutil 不起作用,“无法导入名称 _common”