1

我有一个引导程序(bash),它应该在启动propper python 脚本之前过滤掉一些参数。

问题是,每当我将带有空格的字符串传递给引导程序时,一旦到达 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"']

如您所见,“argl bargl”和“my Test”被拆分为 ['"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

编辑

好的,我花了一些时间分析您的 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 回答