
import os
bashまたはbashfrom 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 変数を拡張する方法を説明します。
あなたがやっていることは、1つ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」に対して動作します。