linux stdin shell,关于shell:如何在Alpine Linux中修复“因为stdin不是终端而不会分配伪终端”?...
我正在編寫一個運行各種shell命令的PHP程序。有時它需要調用su,并且根據設計,我希望它提示輸入提升的特權密碼。在PHP中使用passthru()可以很好地解決這個問題。
我選擇只為我的程序編寫功能測試,因為它依賴于ssh、su和其他shell命令。因此,我想在phpunit內部運行真正的東西,看看它是否如我所期望的那樣工作。
因為這需要一個ssh服務器和用戶帳戶配置,所以我已經設置了要在Docker中運行的測試。這種方法看起來會很好——當圖像運行時,它會生成phpunit,然后退出。我希望有一種方法可以通過Docker將結果返回到調用系統,如Travis CI。
我選擇了AlpineLinux作為我的基本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是通過對localhost的無密碼訪問(出于測試目的)設置的,所以我希望輸入的唯一密碼是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
啊,又一個錯誤!好吧,所以我嘗試過這些想法,特別是強迫終端:
ssh localhost -tt -f 'su -c whoami'
Double-T仍然對Suid發出投訴,但仍然不起作用。
但是,如果我在我的Ubuntu dev機器上這樣做(也配置了對self的ppk訪問),它會很好地工作:
$ ssh localhost -t 'su -c whoami'
Password:
root
Connection to localhost closed.
這使得它看起來像是阿爾卑斯山或布希堡的OpenSSH有問題。我怎么能更深入地研究這個問題呢?
一種解決方案是換成另一個基礎發行版,Ubuntu肯定會工作得很好,但這會大大增加我的Docker圖像的尺寸(目前總共有68m的圖像)。所以,如果可以的話,我想和阿爾卑斯山一起堅持一段時間。不太可能是碼頭工人
我想知道Docker是否會阻止終端的創建或連接,但很快就取消了,因為我可以得到一個與docker exec -it container_name sh交互的shell。此外,我還可以在Docker shell中用兩個單獨的命令來執行ssh和su,這很好。巴什沒用
我注意到Bash在阿爾卑斯山有售,但這也沒有起到任何作用,這讓我吃驚:
/ $ 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.
這使用了標準的阿爾卑斯山脈sh外殼,使用了上述鏈接上的"$()"構造,我不完全理解。它輸出Password:,這是su中的提示,然后等待密碼。輸入密碼后,運行whoami,打印root。
所以看起來它正在運行這個命令,但我不確定它是否立即運行whoami,然后將它傳遞給ssh(不是我想要的),或者它是否正在將遠程shell傳遞給localhost,然后再執行它(這是我想要的)。
無論如何,它試圖運行stdout行,就好像它們是命令本身一樣。我如何才能只打印通過ssh運行的輸出?
我真的不知道,但對完整性很好奇,您的測試是什么樣子的?
謝謝@jeff,問題其實不是phpunit。它確實妨礙了及時觸發expect的輸出,但我可以通過超時來減輕這種影響。看起來問題在于阿爾卑斯山如何允許命令包含在ssh命令中。我不知道ssh中是否有我丟失的標志。
當我有時間的時候,我會簡化這個問題,因為phpunit似乎是一個紅鯡魚。
乍一看,這將是這個問題的一個副本,但那里的解決方案不起作用。我想知道我是否在研究一個阿爾卑斯山脈特有的問題?
我重寫了這個問題,把重點放在我認為問題的核心上。
在我的問題中,我猜想這在Ubuntu容器中是可行的,事實證明這是正確的。有趣的是,我仍然得到"must be run from a terminal"這個命令的錯誤:
su -c whoami
但在這里,終端在ssh無密碼命令中顯式分配給self:
ssh -t localhost 'su -c whoami'
不幸的是,新的操作系統把我68m的圖像提高到430m,呃!因此,我應該很高興收到新的答案,使這項工作阿爾卑斯山。
總結
以上是生活随笔為你收集整理的linux stdin shell,关于shell:如何在Alpine Linux中修复“因为stdin不是终端而不会分配伪终端”?...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux学习项目,[ Linux运维学
- 下一篇: Linux安装weblogic方式,Li