import os
bash 나 bash from sys import stdout
에게 새로운 Python 인터프리터를 생성하고 모듈을 가져오도록 지시할 수 있도록 작은 bash 함수를 작성하고 싶습니다 .
후자의 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가 있다고 생각하는 이유를 이해하고 싶습니다.
답변1
테이블은 안에 있어요이 스택 오버플로 답변(이것은배쉬 해커 위키) 다양한 Bash 변수를 확장하는 방법을 설명합니다.
당신이 하고 있는 일은 python -i -c "from $@"
가 되고 하나의 인수만 허용 python -i -c "from sys" "import" "stdout"
하므로 -c
명령을 실행합니다 from sys
. 을 사용하려고 하면 $*
다음으로 확장됩니다 python -i -c "from sys import stdout"
( $IFS
설정되지 않았거나 공백으로 시작한다고 가정).
답변2
strace
언제나 그렇듯, 무슨 일이 일어나고 있는지 표시됩니다:
bash-4.1$ echo $$
3458
strace bash ...
그리고 다른 곳에서는(또는 함수를 호출하는 방법을 알아낼 수 있습니다 ):
bash-4.1$ strace -ff -o blah -p 3458
첫 번째 셸로 돌아가서:
bash-4.1$ from sys import stdout
File "<string>", line 1
from sys
^
SyntaxError: invalid syntax
>>>
bash-4.1$
strace
그런 다음 셸로 돌아갑니다 .
Process 3458 attached
Process 25224 attached
^CProcess 3458 detached
bash-4.1$ grep exec blah.*
blah.25224:execve("/usr/bin/python", ["python", "-i", "-c", "from sys", "import", "stdout"], [/* 54 vars */]) = 0
따라서 실제 -c
논쟁은 확장 -c "from sys"
방법에 대한 것 입니다 . "$@"
아니면 잘린 명령입니까?python
답변3
$@
요소 목록 "$1" "$2" "$3"
등 으로 큰따옴표로 확장됩니다.
#!/bin/bash
expand () {
for string in "from $@" ; do
echo "$string"
done
}
expand sys import stdout
Python에서는 코드가 일련의 매개변수가 아닌 매개변수에 있을 것으로 예상합니다.
답변4
Strace는 사용된 매개변수를 표시합니다. 그러나 처리 중인 내용을 확인하는 가장 쉬운 방법은 printf '<%s> '
각 관련 줄 앞에 종결자를 추가하는 것 입니다 echo
(새 줄을 생성하기 위해).
따라서 이 기능은 다음과 같이 변경될 수 있습니다.
from () {
printf '<%s> ' "from $@"; echo
printf '<%s> ' python3 -i -c "from $@"; echo
}
호출 시:
$ from sys import stdout
<from sys> <import> <stdout>
<python3> <-i> <-c> <from sys> <import> <stdout>
분명히 "from sys"는 Python에 매개변수로 전송됩니다.
이것이 Python이 수신하는 것이며 Python은 "from sys"에 대해 작동합니다.