Отправить параметры в Python из Bash

1

У меня есть сценарий 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 так, как мне нужно? Спасибо!

  • 3
    no не может сделать, поскольку параметры в $tmp_file не разграничены должным образом, оболочка разделяет параметры, python не имеет к этому никакого отношения. Можете ли вы показать точное содержимое $tmp_file
  • 3
    Почему бы не передать $tmp_file (путь) в python, а затем открыть и проанализировать файл оттуда?
Теги:
split
parameters

3 ответа

1

Это можно сделать с помощью массивов 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
1

Проблема заключается в том, как 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
1

Как насчет

id='python /full_path/script.py $tmp_file'

а также

import sys
for line in open(sys.argv[1]):
    print(line)

?

  • 0
    Привет, спасибо за совет - но скрипт python должен запускаться и вручную, то есть ему нужно получить 3 параметра ...
  • 0
    @Bramat - было бы довольно легко изменить это, чтобы проверить длину sys.argv , чтобы проверить, является ли он> 1, или даже предложить пользователю войти, используя raw_input() (так как вы, кажется, используете старый python 2) ).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню