2011-09-28 44 views
6

Tôi muốn biến như sau:quá trình Bash thay và thoát mã

git status --short && (git status --short | xargs -Istr test -z str)

mà được cho tôi những kết quả mong muốn của mirroring đầu ra để stdout và làm một tấm séc zero chiều dài trên kết quả vào một cái gì đó gần gũi hơn với:

git status --short | tee >(xargs -Istr test -z str)

mà tiếc là trả về mã lối ra của tee (luôn bằng zero).

Có cách nào để lấy mã thoát của quy trình thay thế một cách thanh lịch không?

[EDIT]

tôi sẽ như sau bây giờ, nó ngăn cách chạy lệnh cùng một hai lần nhưng dường như cầu xin cho một cái gì đó tốt hơn:

OUT=$(git status --short) && echo "${OUT}" && test -z "${OUT}"

+0

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 đó? –

+0

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

Trả lời

5

Nhìn đây:

 
    $ echo xxx | tee >(xargs test -n); echo $? 
xxx 
0 
    $ echo xxx | tee >(xargs test -z); echo $? 
xxx 
0 

và xem tại đây:

 
    $echo xxx | tee >(xargs test -z; echo "${PIPESTATUS[*]}") 
xxx 
123 
    $echo xxx | tee >(xargs test -n; echo "${PIPESTATUS[*]}") 
xxx 
0 

Đó là?

Xem thêm Pipe status after command substitution

+0

Tôi không biết về PIPESTATUS, đó là hữu ích, cảm ơn. – jodell

+4

Trong trường hợp bất kỳ ai khác đến và nghĩ rằng PIPESTATUS giải quyết điều này, nó không. Nếu echo $? được di chuyển bên trong cấu trúc> (...), nó cũng hoạt động như mong đợi. Nếu phiên bản PIPESTATUS được di chuyển ra ngoài, nó cũng trả về 0 trong cả hai trường hợp. –

0
#!/bin/bash 
if read q < <(git status -s) 
then 
    echo $q 
    exit 
fi 
2

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:

  1. ${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),
  2. ${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ó.

+0

tee là thực sự không sử dụng ở đây, các stdout net có được chuyển hướng đến stdout. – weynhamz

+0

'exec {GIT_XARGS [1]}> & -' trả về '-bash: exec: {GIT_XARGS [1]}: không tìm thấy' cho tôi. –

+0

Bạn có bash-4.0 hoặc mới hơn không? –

Các vấn đề liên quan