#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
Но:
- Я могу использовать «ls -lt —full-time /path/to/file/*DAI*.txt» и получить результат в терминале. Почему это вызывает проблему с тем же путем?
- Команда 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.