Tôi đã làm việc về vấn đề này trong một thời gian, và có vẻ như không có cách nào để làm điều đó với thay thế tiến trình, ngoại trừ phải dùng đến nội tuyến báo hiệu, và đó có thể thực sự chỉ được sử dụng cho các đường ống đầu vào, vì vậy tôi sẽ không mở rộng trên nó.
Tuy nhiên, bash-4.0 cung cấp các bộ xử lý có thể được sử dụng để thay thế quá trình thay thế trong ngữ cảnh này và cung cấp khả năng dọn sạch.
Đoạn sau đây được cung cấp bởi bạn:
git status --short | tee >(xargs -Istr test -z str)
có thể được thay thế bằng một cái gì đó giống nhau:
coproc GIT_XARGS { xargs -Istr test -z str; }
{ git status --short | tee; } >&${GIT_XARGS[1]}
exec {GIT_XARGS[1]}>&-
wait ${GIT_XARGS_PID}
Bây giờ, đối với một số lời giải thích:
Cuộc gọi coproc
tạo ra một coprocess mới, đặt tên nó là GIT_XARGS
(bạn có thể sử dụng bất kỳ tên nào bạn thích) và chạy lệnh trong niềng răng. Một cặp ống được tạo ra cho coprocess, chuyển hướng stdin và stdout của nó.
Cuộc gọi coproc
đặt hai biến:
${GIT_XARGS[@]}
chứa đường ống để xử lý stdin và stdout, một cách thích hợp ([0]
để đọc từ stdout, [1]
để viết thư cho stdin),
${GIT_XARGS_PID}
chứa coprocess' PID.
Sau đó, lệnh của bạn được chạy và đầu ra của nó được chuyển hướng đến ống thứ hai (tức là đồng bộ hóa). Phần >&${GIT_XARGS[1]}
được tìm kiếm một cách bí mật được mở rộng thành một cái gì đó như >&60
là chuyển hướng đầu ra-sang-fd thông thường.
Xin lưu ý rằng tôi cần phải đặt lệnh của bạn trong niềng răng. Điều này là do một đường ống dẫn đến các quy trình con được sinh ra và chúng không kế thừa các bộ mô tả tệp từ tiến trình cha. Nói cách khác, sau đây:
git status --short | tee >&${GIT_XARGS[1]}
sẽ thất bại với không hợp lệ lỗi mô tả tập tin, kể từ khi fd liên quan tồn tại trong quá trình cha mẹ và không phải là sinh ra tee
quá trình. Đặt nó trong cú đúp gây ra bash để áp dụng chuyển hướng cho toàn bộ đường ống.
Cuộc gọi exec
được sử dụng để đóng đường ống vào coprocess của bạn. Khi bạn sử dụng quá trình thay thế, quá trình này được sinh ra như là một phần của chuyển hướng đầu ra và đường ống đến nó đã bị đóng ngay sau khi chuyển hướng không còn hiệu lực nữa. Vì tuổi thọ của ống đồng bộ kéo dài vượt ra ngoài một chuyển hướng đơn lẻ, chúng ta cần phải đóng nó một cách rõ ràng.
Đóng đường ống đầu ra sẽ khiến quy trình nhận điều kiện EOF trên stdin và chấm dứt một cách duyên dáng. Chúng tôi sử dụng wait
để chờ chấm dứt và gặt hái nó. wait
trả lại trạng thái thoát 'coprocess'.
Lưu ý cuối cùng, xin lưu ý rằng trong trường hợp này, bạn không thể sử dụng kill
để chấm dứt coprocess vì điều đó sẽ thay đổi trạng thái thoát của nó.
Xin lỗi, nhưng chính xác bạn muốn đạt được điều gì? Chỉ cần kiểm tra nếu có trạng thái git trong thư mục đó? –
Có, đó là một phần của tập lệnh triển khai và nên thoát khỏi nonzero nếu thư mục bị bẩn. – jodell