ssh 指令不會終止

ssh 指令不會終止

我編寫了一個腳本來從 Android 手機設定桌面剪貼簿。

#!/bin/sh

ssh -Y user@host "export DISPLAY=:0; echo -n $(termux-clipboard-get) | xclip -selection clipboard"

該腳本按預期運行,但不會終止。我必須按Ctrl+C才能返回提示。

我已經使用了該-f選項,它立即返回。從man ssh

-f
請求ssh在命令執行之前進入後台。如果ssh要詢問密碼或密碼短語,但用戶希望它在背景運行,這非常有用。 […]

我不確定這是否是解決這個問題的正確方法。它不需要在背景運行。它只需要執行一個命令並返回。

為什麼我的還沒ssh回來?有ssh -f什麼好的辦法嗎?有沒有更好的辦法?

答案1

這個答案:

X 中的選擇由兩個X 客戶端合作進行:一個X 客戶端聲稱它有一個選擇(主要、次要、剪貼簿),而另一個想要貼上選擇的X 客戶端聯繫第一個客戶端以接收它。

在您的情況下,原件xclip已死亡,但其子件倖存下來,聲稱它具有選擇並為想要粘貼的未來客戶提供服務。它似乎沒有完全分離,並且 SSH 伺服器等待它退出;所以你的ssh客戶端等待它退出。因此需要Ctrl+ C

稍後,如果另一個客戶端聲稱它有該選擇,則遠端xclip將退出並解鎖您的本地ssh.這意味著您的解決方法並-f沒有那麼糟糕:後台進程不會累積,最多會有一個停滯ssh

連結的答案試圖解決一個似乎有些相關的問題。另一個答案有建議xsel。事實上,在我的測試中這不會阻止:

ssh -Y user@host "export DISPLAY=:0; echo -n foobar | xsel -i -b"

更改xclipxsel至關重要。不過你原來的命令還可以進一步改進。

  • 我認為您不需要-Y(或-X),因為遠端命令不會與您的本地 X 伺服器互動。將DISPLAYright 設定為指向xsel所需的顯示就足夠了當地的xsel

  • 無需export。該變數僅與 相關xsel,因此此程式碼片段應該足夠了:DISPLAY=:0 xsel -i -b

  • 嚴重缺陷。 $(termux-clipboard-get)在本機擴展,您從中獲得的任何內容termux-clipboard-get都會嵌入到您傳遞給遠端 shell 的字串中解釋的作為代碼。

    例如,如果termux-clipboard-get返回; rm -f /very/important/file; true則遠端 shell 將運行

    export DISPLAY=:0; echo -n ; rm -f /very/important/file; true | …
    

    你明白它的作用嗎?正確的做法是透過管道傳輸到ssh

    termux-clipboard-get | ssh user@host 'DISPLAY=:0 xsel -i -b'
    

    這樣,輸出termux-clipboard-get就不會被視為程式碼。

  • 我猜你故意用來獲取沒有任何尾隨換行符echo -n的輸出。termux-clipboard-get如果是這樣,您應該在本機刪除尾隨換行符並不依賴echo:

    printf '%s' "$(termux-clipboard-get)" | …
    

最終的形式可以是:

printf '%s' "$(termux-clipboard-get)" | ssh user@host 'DISPLAY=:0 xsel -i -b'

請注意,該命令甚至會從應解釋為二進位且不更改的資料中移除尾隨換行符。 NUL 字元也會有問題。如果您需要逐字傳遞一些數據,那麼只需直接通過管道termux-clipboard-get

termux-clipboard-get | ssh …

相關內容