Bash 脚本没有退出没有子壳的"exit"(我认为)



我正在使用stow来管理我的点文件,我正在编写一个可以自动设置我的电脑和软件包的脚本。我把所有的配置文件都放在config文件夹中,这就是stow文件夹。我基本上要做的是获取该文件夹中所有文件夹(包(的名称,并将它们存放到我的主目录中。我还有一个函数,它简单地告诉我是否有错误并退出脚本。

我在最近安装的Arch Linux上运行这个脚本,在tty上(我还没有安装窗口管理器(。当它进入stow-bash时,它失败了,因为.bashrc已经存在于home中。它给了我错误消息,但它没有退出,我找不到原因。我不认为我在子shell上运行error函数,就像我从其他有这个问题的人那里看到的那样,除非我在这里缺少了什么。。。

功能如下:

error () {
echo "!! ${1} !!"
exit 1
}

后来我有了这样的东西:

ls -1 config | while read line; do
stow -d config -t ~ -R "${line}" || error "Failed to stow ${line}."
done

以下是从创建函数到装载的全部代码:

step () {
echo "> ${1}"
}
substep () {
echo "--> ${1}"
}
error () {
echo "!! ${1} !!"
exit 1
}
success () {
echo "** ${1} **"
}
commandexists () {
# Check if a command exists
command -v $1 &> /dev/null
if [[ $? -eq 0 ]]; then
return 0
else
return 1
fi
}
pkg-install () {
pkg="${1:?"Error: pkg parameter unset."}"
step "${msg_install}: ${pkg}"
substep "Installing ${pkg} from the Arch Linux Repositories."
sudo pacman -Sy --noconfirm --needed "$pkg"
if [[ $? -ne 0 ]]; then
substep "Installing ${pkg} from the Arch User Repositories."
yay -Sy --noconfirm --needed "$pkg" || error "${msg_fail_install}: ${pkg}"
fi
success "${msg_success_install}: ${pkg}"
}
# Stop installation if yay is not installed
commandexists yay || error "Yay is not installed! Please install yay and try again."
# stow
pkg-install stow
step "Stowing config files"
ls -1 config | while read line; do
substep "Stowing ${line}"
stow -d config -t ~ -R "${line}" || error "Failed to stow ${line}."
done
success "Successfully stowed all config files"

正如您所看到的,在装载之前,通过检查命令是否存在来检查yay是否已安装。如果没有,它会给我一个错误并退出。当我在另一台没有安装yay的电脑上运行此程序时,它可以正常工作。它告诉我yay没有安装,并停在那里。但是,当我在安装了yay的电脑上运行它时,为什么它会忽略stow部分中的exit命令?

在这种特殊情况下,您可以将while循环保留在父shell中,同时将ls移动到子shell中:

while IFS= read -r line; do
stow -d config -t ~ -R "${line}" || error "Failed to stow ${line}."
done < <(ls -1 config)

(使用IFS=可以使代码正确处理以空格开头或结尾的名称;使用-r可以使代码正常处理包含反斜杠的名称(。


。。。但在实践中不要这样做;ls输出不适合编程使用。

相反,使用glob:

for path in config/*; do
[[ -e $path || -L $path ]] || continue # detect case where config/ was empty
file=${path%config/}                   # strip the config/ off the name
stow -d config -t ~ -R "$file" || error "Failed to stow $file"
done

相关内容

  • 没有找到相关文章

最新更新