У меня есть сценарий bash, который вызывает скрипт python с параметрами. В сценарии bash я читаю файл, содержащий одну строку параметров, разделенных символом ", а затем вызывает скрипт python с прочитанной строкой. Моя проблема заключается в том, что python получает параметры, разделенные пробелом.
Строка выглядит так: "param_a" "Параметр B" "Параметр C" Пример кода:
Bash Script:
LINE='cat $tmp_file'
id='python /full_path/script.py $LINE'
Python Script:
print sys.argv[1]
print sys.argv[2]
print sys.argv[3]
Полученный вывод:
"param_a"
"Param
B"
Требуемый результат:
param_a
Param B
Param C
Как я могу отправить параметры в сценарий Python так, как мне нужно? Спасибо!
Это можно сделать с помощью массивов bash
:
tmp_file='gash.txt'
# Set IFS to " which splits on double quotes and removes them
# Using read is preferable to using the external program cat
# read -a reads into the array called "line"
# UPPERCASE variable names are discouraged because of collisions with bash variables
IFS=\" read -ra line < "$tmp_file"
# That leaves blank and space elements in "line",
# we create a new array called "params" without those elements
declare -a params
for((i=0; i < ${#line[@]}; i++))
do
p="${line[i]}"
if [[ -n "$p" && "$p" != " " ]]
then
params+=("$p")
fi
done
# 'backticks' are frowned upon because of poor readability
# I've called the python script "gash.py"
id=$(python ./gash.py "${params[@]}")
echo "$id"
gash.py
:
import sys
print "1",sys.argv[1]
print "2",sys.argv[2]
print "3",sys.argv[3]
дает:
1 param_a
2 Param B
3 Param C
Проблема заключается в том, как bash передает аргументы. Python с этим ничего не поделаешь.
Итак, вы должны решить все эти вещи перед отправкой на Python, я решил использовать awk и xargs для этого. (но xargs является фактическим MVP здесь.)
LINE=$(cat $tmp_file)
awk -v ORS="\0" -v FPAT='"[^"]+"' '{for (i=1;i<=NF;i++){print substr($i,2,length($i)-2)}}' <<<$LINE |
xargs -0 python ./script.py
Первый $ (..) является предпочтительным по сравнению с backticks, потому что он более читабельен. В конце концов, вы делаете переменную.
awk
только читает из stdin или файла, но вы можете заставить его читать из переменной с помощью <<<, также называемой "здесь строка".
С awk
я перебираю все поля (как определено регулярным выражением в переменной FPAT) и печатаю их без знака "".
Селектор выходной записи, который я выбираю, является символом NULL (-v ORF = '\ 0'), xargs будет разделяться на этот символ.
xargs
теперь проанализирует входной xargs
, разделив аргументы на NULL-символы (заданные с помощью -0) и выполнив команду, заданную с помощью проанализированных аргументов.
Обратите внимание, что awk встречается в большинстве систем UNIX, я использую FPAT, который является расширением GNU awk, и у вас может не быть GNU awk по умолчанию (например, Ubuntu), но gnu awk обычно является просто install gawk
.
Кроме того, следующая команда будет быстрым и простым решением, но обычно считается небезопасной, поскольку eval
будет выполнять все, что получает.
eval "python ./script "$LINE
Как насчет
id='python /full_path/script.py $tmp_file'
а также
import sys
for line in open(sys.argv[1]):
print(line)
?
sys.argv
, чтобы проверить, является ли он> 1, или даже предложить пользователю войти, используя raw_input()
(так как вы, кажется, используете старый python 2) ).
$tmp_file
не разграничены должным образом, оболочка разделяет параметры, python не имеет к этому никакого отношения. Можете ли вы показать точное содержимое$tmp_file
$tmp_file
(путь) в python, а затем открыть и проанализировать файл оттуда?