Alpine Linux中&&运算符未按预期生效的原因排查
问题
在alpine:3.16镜像中执行如下脚本:
#!/bin/sh -e wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.32-r0/glibc-2.32-r0.apk apk add glibc-2.32-r0.apk && rm glibc-2.32-r0.apk sleep 1
执行后apk add命令明确报错:
/ # ./script.sh Connecting to github.com (140.82.121.3:443) Connecting to objects.githubusercontent.com (185.199.108.133:443) saving to 'glibc-2.32-r0.apk' glibc-2.32-r0.apk 100% |**************************************************************************************************************************************************************************************************| 4331k 0:00:00 ETA 'glibc-2.32-r0.apk' saved (1/1) Installing glibc (2.32-r0) ERROR: glibc-2.32-r0: trying to overwrite etc/nsswitch.conf owned by alpine-baselayout-data-3.2.0-r23. 1 error; 44 MiB in 20 packages / # echo $? 0
但脚本仍执行成功,且apk add ... && rm ...中的&&运算符未按预期阻止后续rm命令执行,请问原因是什么?
原因分析
核心原因是**apk add在安装失败时仍返回退出码0**,这直接导致了后续逻辑的异常:
&&的执行逻辑:&&仅当前序命令返回退出码0时,才会执行后续命令。由于apk add返回了0,所以rm命令被正常触发。#!/bin/sh -e的作用限制:脚本开头的-e选项会在命令返回非0退出码时终止脚本,但因为apk add返回的是0,脚本不会中断,会继续执行到最后。
之所以apk add会返回0,是因为它的设计逻辑:文件冲突这类安装错误属于"非致命"错误,不会触发非0退出码;只有遇到找不到包、系统依赖完全无法满足等严重错误时,才会返回非0值。
内容的提问来源于stack exchange,提问作者pkaramol
相关产品推荐
相关产品推荐

