我想将字符串参数传递给Bash过程。此过程在控制台上打印字符串,并将副本打印到文件。
在我的用例中,该文件将包含Bash脚本中所有已执行命令的列表,可用于以相同顺序重新运行所有指令。如果发生错误并且我需要将 reproducer 脚本发送到GitHub上的一个开放源代码项目,则需要这样做。还将所有使用过的文件复制到目录中,以便以后创建ZIP文件。
那么,让我们谈谈Bash代码:
#! /bin/bash
open() {
local File=$1
exec 3<> "$File"
}
close() {
exec 3>&-
}
procedure1() {
echo "$1"
echo "echo \"$1\"" >&3
}
procedure2() {
echo "$1" "$2"
echo "echo \"$1\" \"$2\"" >&3
}
procedure3() {
echo "$@"
echo "echo \"$@\"" >&3
}
# ==============================================================================
OUTPUT_FILE="output.sh"
Program_A="foo"
Paramater_A=(
--spam
--egg=4
)
Program_B="bar"
Paramater_B=(
--ham
--spice=4
)
open $OUTPUT_FILE
echo "$Program_A -a ${Paramater_A[@]}"
echo "$Program_B -b ${Paramater_B[@]}"
echo
procedure1 "$Program_A -a ${Paramater_A[@]}" "$Program_B -b ${Paramater_B[@]}"
procedure2 "$Program_A -a ${Paramater_A[@]}" "$Program_B -b ${Paramater_B[@]}"
procedure3 "$Program_A -a ${Paramater_A[@]}" "$Program_B -b ${Paramater_B[@]}"
close
echo
echo -e "\e[33m========================================\e[0m"
echo -e "\e[33mReading output file from disk\e[0m"
echo -e "\e[33m========================================\e[0m"
echo
cat $OUTPUT_FILE
控制台输出为:
$ ./test.sh
foo -a --spam --egg=4
bar -b --ham --spice=4
foo -a --spam
foo -a --spam --egg=4
foo -a --spam --egg=4 bar -b --ham --spice=4
========================================
Reading output file from disk
========================================
echo "foo -a --spam"
echo "foo -a --spam" "--egg=4"
echo "foo -a --spam --egg=4 bar -b --ham --spice=4"
所以我看到的是,".... ${Parameter_A[@]} ..."
包含在字符串中,但是将字符串分成多个字符串。这就是为什么过程中的$1
包含包含第一个参数值的字符串。
如何将所有参数嵌入单个字符串而不将其分解为多个字符串?
$@
可以打印所有文本,因为它包含传递给该过程的所有参数。但是,这不是我的解决方案,因为我无法区分$2
中的字符串何时开始或换句话说,$1
中有多少部分。
答案 0 :(得分:0)
根据Cyrus的提议,我使用shellcheck.net检查我的Bash脚本。
以下是检查器的输出:
$ shellcheck myscript
Line 24:
echo "echo \"$@\"" >&3
^-- SC2145: Argument mixes string and array. Use * or separate argument.
Line 33:
--egg=4
^-- SC2191: The = here is literal. To assign by index, use ( [index]=value ) with no spaces. To keep as literal, quote it.
Line 39:
--spice=4
^-- SC2191: The = here is literal. To assign by index, use ( [index]=value ) with no spaces. To keep as literal, quote it.
Line 44:
echo "$Program_A -a ${Paramater_A[@]}"
^-- SC2145: Argument mixes string and array. Use * or separate argument.
Line 45:
echo "$Program_B -b ${Paramater_B[@]}"
^-- SC2145: Argument mixes string and array. Use * or separate argument.
Line 47:
procedure1 "$Program_A -a ${Paramater_A[@]}" "$Program_B -b ${Paramater_B[@]}"
^-- SC2145: Argument mixes string and array. Use * or separate argument.
>> ^-- SC2145: Argument mixes string and array. Use * or separate argument.
Line 48:
procedure2 "$Program_A -a ${Paramater_A[@]}" "$Program_B -b ${Paramater_B[@]}"
^-- SC2145: Argument mixes string and array. Use * or separate argument.
>> ^-- SC2145: Argument mixes string and array. Use * or separate argument.
Line 49:
procedure3 "$Program_A -a ${Paramater_A[@]}" "$Program_B -b ${Paramater_B[@]}"
^-- SC2145: Argument mixes string and array. Use * or separate argument.
>> ^-- SC2145: Argument mixes string and array. Use * or separate argument.
它表明已使用的@
需要更改为*
。双引号中包含的@
扩展为双引号中包含的每个数组元素,而*
扩展为字符串。