2016-08-20 4 views
3

Я пытаюсь создать скрипт, который выполняет некоторый поиск grep в моих журналах и печатает результаты. Я пытаюсь использовать Посланника, потому что это проще, чем подпроцесс, но когда я выполняю команду grep, он возвращает мне ошибку такого каталога o o.grep Нет такого файла или каталога с envoy.run

реж структура легко:

  • . # Корень сценария
  • test.py файл # скрипт
  • web_logs/Журнал/# реж который содержит журнал для поиска в

Мой test.py легко:

import envoy 

def test(value): 

    search = "grep 'cv="+str(value)+"' ./web_logs/log/log_*" 
    print(search) #check of the search string 
    r = envoy.run(search) 
    print(r.status_code, r.std_out, r.std_err)#check of the command 
    response = r.std_out 

if __name__ == "__main__": 
    test(2) 

Выход является:

grep 'cv=2' ./web_logs/log/log_* 
(2, '', 'grep: ./web_logs/log/log_*: No such file or directory\n') 

Если я выполнить ту же команду:

grep 'cv=2' ./web_logs/log/log_* 

Я могу найти нахождение строки «cv = 2» в файлах журнала.

Где ошибка?

Update после ответа проблемы в использовании *, что посланник не может взорваться без использования модуля Глобы, так что я с помощью подпроцесса, как это и я стараюсь учиться лучше с помощью модуля Глобы для улучшения посланца.

Новый код я использовал:

import subprocess 

def test(value): 

    search = "grep 'cv="+str(value)+"' ./web_logs/log/log_*" 
    print(search) #check of the search string 
    proc = subprocess.check_output(search, shell=True) 
    print proc.split('\n') 

if __name__ == "__main__": 
    test(2) 
+0

Он работает, если вы измените 'c = 2' на термин, который не содержит знак равенства? Я не знаком с «посланником», так что это определенно выстрел в темноте. – tripleee

ответ

1

@baptistemm на самом деле правы в том, что, так как вы не работает Баш как часть вашего процесса универсализации не работает.

Однако то, что происходит, немного глубже.

При запуске подпроцесса это может быть сделано одной из нескольких системных служб (системных вызовов).

Короткий ответ (TLDR;)

Вот правильный способ сделать это:

import envoy 

def test(value): 

    search = "/bin/sh -c \"grep 'cv="+str(value)+"' ./web_logs/log/log_*\"" 
    print(search) #check of the search string 
    r = envoy.run(search) 
    print(r.status_code, r.std_out, r.std_err)#check of the command 
    response = r.std_out 

if __name__ == "__main__": 
    test(2) 

Выполнение команды как команды оболочки будет заботиться о подстановку.

Длинный ответ

Всякий раз, когда процесс суб выполняется, он в конце концов получает перевод в системе execve вызова (или эквивалент).

В C библиотеке вы вспомогательные функции, такие как system(3) и popen(3), которые оборачиваются вокруг execve(2), чтобы обеспечить более простые способы выполнения процессов. system запускает оболочку и передает ее аргумент как -c вариант оболочки. popen делает дополнительную магию, вроде как то, что делает посланник в python.

В посланнике аргумент анализируется на | (см. def expand_args(command):) в полевого кода. а затем использует эквивалент popen для выполнения процессов. envoy - это в основном то, что делает оболочка с маркером | (разбивает вещи на |, а затем использует popen).

Что делать, что делать, это интерпретировать *, как это делает оболочка, как при расширении его в соответствии с файлами с использованием функции glob. Бэш делает. Таким образом, мой ответ.

Веселое упражнение было бы для вас вносить код посланнику :-) и заставить его делать глобусы.

+0

Спасибо вам обоим baptistemm и @Ahmed, я выбрал Ахмеда как правого, даже другого центра, проблемы с моим кодом, я скоро обновляю свой ответ с использованием подпроцесса и после того, как я лучше изучу проблему с glob I попробуйте изменить посланника (даже последнее обновление сделано давно ...) – Smilzao

1

Почему это работает в терминале, но не посланником связан с универсализации (bash example).

При запуске в терминале

grep 'cv=2' ./web_logs/log/log_* 

Баш разбирает командную строку и заменить символ звездочки с каждым вхождением файла совпадает. Так что если у вас есть ./web_logs/log/log_1./web_logs/log/log_2 и ./web_logs/log/log_foo ваша команда будет на самом деле

grep 'cv=2' ./web_logs/log/log_1 ./web_logs/log/log_2 ./web_logs/log/log_foo 

При выполнении же в посланнику, что бы другой, он не будет выполнять globing файлов, то он будет переходить к grep файл с именем ./web_logs/log/log_*, которого не существует, это фактически подтверждается линией, вставленной в ваш вопрос.

print r.std_err 
'grep: ./web_logs/log/log_*: No such file or directory\n' 

пс: есть glob module для питона

+0

Было бы хорошо, если бы вы исправили его сценарий. –

+0

Дело в том, что его ошибка на самом деле неверна в интерпретации того, как envoy.run выполняет подпроцессы, а тот факт, что он появляется как проблема с глобализацией, является лишь побочным эффектом. –

+0

Хотя я знаю причину, в которой у меня не было решения, потому что я не знаю посланника. – baptistemm

Смежные вопросы