L'exécution de multi-instructions de ligne dans la ligne la ligne de commande?
Je suis à l'aide de Python avec -c
pour exécuter une seule toile de boucle, c'est à dire:
$ python -c "for r in range(10): print 'rob'"
Cela fonctionne bien. Cependant, si je importer un module avant la boucle for, j'obtiens une erreur de syntaxe:
$ python -c "import sys; for r in range(10): print 'rob'"
File "<string>", line 1
import sys; for r in range(10): print 'rob'
^
SyntaxError: invalid syntax
Une idée de comment cela peut être corrigé?
Il est important pour moi d'avoir cela comme un one-liner pour que je puisse l'inclure dans un fichier Makefile.
OriginalL'auteur user248237dfsf | 2010-01-11
Vous devez vous connecter pour publier un commentaire.
vous pourriez faire
ou w/out tuyaux:
ou
ou @SilentGhost réponse /@Crast réponse
OriginalL'auteur jspcal
ce style peut être utilisé dans les makefiles trop (et en fait, il est utilisé assez souvent).
ou
dans ce dernier cas, leader des caractères de tabulation sont supprimés (et certains structuré outlook peut être atteint)
au lieu des expressions du FOLKLORE peut supporter un marqueur de mots ne figurant pas dans le document ici au début d'une ligne (voir aussi ici des documents dans la page de manuel de bash ou ici).
<<EOF
. Notez, cependant, que c'est mieux de citation le délimiteur - par exemple,<<'EOF'
- afin de protéger le contenu de la ici-document d'avance shell extensions.OriginalL'auteur xorho
Le problème n'est pas fait avec l'instruction d'importation, c'est avec quoi que ce soit avant la boucle for. Ou plus précisément, tout ce qui apparaît avant un inline block.
Par exemple, à tous les travaux:
Si l'importation d'une déclaration ont été un problème, ce serait le travail, mais il n'a pas d':
Pour votre exemple de base, vous pouvez réécrire comme ceci:
Cependant, les lambdas ne peut exécuter les expressions, pas de déclarations ou de plusieurs états, de sorte que vous peut-être encore incapable de faire la chose que vous voulez faire. Cependant, entre le générateur d'expressions, de la compréhension de liste, les lambdas, sys.la sortie standard stdout.écrire, la "carte" builtin, et de façon créative chaîne d'interpolation, vous pouvez faire quelques puissants one-liners.
La question est de savoir jusqu'où vous voulez aller, et à quel point est-il pas mieux d'écrire un petit
.py
fichier de votre makefile s'exécute à la place?OriginalL'auteur Crast
- Pour faire cette réponse travailler avec Python 3.x ainsi,
print
est appelé comme un fonction: en 3.x, seulementprint('foo')
œuvres, tandis que le 2.x accepte aussiprint 'foo'
.- Une croix-plate-forme de perspective qui inclut Windows, voir kxr de réponse utile.
Dans
bash
,ksh
, ouzsh
:Utiliser un C ANSI-chaîne entre guillemets (
$'...'
), qui permet d'utiliser\n
pour représenter les retours à la ligne qui sont développés de réels retours à la ligne avant de la chaîne est passée àpython
:Note le
\n
entre lesimport
etfor
déclarations à l'effet d'un saut de ligne.À passer shell valeurs de la variable à une telle commande, il est plus sûr d'utiliser arguments et d'y accéder via
sys.argv
à l'intérieur du script Python:Voir ci-dessous pour une discussion sur les avantages et les inconvénients de l'utilisation d'une séquence d'échappement-prétraitées) double-cité chaîne de commande avec intégré shell-les références à des variables.
De travailler en toute sécurité avec
$'...'
chaînes:\
des instances de votre original code source.\<char>
des séquences telles que\n
dans ce cas, mais aussi les suspects habituels comme\t
,\r
,\b
- sont développées par$'...'
(voirman printf
pour les prises en charge s'échappe)'
instances\'
.Si vous devez rester conforme à POSIX:
Utilisation
printf
avec un la substitution de commande:De travailler en toute sécurité avec ce type de chaîne:
\
des instances de votre original code source.\<char>
des séquences telles que\n
dans ce cas, mais aussi les suspects habituels comme\t
,\r
,\b
- sont développées parprintf
(voirman printf
pour la pris en charge des séquences d'échappement).Passer un unique cité chaîne de
printf %b
et échapper incorporé des guillemets simples comme'\''
(sic).D'utiliser des guillemets simples protège la chaîne du contenu à partir de l'interprétation par le shell.
Cela dit, pour court scripts Python (comme dans ce cas), vous pouvez utiliser une chaîne de caractères entre guillemets pour intégrer shell les valeurs de la variable dans vos scripts, aussi longtemps que vous êtes conscient des pièges associés (voir le point suivant); par exemple, le shell étend
$HOME
à l'utilisateur actuel de la maison dir. dans la commande suivante:python -c "$(printf %b "import sys\nfor r in range(10): print('rob is $HOME')")"
Cependant, une approche privilégiée consiste à transmettre des valeurs à partir du shell via arguments, et d'y accéder via
sys.argv
en Python, et l'équivalent de la commande ci-dessus est:python -c "$(printf %b 'import sys\nfor r in range(10): print("rob is " + sys.argv[1])')" "$HOME"
Tout en utilisant un double-cité chaîne est plus pratique - il vous permet d'utiliser embedded guillemets simples sans échappement et intégré des guillemets doubles comme
\"
- il rend également la chaîne soumis à l'interprétation par la shell, qui peut ou peut ne pas être l'intention;$
et`
caractères dans votre code source qui ne sont pas destinés à la coque peut entraîner une erreur de syntaxe ou de modifier la chaîne de façon inattendue.\
de traitement en double-cité des chaînes peut obtenir de la manière; par exemple, pour obtenir Python pour produire littérale de sortiero\b
, vous devez passerro\\b
; avec un'...'
shell chaîne et doublé\
cas, nous obtenons:python -c "$(printf %b 'import sys\nprint("ro\\\\bs")')" # ok: 'ro\bs'
En revanche, cela ne pas fonctionner comme prévu avec un
"..."
shell chaîne:python -c "$(printf %b "import sys\nprint('ro\\\\bs')")" # !! INCORRECT: 'rs'
Le shell interprète les deux
"\b"
et"\\b"
littérale\b
, nécessitant une vertigineuse du nombre de supplémentaires\
instances pour obtenir l'effet désiré:python -c "$(printf %b "import sys\nprint('ro\\\\\\\\bs')")"
À passer le code via
stdin
plutôt que-c
:Note: je me concentre sur les uniqueligne de solutions ici; xorho réponse montre comment utiliser un multi-ligne ici-document - assurez-vous de devis le délimiteur, cependant; par exemple,
<<'EOF'
, à moins que vous ne souhaitiez la coquille d'étendre la chaîne à l'avant (qui est livré avec les mises en garde mentionnées ci-dessus).Dans
bash
,ksh
, ouzsh
:Combiner un C ANSI-chaîne entre guillemets (
$'...'
) avec un chaîne ici (<<<...
):-
ditpython
explicitement à lire à partir de stdin (ce qu'il fait par défaut).-
est facultatif dans ce cas, mais si vous aussi vous souhaitez passer arguments pour les scripts, vous n'avez besoin de lever l'ambiguïté de l'argument à partir d'un script nom de fichier:Si vous devez rester conforme à POSIX:
Utilisation
printf
comme ci-dessus, mais avec un pipeline de façon à passer sa production via stdin:Avec un argument:
OriginalL'auteur mklement0
Votre problème est créé par le fait que des instructions Python, séparés par
;
, ne sont autorisés à être les "petits états", qui sont tous des one-liners. À partir du fichier de grammaire dans le Python docs:Composé déclarations ne peuvent pas être inclus sur la même ligne avec d'autres états par des points-virgules - donc faire avec les
-c
drapeau devient très gênant.Lors de la démonstration de Python, le tout dans un shell bash de l'environnement, je trouve qu'il est très utile d'inclure composé consolidés. La seule façon simple de le faire est avec heredocs.
Heredocs
Utiliser un heredoc (créé avec
<<
) et Python interface de ligne de commande option,-
:L'ajout de la
-
après<<
(le<<-
) vous permet d'utiliser onglets de tiret (Stackoverflow convertit les tabulations en espaces, j'ai donc mis en retrait de 8 espaces de le souligner). Les principaux onglets sera dépouillé.Vous pouvez le faire sans les onglets avec juste
<<
:De mettre des guillemets autour de
EOF
empêche paramètre et l'expansion arithmétique. Cela rend le heredoc plus robuste.Critique de la accepté de répondre (et d'autres)
Ce n'est pas très lisible:
Pas très lisible, et en plus difficiles à résoudre dans le cas d'une erreur:
Peut-être un peu plus lisible, mais encore assez laid:
Vous aurez un mauvais moment si vous avez
"
's dans votre python:Ne pas abuser de
map
ou interprétations de la liste pour obtenir des boucles:Ce sont tous tristes et mal. Ne les faites pas.
bash
,ksh
, ouzsh
) est une solution raisonnable:python -c $'import sys\nfor r in range(10): print(\'rob\')'
(vous n'aurez à vous inquiéter au sujet d'échapper les guillemets simples (que vous pouvez éviter en utilisant les guillemets) et anti-slash).OriginalL'auteur Aaron Hall
l'utilisation juste de retour et le type sur la ligne suivante:
python $(srcdir)/myscript.py
pour la justice.OriginalL'auteur SilentGhost
Le problème n'est pas le
import
déclaration. Le problème est que les instructions de flux de contrôle ne fonctionnent pas inline dans une commande python. Remplacer queimport
déclaration avec une autre déclaration, et vous verrez le même problème.Pensez-y: python ne peut pas inline tout. Il utilise l'indentation du groupe de contrôle de flux.
OriginalL'auteur David Berger
Si votre système est Posix.2 conforme, il doit fournir à l'
printf
utilitaire:printf %b '...' | python
pour une plus grande robustesse, car il empêcheprintf
à partir de l'interprétation des séquences telles que%d
(les spécificateurs de format) dans la chaîne d'entrée. Aussi, à moins que vous ne souhaitiez appliquer shell extensions de votre Python chaîne de commande à l'avant (ce qui peut prêter à confusion), il est préférable d'utiliser'
(guillemets simples) à l'extérieur pour la citer, pour éviter à la fois les expansions et les réactions de transformation que la coquille s'applique à double-chaînes entre guillemets.OriginalL'auteur Alex Martelli
$ python2.6 -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"
Fonctionne très bien.
Utilisez "[ ]" aux commandes de votre boucle.
OriginalL'auteur Pierre Pericard
(réponse Nov 23 '10 à 19:48)
Je ne suis pas vraiment un grand Pythoner mais j'ai trouvé cette syntaxe une fois, j'ai oublié d'où, donc, j'ai pensé document:
si vous utilisez
sys.stdout.write
au lieu deprint
(la différence étant,sys.stdout.write
prend les arguments de la fonction, dans la parenthèse - alors queprint
n'est pas), puis pour un one-liner, vous pouvez vous en sortir avec l'inversion de l'ordre de la commande et de lafor
, la suppression du point-virgule, et en joignant la commande entre crochets, c'est à dire:N'ai aucune idée de comment cette syntaxe serait appelé en Python 🙂
Espère que cette aide,
Cheers!
(EDIT Mar Avr 9 20:57:30 2013) eh Bien, je pense que j'ai enfin trouvé ce que ces crochets en one-liners sont; ils sont des "interprétations de la liste" (apparemment); abord de noter ce en Python 2.7:
Donc la commande dans les parenthèses/parenthèse est vu comme un "générateur d'objet"; si nous "itérer" grâce à en appelant
next()
- la commande à l'intérieur de la parenthèse sera exécuté (notez le "abc" dans la sortie):Si nous avons maintenant utiliser les crochets de noter que nous n'avons pas besoin d'appeler
next()
avoir la commande exécuter, il s'exécute immédiatement lors de la cession; cependant, plus tard, l'inspection révèle quea
estNone
:Cela ne laisse pas beaucoup d'infos à rechercher, pour les crochets cas - mais je suis tombé sur cette page qui, je pense, explique:
Python Trucs Et Astuces – Première Édition - Python Tutoriels | Rêve.Dans.Code:
Et en effet c'est une liste - c'est juste son premier élément devient néant dès qu'elle est exécutée:
Interprétations de la liste sont par ailleurs documenté dans 5. Structures De Données: 5.1.4. Interprétations de la liste — Python v2.7.4 documentation "interprétations de la Liste de fournir de manière concise pour créer des listes"; sans doute, c'est là où le "executability" des listes intervient dans des one-liners.
Bien, espérons que je ne suis pas terriblement trop large de la marque ici ...
EDIT2: et voici un one-liner ligne de commande avec deux non-imbriquées pour des boucles; les deux enfermés à l'intérieur de la liste des "compréhension" entre crochets:
Avis que la seconde "liste"
b
a maintenant deux éléments, depuis sa boucle explicitement couru deux fois; toutefois, le résultat desys.stdout.write()
dans les deux cas était (apparemment)None
.OriginalL'auteur sdaau
single/double quotes
etbackslash
partout:Beaucoup mieux:
OriginalL'auteur kev
Cette variante est plus portable pour mettre multi-scripts de ligne sur la ligne de commande sur Windows et *nix, py2/3, sans tuyaux:
(Aucun des autres exemples vus jusqu'ici l'a fait)
Soigné sous Windows est:
Soigné sur bash/*nix:
Cette fonction transforme n'importe quel multi-script dans un portable de commande one-liner:
Utilisation:
Entrée a été:
--%
avant de la chaîne de commande de l'argument.shell expansions": ainsi, l'insertion de la coquille expansions de quelque chose comme
print "path is %%PATH%%"
resp.print "path is $PATH"
est généralement l'option que l'on veut dans un script de ligne de commande ou - à moins que l'une des évasions les choses comme d'habitude pour la plate-forme. Même avec d'autres langues. (La syntaxe de Python lui-même n'est pas régulièrement suggèrent l'utilisation d' % et $'s de façon concurrente.)Si vous insérez shell-les références à des variables directement dans le code source Python, il sera, par définition, pas être portable. Mon point est que même si vous construit à la plate-forme des références spécifiques dans distinct variables que vous passez arguments single, "shell-free" de commande Python, fonctionne pas toujours, parce que vous ne pouvez pas protéger la chaîne de caractères entre guillemets de façon portable: par exemple, que faire si vous avez besoin d' littérale
$foo
dans votre code Python? Si vous échapper que\$foo
pour le bénéfice de POSIX, comme des coquillages,cmd.exe
pourront toujours voir l'extra\
. Il peut être rare, mais il vaut la peine de connaître.Essayez de faire cela dans Windows PowerShell, mais le problème est que python -c exec("""...""") ne produit pas de sortie que ce soit, peu importe si le code de ... est capable d'être exécuté ou pas; je pouvais mettre n'importe quel charabia là, et le résultat serait le même. Je me sens comme la coquille est "manger" à la fois le stdout et stderr flux - comment puis-je rendre leur cracher?
OriginalL'auteur kxr
Ce script fournit un Perl-comme l'interface de ligne de commande:
Pyliner - Script à exécuter arbitrairement du code Python en ligne de commande (Python recette)
Je suis d'accord avec @enrico.bacis, mais je suis toujours heureux que vous avez ajouté cette réponse. Il répond à la question I eu quand j'ai Googlé cette page.
OriginalL'auteur Drew Gulino
Je voulais une solution avec les propriétés suivantes:
Deux exigences n'ont pas été fournis dans les autres réponses, donc voici comment lire stdin tout en faisant tout sur la ligne de commande:
OriginalL'auteur Nick
il y a une option de plus, sys.la sortie standard stdout.écrire retourne Aucun, à ceux qui gardent la liste vide
OriginalL'auteur user993533
Si vous ne voulez pas toucher stdin et simuler comme si vous aviez passé "python cmdfile.py", vous pouvez effectuer les opérations suivantes à partir d'un shell bash:
Comme vous pouvez le voir, il vous permet d'utiliser l'entrée standard stdin pour la lecture des données d'entrée. En interne, le shell crée un fichier temporaire pour l'entrée de commande de contenu.
-c "$(...)"
fait la même chose, et est conforme à POSIX); donner la<(...)
construire un nom: processus de substitution; elle travaille également dansksh
etzsh
.OriginalL'auteur Thava
Quand j'en avais besoin pour ce faire, j'utilise
Note la triple barre oblique inverse pour le retour à la ligne dans le sys.la sortie standard stdout.écrire déclaration.
echo -e
, qui est non standard et nécessitebash
,ksh
, ouzsh
, vous pouvez aussi bien utiliser une$'...'
chaîne directement, ce qui simplifie également l'échappement:python -c $'import sys\nsys.stdout.write("Hello World!\\n")'
OriginalL'auteur Devilholk