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

275 天前
 amiwrong123

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

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

有两点不明白:

  1. 为什么执行 echo ' ' | sudo su 不会马上切换用户?
  2. 为什么第二步执行 sudo su 不需要密码,并且为什么要第二步才会切换过去?
2028 次点击
所在节点    程序员
19 条回复
ganxiyun
275 天前
第一步没有出现让你输入一遍密码嘛?


另外,echo ' '| sudo -S su 试试
amiwrong123
275 天前
@ganxiyun
第一步没有出现让你输入一遍密码嘛?
--
没有。

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

本质上,是为了每次 少输一个命令。
amiwrong123
275 天前
@V2ALL2B
本质等于 sudo password 吗,但我执行 sudo ' '也不会成功的呀
geelaw
275 天前
虽然不用 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
275 天前
@amiwrong123 你这么干也太不安全了,把密码什么的都给远程工具是一件很危险的事情
如果某个指令必须用 sudo 权限执行,干脆把这个指令放到 /etc/sudoers.d 下面去,这样 sudo group 的用户不需要验证密码也可以顺利执行
V2ALL2B
275 天前
@amiwrong123 sudo ' ' 当然不会成功啊,你的密码又不是系统里的任何指令,你怎么成功啊?
意思就是 echo 'password' | sudo su 压根就是个非法行为,你的想法是错的
ganxiyun
275 天前
@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
275 天前
第二个问题中的第二个小问题,不知道原因。
panzhc
275 天前
第一个问题,如果 sudo 没有做特殊配置,应该会要求输入密码,除非做了 alias sudo='sudo -S '之类的别名,这时候会从标准输入读取密码,-S 是 --stdin ,否则是从 tty 读取密码。
第一个命令结束的时候,echo 完成了标准输出,sudo 完成了标准输入,所以命令就退出了。
第二个问题的第一部分好理解,因为第一个命令已经给了密码,还在有效期内。
推荐配置实现免密,或者尝试 expect 类的工具,因为直接带密码的命令会被记录到 history 。
如果是第一次配置或者因为什么特别的原因,可以试试 SUDO_ASKPASS
azel
275 天前
是不是可以换一种思路,把当前用户的 sudo 命令设置成免密。
nuk
275 天前
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
275 天前
如果实在是想把 root 密码写进脚本,可以这样
$ echo $pass | sshpass su root -c id
uid=0(root) gid=0(wheel) groups=0(wheel),5(operator)
davidpi
274 天前
你那个 sudo 是执行在 pipe 里面的,一个 subshell ,影响不了父进程也就是你的 shell 。正确写法是:
`sudo su <<<' '`
tairan2006
274 天前
那啥,你的解决思路是错的

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

后面输入 sudo su 就不需要密码了…

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/964243

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX