2010-07-29 8 views
4

J'ai un script bash (appelons-le /usr/bin/bosh) en utilisant la ligne elle-bang suivant:supercherie bash en utilisant --init fichier

#!/bin/bash --init-file 

Il définit deux fonctions, et met généralement interactive shell dans un environnement où l'utilisateur peut contrôler un tas de choses que je veux. Cela fonctionne plutôt bien. Maintenant, pour la partie intéressante, j'aimerais pouvoir laisser les utilisateurs utiliser cette couche intermédiaire pour écrire de nouveaux scripts, sans avoir explicitement besoin de la source. Est-ce possible?

J'ai essayé d'écrire un script (appelons-le /usr/bin/foo) en utilisant la ligne elle-bang

#!/usr/bin/bosh 

Ce que je pensais, serait réécrite pour exécuter la commande

/usr/bin/bosh /usr/bin/foo 

qui à son tour résultat en

/bin/bash --init-file /usr/bin/bosh /usr/bin/foo 

Mais cela ne fonctionne pas, /usr/bin/foo est exécuté, mais /usr/bin/bosh n'est pas source avant cela.

Comment puis-je faire en sorte que le fichier init soit source même si le script n'est pas interactif? Ou devrais-je écrire un script d'emballage pour cela? Je pensais avoir un script comme celui-ci

#!/bin/bash 
. /usr/bin/bosh 
. "$1" 

Mais ce ne serait pas se transformer en un shell interactif si je ne spécifie pas un script à exécuter, ce qui serait un peu dommage.

EDIT
Pour plus de précisions, ce que je demande vraiment, comment puis-je faire la source bash un fichier (comme --init-file), peu importe que ce soit interactif (avant de commencer la partie interactive) ou non (avant d'exécuter le script)? S'il n'y a aucun moyen, y a-t-il un autre moyen de résoudre mon problème peut-être?

Répondre

3

Le programme spécifié par le #! Je ne peux pas être un autre script j'ai peur au moins jusqu'à Linux noyau 2.6.27.9, qui permet cette fonctionnalité. Si vous exécutez strace sur foo, vous verrez une erreur de format ENOEXEC ou exec, car bosh ne peut pas être exécuté en tant que programme autonome. Qu'est-ce qui se passe, c'est qu'au lieu de/bin/bosh étant exécuté et remis foo en entrée, votre shell de connexion retombe simplement silencieusement à l'exécution de foo lui-même dans une sous-shell, ce qui semble presque fonctionner.

Un wrapper ou un programme C qui lance bash comme vous le souhaitez sont probablement vos seules options. Même avec une mise à jour de votre noyau, ça ne fonctionnera pas comme vous le voulez, j'en ai peur.

Tout ce que vous avez toujours voulu savoir sur #!ici: http://www.in-ulm.de/~mascheck/various/shebang/

EDIT: Si votre noyau ne vraiment charge les scripts chaînés, puis un travail autour de /usr/bin/bosh pourrait être quelque chose comme:

#!/bin/bash 
if [ ! $PS1 ]; then 
    exec /bin/bash --init-file "$0" -i "[email protected]" 
fi 
... rest of bosh init file ... 

Un exec semble inévitable pour que cela fonctionne la manière tu le veux.

+1

Ce n'est pas vrai, ça marche bien sur 2.6.16. Le problème se trouve dans le fichier --init, si vous lisez la page de manuel, vous remarquerez qu'il ne sera pas exécuté s'il ne s'agit pas d'un shell interactif. Je ne peux donc tirer parti que de ce fichier interactif. Je n'ai pas downvote cependant. – falstro

+0

Ensuite, vous ne devez pas utiliser un noyau vanilla. Pour quiconque a voté contre moi, ce qui précède est la vérité telle que je la connais, alors ne me votez pas parce que vous vivez dans votre pays spécial Red-Hat ou autre chose. –

+0

Bonne idée avec l'exec! Pourquoi n'ai-je pas pensé à ça ... Merci! (Bien que votre exemple ne fasse pas vraiment ce que je veux, mais je peux quand même vérifier si je n'ai pas d'argument de script, et exécuter le shell interactif dans ce cas) – falstro

0

Un script n'est pas un environnement d'exécution. Cela peut être votre problème. Le shebang défnies l'environnement d'exécution. c'est-à-dire .../bin/java/bin/python/bin/bash/bin/dash. Votre script n'est pas un environnement. Votre "exemple de wrapper" serait approprié.

+0

Vous ne savez pas vraiment ce que le shebang fait, n'est-ce pas? :) – falstro

+0

C'est un interperater pour l'exécution. En fait, au lieu de/bin/bash "mon commmand", vous dites/bin/bosh "ma commande". Cela ne semble pas avoir beaucoup de sens de cette façon. –

+0

Je ne vois pas vraiment ce que vous essayez de faire. Votre ". /path/to/file.config" semble être le chemin à suivre et c'est ainsi que je charge les variables d'environnement à partir des paramètres de mes scripts. –

Questions connexes