2009-11-02 6 views
19

J'ai essayé de créer un script d'initialisation en utilisant start-stop-daemon. Je suis bloqué sur les arguments du démon. Je veux les garder dans une variable en haut du script mais je ne peux pas obtenir les citations à filtrer correctement.arguments cotés start-stop-daemon mal interprétés

Je vais utiliser ls ici, donc nous n'avons pas à regarder les binaires et les arguments que la plupart des gens ne connaissent pas ou ne se soucient pas.

Le résultat final Je cherche est start-stop ... pour exécuter ls- "/ dossier avec l'espace /"

DAEMON=/usr/bin/ls 
DAEMON_OPTS='-la "/folder with space/"' 

start-stop-daemon --start --make-pidfile --pidfile $PID --exec $DAEMON -- $DAEMON_OPTS 

Double échapper aux options et à essayer d'innombrables variations de citations n'aide pas ... Alors ils finissent au démon ils sont toujours foirés. Enfermer $ imprime DAEMON_OPTS entre guillemets change les choses ... ils sont considérés comme une citation depuis ... jamais le bon nombre bien :)

Faisant écho à la ligne de commande (start-stop ...) exactement bonnes choses à l'écran. Mais le démon (le vrai, pas ls) se plaint du mauvais nombre d'arguments.

Comment est-ce que je spécifie une variable pour que les citations à l'intérieur soient amenées correctement au démon?

+0

Pour clarifier. J'ai essayé beaucoup de variations de citation habituelles. guillemets simples à l'intérieur, "-la '/ dossier ... double guillemets simples à l'intérieur,' -la"/dossier ... guillemets échappés, "-la \"/dossier ... \ "" en utilisant seulement backslash pour chaque espace à la place, dossier \ avec ... J'imagine vaguement que le problème est en quelque sorte avec start-stop-daemon et ses interprétations ... mais cela n'a pas beaucoup de sens non plus depuis le remplacement de la variable sur le ligne de commande donne des résultats fonctionnels. –

Répondre

7

Je pensais que je posterai les citations finales utilisées dans mon script d'initialisation de travail:

COMMAND="/path/to/script -opt param param2 param3" 
DAEMON_OPTS=" 0.0.0.0:$PORT -dest $OUTPUT_DIRECTORY -command" 

start-stop-daemon --start --background --make-pidfile --pidfile $PID --exec $DAEMON -- $DAEMON_OPTS "\"$COMMAND\"" 

Il est évident qu'un exemple incomplet et non fonctionnel, mais je l'espère, vous obtenez l'essentiel de celui-ci. Les doubles citations avec la paire intérieure ont échappé est ce qui a fait l'affaire.

+0

Cela peut fonctionner, mais cela nécessite de modifier le script d'initialisation lui-même, ce qui représente une grosse perte. Je veux pouvoir définir des variables dans/etc/default/whatever et ne pas avoir à les conserver dans un script init lorsque vous mettez à jour un paquet. – deltaray

+0

Je pense que vous devriez toujours inclure des exemples complets au lieu de demi-exemples. –

13

Essayez

DAEMON_OPTS="-la '/folder with space/'" 
start-stop-daemon --start ... -- $DAEMON_OPTS 

Qu'est-ce qui se passe est que les citations extérieures de DAEMON_OPTS sont supprimés, mais les (guillemets simples) internes restent. Ainsi, la ligne suivante sera lu:

start-stop-daemon --start ... -- -la '/folder with space/' 

qui est ce que vous voulez.

Il est également possible d'obtenir le même effet échapper, mais il faut beaucoup d'évasions pour cela: Tout d'abord, pour protéger les citations au cours de la mission, puis plus tard, lorsque la ligne de départ est analysée et les variables sont et peut-être même une fois de plus ou moins. :) bash -x est votre ami pour des choses comme ça. [EDIT] Le code ci-dessus fonctionne avec Bourne et Korn shell sur n'importe quoi sauf Linux. Sous Linux, avec ksh ou bash, le shell ajouter des guillemets supplémentaires gâcher la chose entière:

FOLDER="/folder with space/" 
DAEMON_OPTS="-la $FOLDER" 
start-stop-daemon --start ... -- $DAEMON_OPTS 

Si vous exécutez avec -x, vous verrez:

FOLDER='/folder with space/' 
DAEMON_OPTS='-la ~/folder with space/' 
ls -la '~/folder' with space/ 

Alors seulement le premier mot obtient la protection (probablement parce qu'il contient un caractère spécial). Si j'ajoute des guillemets simples autour $FOLDER, je reçois:

FOLDER='/folder with space/' 
DAEMON_OPTS='-la '\''~/folder with space/'\''' 
ls -la ''\''~/folder' with 'space/'\''' 

bien fait. Solution: Diviser les options en deux variables: une avec les options et l'autre avec le chemin:

start-stop-daemon --start ... -- $DAEMON_OPTS "$DAEMON_PATH" 

[EDIT2] Cela fonctionne aussi:

FOLDER="$HOME/folder with space/" 
opt[0]=-la 
opt[1]=$FOLDER 
ls "${opt[@]}" 

dire mettre les mots dans un tableau.

+0

Peut-être que je fais quelque chose de mal, mais cette solution ne fonctionne pas quand je l'essaie? –

+0

Oui, ne fonctionne pas avec bash:/J'ai utilisé avec succès pour passer des arguments aux indices en utilisant une boucle sur les arguments et en utilisant 'args =" $ args '$ opt' "', puis en utilisant $ cmd $ args' (pas de guillemets). Fonctionne avec Bourne et Korn Shell. –

+0

Sauf si vous utilisez ksh sur linux (testé avec ksh-93s-59.7). –

0

Avez-vous essayé de le faire dans l'autre sens avec les guillemets? Comme ceci:

 
DAEMON_OPTS='-la "/folder with space/"' 

Je ne suis pas sûr, mais cela pourrait fonctionner?

(Je l'aurais posté comme commentaire à la réponse précédente, si seulement j'avais eu assez de réputation pour le faire).

+0

J'ai essayé cela et toute autre combinaison de citation que je connais ... pas de chance. –

0

Chaque fois que vous avez une variable bash avec des espaces, veillez à utiliser des guillemets lorsque vous y faites référence.

start-stop-daemon --start --make-pidfile --pidfile $ PID --exec $ Daemon - "$ DAEMON_OPTS"