Я хотел написать небольшую функцию bash, чтобы я мог сказать bash, import os
или from sys import stdout
она создаст новый интерпретатор Python с импортированным модулем.
Последняя from
функция выглядит так:
from () {
echo "from $@" | xxd
python3 -i -c "from $@"
}
Если я назову это:
$ from sys import stdout
00000000: 6672 6f6d 2073 7973 2069 6d70 6f72 7420 from sys import
00000010: 7374 646f 7574 0a stdout.
File "<string>", line 1
from sys
^
SyntaxError: invalid syntax
>>>
Байты в from sys
это
66 72 6f 6d 20 73 79 73 20
f r o m s y s
Там нет EOF, но интерпретатор Python ведет себя так, как будто читает EOF. В конце потока есть новая строка, чего и следовало ожидать.
from
Сестра, которая импортирует весь модуль Python, выглядит следующим образом и решает проблему путем очистки и обработки строки, а также из-за сбоя в несуществующих модулях.
import () {
ARGS=$@
ARGS=$(python3 -c "import re;print(', '.join(re.findall(r'([\w]+)[\s|,]*', '$ARGS')))")
echo -ne '\0x04' | python3 -i
python3 -c "import $ARGS" &> /dev/null
if [ $? != 0 ]; then
echo "sorry, junk module in list"
else
echo "imported $ARGS"
python3 -i -c "import $ARGS"
fi
}
Это решает проблему необъяснимого EOF в потоке, но я хотел бы понять, почему Python считает, что EOF существует.
strace
как всегда покажет что происходит:И в другом месте (или вы могли бы выяснить, как
strace bash ...
вызов функции):И обратно в эту первую оболочку:
А потом обратно в
strace
оболочку:Таким образом, фактический
-c
аргумент --c "from sys"
из-за того, как"$@"
раскрывается, или из-за усеченной команды, на которойpython
действует barfs.источник
$@
в двойных кавычках расширяется до списка элементов"$1" "$2" "$3"
и т. д.Python ожидает, что код будет в одном аргументе, а не в серии аргументов.
источник
Python вызывается как
(см . ответ Трига ).
Чтобы
$@
раскрыть как одну строку (при условии здравого смысла$IFS
), вы можете использовать$*
внутри двойных кавычек:Подтверждено с
strace -e execve
:источник
Strace показывает, какие аргументы используются. Но самый простой способ увидеть, что именно обрабатывается, - это добавить
printf '<%s> '
перед каждой соответствующей строкой и закрыватьecho
(генерировать как новую строку):Таким образом, функция может быть изменена на это:
И когда называется:
Понятно, что «от sys» отправляется на python как один аргумент.
Это то, что получает Python, и Python действует «от sys».
источник