Bash parse & concatenate arguments pour exécuter python

J’ai un bootstrap (bash) qui devrait filtrer certains arguments avant de lancer le script python propper.

Le problème est que chaque fois que je passe une chaîne avec des espaces dans le bootstrap, elle devient une fois arrachée à python.

par ex.

./myBootStrap.sh --preload "argl bargl" -j -as -argl --postload "my Test" 

imprime ceci

 Executing myBootStrap --preload "argl bargl" -j -as -argl --postload "my Test" 

et mon script python imprime son argument

 got arguments ['myBootStrap','--preload', '"argl', 'bargl"', '-j', '-as', '-argl', '--postload', '"my', 'Test"'] 

Comme vous le voyez, “argl bargl” et “my Test” sont divisés en [‘”argl”, “bargl”‘] & [‘”my’, ‘Test”‘] au lieu de restr combinés.

une idée de ce qui ne va pas avec mon code?

merci des tas!


myBootStrap.sh

 #!/bin/bash declare -a argv for ((i=1;i<=${#@};i+=1)) do arg=${@:i:1} if [[ "$arg" == "--preload"* ]];then i=$i+1 marg=${@:$((i)):1} preLoadO=$arg preLoadA=" \"${marg}\"" argv=("${argv[@]}" $arg) argv=("${argv[@]}" $preLoadA) elif [[ "$arg" == "--postload"* ]];then i=$i+1 marg=${@:$((i)):1} postLoadO=$arg postLoadA=" \"${marg}\"" argv=("${argv[@]}" $arg) argv=("${argv[@]}" $postLoadA) else argv=("${argv[@]}" $arg) fi done arguments=$(printf " %s" "${argv[@]}") arguments=${arguments:1} echo "Executing myBootStrap" $arguments exec myBootStrap $arguments 

et le script python myBootStrap

 #!/usr/bin/env python import sys print 'got arguments %s'%sys.argv 

Citer presque toujours corrige ce type de problème.

 exec myBootStrap "$arguments" 

Démo:

 $ a='"abc def" ghi' $ echo "$a" "abc def" ghi $ args $a 3 args: <"abc>   $ args "$a" 1 args: <"abc def" ghi> $ cat args #! /bin/sh # Greg Wooledge's args script printf "%d args:" $# printf " <%s>" "$@" echo 

Modifier :

OK, j’ai passé du temps à parsingr ce que fait votre script Bash. Il faut faire beaucoup de mouvements pour essayer de produire exactement les mêmes arguments que ceux qui ont été donnés, puis les transmettre au script Python.

Il pourrait simplement être remplacé par:

 exec myBootStrap "$@" 

Cependant, je présume que vous êtes en train de faire un autre traitement que nous ne voyons pas. Sur cette base, j’ai modifié votre script pour pouvoir l’utiliser comme base.

 #!/bin/bash declare -a argv for ((i = 1; i <= $#; i += 1)) do arg=${@:i:1} if [[ "$arg" == "--preload"* ]]; then marg=${@: ++i:1} preLoadO=$arg preLoadA="${marg}" argv+=("$arg") argv+=("$preLoadA") elif [[ "$arg" == "--postload"* ]]; then marg=${@: ++i:1} postLoadO=$arg postLoadA="${marg}" argv+=("$arg") argv+=("$postLoadA") else argv+=("$arg") fi done exec ./myBootStrap "${argv[@]}" 

Les arguments doivent être passés en tant que tableau cité. Vous avez déjà construit le tableau, mais vous l'avez ensuite aplati avec un printf .

Notez qu'une tranche de tableau est déjà un contexte arithmétique, vous n'avez donc pas besoin de $(()) . J'ai enlevé le i=i+1 séparé (qui concatène les caractères pour obtenir 1+1+1+1 après un moment) et je mets juste un pré-incrément dans la tranche de tableau. L'espace avant le premier plus est requirejs puisque :+ est significatif dans une extension d'accolade. Si vous voulez, vous pouvez faire l'incrément séparément comme ceci: ((i++)); marg=${@:i:1} ((i++)); marg=${@:i:1} (bien sûr sur des lignes séparées si vous préférez).

J'ai changé votre tableau ajoute à la forme beaucoup plus simple += et leur ai ajouté des guillemets.