2009-09-29 5 views
1

J'ai un script python qui est toujours appelé depuis un shell, qui peut être zsh ou bash.Python: pouvez-vous indiquer le nom du shell appelant?

Comment puis-je savoir lequel a appelé le script?

+0

!?! Pourquoi voudriez-vous savoir cela? –

+0

Pour renvoyer les données d'achèvement qu'ils peuvent comprendre. –

+0

Ah. Je pense que os.getenv ('SHELL') vaut la peine d'être essayé. Devrait travailler dans la plupart des unités (mais bon, qui sait), et s'il n'existe pas, demandez à l'utilisateur de l'ajouter. –

Répondre

6

Sous Linux, vous pouvez utiliser procfs:

>>> os.readlink('/proc/%d/exe' % os.getppid()) 
'/bin/bash' 

os.getppid() renvoie le PID du processus parent. C'est portable. Mais l'obtention du nom du processus ne peut pas être effectuée de manière portable. Vous pouvez analyser la sortie ps qui est disponible sur tous les unices, par ex. avec psutil.

+0

Merci, c'est la première réponse de travail! De plus, il est merveilleusement cryptique :) –

+0

Je préférerais une solution qui fonctionne sur tous les sous-systèmes, cependant. –

+1

J'ai ajouté quelques conseils pour le rendre plus portable. –

-2

os.system ("echo $ 0")

Cela fonctionne sur mon système parfaitement:

cat shell.py: 

    #!/ms/dist/python/PROJ/core/2.5/bin/python 

    import os 
    print os.system("echo $0") 


bash-2.05b$ uname -a 
Linux pi929c1n10 2.4.21-32.0.1.EL.msdwhugemem #1 SMP Mon Dec 5 21:32:44 EST 2005 i686 athlon i386 GNU/Linux 


pi929c1n10 /ms/user/h/hirscst 8$ ./shell.py 
/bin/ksh 
pi929c1n10 /ms/user/h/hirscst 9$ bash 
bash-2.05b$ ./shell.py 
/bin/ksh 
bash-2.05b$ 
+0

Ceci est incorrect, car il démarre un nouveau shell, il ne donne aucune information sur le shell "appelant". –

+0

Cela ne retourne pas le nom du shell, il l'imprime à l'écran. Aussi, au moins sur mon système, cela imprime toujours 'sh', peu importe de quel shell j'appelle python. – sepp2k

+0

um, cela va commencer un sous-shell avec le même SHELL EXECUTABLE que le script a été appelé avec !!! – ennuikiller

0

Vous ne pouvez pas faire cela d'une manière automatisée fiable .

  • Les variables d'environnement peuvent être trompeuses (un utilisateur peut les commuter de manière malveillante). La plupart des variables de shell automatiques ne sont pas "fuites", c'est-à-dire qu'elles ne sont visibles que dans le processus shell, et non pour les processus enfants.

  • Vous pouvez déterminer votre PID parent et ensuite rechercher la liste des processus pour cet ID. Ne fonctionne pas si vous êtes exécuté en arrière-plan (dans ce cas, le PPID est toujours 1).

  • Un utilisateur peut démarrer votre programme à partir d'un script. Quel est le bon shell dans ce cas? Celui dans lequel le script a été lancé ou le shell du script?

  • D'autres programmes peuvent utiliser les appels système pour exécuter votre script. Dans ce cas, vous obtiendrez leur shell ou rien.

Si vous avez le contrôle absolu sur l'environnement de l'utilisateur, puis mettre une variable dans leur profil (consultez les manuels pour BASH et zsh un fichier qui est toujours lu au démarrage. IIRC, il est .profile pour BASH).

[EDIT] Crée un alias qui est appelé pour les deux shells. Dans l'alias, utilisez

env SHELL_HINT="x$BASH_VERSION" your_script.py 

Cela devrait correspondre à "x" pour zsh et à autre chose pour bash.

+0

Eh bien, ce ne sera pas, peu importe combien vous vous plaignez :) Sur Unix, les processus sont destinés à être isolés. Habituellement, ils ne fuient pas les choses dans les processus de l'enfant à moins que vous le leur disiez spécifiquement et que les coquilles soient particulièrement conservatrices. –

0
import os 
shell = os.getenv('SHELL') 
+2

Cela ne fonctionnera pas si le script n'est pas exécuté à partir du shell du système. –

+0

Pas particulièrement fiable, mais simple, et n'est pas du tout faux. :-) –

+1

@Lennart: et ne fonctionne pas exactement quand OP en a besoin. – SilentGhost

Questions connexes