【问题标题】:How to call LC_ALL=C sort from python subprocess [duplicate]如何从python子进程调用LC_ALL = C排序[重复]
【发布时间】: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'

【问题讨论】:

标签: python sorting subprocess


【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2012-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多