【问题标题】:Detecting shell error in python when using os.sytem()?使用 os.system() 时在 python 中检测 shell 错误?
【发布时间】:2013-11-06 14:07:04
【问题描述】:

我从http://www.linguistics.ruhr-uni-bochum.de/~dipper/software/tokenize.perl 调用这个perl 脚本,在给定输入文件的地方,它会输出另一种格式的文件。

但是当 perl 脚本通过 python 的os.system() 给出 shell 错误时,我怎样才能捕捉到错误?当我从 os.system() 调用 unix 命令时,有没有办法尝试从 shell 捕获错误?

def rb_tokenize(text):
  os.system("echo '''"+text+"'''> tmp.in")
  os.system("perl rbtokenize.pl tmp.in tmp.out")
  return " ".join([i.strip() for i in codecs.open("tmp.out","r","utf8").readlines()])

sentence1 = """Ich bin schwanger."""

sentence2 = """Herr Präsident! Ich freue mich, in der Aussprache über diesen Bericht das Wort zu ergreifen und Frau Theato zu beglückwünschen. Ich halte dies für einen Bericht, bei dem die Zusammenarbeit zwischen den Ausschüssen sehr gut funktioniert hat, und das Ergebnis, das uns heute vorliegt, ist ein nüchterner, sachlicher Bericht auf einem besonders delikaten Gebiet. Nüchternheit und Sachlichkeit, die folglich bei der Entwicklung des Artikels 280.4 besonders notwendig sind. Denn wenn wir einen Preis für den Artikel vergeben müßten, der am schwersten verständlich, am wenigsten eindeutig, am unklarsten ist - wie Sie es auch bezeichnen wollen -, dann gäbe es sicher einen harten Wettstreit, weil der Vertrag eine Musterkollektion von komplizierten Artikeln ist, aber dieser ist ohne Zweifel einer der aussichtsreichsten Anwärter auf diesen Preis. Gleichzeitig ist es eine besonders delikate Frage, weil sie den Schutz der finanziellen Interessen der Gemeinschaft betrifft, wie Frau Theato sehr richtig gesagt hat. Wir sind uns alle der Notwendigkeit bewußt - und dieses Parlament hat diese Sorge aufgeworfen bzw. ist ein großer Vorkämpfer in dieser Sache gewesen -, die finanziellen Interessen der Gemeinschaft zu schützen. Aber Vorsicht, wie die Franzosen sagen, "ne jettons pas le bébé avec l'eau du bain ", man darf das Kind nicht mit dem Bade ausschütten, das heißt, beim Schutz der finanziellen Interessen der Gemeinschaft sind einerseits - und Frau Theato hat es gesagt - die Zuständigkeiten der Nationalstaaten zu respektieren, aber auch andere Dinge, die die Bürger angehen, die die wesentlichen Garantien betreffen. Durch die Schlußfolgerungen des Berichts Theato werden sie uneingeschränkt bewahrt. Deshalb hoffe ich in meiner Eigenschaft als Vorsitzende des Ausschusses für Recht und Binnenmarkt und selbstverständlich auch in meiner Eigenschaft als Abgeordnete, daß dieses Parlament morgen mit einer breiten Mehrheit den Bericht unterstützt und daß er durch die Kommission eine gute Umsetzung erfährt."""

# This gives a correct string output.
rb_tokenize(sentence1) 

# Wrong output
# The perl script gives an error and the new tmp.out 
# isn't updated and it gives the output from sentence1
rb_tokenize(sentence2)

第二句会在os.ystem()处出现错误:

sh: 1: Syntax error: Unterminated quoted string

我试过了:

def rb_tokenize(text):
  os.system("echo '''"+text+"'''> tmp.in")
  noerror = os.system("perl rbtokenize.pl tmp.in tmp.out")
  print noerror
  return " ".join([i.strip() for i in codecs.open("tmp.out","r","utf8").readlines()])

rb_tokenize(sentence2)

但是noerrror == 0 尽管它给出了sh: 1: Syntax error: Unterminated quoted string 错误。

经过一些尝试,我意识到以下 echo 命令甚至在 unix 终端上都不起作用:

