Ich wollte eine kleine Bash-Funktion schreiben, die Bash erkennt import os
oder from sys import stdout
einen neuen Python-Interpreter mit dem importierten Modul erzeugt.
Die letztere from
Funktion sieht folgendermaßen aus:
from () {
echo "from $@" | xxd
python3 -i -c "from $@"
}
Wenn ich das nenne:
$ 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
>>>
Die Bytes in from sys
sind
66 72 6f 6d 20 73 79 73 20
f r o m s y s
Es gibt kein EOF, aber der Python-Interpreter verhält sich so, als würde er EOF lesen. Es gibt eine neue Zeile am Ende des Streams, was zu erwarten ist.
from
Die Schwester von Python, die ein ganzes Python-Modul importiert, sieht so aus und löst das Problem, indem sie die Zeichenfolge bereinigt und verarbeitet und bei nicht vorhandenen Modulen Fehler verursacht.
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
}
Das löst das Problem eines ungeklärten EOF im Stream, aber ich würde gerne verstehen, warum Python denkt, dass es einen EOF gibt.
strace
wird wie immer zeigen, was los ist:Und an anderer Stelle (oder Sie könnten herausfinden, wie
strace bash ...
der Funktionsaufruf funktioniert):Und zurück in dieser ersten Schale:
Und dann zurück in die
strace
Schale:Das eigentliche
-c
Argument liegt also-c "from sys"
daran, wie der"$@"
Befehl erweitert oder abgeschnitten wirdpython
.quelle
$@
in doppelten Anführungszeichen wird zu einer Liste von Elementen"$1" "$2" "$3"
usw. erweitert.Python erwartet, dass sich der Code in einem Argument befindet, nicht in einer Reihe von Argumenten.
quelle
Python wird aufgerufen als
(Siehe Thrigs Antwort ).
Wenn Sie
$@
als einzelne Zeichenfolge erweitert werden möchten (vorausgesetzt, es handelt sich um eine vernünftige Zeichenfolge$IFS
), können Sie$*
doppelte Anführungszeichen verwenden:Bestätigt mit
strace -e execve
:quelle
Strace zeigen, was sind die Argumente verwendet. Die einfachste Methode, um zu sehen, was verarbeitet wird, ist das Hinzufügen eines
printf '<%s> '
vor jeder relevanten Zeile und eines Abschlussesecho
(um als neue Zeile zu generieren):Die Funktion könnte also folgendermaßen geändert werden:
Und wenn angerufen:
Es ist klar, dass "from sys" als ein Argument an Python gesendet wird.
Das ist es, was Python empfängt, und Python wirkt auf "from sys".
quelle