1

適切なPythonスクリプトを開始する前に、いくつかの引数を除外するブートストラップ(bash)があります。

問題は、スペースを含む文字列をブートストラップに渡すと、Pythonに到達すると壊れてしまうことです。

例:実行

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

これを印刷します

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

そして私のPythonスクリプトはその引数を出力します

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

ご覧のとおり、「arglbargl」と「myTest」は、結合されたままではなく、['"argl'、'bargl"']と['"my'、'Test"']に分割されます。

私のコードの何が問題になっていますか?

ヒープに感謝します!


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 

およびPythonスクリプトmyBootStrap

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

1 に答える 1

4

ほとんどの場合、引用するとこのタイプの問題が修正されます。

exec myBootStrap "$arguments"

デモ:

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

編集

OK、私はあなたのBashスクリプトが実際に何をしているのかを分析するのに少し時間を費やしました。与えられたのとまったく同じ引数を生成し、それらをPythonスクリプトに渡すために、多くの回転が行われます。

簡単に次のように置き換えることができます。

exec myBootStrap "$@"

ただし、実際には、ここでは表示されない他の処理を行っていると思います。これに基づいて、スクリプトを変更して、そのようなものの基礎として使用できるようにしました。

#!/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[@]}"

引数は引用符で囲まれた配列として渡す必要があります。すでに配列を作成しましたが、それを。でフラット化しましたprintf

配列スライスはすでに算術コンテキストであるため、その中には必要ないことに注意してください$(())。セパレートi=i+1(文字を連結1+1+1+1してしばらくすると取得できるようにする)を削除し、配列スライス内にプリインクリメントを配置しました。:+ブレース拡張の内側で重要であるため、最初のプラスの前のスペースが必要です。必要に応じて、次のように個別にインクリメントを実行できます((i++)); marg=${@:i:1}(もちろん、必要に応じて個別の行で)。

配列の追加をはるかに単純な+=形式に変更し、引用符を追加しました。

于 2012-05-14T13:34:01.120 に答える