- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在编写一个运行各种 shell 命令的 PHP 程序。有时它需要调用 su
,根据设计,我希望它提示输入提升权限的密码。在 PHP 中使用 passthru()
可以很好地实现此目的。
我选择仅为我的程序编写功能测试,因为它依赖于 ssh
、su
和其他 shell 命令。因此,我想在 PHPUnit 中运行真实的东西,看看它是否按我的预期工作。
由于这需要 SSH 服务器和用户帐户配置,因此我已将测试设置为在 Docker 中运行。这种方法看起来不错 - 图像构建,运行时调用 PHPUnit,然后退出。我希望有一种方法可以通过 Docker 将结果返回到调用系统,例如 Travis CI。
我已选择 Alpine Linux 作为我的基础 Docker 镜像,但我在终端分配方面遇到问题。我最初认为 PHPUnit 妨碍了(请参阅此问题的原始版本),但我现在将其范围缩小到 SSH,它可以由 PHP 运行,甚至可以在控制台上运行。
这工作正常:
su -c whoami
但是,这不会:
ssh localhost -t 'su -c whoami'
我得到:
su: must be suid to work properly
Connection to localhost closed.
请注意,ssh
设置为对本地主机进行无密码访问(用于测试目的),因此我期望输入的唯一密码是 su
密码。
ssh
手册建议 -f
对于要求输入密码的位置很有帮助(开关“要求 ssh 在命令执行之前进入后台”)所以我尝试这个:
ssh localhost -t -f 'su -c whoami'
我得到:
Pseudo-terminal will not be allocated because stdin is not a terminal.
4275760bde94:~$ su: must be suid to work properly
啊,又一个错误!好的,所以I've tried these ideas ,特别是强制终端:
ssh localhost -tt -f 'su -c whoami'
double-t 仍然发出有关 SUID 的提示,并且仍然不起作用。
但是,如果我在我的 Ubuntu 开发计算机上执行此操作(也配置了对自身的 PPK 访问权限),则它可以正常工作:
$ ssh localhost -t 'su -c whoami'
Password:
root
Connection to localhost closed.
这使得 Alpine 或 BusyBox 的 OpenSSH 看起来有问题。我怎样才能进一步深入研究这个问题?
一个解决方案就是切换到另一个基础发行版,Ubuntu 肯定可以正常工作,但这会大大增加我的 Docker 镜像大小(目前总计为 68M,非常不错)。因此,如果可以的话,我想继续使用 Alpine 一段时间。
我确实想知道 Docker 是否可能会阻止创建或附加终端,但很快就放弃了这一点,因为我可以使用 docker exec -it container_name sh 获得交互式 shell。此外,我可以在 Docker shell 中使用两个单独的命令执行 ssh
,然后执行 su
。
我注意到 Bash 在 Alpine 中可用,但这也没有帮助,这让我感到惊讶:
/ $ apk add bash
bash-4.3$ bash
bash-4.3$ su nonpriv
bash-4.3$ ssh localhost whoami
nonpriv
bash-4.3$ ssh localhost 'su -c whoami'
su: must be suid to work properly
bash-4.3$ ssh localhost 'su -s /bin/bash -c whoami'
su: must be suid to work properly
bash-4.3$ ssh -t localhost 'su -s /bin/bash -c whoami'
su: must be suid to work properly
Connection to localhost closed.
bash-4.3$ ssh -tt localhost 'su -s /bin/bash -c whoami'
su: must be suid to work properly
Connection to localhost closed.
bash-4.3$ ssh -tf localhost 'su -s /bin/bash -c whoami'
Pseudo-terminal will not be allocated because stdin is not a terminal.
bash-4.3$ su: must be suid to work properly
bash-4.3$ ssh -ttf localhost 'su -s /bin/bash -c whoami'
bash-4.3$ su: must be suid to work properly
Connection to localhost closed.
我发现这几乎有效:
/ $ ssh -t localhost "$( su -c whoami )"
sh: Password:: not found
sh: root: not found
Connection to localhost closed.
这使用标准的 Alpine sh
shell,并使用 "$()"
构造,可以在上述链接中找到,但我并不完全理解。它输出Password:
,即su
中的提示符,然后等待密码。输入密码后,将运行 whoami
,并打印 root
。
所以看起来它正在运行命令,但我不确定它是否立即运行 whoami
然后将其传递给 ssh
(不是我想要的)或者是否获取本地主机的远程 shell,然后执行此操作(这就是我的意图)。
无论如何,它都会尝试运行 stdout 行,就好像它们本身就是命令一样。我怎样才能得到它来打印通过 SSH 运行的输出?
最佳答案
我在问题中猜测这可以在 Ubuntu 容器中工作,事实证明这是正确的。有趣的是,使用此命令我仍然收到“必须从终端运行”错误:
su -c whoami
但不是在这里,终端在 SSH 无密码命令中显式分配给 self:
ssh -t localhost 'su -c whoami'
不幸的是,新操作系统将我的 68M 镜像增加到 430M,呃!因此,我应该非常高兴收到新的答案,使这个问题能够在 Alpine 上运行。
关于shell - 如何修复 Alpine Linux 中的 "Pseudo-terminal will not be allocated because stdin is not a terminal"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44272969/
我是一名优秀的程序员,十分优秀!