Awk в подпроцессе Python выдает недопустимые выражения «‘» ошибка

#python #bash #awk #subprocess #ls

#python #bash #awk #подпроцесс #ls

Вопрос:

Я пытаюсь прочитать имя файла и filestamp для самых последних файлов каждой из двух схем именования, как показано в коде. У меня есть следующий код, примерно:

 #!/usr/bin/env python
import string, subprocess, sys, os
mypath = "/path/to/file"


my_cmd = (["ls -lt --full-time "   mypath   "*DAI*.txt",
          "ls -lt --full-time "   mypath   "*CA*.txt"]
         )
getmostrecent_cmd = "head -n 1"
getcols_cmd = "awk '{ print $6, $7, $9 }'"

for cmd in my_cmd:
    p1 = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
    p2 = subprocess.Popen(getmostrecent_cmd.split(), stdin=p1.stdout, stdout=subprocess.PIPE)
    p3 = subprocess.Popen(getcols_cmd.split(), stdin=p2.stdout, stdout=subprocess.PIPE)
    output = p3.communicate()[0]

    print output
  

которые выдают мне следующие ошибки:

 ls: cannot access /path/to/file/*DAI*.txt: No such file or directory
awk: '{
awk: ^ invalid char ''' in expression

ls: cannot access /path/to/file/*CA*.txt: No such file or directory
awk: '{
awk: ^ invalid char ''' in expression
  

Но:

  1. Я могу использовать «ls -lt —full-time /path/to/file/*DAI*.txt» и получить результат в терминале. Почему это вызывает проблему с тем же путем?
  2. Команда awk, введенная непосредственно в подпроцесс, работает нормально; Например, подпроцесс.Popen([«awk», ….], stdin=…., stdout =….) сработал нормально. Но теперь я получаю проблему с одинарной кавычкой. Я попытался заключить строку в тройные кавычки и экранировать одинарную кавычку.

Ответ №1:

Я могу использовать «ls -lt —full-time /path /to/file/DAI.txt» и получить результат в терминале. Почему это вызывает проблему с тем же путем?

Расширение глобуса выполняется оболочкой. По умолчанию shell не участвует в запуске нового подпроцесса через Popen() . Для этого вы должны передать ему shell=True аргумент:

 p1 = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, shell=True)
#                                                          ^^^^^^^^^^
  

Команда awk, введенная непосредственно в подпроцесс, работает нормально; Например.
подпроцесс.Popen([«awk», ….], stdin=…., stdout =….) сработал нормально. Но теперь я получаю проблему с одинарной кавычкой. Я пытался
тройное взятие строки в кавычки и экранирование одинарной кавычки.

В командной строке оболочки одинарные кавычки в awk '{ print $6, $7, $9 }' необходимы для того, чтобы строка { print $6, $7, $9 } обрабатывалась как единственный аргумент (а также для предотвращения расширения переменной). Оболочка удаляет одинарные кавычки и awk видит только строку { print $6, $7, $9 } . Поскольку Popen() по умолчанию не использует shell при выполнении команды подпроцесса и передает аргументы команде дословно, вам не нужны одинарные кавычки:

 subprocess.Popen(["awk", "{ print $6, $7, $9 }"], stdin=...., stdout=....) 
  

Комментарии:

1. Спасибо, приятель. Ваш ответ на запрос 2 очень помог. Для 1 я не должен был использовать shell = True. Мой обходной путь заключался в том, чтобы указать полный путь, а затем выполнить grep для DAI и CA.