You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何./test.sh与sh test.sh执行同Shell脚本结果不同?

两种Shell脚本执行方式结果不同的原因解析

问题背景

测试脚本

#!/bin/sh
echo "$PATH"
[ "$UID" -eq 0 ] || exec sudo "$0" "$@"
echo "$UID"
echo "$SUDO_USER"

执行结果差异

  1. 通过./test.sh执行:无限循环输出如下内容
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin  
./test.sh: 3: [: Illegal number:  
...
  1. 通过sh test.sh执行:仅输出一次后终止
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin  
test.sh: 3: [: Illegal number:  
sudo: test.sh: command not found  

环境信息

  • 已安装sudo
  • 系统默认sh链接至dash
  • 系统内核版本:
Linux version 5.19.0-32-generic (buildd@lcy02-amd64-026) (x86_64-linux-gnu-gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #33~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC

原因解析

1. $0变量取值差异是循环/终止的关键

  • ./test.sh执行场景:
    $0的值为./test.sh,当执行sudo "$0"时,./明确指定了当前目录的相对路径,sudo能直接找到并执行脚本。但由于后续判断逻辑始终不成立,会反复触发sudo "$0",形成无限循环。

  • sh test.sh执行场景:
    $0的值为test.sh,执行sudo "$0"时,sudo会在$PATH配置的系统目录中查找该脚本,但你的$PATH未包含当前工作目录(.),因此找不到test.sh,报错后脚本直接终止,不会进入循环。

2. dash不支持$UID是判断逻辑失效的根源

bash内置了$UID变量存储当前用户ID,但你的系统默认sh是dash——dash作为POSIX标准的轻量shell,没有内置$UID变量,所以脚本中$UID的值为空字符串。这就导致[ "$UID" -eq 0 ]变成[ "" -eq 0 ],触发[: Illegal number:的语法错误,条件判断结果为假,进而触发exec sudo "$0"的逻辑,这也是两种执行方式都会出现错误提示的原因。

内容的提问来源于stack exchange,提问作者er3s56

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 02:00:30