V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
amiwrong123
V2EX  ›  程序员

用 echo 来代替输入密码后,为什么要执行两遍 sudo su?

  •  
  •   amiwrong123 · 2023-08-10 22:09:14 +08:00 · 2325 次点击
    这是一个创建于 506 天前的主题,其中的信息可能已经有所发展或是发生改变。

    正常情况下,用远程登录工具 登录 linux 机器后,需要 sudo su 一下切换到 root 用户。 就是两步:sudo su ;输入密码 回车;

    但是我现在想用 echo 代替输入密码这一步:也就是 echo ' ' | sudo su ,这里我的密码是空格。 然后我发现执行完 echo ' ' | sudo su ,用户并没有切换。但马上我再执行一遍 sudo su ,此时不需要输入密码马上就切换到 root 用户了。

    有两点不明白:

    1. 为什么执行 echo ' ' | sudo su 不会马上切换用户?
    2. 为什么第二步执行 sudo su 不需要密码,并且为什么要第二步才会切换过去?
    19 条回复    2023-08-11 09:09:05 +08:00
    ganxiyun
        1
    ganxiyun  
       2023-08-10 22:15:54 +08:00
    第一步没有出现让你输入一遍密码嘛?


    另外,echo ' '| sudo -S su 试试
    amiwrong123
        2
    amiwrong123  
    OP
       2023-08-10 22:19:05 +08:00
    @ganxiyun
    第一步没有出现让你输入一遍密码嘛?
    --
    没有。

    echo ' '| sudo -S su 也是一样,要走第二步。
    busier
        3
    busier  
       2023-08-10 22:20:44 +08:00
    用户本身属于 sudo 组的话,切换到 root 环境应该使用 sudo -i 命令!
    amiwrong123
        4
    amiwrong123  
    OP
       2023-08-10 22:21:09 +08:00
    @ganxiyun
    echo ' ' | sudo su 会让输入一遍密码。帖子写错了,第一个命令是,echo ' '| sudo -S su ,然后还需要第二步。
    V2ALL2B
        5
    V2ALL2B  
       2023-08-10 22:25:49 +08:00
    谁教你这样玩的?
    echo 'password' | sudo su 相当于把 password 当成 command ,用 sudo 权限来执行
    等于 sudo password
    V2ALL2B
        6
    V2ALL2B  
       2023-08-10 22:28:28 +08:00   ❤️ 1
    第二遍 sudo su 不需要密码,是因为短时间内 sudo 只需要验证一次密码,你隔很长时间再执行第二遍 sudo su ,同样会再次要求输入密码的
    amiwrong123
        7
    amiwrong123  
    OP
       2023-08-10 22:34:26 +08:00
    @V2ALL2B
    我是有这么一个需求,远程登录上后,总是会执行一次 sudo su 。
    但我发现远程登录工具,有一个高级功能,就是登录上后,自动帮你执行一些命令,我就想让这个自动功能,帮我把 sudo su 给做了。
    但是这样的话,必须要用 echo 'password' | sudo su 的形式。

    本质上,是为了每次 少输一个命令。
    amiwrong123
        8
    amiwrong123  
    OP
       2023-08-10 22:36:20 +08:00
    @V2ALL2B
    本质等于 sudo password 吗,但我执行 sudo ' '也不会成功的呀
    geelaw
        9
    geelaw  
       2023-08-10 22:38:35 +08:00   ❤️ 1
    虽然不用 Linux ,但是可以尝试一下 psychic debugging 。

    我的猜想是 sudo 启动的 su 会继承 sudo 的标准文件,而 su 启动的 shell 进程又会继承 su 的标准文件。因此第一次运行 echo ' ' | sudo -S su 的结果是 su 的标准输入是 echo 的标准输出,然后启动的 shell 的标准输入是 echo 的标准输出,此时 shell 认为标准输入是需要执行的命令,这是空的,因此直接结束了。

    测试:echo 'echo 1' | bash 的结果是 1 ,并且回到了开始的 shell 进程。

    楼主可以试试(注意第一行的结尾是单引号加上空格)

    echo '
    echo 1' | sudo --stdin su

    是否会得到 1 并且回到开始的 shell 进程。(我并不知道 sudo 是否会读取多行密码……)
    V2ALL2B
        10
    V2ALL2B  
       2023-08-10 22:39:31 +08:00
    @amiwrong123 你这么干也太不安全了,把密码什么的都给远程工具是一件很危险的事情
    如果某个指令必须用 sudo 权限执行,干脆把这个指令放到 /etc/sudoers.d 下面去,这样 sudo group 的用户不需要验证密码也可以顺利执行
    V2ALL2B
        11
    V2ALL2B  
       2023-08-10 22:42:17 +08:00
    @amiwrong123 sudo ' ' 当然不会成功啊,你的密码又不是系统里的任何指令,你怎么成功啊?
    意思就是 echo 'password' | sudo su 压根就是个非法行为,你的想法是错的
    ganxiyun
        12
    ganxiyun  
       2023-08-10 23:15:43 +08:00
    @amiwrong123 第二个问题的第一个小问题,可以看 man sudo ,


    Security policies may support credential caching to allow the user to run
    sudo again for a period of time without requiring authentication. By de‐
    fault, the sudoers policy caches credentials on a per-terminal basis for
    15 minutes. See the timestamp_type and timestamp_timeout options in
    sudoers(5) for more information. By running sudo with the -v option, a
    user can update the cached credentials without running a command.


    可以加个参数,可以看到第二次也要 password 了

    -k, --reset-timestamp
    When used without a command, invalidates the user's cached
    credentials. In other words, the next time sudo is run a
    password will be required. This option does not require a
    password, and was added to allow a user to revoke sudo per‐
    missions from a .logout file.
    ganxiyun
        13
    ganxiyun  
       2023-08-10 23:16:39 +08:00
    第二个问题中的第二个小问题,不知道原因。
    panzhc
        14
    panzhc  
       2023-08-11 01:14:20 +08:00
    第一个问题,如果 sudo 没有做特殊配置,应该会要求输入密码,除非做了 alias sudo='sudo -S '之类的别名,这时候会从标准输入读取密码,-S 是 --stdin ,否则是从 tty 读取密码。
    第一个命令结束的时候,echo 完成了标准输出,sudo 完成了标准输入,所以命令就退出了。
    第二个问题的第一部分好理解,因为第一个命令已经给了密码,还在有效期内。
    推荐配置实现免密,或者尝试 expect 类的工具,因为直接带密码的命令会被记录到 history 。
    如果是第一次配置或者因为什么特别的原因,可以试试 SUDO_ASKPASS
    azel
        15
    azel  
       2023-08-11 01:51:58 +08:00
    是不是可以换一种思路,把当前用户的 sudo 命令设置成免密。
    nuk
        16
    nuk  
       2023-08-11 05:13:13 +08:00
    su 是基于 pam 框架的,你想要 su 不用输入密码,就给自己用户 wheel 组权限,然后在/etc/pam.d/su 设置 wheel 直接通行就行了
    # Uncomment this if you want wheel members to be able to
    # su without a password.
    # auth sufficient pam_wheel.so trust
    nuk
        17
    nuk  
       2023-08-11 05:23:50 +08:00
    如果实在是想把 root 密码写进脚本,可以这样
    $ echo $pass | sshpass su root -c id
    uid=0(root) gid=0(wheel) groups=0(wheel),5(operator)
    davidpi
        18
    davidpi  
       2023-08-11 05:50:21 +08:00
    你那个 sudo 是执行在 pipe 里面的,一个 subshell ,影响不了父进程也就是你的 shell 。正确写法是:
    `sudo su <<<' '`
    tairan2006
        19
    tairan2006  
       2023-08-11 09:09:05 +08:00
    那啥,你的解决思路是错的

    正确的做法是使用`visudo`工具,给自己或者 sudo 组加上 `NOPASSWD`标识

    后面输入 sudo su 就不需要密码了…
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2746 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 12:08 · PVG 20:08 · LAX 04:08 · JFK 07:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.