Vấn đề với xử lý Python 2 SIGPIPE
theo cách không chuẩn (tức là bị bỏ qua) đã được đặt trong câu trả lời của Leon và sửa lỗi được đưa ra trong liên kết: đặt SIGPIPE
thành mặc định (SIG_DFL
) với, ví dụ:
import signal
signal.signal(signal.SIGPIPE,signal.SIG_DFL)
bạn có thể cố gắng để unset SIGPIPE
từ bên trong kịch bản của bạn với, ví dụ như,
#!/bin/bash
trap SIGPIPE # reset SIGPIPE
cat /dev/urandom | tr -dc 'a-z1-9' | fold -w 4 | head -n 1
nhưng, unfortu nately, nó không hoạt động, theo các số Bash reference manual
Tín hiệu bị bỏ qua khi nhập vào trình bao không thể bị bẫy hoặc đặt lại.
Một bình luận cuối cùng: Bạn có sử dụng vô dụng của cat
đây; nó tốt hơn để viết kịch bản của bạn như:
#!/bin/bash
tr -dc 'a-z1-9' < /dev/urandom | fold -w 4 | head -n 1
Tuy nhiên, kể từ khi bạn đang sử dụng Bash, bạn cũng có thể sử dụng read
BUILTIN như sau (điều này sẽ thuận lợi thay thế fold
và head
):
#!/bin/bash
read -n4 a < <(tr -dc 'a-z1-9' < /dev/urandom)
printf '%s\n' "$a"
Nó chỉ ra rằng với phiên bản này, bạn sẽ có một ý tưởng rõ ràng về những gì đang xảy ra (và kịch bản sẽ không treo):
$ python -c "import subprocess; subprocess.call(['./foo'])"
hcwh
tr: write error: Broken pipe
tr: write error
$
$ # script didn't hang
(Tất nhiên, nó hoạt động tốt mà không có lỗi với Python3).Và nói với Python sử dụng tín hiệu mặc định cho SIGPIPE
cũng hoạt động tốt:
$ python -c "import signal; import subprocess; signal.signal(signal.SIGPIPE,signal.SIG_DFL); subprocess.call(['./foo'])"
jc1p
$
(và cũng hoạt động với Python3).
thử trong terminal 'cat/dev/urandom' và bạn thấy rằng nó không bao giờ dừng lại. Có lẽ 'call()' nghĩ rằng 'cat/dev/urandom' nên nó không ngừng chạy. Tôi không thể giải thích rõ hơn. Nếu bạn thử với 'cat some_normal_file thay vì' của 'cat/devurandom' thì bạn không phải gặp vấn đề này - có thể là tập tin chuẩn gửi thông tin EOF. – furas
Đây là sự cố với phiên bản python. Tôi đã thử với 2.6 và nó treo cứng. Nhưng nó đã làm việc với 3.5.1. Bạn đang sử dụng phiên bản nào? Bạn đã cố gắng chuyển sang phiên bản mới hơn chưa? –
@DawidGrabowski Tôi đang sử dụng 2.7.6 - Tôi cũng có thể làm cho nó hoạt động khi tôi sử dụng 3 (3.4.3). Điều thú vị là, mặc dù 'python3 -c" nhập subprocess; subprocess.call (['./ foo.sh']) "' không treo, 'python3 -c" os nhập khẩu; os.system ('./ foo.sh') "' * không * treo ... –