2016-02-12 116 views
2

因此,我正在編寫一個命令行工具,並遇到了一個我很好奇的問題。如何檢查是否通過ssh遠程調用python腳本

該實用程序可以使用文件參數調用,也可以從sys.stdin中讀取。本來我是用sys.stdin.isatty()弄清楚,如果數據被管道中,但是,我發現,如果我通過ssh server utility遠程調用的效用,sys.stdin.isatty()將返回false,儘管沒有實際的數據被輸送。

作爲解決方法,我使用-作爲強制從標準輸入讀取的文件參數(例如:echo "data_here" | utility -f -),但我很想知道是否有一種可靠的方法來區分從一個進程獲取數據的管道與因爲這個調用是通過ssh來打開的。

系統編程不是我的專長,所以我很感激我能從你們那裏得到任何幫助。

+0

所有管道都是一樣的,所以不要以爲你可以。你可能不得不考慮進程組和父進程 - 但這變得非常討厭 – Soren

回答

3

你可以通過檢查你的環境來判斷你是否通過SSH被調用。如果通過SSH連接調用,則將設置環境變量SSH_CONNECTIONSSH_CLIENT。您可以測試,如果它們被設置着,說:

if "SSH_CONNECTION" in os.environ: 
    # do something 

另一種選擇,如果你想只是你原來的sys.stdin.isatty()辦法堅持,將分配一個僞終端的SSH連接。通常情況下,如果您只是在交互式會話中進行SSH連接,SSH默認會執行此操作,但如果您提供命令,則SSH不會。但是,您可以迫使它這樣做通過傳遞-t標誌提供一個命令時:

ssh -t server utility 

不過,我警告你不要做任何的這些。正如你所看到的,試圖檢測你是否應該接受來自stdin的輸入,基於它是否是TTY可能會導致一些令人驚訝的行爲。如果他們想要一種方式來在調試某些東西時交互地爲程序提供輸入,它也可能會導致用戶感到沮喪。

添加顯式-參數的方法使得它更加明確,並且不太令人驚訝您獲得了哪種行爲。一些實用程序也只是使用缺少任何文件參數來表示從stdin讀取,所以這也是一個不太令人吃驚的選擇。

+0

謝謝,這是我正在尋找。看起來我會堅持我的解決方法。 – Laharah

2

根據this answer應該聲明SSH_CLIENTSSH_TTY環境變量。從這一點,下面的代碼應該工作:

import os 

def running_ssh(): 
    return 'SSH_CLIENT' in os.environ or 'SSH_TTY' in os.environ 

一個更完整的示例將檢查父進程,以檢查其中是否是sshd這可能將需要psutil模塊。

+0

這將拋出這些變量的異常沒有設置,不返回布爾值。 –

+0

感謝您的回覆!我確實可以使用'os.environ ['SSH_TTY']'來判斷這個調用是否是一個遠程的ssh調用。然而,它無助於分辨這兩個調用之間的區別:'ssh server utility'和'echo「data」| ssh服務器工具' – Laharah

+0

謝謝@BrianCampbell。我更新了這個例子。 JavaScript領域的時間太長了。 –

相關問題