Shell 用于为 PERL 脚本构建 CLI args 的脚本
Shell script to build CLI args for a PERL script
我有一个 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
的方法,但到目前为止都没有成功。我哪里出错了?
您似乎无法在 $cmd_options
、
中嵌入列表
因为它会阻止您正确使用引号 -
"escaping" 带反斜杠的引号 (\"
)
将它们转换为常规 "
字符 - 而不是定界符,因此,
它们只是连接到 $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
没有空格 -
它将允许将列表作为单个参数传递,并且不再需要引号。
构建命令时,延迟插值并使用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
假设您不再需要脚本的位置参数,您可以自己设置它们。 (这将适用于数组不可用的任何 POSIX shell。)
# Save any positional parameters first, if necessary;
# we're going to overwrite them.
first_arg=
second_arg=
# etc.
set -- --hostnames "$HOSTNAMES"
perl myscript.pl "$@"
我有一个 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
的方法,但到目前为止都没有成功。我哪里出错了?
您似乎无法在 $cmd_options
、
中嵌入列表
因为它会阻止您正确使用引号 -
"escaping" 带反斜杠的引号 (\"
)
将它们转换为常规 "
字符 - 而不是定界符,因此,
它们只是连接到 $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
没有空格 -
它将允许将列表作为单个参数传递,并且不再需要引号。
构建命令时,延迟插值并使用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
假设您不再需要脚本的位置参数,您可以自己设置它们。 (这将适用于数组不可用的任何 POSIX shell。)
# Save any positional parameters first, if necessary;
# we're going to overwrite them.
first_arg=
second_arg=
# etc.
set -- --hostnames "$HOSTNAMES"
perl myscript.pl "$@"