
我編寫了一個腳本來從 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"
更改xclip
為xsel
至關重要。不過你原來的命令還可以進一步改進。
我認為您不需要
-Y
(或-X
),因為遠端命令不會與您的本地 X 伺服器互動。將DISPLAY
right 設定為指向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 …