2011-05-13 3 views
2

J'ai un script python qui doit appeler le $EDITOR ou $VISUAL défini. Lorsque le script Python est appelé seul, je peux lancer le $EDITOR sans accroc, mais au moment où je redirige quelque chose vers le script Python, le $EDITOR est incapable de se lancer. En ce moment, je me sers nano qui montreImpossible de lancer le programme interactif pendant que vous redirigez vers un script en Python

reçu SIGHUP ou SIGTERM

chaque fois. Il semble que ce soit le même numéro described here.

sinister:Programming [1313]$ echo "import os;os.system('nano')" > "sample.py" 
sinister:Programming [1314]$ python sample.py 
# nano is successfully launched here. 
sinister:Programming [1315]$ echo "It dies here." | python sample.py 
Received SIGHUP or SIGTERM 

Buffer written to nano.save.1 

EDIT: Clarification; à l'intérieur du programme, je ne passe pas à l'éditeur. Le code est le suivant:

editorprocess = subprocess.Popen([editor or "vi", temppath]) 
editorreturncode = os.waitpid(editorprocess.pid, 0)[1] 
+1

Pouvez-vous coller un code de reproduction facile? :) – sarnold

+0

Vous ne pouvez pas vous attraper, voulez-vous démarrer un éditeur à partir d'un script python et garder l'entrée du terminal comme entrée standard? –

+0

@xiao Oui, c'est ce que je voulais faire. La solution de Nicholas fait juste cela. –

Répondre

4

Lorsque vous acheminez quelque chose à un processus, le tuyau est connecté à l'entrée standard de ce processus. Cela signifie que votre entrée de terminal ne sera pas connectée à l'éditeur. La plupart des éditeurs vérifient également si leur entrée standard est un terminal (isatty), ce qui n'est pas le cas d'un tube; et si ce n'est pas un terminal, ils refuseront de démarrer. Dans le cas de nano, cela semble l'amener à sortir avec le message que vous avez inclus:

% echo | nano 
Received SIGHUP or SIGTERM 

Vous devrez fournir l'entrée à votre script Python d'une autre manière, par exemple via un fichier, si vous vouloir être en mesure de transmettre son entrée standard à un éditeur basé sur un terminal.

Maintenant, vous avez précisé votre question, que vous ne voulez pas le stdin du processus Python attaché à l'éditeur, vous pouvez modifier votre code comme suit:

editorprocess = subprocess.Popen([editor or "vi", temppath], 
           stdin=open('/dev/tty', 'r')) 
+0

@eric, mais 'echo salut | vidir' échoue toujours, même que votre script. 'echo salut | mutt' n'essaie même pas de démarrer l'éditeur, il essaie de fonctionner en mode 'mail (1)' ... – sarnold

+0

Eh bien, vous pouvez vous sentir libre de réécrire votre noyau, mais sérieusement, c'est comme ça que les OS ressemblent à Unix travail. Quand 'mutt' engendre un éditeur, il utilise un fichier temporaire exactement pour cette raison. –

+0

@sarnold essayez 'vidir -' à la place; 'find -type f | vidir -' –

2

Le cas particulier de find -type f | vidir - est traitée ici :

foreach my $item (@ARGV) { 
    if ($item eq "-") { 
     push @dir, map { chomp; $_ } <STDIN>; 
     close STDIN; 
     open(STDIN, "/dev/tty") || die "reopen: $!\n"; 
    } 

Vous pouvez recréer ce comportement en Python, ainsi:

#!/usr/bin/python 

import os 
import sys 

sys.stdin.close() 
o = os.open("/dev/tty", os.O_RDONLY) 
os.dup2(o, 0) 
os.system('vim') 

Bien sûr, ferme le le descripteur de fichier d'entrée standard, donc si vous avez l'intention de le lire à nouveau après avoir démarré l'éditeur, vous devriez probablement dupliquer son descripteur de fichier avant de le fermer.

+0

Cela fonctionne également, mais je marque la réponse de Nicholas comme la solution préférée car elle ne nécessite pas la fermeture de stdin. Je vous remercie. –

+0

@Eric, oui, sa réponse m'a semblé assez élégant quand je l'ai vu :) plus utile pour les routines de la bibliothèque. – sarnold

Questions connexes