我有以下 bash 功能,让我很困惑。如果我在 zenity 框中输入以下内容...
员工 ID = 2 类别 ID = 3
我得到以下信息:2 3
如果...
员工 ID = 类别 ID = 3
在第二个 zenity 窗口打开后,我输入 2 并得到以下信息:2 3
但是,当我进入
员工 ID = 2 类别 ID =
没有额外的 Zenity 窗口打开,我得到以下信息:2
在测试运行后,我真正想要的结果是 2,3。
有谁知道这里有什么问题?
#!/bin/bash
num(){
emp=$(echo "$1" | awk -F, -v OFS=, '{print $1 "," $2}')
IFS=, read -ra array1 <<<"$emp"
p=$(for i in "${array1[@]}"
do
if [[ "${i}" =~ ^[0-9]+$ ]]; then
out="${i}"
elif
[[ "${i}" = NULL ]]; then
out="${i}"
else local var2
until [[ ${var2} =~ ^[0-9]+$ ]] || [[ ${var2} = NULL ]]; do
var2="$(zenity --forms --title="table salaries_wages" --text "Add a number" --separator="," \
--add-entry="WARNING! You either forgot to enter or didn't enter a number. Please enter a valid number: ")"
done
out="${var2}"
fi
echo "$out"
done)
echo "$p"
}
input="$(zenity --forms --title="table salaries_wages" --text="Add a new salaries_wages entry" --separator="," \
--add-entry="ENTER employeeid: " \
--add-entry="ENTER categoryid: ")"
num "$input"
您对工作方式的假设与实际工作
read
方式不同read
。在 Bash 中运行此代码:你会得到
2
,2
,1
. 最后一个数字很突出。这意味着尾随分隔符(,
在这种情况下)read
更像是一个终止符:它没有被读入数组之后的空字段,并且数组最终成为一个太短的元素。如果这发生在您的代码中,那么for i in "${array1[@]}"
将只针对第一个字段运行循环。解决方法可能是故意引入一个额外的
,
作为尾随终止符。然后read
永远不会读取第三个字段,但它总是会读取两个字段(即使第二个字段为空)。当我添加额外内容时,请查看差异,
:输出是
2
每次。要以这种方式修复您的代码,请使用
<<<"$emp,"
而不是<<<"$emp"
.如果您修复代码,那么当
else
块运行不止一次时(即两个字段最初都无效时),它将出现异常;因为您再次重用该var2
变量。我猜你曾经
local var2
避免过这种情况,但是local
在函数中使变量局部化,而不是在else
块中或循环的单次迭代中for
。您在函数var2
的同一个实例中重用num
。您正在调用该函数一次。在内部它
var2
总是相同的var2
,local
只是使它与var2
外部的任何函数调用不同。如果您var2
在函数之外使用,则函数中的那个将是不同的。如果您num
多次调用,则每次调用都将使用自己的 distinctvar2
。这些都不会发生。您调用该函数一次并在那里重用该变量。当两个字段无效时,该变量用于第一个字段,然后再用于第二个字段。但是如果你重建你的代码,那么
validate
从循环中调用一些函数(例如):并
local var2
在validate
函数中使用,那么var2
在函数的每次调用中都是不同的。这是如何local
提供帮助的。在每个循环validate
中将被重新调用,其局部变量将被重新初始化,而与其他具有相同名称的变量没有任何连接。但是,您仍然可以在函数内以破坏某些内容的方式重用局部变量(类似于您当前var2
在num
函数中重用的方式)。在我写完以上内容后,在已链接的答案中添加了一个示例。
Note
p=$(stuff); echo "$p"
几乎等同于echo "$(stuff)"
,几乎总是应该是 juststuff
。请阅读详细说明的此答案var=$(stuff); echo "$var"
。