2009-10-20 29 views
2

je besoin d'une simple enveloppe busybox sh qui fera:wrapper busybox sh pour ajouter des fonctionnalités supplémentaires

IF "-Q" PARAMETER IS PROVIDED THEN 
    acommand ALL PARAMETERS BUT "-Q" 2>&1 1>/dev/null 
ELSE 
    acommand ALL PARAMETERS 
FI 

Les paramètres peuvent inclure des espaces.

BTW Je veux exécuter le script avec busybox sh et il ne supporte pas les tableaux.

+0

Si vous voulez exécuter le script shell avec busybox, pourquoi cela est étiqueté 'bash'? Et pourquoi voulez-vous utiliser busybox shell quand bash fournit les fonctionnalités dont vous avez besoin? –

+0

Vous avez raison. Pardon. –

Répondre

2

Il est possible de le faire tout en busybox « s shell ash:

#!/bin/sh 
for i in "${@}" 
do 
    if [ "$i" = "-Q" ] 
    then 
     flagQ=1 
    else 
     args="$args \"$i\"" 
    fi 
done 
if [ "$flagQ" = "1" ] 
then 
    eval acommand "$args" 2>&1 1>/dev/null 
else 
    eval acommand "$args" 
fi 
+0

L'eval ne fonctionnera pas quand j'utilise "Il a dit ne pas!" comme argument; il est également malheureux si j'écris "Il a dit use \' ls \ 'et je l'ai fait". Dans le premier cas, vous avez des guillemets simples déséquilibrés qui gâchent l'interprétation; dans la seconde, vous allez exécuter la commande 'ls'. –

+0

'diff <(./ myscript" il a dit utiliser \ 'ls \' et j'ai fait ") <(./ acommand" il a dit utiliser \ 'ls \' et j'ai fait ")' ne donne aucune différence. Cela va aussi exécuter 'ls':' echo 'Il a dit use \ 'ls \' et je l'ai fait '', mais vous avez raison sur l'apostrophe. –

+0

... qui utilise votre script 'acommand' dans la commande' diff'. –

0

Il est dommage que vous avez besoin pour gérer les espaces dans les arguments autrement cela pourrait fonctionner:

#!/bin/sh 
Q=0 
ARGS= 

while [ $# -ge 1 ]; do 
    case $1 in 
     -Q) 
      Q=1 
      ;; 
     *) 
      ARGS="$ARGS $1" 
      ;; 
    esac 
    shift 
done 

if [ $Q -eq 1 ] ; then 
    acommand $ARGS 2>&1 1>/dev/null 
else 
    acommand $ARGS 
fi 

EDIT:

donc cette version gère les espaces, au détriment de l'interprétation en arrière-tiques.

#!/bin/busybox ash 
Q=0 
ARGS= 

while [ $# -ge 1 ]; do 
    case $1 in 
     -Q) 
      Q=1 
      ;; 
     *) 
      ARGS="$ARGS \"$1\"" 
      ;; 
    esac 
    shift 
done 

if [ "$Q" -eq 1 ] ; then 
    eval acommand $ARGS 2>&1 1>/dev/null 
else 
    eval acommand $ARGS 
fi 

Je pense avoir une solution complète, vous allez devoir le code en C, qui sera un peu laid.

+0

La seule façon de voir les espaces de support est avec les tableaux - mais je ne sais pas si busybox sh supporte les tableaux? –

+0

Malheureusement, ce n'est pas le cas. –

0

Cela utilise bash arrays - mais je vois dans les commentaires à une autre réponse que le code n'est pas censé s'exécuter sous bash (malgré la balise bash appliquée à l'origine à la question); il est destiné à fonctionner sous le shell busybox.

Je suis presque certain qu'il ne répond pas à la question parce que la question est pratiquement impossible à répondre étant donné les limites de busybox. Par le passé, j'ai utilisé un programme personnalisé que j'ai appelé 'escape' pour construire une chaîne d'arguments qui peut être évaluée pour obtenir les arguments originaux - espaces et tout. Mais cela nécessite un soutien de l'extérieur du shell.


Cette solution utilise uniquement 'bash'. Je ne suis pas sûr que ce code soit entièrement idiomatique, mais cela fonctionne.

#!/bin/bash 

i=0 
Qflag=0 
for arg in "[email protected]" 
do 
    if [ "X$arg" = "X-Q" ] 
    then Qflag=1 
    else args[$((i++))]=$arg 
    fi 
done 

if [ $Qflag = 1 ] 
then exec acommand "${args[@]}" 2>&1 >/dev/null 
else exec acommand "${args[@]}" 
fi 

Les premières boucles construit un tableau, args, avec les arguments du script, sauf qu'il n'ajoute « -Q » à la liste et enregistre sa présence dans qflag variable. L'instruction if à la fin indique si Qflag a été mis à 1 et, si c'est le cas, envoie les erreurs de 'acommand' à la sortie standard et envoie la sortie standard standard à/dev/null (ce qui est différent de l'effet si les redirections d'E/S sont inversées - cela enverrait la sortie standard à/dev/null et enverrait l'erreur standard au même endroit, forçant le silence sur 'acommand').

L'utilisation de 'exec' est une optimisation triviale qui simplifie le traitement de l'état de sortie dans ce cas.

Testé avec 'acommand' qui imprime ses arguments sur des lignes distinctes:

#!/bin/sh 
for arg in "[email protected]" 
do echo "$arg" 
done 

et avec des lignes de commande tels que:

bash wrapper.sh -c -d 'arg with spaces' 

qui produit la sortie:

-c 
-d 
arg with spaces 

Évidemment, avec la redirection d'E/S en place, il n'y a pas de sortie de:Toutefois, si vous omettez la redirection d'E/S, vous obtenez la même sortie.

+0

Puisque vous utilisez Bash, il n'est pas nécessaire d'utiliser des guillemets et un "X" dans votre test - les guillemets seuls suffiront. –

+0

@ Dennis Williamson: Fine - j'ai grandi dans la vieille école; Au cours des 25 prochaines années, je m'y adapterai. Ce que j'ai écrit _does_ fonctionne, et la différence de coût est minime (comme dans, non mesurable). En outre, tous les opérateurs de test shell POSIX devraient être OK sans les X; Cependant, j'ai utilisé suffisamment de coques non conformes à POSIX pour ne pas risquer de se brûler. –

+0

J'ai grandi à la "vieille école" aussi. Beaucoup de mon script plus ancien ont des X dedans. –