-1

I am calling this perl script from http://www.linguistics.ruhr-uni-bochum.de/~dipper/software/tokenize.perl where given an input file, it gives outputs a file in another format.

But when the perl script gives a shell error through python's os.system(), how can I catch the error? Is there a way to do try-except to catch the error from shell when i call a unix command from os.system()?

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)

The second sentence would have got the error following error at os.ystem():

sh: 1: Syntax error: Unterminated quoted string

I've tried:

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)

but noerrror == 0 although it gives the sh: 1: Syntax error: Unterminated quoted string error.

After some tries, i realize that the following echo command don't even work on the unix terminal:

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."""
alvas
  • 115,346
  • 109
  • 446
  • 738
  • 2
    You can capture the return value of os.system. That gives an indication whether the command executed finished successfully (return 0 in Unix) or not. – marekful Nov 06 '13 at 14:10
  • does it return an `int(0)` or a `str(0)`. I tried checking for both it didn't catch the sh error. – alvas Nov 06 '13 at 14:13
  • Readin about os.system (http://docs.python.org/2/library/os#os.system) it seems you may need to combine it with os.wait since os.system is executed in a subshell. (The main execution thread doesn't wait for its completation?) – marekful Nov 06 '13 at 14:18
  • May I suggest to tackle your problem a different way? I'm sure whatever that perl stuff does can better be done within Python alone. Maybe you want to tell us what the goal to achieve in the end is. – Alfe Nov 06 '13 at 14:22
  • @Alfe, it's german sentence tokenization. It's no easy feat, even with NLTK and its extension, it's not doing as well as what this rule based perl script does =) – alvas Nov 06 '13 at 14:26
  • 2
    Then for christ's sake please at least use decent Python for writing that stuff into the temp file: `with open('tmp.in', 'w') as tmpfile:` `tmpfile.write(text)` – Alfe Nov 06 '13 at 14:30
  • your sentence is too long for a question. please reduce the amount of code/data to the minimum that reproduce the behavior. – njzk2 Nov 06 '13 at 14:31
  • the short sentences has no problem, it is the long sentence2 that created the error. I've tried to echo sentence2 but it didn't work even in the terminal =) – alvas Nov 06 '13 at 14:32

2 Answers2

2

A call to os.system("your command") returns a unix status code.

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

Edit: os.system is a bit old and out of date and it's recommended that you use the subprocess module instead. See http://docs.python.org/2/library/subprocess.html#module-subprocess

wdh
  • 1,612
  • 12
  • 16
  • I've tried this but it didn't work. The unix command returns a `0` and also the `syntax error` – alvas Nov 06 '13 at 14:19
  • Opps, my bad, got confused with something else. I've amended the answer. – wdh Nov 06 '13 at 14:19
  • the updated code still doesn't work ;P `pid, code = os.system("your command")` returns `TypeError: 'int' object is not iterable` – alvas Nov 06 '13 at 14:21
  • Sorry, I was thinking of os.wait(). Let's try changing tact with this, if you manually run your command and then run echo $? afterwards, what do you get? – wdh Nov 06 '13 at 14:25
  • interesting, i can't even echo the sentence2. – alvas Nov 06 '13 at 14:29
  • What are you typing into your shell to make it fail? – wdh Nov 06 '13 at 14:33
  • i've added the failling echo to the main question – alvas Nov 06 '13 at 14:36
1

bash doesn't play nice with Germen encoding out of the box. Try something like

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 
wdh
  • 1,612
  • 12
  • 16
  • actually you can echo triple quotes. but you and alfe was right to write file using python instead of echo. the error occurs because of an encoding issue. – alvas Nov 06 '13 at 14:44