當通過管道與|
,要重定向從所述第一命令的輸出到第二輸入。這意味着第二個命令的標準輸入沒有連接到終端,因此無法讀取鍵盤輸入。因此,表格curl xxx | bash
僅適用於非交互式腳本。這不是Python特有的。
,你可以在工作原則解決此通過下另一個號碼保存輸入描述符,但它確實變得相當複雜:
$ (echo 'exec <&3 3<&- ; echo script starts ; read hello ; echo you entered $hello ; exit' | bash) 3<&0
script starts
something
you entered something
在這裏,我用()
創建一個子shell,在標準輸入上的文件複製描述符使用3<&0
3,而在管道中產生兩個腳本將重命名背面與exec <&3 3<&-
和exit
小號stdin中,以防止從恢復的標準輸入被讀取進一步的命令。這有副作用,如描述符3打開echo
命令。
由於主要的原因首先使用curl address | bash
是保留命令簡單,這是不是你追求的。此外,如果在下載過程中出現任何問題,管道將阻止您進行處理;你的腳本可能會被中斷。傳統的下載然後運行是不是差很多:
curl -O http://somewhere/somefile.py && python somefile.py
相比之下,這樣可以節省somefile.py
到你的文件系統。這有缺點,就像需要一個可寫的文件系統並替換那個特定的文件名一樣。從正面看,如果有什麼錯了,它停在那裏,不運行腳本損壞,由於&&
。
最後一個可能性,如果你在命令行中下載適合的劇本可能是把它放在那裏,而不是在管:
python -c "$(curl $url)"
這對進行中斷的下載相同的弱點,另外的地方在命令行通常爲公共信息的腳本內容(考慮ps ax
輸出)。但如果你只是用curl來下載腳本,那麼關於如何獲得它的信息也是可以的。由於這不會重定向標準輸入,它可能是您的直接問題的答案。
一般情況下,我建議不運行任何腳本直接關閉互聯網,而無需驗證,因爲這curl something | bash
命令行一樣。它太容易受到劫持,因爲任何步驟都沒有涉及驗證。最好使用一個檢查簽名的軟件包庫,比如apt。
另一種在Linux上訪問終端的方法是通過設備/dev/tty
。該方法用於例如when ssh
asks for a password。也可以重新打開stdout或stderr以進行輸入,如(exec < /dev/null ; read foo <&2 ; echo $foo)
。