Saya ingin menulis fungsi bash kecil sehingga saya dapat memberitahu bash, import os
atau from sys import stdout
dan itu akan menelurkan juru bahasa Python baru dengan modul yang diimpor.
Fungsi yang terakhir from
terlihat seperti ini:
from () {
echo "from $@" | xxd
python3 -i -c "from $@"
}
Jika saya menyebutnya:
$ 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
>>>
Bytes dalam from sys
adalah
66 72 6f 6d 20 73 79 73 20
f r o m s y s
Tidak ada EOF di sana, namun interpreter Python bersikap seolah-olah itu membaca EOF. Ada baris baru di ujung sungai, yang diharapkan.
from
Saudari kita, yang mengimpor seluruh modul Python, terlihat seperti ini, dan yang menyelesaikan masalah dengan membersihkan dan memproses string, dan dengan gagal pada modul yang tidak ada.
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
}
Itu memecahkan masalah EOF yang tidak dapat dijelaskan dalam aliran, tapi saya ingin memahami mengapa Python berpikir ada EOF.
strace
, seperti biasa, akan menunjukkan apa yang sedang terjadi:Dan, di tempat lain (atau Anda bisa mengetahui cara
strace bash ...
panggilan fungsi):Dan kembali ke shell pertama:
Dan kemudian kembali ke
strace
shell:Dengan demikian,
-c
argumen yang sebenarnya adalah-c "from sys"
karena bagaimana"$@"
diperluas, atau perintah terpotong yangpython
muntah.sumber
$@
dalam tanda kutip ganda diperluas ke daftar elemen"$1" "$2" "$3"
dll.Python mengharapkan kode berada dalam satu argumen, bukan serangkaian argumen.
sumber
Python sedang dipanggil sebagai
(lihat jawaban thrig ).
Untuk
$@
diperluas sebagai string tunggal (dengan asumsi waras$IFS
), Anda dapat menggunakan$*
di dalam tanda kutip ganda:Dikonfirmasi dengan
strace -e execve
:sumber
Strace menunjukkan argumen apa yang digunakan. Tetapi metode paling sederhana untuk melihat apa yang sedang diproses adalah menambahkan
printf '<%s> '
sebelum setiap baris yang relevan, dan penutupecho
(untuk menghasilkan sebagai baris baru):Jadi, fungsinya dapat diubah menjadi ini:
Dan ketika dipanggil:
Jelas bahwa "from sys" dikirim ke python sebagai satu argumen.
Itulah yang diterima python, dan python bekerja pada "from sys".
sumber