0
Here's an extract from a bash script to reconfigure grub
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"
Those final echo
and rm
lines output
rm /tmp/default.grub.made
rm /tmp/default.grub.made
rm: cannot remove ‘/tmp/default.grub.made:‘ No such file or directory
Somehow NEW
is being assigned the value of CFG
.
Looking in cp_if_change_confirmed
, which is a bash function, it contains
NEW="$1"
Which I guess explains the problem -- these variables don't have limited-enough scope.
But this is a maintenance problem -- I need to be able to include third party functions and know that they're not going to clobber values in the parent script.
Can I do this in bash, or is it a hopeless case and I just need to either be vigilant about variable names or use a real language?
In functions, use
local
. A real language would make sense for larger scripts, with Perl or Ruby you don't have to go that far from the shell syntax. – choroba – 2016-10-07T11:03:26.377