2013-04-15 4 views
1

Я пытаюсь включить эту строку в скрипт python.os.system жалуется на круглые скобки

!#/bin/bash/env python 

import os 

os.system("paste <(awk '!/^($|[:space:]*#)/{print $0}' file1) <(awk '!/^($|[:space:]*#)/{print $0} file2) > out_file") 

Команда отлично работает при запуске непосредственно из bash. Тем не менее, внутри сценария, я получаю:

sh: -c: line0: syntax error near unexpected token `(' 

Проблема сохраняется при использовании просто:

os.system("paste <(cat file1) > output_file") 

Есть идеи?

+5

Похоже, что ваша оболочка по умолчанию - 'sh', а не' bash'. И обе ваши командные строки недействительны с помощью 'sh'. – abarnert

+0

@MartijnPieters: Он не использует 'subprocess', он использует' os.system'. Который в Unix-системах просто вызывает функцию libc 'system', которая использует ... ну, это зависит от вашей ОС, и мы не знаем, какую ОС использует OP. – abarnert

+0

@abarnert: верно, действительно; виноват. Затем я укажу на ['man system'] (http://linux.die.net/man/3/system), в котором говорится, что он использует'/bin/sh -c'. –

ответ

1

убить двух зайцев одним awk сценария:

awk -v DELIM=' ' '!/^($|[[:space:]]*#)/{a[FNR]=a[FNR]DELIM$0}END{for(i=1;i<=FNR;i++)print substr(a[i],2)}' file1 file2 

Это исключает необходимость замены процессов и является для них sh соответствует.

+0

Спасибо за ваше предложение, но ситуация немного сложнее: я не указываю количество файлов напрямую, но скорее они являются аргументами скрипта, например. script.py file1 file2 file3 ... Другими словами: я понятия не имею, как расширить свой пример до N файлов. Должен ли я делать это за пару раз? file1 + file2 = part1 part1 + file3 = part2 partN-1 + fileN = final? – astabada

+0

@astabada Вы просто разобрали бы список файлов после скрипта 'file1 file2 ... fileN'. Вызов 'awk' несколько раз (один раз для файла) является неправильным подходом, когда один скрипт может справиться с этим. Впоследствии это устраняет вашу оригинальную проблему. –

+0

ОК, он работает ... Еще один (и, надеюсь,) вопрос. Знаете ли вы о каком-либо всеобъемлющем месте, где нужно понимать команду? man awk не кажется достаточным. – astabada

4

Команда отлично работает при запуске непосредственно из bash. Тем не менее, внутри сценария, я получаю:

sh: -c: line0: syntax error near unexpected token `(' 

Это потому, что внутри скрипта, вы запускаете команду с sh, а не bash. И эта команда, и более простая, используют bash -специальные функции. Попробуйте запустить оболочку sh и введите те же строки, и вы получите ту же ошибку.

os.system вызов не документ, что оболочка использует, потому что:

посредством вызова функции Standard C system()

На большинстве Unix-подобных систем, это вызывает sh. Вы, вероятно, не должны полагаться на это ... но вы определенно не должны полагаться на него, звоня по телефону bash!

Если вы хотите запустить bash команды, используйте subprocess модуль и запустить bash явно:

subprocess.call(['bash', '-c', 'paste <(cat file1) > output_file']) 

Вы могли бы, я полагаю, попытаться получить квотирование право запускать bash как субоболочке внутри оболочки system использует ... но зачем беспокоиться?

Это одна из многих причин, по которой в документации неоднократно указывается, что вы должны использовать subprocess вместо os.system.

+0

И вы должны добавить, что для запуска команды в' bash' вы можете используйте подпроцесс, как в [этом ответе] (http://stackoverflow.com/a/4256153/418609). – adrianp

+0

@adrianp: этот ответ не показывает, как использовать 'bash' явно; он показывает, как запускать команду 'cwm' без использования оболочки, чего не хочет OP. – abarnert