Bash解析&连接执行python的参数

时间:2012-05-14 08:27:41

标签: python bash unix arguments

我有一个bootstrap(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'']& ['“我的','测试'']而不是保持联合。

我的代码有什么问题吗?

谢谢堆!


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

1 个答案:

答案 0 :(得分: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}(当然,如果您愿意,可以单独使用)。

我更改了您的数组附加到更简单的+=表单并添加了引用。