echo """Herr Präsident! Ich freue mich, in der Aussprache über diesen Bericht das Wort zu ergreifen und Frau Theato zu beglückwünschen. Ich halte dies für einen Bericht, bei dem die Zusammenarbeit zwischen den Ausschüssen sehr gut funktioniert hat, und das Ergebnis, das uns heute vorliegt, ist ein nüchterner, sachlicher Bericht auf einem besonders delikaten Gebiet. Nüchternheit und Sachlichkeit, die folglich bei der Entwicklung des Artikels 280.4 besonders notwendig sind. Denn wenn wir einen Preis für den Artikel vergeben müßten, der am schwersten verständlich, am wenigsten eindeutig, am unklarsten ist - wie Sie es auch bezeichnen wollen -, dann gäbe es sicher einen harten Wettstreit, weil der Vertrag eine Musterkollektion von komplizierten Artikeln ist, aber dieser ist ohne Zweifel einer der aussichtsreichsten Anwärter auf diesen Preis. Gleichzeitig ist es eine besonders delikate Frage, weil sie den Schutz der finanziellen Interessen der Gemeinschaft betrifft, wie Frau Theato sehr richtig gesagt hat. Wir sind uns alle der Notwendigkeit bewußt - und dieses Parlament hat diese Sorge aufgeworfen bzw. ist ein großer Vorkämpfer in dieser Sache gewesen -, die finanziellen Interessen der Gemeinschaft zu schützen. Aber Vorsicht, wie die Franzosen sagen, "ne jettons pas le bébé avec l'eau du bain ", man darf das Kind nicht mit dem Bade ausschütten, das heißt, beim Schutz der finanziellen Interessen der Gemeinschaft sind einerseits - und Frau Theato hat es gesagt - die Zuständigkeiten der Nationalstaaten zu respektieren, aber auch andere Dinge, die die Bürger angehen, die die wesentlichen Garantien betreffen. Durch die Schlußfolgerungen des Berichts Theato werden sie uneingeschränkt bewahrt. Deshalb hoffe ich in meiner Eigenschaft als Vorsitzende des Ausschusses für Recht und Binnenmarkt und selbstverständlich auch in meiner Eigenschaft als Abgeordnete, daß dieses Parlament morgen mit einer breiten Mehrheit den Bericht unterstützt und daß er durch die Kommission eine gute Umsetzung erfährt."""

【问题讨论】:

  • 可以抓取os.system的返回值。这表明执行的命令是否成功完成(在 Unix 中返回 0)。
  • 它是否返回int(0)str(0)。我尝试检查两者都没有发现 sh 错误。
  • 阅读 os.system (docs.python.org/2/library/os#os.system) 似乎您可能需要将它与 os.wait 结合起来,因为 os.system 是在子 shell 中执行的。 (主执行线程不等待其完成?)
  • 我可以建议以不同的方式解决您的问题吗?我确信无论 perl 的东西做什么,都可以单独在 Python 中更好地完成。也许你想告诉我们最终要达到的目标是什么。
  • 那么看在上帝的份上,请至少使用像样的 Python 将这些内容写入临时文件:with open('tmp.in', 'w') as tmpfile:tmpfile.write(text)

标签: python shell nlp os.system


【解决方案1】:

os.system("your command") 的调用会返回一个unix 状态码。

code = os.system("your command")
if code == 0:
    print "Success! :)"
else:
    print "Fail! :("

编辑:os.system 有点老旧,建议您改用 subprocess 模块。见http://docs.python.org/2/library/subprocess.html#module-subprocess

【讨论】:

  • 我试过了,但没有用。 unix 命令返回 0syntax error
  • Opps,我的错,与别的东西混淆了。我已经修改了答案。
  • 更新后的代码还是不行;Ppid, code = os.system("your command")返回TypeError: 'int' object is not iterable
  • 对不起,我在想 os.wait()。如果您手动运行命令然后运行 ​​echo $?之后,你得到了什么?
  • 有趣,我什至无法呼应这句话2。
【解决方案2】:

bash 不能很好地与开箱即用的德语编码配合使用。尝试类似

fil = open('path/to/file.txt','w')
fil.write(text)
fil.close()
code = os.system("perl rbtokenize.pl path/to/file.txt tmp.out")
if code == 0:
    return ... #Success

# Failed
raise SomethingSensible 

【讨论】:

  • 实际上你可以回显三引号。但是您和 alfe 使用 python 而不是 echo 编写文件是正确的。由于编码问题而发生错误。
猜你喜欢
  • 2017-11-29
  • 2013-02-20
  • 1970-01-01
  • 1970-01-01
  • 2013-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-07
相关资源
最近更新 更多