вызвать командную строку из скрипта, используя python, ОС Ubuntu - PullRequest
0 голосов
/ 06 мая 2020

У меня возникли трудности с вызовом командной строки из моего скрипта. Я запускаю скрипт, но не получаю никакого результата. Через эту командную строку в моем скрипте я хочу запустить инструмент, который создает папку с файлами вывода для каждой строки. Путь ввода уже определен. Не могли бы вы мне помочь?

for line in inputFile:
cmd = 'python3 CRISPRcasIdentifier.py -f %s/%s.fasta -o %s/%s.csv -st dna -co %s/'%(inputpath,line.strip(),outputfolder,line.strip(),outputfolder)
os.system(cmd)

Ответы [ 3 ]

1 голос
/ 06 мая 2020

Вы действительно хотите использовать Python стандартный библиотечный модуль подпроцесс . Используя функции из этого модуля, вы можете построить свою командную строку как список строк, и каждая из них будет обрабатываться как одно имя файла, параметр или значение. Это обходит экранирование оболочки и избавляет от необходимости массировать аргументы сценария перед вызовом.

Кроме того, ваш код не будет работать, потому что блок тела оператора for не имеет отступа. Python просто не примет этот код (возможно, вы вставили его в вопрос без соответствующих отступов).

0 голосов
/ 06 мая 2020

Я обычно так делаю для stati c command

from subprocess import check_output

def sh(command):
    return check_output(command, shell=True, universal_newlines=True)

output = sh('echo hello world | sed s/h/H/')

НО ЭТО НЕ БЕЗОПАСНО !!! Вы должны сделать инъекцию оболочки

from subprocess import check_output
from shlex import split

def sh(command):
    return check_output(split(command), universal_newlines=True)

output = sh('echo hello world')

Разница небольшая, но важная. shell = True создаст новую оболочку, поэтому трубы et c будут работать. Я использую это, когда у меня есть большая командная строка с конвейерами, и это stati c, я имею в виду, это не зависит от ввода пользователя. Это связано с тем, что в этом варианте возможна инъекция оболочки, пользователь может ввести something; rm -rf /, и он будет запущен.

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

universal_newlines=True предназначен для вывода в виде строки, а не байтов. Используйте его для вывода текста, если вам нужен двоичный вывод, просто опустите его. По умолчанию - false.

Итак, вот полный пример

from subprocess import check_output
from shlex import split

def sh(command):
    return check_output(split(command), universal_newlines=True)

for line in inputFile:
    cmd = 'python3 CRISPRcasIdentifier.py -f %s/%s.fasta -o %s/%s.csv -st dna -co %s/'%(inputpath,line.strip(),outputfolder,line.strip(),outputfolder)
    sh(cmd)

Ps: Я не тестировал это

0 голосов
/ 06 мая 2020

как упоминалось ранее, выполнение команды vias: os.system (command) не рекомендуется. используйте подпроцесс (читайте в python документации об этом модуле subprocess_module_docs ). см. код здесь:

for command in input_file:
    p = subprocess.Popen(command, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
    # use this if you want to communicate with child process
    # p = subprocess.Popen(command, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
    p.communicate()
    # --- do the rest
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...