以下是重新配置 grub 的 bash 脚本的摘录
OLD="/etc/default/grub"
NEW="/tmp/default.grub"
SEC="1"
cp "$OLD" "$NEW" || { >&2 echo "Couldn't copy $OLD" && exit 1; }
sed -i "s/GRUB_TIMEOUT=[0-9]\+/GRUB_TIMEOUT=3/$SEC" "$NEW"
cp_if_change_confirmed "$NEW" "$OLD"
diff "$OLD" "$NEW" >/dev/null 2>&1 && \
{
CFG="$NEW.made"
grub2-mkconfig --output="$CFG"
echo "made $CFG from $NEW"
cp_if_change_confirmed "$CFG" "/boot/grub2/grub.cfg"
echo rm "$CFG"
rm "$CFG"
}
echo rm "$NEW"
rm "$NEW"
这些最终echo
和rm
行输出
rm /tmp/default.grub.made
rm /tmp/default.grub.made
rm: cannot remove ‘/tmp/default.grub.made:‘ No such file or directory
以某种方式NEW
被赋予了 的值CFG
。
查看cp_if_change_confirmed
bash 函数,它包含
NEW="$1"
我想这解释了问题所在——这些变量的范围不够有限。
但这是一个维护问题——我需要能够包含第三方函数并且知道它们不会破坏父脚本中的值。
我可以在 bash 中执行此操作吗?或者这是一个无望的情况,我只需要对变量名保持警惕或使用真正的语言?
答案1
使用local
。请注意,bash 有仅有的函数作用域(类似var
JavaScript),而不是块作用域。
myfunc() {
local foo bar=$1 baz=$2
foo=/tmp/$bar
echo "value inside: $foo, $bar"
}
foo=123 bar=234
myfunc quux
echo "value outside: $foo, $bar"
如果你有一个不需要的区块任何持久性,你可以使用以下命令调用子 shell ( ... )
:
foo=123
( foo=345; echo "value inside: $foo" )
echo "value outside: $foo"
请注意,子 shell 具有 fork() 的全部开销 - 它们是独立的进程。此外,它们不允许您选择要本地化的变量 - 要么全部,要么全部。