簡體   English   中英

管道到頭導致從 python 調用的 shell 腳本中的管道損壞

[英]Piping to head results in broken pipe in shell script called from python

我有一個命令可以運行以生成隨機字符串:

var=`< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c8`

當我在交互式 bash 會話中運行此命令時,我絕對沒有錯誤。 但是,當我將此命令放入腳本並將其作為腳本運行時,我收到 tr 指示的管道損壞錯誤。 我已經閱讀了幾個相關主題,但仍然沒有答案為什么腳本和交互行為不同,有沒有辦法用 shell 選項或其他東西來控制它?

編輯我:

關於給出的評論,我發現可以通過以下方式控制指示損壞的管道錯誤:

 trap - SIGPIPE # to ignore errors

 trap "" SIGPIPE # to display errors

編輯二:

好吧,我提供了有關繁殖條件的錯誤信息。 最后,問題似乎是由使用 os.system() 調用腳本的 python 包裝器引起的:

 python -c "import os; os.system('sh -c \"< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c8\"')"

給定的行會產生與使用的操作系統無關的斷管錯誤。

編輯三:

這個話題在這里討論過: https : //mail.python.org/pipermail/python-dev/2005-September/056341.html

如果其中一個父進程陷阱sigpipe ,那么管道將繼承ignore信號處理,這將導致您遇到此問題。

這可以(安全地)復制:

( trap '' pipe; var=`< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c8 )

通常, head -c8命令很快就會完成,此時stdin將關閉。 由於它的stdin連接到管道stdouttr ,它現在不再是有道理的, tr寫入其stdout 一旦嘗試,系統將使用SIGPIPE殺死它。 除非tr忽略此信號或從其父級繼承了此信號的ignoreSIG_IGN )處置。 然后write tr的破壞stdout將簡單地導致常規錯誤並將errnoEPIPE ,此時tr很可能會串行化並將此錯誤輸出到其stderr並退出。

這個答案提供了從Python到head管道問題的一個很好的總結,並展示了一些解決方法。

https://stackoverflow.com/a/30091579/456550

問題似乎是head從輸入流中讀取指定(或默認)行數,打印它們,然后退出。 因此,仍在寫入的管道中的上游程序發現輸出流已關閉。 在我看來,這是head本身設計的一個限制。 您可以改為使用sed ,它讀取整個流: sed -n "1,10p"等效於head -n10

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM