sudo使用什么shell

Pet*_*ert 2 linux bash shell sudo

我道歉,因为这必须是其他人提出的问题,但似乎谷歌证明.我正在试图弄清楚调用了什么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
Run Code Online (Sandbox Code Playgroud)

如果我用#!/ bin/sh指定命令解释器,它仍然会失败,但更具体的是#!/ bin/bash.

(现在)知道这[[是特定的bash但是尽管响应它似乎并不像sudo的默认shell是bash.

Joh*_*ica 9

简短回答:没有默认解释器.你的脚本需要#!/bin/bash顶部的shebang线.

答案很长: sudo不运行shell.它运行您直接传递的命令,没有中间shell.如果你想要一个shell,你需要明确地传递它.

sudo echo $0
Run Code Online (Sandbox Code Playgroud)

此命令具有误导性,因为调用之前$0由shell进行扩展.它打印您的当前,不是价值的内部"d环境.sudo$0$0sudo

让我们比较一些命令:

  • sudo ls
    Run Code Online (Sandbox Code Playgroud)

    /bin/ls直接执行可执行文件.没有涉及shell.当区别发挥作用时,将显示以下命令.

  • sudo ls /root/*
    Run Code Online (Sandbox Code Playgroud)

    当前的shell扩展了glob.如果你不能访问/root/那么glob不会扩展而你得到ls: cannot access /root/*: No such file or directory.

  • sudo 'ls /root/*'
    Run Code Online (Sandbox Code Playgroud)

    这会尝试执行一个名为的程序ls /root/*.从字面上看,它*root子目录中命名ls (ls带尾随空格).它失败了sudo: ls /root/*: command not found.

  • sudo ls '/root/*'
    Run Code Online (Sandbox Code Playgroud)

    这会运行/bin/ls并传递文字字符串/root/*.没有全球扩张.它失败了ls: cannot access /root/*: No such file or directory.

  • sudo bash -c 'ls /root/*'
    Run Code Online (Sandbox Code Playgroud)

    这将执行/bin/bash并插入ls /root/*命令行,扩展glob.最后,这个是有效的,因为我们有一个显式的shell来扩展glob,而我们正在扩展sudo而不是在它之外.


mkl*_*nt0 5

通过解决帖子标题所暗示的更普遍的问题来补充John Kugelman 的有用回答

附带说明:最好始终使用 shebang 行启动脚本,以明确控制它运行的 shell。

sudo默认情况下不运行外壳,但可以使用以下任一选项运行外壳:

  • -s (非登录外壳)
  • -i (登录外壳)

至于使用什么shell:manstates for -s(类似于-i;强调我的):

运行由 SHELL 环境变量指定shell(如果已设置)或由调用用户的密码数据库条目指定的 shell。如果指定了命令,则会通过 shell 的 -c 选项将其传递给 shell 以执行。如果未指定命令,则执行交互式 shell。

换句话说:sudo使用当前用户的默认shell。