Пользовательский ввод в subprocess.call
Я пишу программу для автоматизации некоторых команд qiime2. Я хочу включить пользовательский ввод.
Пока что у меня есть:
# Items to import
import subprocess
from sys import argv
#Variables
format=argv[1]
# Import sequences for Phred33 format
if format=='Phred33':
cmnd = 'qiime tools import --type SampleData[PairedEndSequencesWithQuality] --input-path manifest.csv --output-path paired-end-demux.qza --source-format PairedEndFastqManifestPhred33'
print('executing {}'.format(cmnd))
res = subprocess.call(cmnd, shell=True)
print('command terminated with status', res)
# Import sequences for Phred64 format
if format=='Phred64':
cmnd = 'qiime tools import --type SampleData[PairedEndSequencesWithQuality] --input-path manifest.csv --output-path paired-end-demux.qza --source-format PairedEndFastqManifestPhred64'
print('executing {}'.format(cmnd))
res = subprocess.call(cmnd, shell=True)
print('command terminated with status', res)
Это прекрасно работает, так как есть только два возможных пользовательских ввода, но я бы предпочел, чтобы операторы if не были включены, когда будет множество возможных пользовательских вводов.
Это было бы лучше:
cmnd = 'qiime tools import --type SampleData[PairedEndSequencesWithQuality] --input-path manifest.csv --output-path paired-end-demux.qza --source-format PairedEndFastqManifest', format
Но qiime2 дает мне ошибки с этим. Есть ли другой способ?
Спасибо!
1 ответ
Решение
Не использовать shell=True
когда команда, которую вы выполняете, построена из неанизированного пользовательского ввода. Это может привести к тому, что пользователь сможет выполнять произвольные команды, даже если это нежелательно.
Также передайте команду в виде списка subprocess.call
чтобы избежать проблем с цитированием.
cmnd = [
'qiime', 'tools', 'import',
'--type', 'SampleData[PairedEndSequencesWithQuality]',
'--input-path', 'manifest.csv',
'--output-path', 'paired-end-demux.qza',
'--source-format', 'PairedEndFastq{}'.format(format)
]
print('executing {}'.format(' '.join(cmnd)))
res = subprocess.call(cmnd)