我需要撰寫一種方法來執行以下操作(請注意,所有操作均以 root 身份在本地計算機上完成):
runuser -l user1 -c 'ssh localhost' &
runuser -l user1 -c 'systemctl --user list-units'
第一個命令應該以 root 身份運行。最終目標是以“user1”身份登錄,以便任何用戶運行who“user1”時都會出現在此串列中。注意到在運行下一個命令之前第一個命令是如何后臺運行的。下一個命令也應該以 root 身份運行,而不是 user1。
問題:這些命令單獨運行時運行良好,但在腳本“user1”中運行時,在運行who. 這是我的腳本
#!/bin/bash
echo "[ ] Becoming user1"
runuser -l user1 -c 'ssh -q localhost 2>/dev/null' &
echo
sleep 1
echo "[ ] Running systemctl --user commands as root."
runuser -l user 1 -c 'systemctl --user list-units'
echo "[ ] Killing active ssh sessions."
kill $(ps aux | grep ssh | grep "^user1.*" | grep localhost | awk '{print$2}') 2>/dev/null
echo "[ ] Done."
運行腳本時,腳本似乎能夠通過 ssh 進入系統,但who不顯示用戶登錄,也沒有任何ps aux輸出顯示 ssh 會話。注意:我注釋掉了該kill行以確認行程是否保留,我根本沒有看到它。如何讓 bash 腳本分叉兩個行程。行程 1 的目標是以“user1”身份登錄并等待。那么行程2是在user1登錄的情況下以root身份執行命令?
uj5u.com熱心網友回復:
我的目標是通過腳本以 root 身份運行 systemctl --user 命令。如果您熟悉 systemctl --user 域,則無法管理 systemctl --user 單元,除非用戶通過傳統方法(ssh、直接終端或 gui)登錄。我也不能以 root 身份“su - user1”。所以我想通過 runuser 命令以 root 用戶身份強制 ssh 會話到 vdns11 用戶。一旦用戶通過身份驗證并通過誰顯示我可以運行 systemctl --user 命令。如何在我的代碼中保持 ssh 會話處于活動狀態?
有了這些附加資訊,問題基本上可以歸結為“如何啟動互動式ssh 會話并將其設為后臺?'。
你可以用script它。它可用于誘使應用程式認為它們正在以互動方式運行:
echo "[ ] Starting SSH session in background"
runuser -l user1 -c "script -c 'ssh localhost'" &>/dev/null &
pid=$!
...
echo "[ ] Killing active SSH session"
kill ${pid}
OP 之前的原始答案提供了更多詳細資訊(以供將來參考):
讓我們剖析一下這里發生了什么。
我假設您以 root 身份啟動腳本:
echo "[ ] Becoming user1"
runuser -l user1 -c 'ssh -q localhost 2>/dev/null' &
所以root運行runuser -l user1 -c '...',它本身ssh -q localhost 2>/dev/null作為user1. 由于&.
ssh將列印Pseudo-terminal will not be allocated because stdin is not a terminal.(由于 隱藏2>/dev/null)并立即退出。這就是為什么您在跑步who或跑步時看不到任何東西的原因ps。
你echo說[ ] Becoming user1,這與正在發生的事情完全不同。
sleep 1
腳本會休眠一秒鐘。沒有錯。
echo "[ ] Running systemctl --user commands as root."
#runuser -l user 1 -c 'systemctl --user list-units'
# ^ typo!
runuser -l user1 -c 'systemctl --user list-units'
忽略錯別字,root再次運行runuser,它本身systemctl --user list-units就像user1這次一樣運行。
您echo說[ ] 以 root 身份運行 systemctl --user 命令。,但實際上您正在systemctl --user list-units按照user1上述說明運行。
echo "[ ] Killing active ssh sessions."
kill $(ps aux | grep ssh | grep "^user1.*" | grep localhost | awk '{print$2}') 2>/dev/null
這將殺死在ssh腳本開頭啟動的行程,但它已經退出,所以這什么都不做。作為旁注,這可以更容易地完成:
echo "[ ] Becoming user1"
runuser -l user1 -c 'ssh -q localhost 2>/dev/null' &
pid=$!
...
echo "[ ] Killing active ssh sessions."
kill $(pgrep -P $pid)
所以這應該讓你更好地理解腳本的實際作用,但是在你描述的目標和echo腳本中的沖突之間,很難弄清楚這應該去哪里。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/333650.html
下一篇:C#基礎的誤用?
