1

我有一份 Jenkins 工作,作为参数化构建触发。它接受一个可选的字符串参数 (HOSTNAMES),该参数可以是逗号分隔的主机名列表。

我需要将此逗号分隔的主机名列表作为命令行参数传递给 PERL 脚本(在执行 shell 构建步骤中)。

以下是我在执行 shell 构建步骤中处理输入参数和构造命令行参数的方式:

cmd_options=''
echo hostnames is $HOSTNAMES
if [ "$HOSTNAMES" != "" ]
  then
  cmd_options+=" --hostnames \"$HOSTNAMES\""
fi
perl myscript.pl $cmd_options

不过,在构建的控制台输出中,我看到参数传递不正确。这是控制台输出:

+ cmd_options=
+ echo hostnames is host1, host2
hostnames is host1, host2
+ '[' 'host1, host2' '!=' '' ']'
+ cmd_options+=' --hostnames "host1, host2"'
+ perl myscript.pl --hostnames '"host1,' 'host2"'

我想myscript.pl被这样称呼:

perl myscript.pl --hostnames "host1, host2"

我尝试了各种$cmd_options使用单引号和双引号进行操作的方法,但到目前为止都没有成功。任何关于我哪里出错的指示?

4

3 回答 3

2

当您构建命令时,延迟插值并使用eval它来执行它。

HOSTNAMES='host1, host2'

cmd_options=''
if [ "$HOSTNAMES" != "" ]; then
   cmd_options+='--hostnames "$HOSTNAMES"'
fi

eval "prog $cmd_options"

更好的解决方案是使用数组。

HOSTNAMES='host1, host2'

cmd_options=()
if [ "$HOSTNAMES" != "" ]; then
   cmd_options+=(--hostnames "$HOSTNAMES")
fi

prog "${cmd_options[@]}"

如果prog是以下程序:

#!/usr/bin/perl
use feature qw( say );
say 0+@ARGV; say for @ARGV

两个片段都输出以下内容:

2
--hostnames
host1, host2
于 2015-04-24T17:39:37.600 回答
0

看起来您将无法在其中嵌入列表$cmd_options
因为它会阻止您正确使用引号- 用反斜杠 ( )
“转义”引号 会将它们转换为常规字符 - 而不是分隔符,并且作为因此, 它们只是连接到列表的第一项和最后一项。\"
"
$HOSTNAMES

建议您删除此行:

cmd_options+=" --hostnames \"$HOSTNAMES\""

而是根据需要使用以下两行
(假设您仍然需要$cmd_options传递其他参数)

perl myscript.pl $cmd_options --hostnames "$HOSTNAMES"
perl myscript.pl $cmd_options

包装在一个if语句中,它应该如下所示:

if [ "$HOSTNAMES" != "" ]
then
  perl myscript.pl $cmd_options --hostnames "$HOSTNAMES"
else
  perl myscript.pl $cmd_options
fi

另一种选择是确保列表中没有空格$HOSTNAMES-
它允许将列表作为单个参数传递,并且不再需要引号。

于 2015-04-24T14:22:13.993 回答
0

假设您不再需要脚本的位置参数,您可以自己设置它们。(这将适用于任何 POSIX shell,其中数组不可用。)

# Save any positional parameters first, if necessary;
# we're going to overwrite them.
first_arg=$1
second_arg=$2
# etc.
set -- --hostnames "$HOSTNAMES"
perl myscript.pl "$@"
于 2015-04-25T12:45:47.063 回答