Ich brauchte ein direkt ausführbares Python-Skript, also startete ich die Datei mit #!/usr/bin/env python
. Allerdings brauche ich auch ungepufferte Ausgabe, also habe ich es versucht #!/usr/bin/env python -u
, aber das schlägt fehl python -u: no such file or directory
.
Ich fand , dass heraus #/usr/bin/python -u
funktioniert, aber ich brauche es die zu bekommen python
in PATH
virtuellen zu unterstützen env
Umgebungen.
Was sind meine Optionen?
Antworten:
Es ist besser, Umgebungsvariablen zu verwenden, um dies zu aktivieren. Siehe Python-Dokument: http://docs.python.org/2/using/cmdline.html
für Ihren Fall:
export PYTHONUNBUFFERED=1 script.py
quelle
In einigen Umgebungen teilt env keine Argumente auf. Also sucht deine Umgebung
python -u
auf deinem Weg. Wir können sh verwenden, um herumzuarbeiten. Ersetzen Sie Ihren Shebang durch die folgenden Codezeilen und alles wird gut.#!/bin/sh ''''exec python -u -- "$0" ${1+"$@"} # ''' # vi: syntax=python
ps wir brauchen uns keine sorgen um den weg zu sh, oder?
quelle
${1+"$@"}
Hack war wahrscheinlich seit mindestens 20 Jahren unnötig :)"exec" "python" "-u" "--" "$0" "$@"
vielleicht einfacher zu verstehen - gibt es einen Fehler darin? (Ich denke, es ist nicht kompatibel mit dem1+
Hack?)'
oder"
, ist Ihre Methode zuverlässiger. Es ist ein interessantes Thema! Meins ist vielleicht leichter zu verstehen, aber deins ist robuster. Vielleicht sollte Ihre Antwort klarstellen, dass sie mit beginnen muss''''exec
und die Zeichenfolge# '''
mit (mit einem Leerzeichen vor dem#
) enden muss . Solange wir diese Regeln befolgen und keine zusätzlichen Anführungszeichen haben'''
, ist Ihre Methode perfekt und flexibel.${1+"$@"}
. Sollte also"$@"
in den meisten Fällen von alleine gut funktionieren.Wenn Sie shebang unter Linux verwenden, wird der gesamte Rest der Zeile nach dem Interpreternamen als einzelnes Argument interpretiert. Das
python -u
wird an übergeben,env
als ob Sie Folgendes eingegeben hätten :/usr/bin/env 'python -u'
. Die/usr/bin/env
Suche nach einer Binärdatei namenspython -u
, die es keine gibt.quelle
Das Übergeben von Argumenten an die Shebang-Zeile ist nicht Standard und funktioniert, wie Sie experimentiert haben, unter Linux nicht in Kombination mit env. Die Lösung mit bash besteht darin, den eingebauten Befehl "set" zu verwenden, um die erforderlichen Optionen festzulegen. Ich denke, Sie können das Gleiche tun, um die ungepufferte Ausgabe von stdin mit einem Python-Befehl festzulegen.
my2c
quelle
Dies mag etwas veraltet sein, aber das Handbuch env (1) sagt, dass man für diesen Fall '-S' verwenden kann
#!/usr/bin/env -S python -u
Es scheint ziemlich gut auf FreeBSD zu funktionieren.
quelle
-S
Option spezifisch für die BSD-Variante von ist,env(1)
aber es ist gut zu wissenenv -S
jetzt auch - ab Coreutils 8.30 1 (es kann eine Weile dauern, bis es in einer Distribution in Ihrer Nähe erscheint). Gleiche Semantik wie bei FreeBSDenv(1)
- Hurra für die Portabilität guter Funktionen.Hier ist eine Skriptalternative zu
/usr/bin/env
, die die Übergabe von Argumenten in der Hash-Bang-Zeile ermöglicht, basierend auf/bin/bash
und mit der Einschränkung, dass Leerzeichen im ausführbaren Pfad nicht zulässig sind. Ich nenne es "envns" (env No Spaces):#!/bin/bash ARGS=( $1 ) # separate $1 into multiple space-delimited arguments. shift # consume $1 PROG=`which ${ARGS[0]}` unset ARGS[0] # discard executable name ARGS+=( "$@" ) # remainder of arguments preserved "as-is". exec $PROG "${ARGS[@]}"
Angenommen, dieses Skript befindet sich unter / usr / local / bin / envns, dann ist hier Ihre Shebang-Zeile:
#!/usr/local/bin/envns python -u
Getestet auf Ubuntu 13.10 und Cygwin x64.
quelle
Dies ist ein Kludge und erfordert Bash, aber es funktioniert:
#!/bin/bash python -u <(cat <<"EOF" # Your script here print "Hello world" EOF )
quelle
Aufbauend auf Larry Cais Antwort
env
können Sie eine Variable direkt in der Befehlszeile festlegen. Das bedeutet, dass-u
dies durch die entsprechendePYTHONUNBUFFERED
Einstellung vor ersetzt werden kannpython
:#!/usr/bin/env PYTHONUNBUFFERED="YESSSSS" python
Funktioniert mit RHEL 6.5. Ich bin mir ziemlich sicher, dass diese Funktion
env
nahezu universell ist.quelle
ps
Ausgabe zu betrachten, sollte es keinen Unterschied geben), aber es kehrt nie zurück. Es ist nicht sehr klar, ob Python selbst überhaupt läuft, wenn Sie dies in Debian tun. Ich habe dies an einigen Stellen versucht - funktioniert definitiv nicht wie erwartet im Vergleich zur entsprechenden Befehlszeile.env
oder sogarpython
Sie verwenden.Ich habe kürzlich einen Patch für die GNU Coreutils-Version von geschrieben
env
, um dieses Problem zu beheben :http://lists.gnu.org/archive/html/coreutils/2017-05/msg00018.html
Wenn Sie dies haben, können Sie tun:
#!/usr/bin/env :lang:--foo:bar
env
wird:lang:foo:--bar
in die Felder aufgeteiltlang
,foo
und--bar
. Es suchtPATH
für den Dolmetscherlang
, und dann rufen Sie es mit Argumenten--foo
,bar
sowie der Pfad zum Skript und das Skript Argumente.Es gibt auch eine Funktion, mit der Sie den Namen des Skripts in der Mitte der Optionen übergeben können. Angenommen, Sie möchten ausführen
lang -f <thecriptname> other-arg
, gefolgt von den verbleibenden Argumenten. Mit diesem Patchenv
wird es folgendermaßen gemacht:#!/usr/bin/env :lang:-f:{}:other-arg
Das Feld ganz links, das äquivalent ist,
{}
wird durch das erste folgende Argument ersetzt, das unter Hash-Bang-Aufruf der Skriptname ist. Dieses Argument wird dann entfernt.Hier
other-arg
könnte etwas vonlang
oder vielleicht etwas von dem Skript verarbeitet werden.Weitere Informationen finden Sie in den zahlreichen
echo
Testfällen im Patch.Ich habe das
:
Zeichen gewählt, weil es ein vorhandenes Trennzeichen ist, dasPATH
auf POSIX-Systemen verwendet wird. Daenv
diePATH
Suche durchgeführt wird, ist es offensichtlich unwahrscheinlich, dass sie für ein Programm verwendet wird, dessen Name einen Doppelpunkt enthält. Die{}
Markierung stammt vomfind
Dienstprogramm, mit dem das Einfügen eines Pfads in die-exec
Befehlszeile bezeichnet wird.quelle