我很抱歉,因为这是一个其他人问过的问题,但它似乎谷歌证明。我试图找出什么shell被调用,因为我遇到了一个不一致。我的脚本不工作,如果我sudo
,但工作,如果我sudo bash
。然而,当我sudo echo $0
,它说bash。
cpu=$(cat /proc/cpuinfo | grep Revision | cut -d' ' -f 2-);
if [[ "a22082" = $cpu || "a02082" = $cpu ]]; then
echo 'do stuff';
fi
如果我用 #!/bin/sh 指定命令解释器,它仍然会失败,但更具体的 #!/bin/bash 会失败。
我 (现在) 知道[[
是特定于bash的,但尽管有响应,但sudo的默认shell似乎不是bash。
2条答案
按热度按时间shstlldc1#
**简答:**没有默认的解释器,你的脚本需要在顶部有一个shebang行
#!/bin/bash
。详细回答:
sudo
不运行shell,直接传递命令就运行,没有中间shell,如果需要shell需要显式传递。这个命令是误导性的,因为
$0
在sudo
被调用 * 之前被shell * 展开。它打印的是当前的$0
,而不是sudo
环境中的$0
的值。让我们比较一些命令:
这将直接执行
/bin/ls
可执行文件。不涉及shell。下面的命令将显示何时进行区分。当前shell展开glob。如果您无法访问
/root/
,则glob不会展开,您将得到ls: cannot access /root/*: No such file or directory
。这将尝试执行一个名为
ls /root/*
的程序。从字面上看,它的名称为*
,位于ls
的root
子目录中(ls
后面有一个空格)。它失败并返回sudo: ls /root/*: command not found
。这将运行
/bin/ls
并传递给它文字字符串/root/*
。没有glob扩展。它会失败并传递ls: cannot access /root/*: No such file or directory
。这个函数执行
/bin/bash
,并插入ls /root/*
命令行,扩展glob。这个函数终于可以工作了,因为我们有一个显式的shell来扩展glob,而且我们是在sudo
内部而不是外部进行扩展。2exbekwf2#
为了补充John Kugelman's helpful answer,解决了帖子标题所暗示的更一般的问题:
顺便说一句:最好总是以shebang行开始脚本,以显式地控制运行它的shell。
sudo
不运行shell * 默认情况下 *,但可以使用以下任一选项运行shell:-s
(非登录shell)$SHELL
环境变量指定的shell(如果已定义),否则使用在用户密码数据库条目(/etc/passwords
)中定义的shell-i
(登录shell,始终使用用户的shell)换句话说:**
sudo
使用 * 当前 * 用户的默认shell,除非通过$SHELL
**覆盖(仅适用于-s
)。详情请参见
man sudo
。