【问题标题】:Taking Linux Command as Raw String in Python在 Python 中将 Linux 命令作为原始字符串
【发布时间】:2014-04-09 10:21:47
【问题描述】:

)我已经确认我的 Linux 命令可以在终端中运行,但是当我尝试从 python 调用它时它会中断。

该命令有点长并且有很多单引号,所以我将它包裹在三个双引号 (""") 中,以便 python 可以解释为原始字符串(或者我认为是这样)。但是,当我运行它时我得到了

sh: -c: line 0: unexpected EOF while looking for matching `''
sh: -c: line 1: syntax error: unexpected end of file 

但是我已经两次和三次检查了我的单引号和双引号,我不知道从这里去哪里。

查看下面的测试脚本

import os

os.system("""awk -F ' *[[:alnum:]_]*: *' 'BEGIN         {h="insert_job;box_name;command;owner;permission;condition;description;std_out_file;std_err_file;alarm_if_fail"; print h; n=split(h,F,/;/)} function pr() {if(F[1] in A) {for(i=1;i<=n;i++)printf "%s%s",A[F[i]],(i<n)?";":RS}} /insert_job/  {pr(); delete A} {for(i in F){if($0~"^"F[i])A[F[i]]=$2}} END           {pr()}' ./output/JILS/B7443_dev_jil_20140306104313.csv > /trvapps/autosys/admin/EPS/output/JILS/testout.txt""")

仅供参考,我使用的是 Python 2.4.3,因此我使用的是 os 而不是子进程。

【问题讨论】:

  • 你没有关闭(是一个错字?
  • """ 将使其成为字符串,但不是原始字符串。 r""" 会变成 a raw string
  • 阿不思,一个错字。已修复,谢谢。
  • os.system() 已被弃用,取而代之的是 subprocess 模块中的工具。即使您打算为此使用 awk,subprocess.Popen(['awk', '-F', awk_script], stdout=open('testout.txt', 'w')) 也将是正确的选择——这将避免 sh -c 出现此错误,因为使用带有数组的 subprocess.Popen() 而没有 @987654332 @ 标志根本不涉及 sh 实例。
  • @Matt,回复:您最近的编辑,子进程模块在 Python 2.4.3 中可用。

标签: python linux string bash


【解决方案1】:

为了您自己的理智,请尝试使用pipes.quote(或类似的东西,如果它在 2.4 中不存在)、' '.join(words)'\n'.join(lines) 以便能够构建命令而不是使用单个复杂字符串,如果你必须把它放在 Python 中。更好的解决方案是调用像 @kojiro suggested 这样的脚本。

看起来您正在做一些简单的 CSV 处理。检查 SO 以获取有关在 Python 中执行此操作的提示如何?

无论如何,一行 400 多个字符的 awk 足以让任何人感到不安,而在已经具有出色字符串处理功能的 Python 中这样做只是将痛苦传递给下一个开发人员。这会很生气。

【讨论】:

  • 或者,你知道,将模板化的 shell 脚本放在一个单独的文件中。
  • +1 建议使用纯 Python。使用 subprocess 访问现有的非 Python 代码,而不是在脚本中嵌入其他语言。
【解决方案2】:

将 awk 脚本塞进一大行是很糟糕的,并且几乎无法阅读和维护。不要那样做——如果你真的必须使用 awk(一个可疑的声明),把它写成多行,并带有适当的缩进,就像你使用任何其他脚本一样。

要修复sh -c 解释错误的错误,请使用subprocess 模块(传递参数数组和not 设置shell=True)而不是os.system()

import subprocess

awk_script = r'''
*[[:alnum:]_]*: *

BEGIN {
   h="insert_job;box_name;command;owner;permission;condition;description;std_out_file;std_err_file;alarm_if_fail";
   print h;
   n=split(h,F,/;/)
}

function pr() {
  if(F[1] in A) {
    for(i=1;i<=n;i++)
      printf "%s%s", A[F[i]], (i<n) ? ";" : RS
  }
}

/insert_job/ {
  pr();
  delete A;
}

{
  for(i in F) {
    if($0~"^"F[i])
      A[F[i]]=$2
  }
}

END {pr()}
'''

exit_status = subprocess.call(['awk', '-F', awk_script],
  stdin=open('./output/JILS/B7443_dev_jil_20140306104313.csv', 'r'),
  stdout=open('/trvapps/autosys/admin/EPS/output/JILS/testout.txt', 'w'))
if exit_status != 0:
  raise RuntimeException('awk failed')

【讨论】:

  • 谢谢查尔斯。我尝试运行该测试,尽管当只有 36 行时脚本在“37”行出错。在您的答案中打开文件后,可能需要关闭文件?
  • @matt,不,文件不需要明确关闭。我在这里看到的唯一明显的错误是末尾缺少关闭括号,现在已修复。
  • @Matt,顺便说一句,“错误输出”不是一个非常有用的描述,没有任何关于存在问题的错误的任何信息。今后,请尽量做到更具描述性。
  • 感谢您的帮助,查尔斯。但是,正如我在我的 OP 子流程中所述,我的 python 版本(2.4.3)不支持。所以,我需要我们的操作系统。
  • @Matt,这是不正确的; subprocess 模块是在 Python 2.4 中引入的,并且肯定存在于 2.4.3 中。此外,对于您最近编辑的内容,使用“已声明”这个词有些误导。
猜你喜欢
  • 2010-10-05
  • 1970-01-01
  • 2011-05-23
  • 2020-07-12
  • 2021-10-22
  • 2021-05-21
  • 2022-01-19
  • 2014-08-19
  • 1970-01-01
相关资源
最近更新 更多