Подпроцесс Python не работает должным образом для команды поиска - PullRequest
0 голосов
/ 11 февраля 2019

Я пытаюсь найти потерянные файлы на узле в python.Ниже приведен фрагмент кода

#!/usr/bin/python
import subprocess
try:
        s = subprocess.check_output(["find", "/", "-fstype", "proc", "-prune", "-o", "\( -nouser -o -nogroup \)", "-print"])
except subprocess.CalledProcessError as e:
    print e.output
else:
    if len(s) > 0:
        print ("List of Orphan Files are \n%s\n" % s)
    else:
        print ("Orphan Files does not Exists on the NE")

Когда я пытаюсь запустить этот код Python

> python test.py 
find: paths must precede expression: \( -nouser -o -nogroup \)
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]

Когда я запускаю ту же команду на CLI, она работает нормально.

> find / -fstype proc -prune -o \( -nouser -o -nogroup \) -print
/root/a

Мало кто из вас предложил использовать shell = true, согласно документации по питону для подпроцесса это угроза безопасности.Warning Using shell=True can be a security hazard.

Ответы [ 5 ]

0 голосов
/ 11 февраля 2019

Я попробовал ваш скрипт и получил ту же ошибку, что и вы.Я пробовал разные вещи и нашел то, что мне помогло.Я изменил

-print

на

-exec

, и это сработало.Но я не уверен, почему это было поведение.

0 голосов
/ 11 февраля 2019

Вы можете установить опцию shell=True, а затем просто передать всю команду оболочки.Я думаю, что пробел вызывает проблему.

s = subprocess.check_output("find / -fstype proc -prune -o \( -nouser -o -nogroup \) -print", shell=True)

Примечание это предупреждение , касающееся настройки shell=True.По сути, не делайте этого, если входные данные поступают из внешнего источника (например, пользовательского ввода).В этом случае все должно быть хорошо.

0 голосов
/ 11 февраля 2019

Каждый параметр командной строки должен передаваться как отдельный элемент списка, включая скобки и их содержимое:

s = subprocess.check_output(["find", "/", "-fstype", "proc", "-prune", "-o",
                            "(", "-nouser", "-o", "-nogroup", ")", 
                            "-print"])
0 голосов
/ 11 февраля 2019

Вы должны разделить команду на каждый пробел.Самый простой способ сделать это с помощью shlex.split:

import shlex
import subprocess

cmd = shlex.split('find / -fstype proc -prune -o \( -nouser -o -nogroup \) -print')
subprocess.check_output(cmd)
0 голосов
/ 11 февраля 2019

Просто добавьте shell = True в ваш check_output

s = subprocess.check_output(["find", "/", "-fstype", "proc", "-prune", "-o", "\( -nouser -o -nogroup \)", "-print"], shell=True)
...