2012-02-14 32 views
12

Tôi làm cách nào để lấy mã thoát của wget từ quá trình bán vỏ?Lấy mã thoát từ subshell qua các đường ống

Vì vậy, vấn đề chính là $? bằng 0. Ở đâu có thể $?=8 được thành lập?

$> OUT=$(wget -q "http://budueba.com/net" | tee -a "file.txt"); echo "$?" 
0 

Nó hoạt động mà không cần tee.

$> OUT=$(wget -q "http://budueba.com/net"); echo "$?" 
8 

Nhưng ${PIPESTATUS} mảng (Tôi không chắc chắn nó liên quan đến trường hợp đó) cũng không chứa giá trị đó.

$> OUT=$(wget -q "http://budueba.com/net" | tee -a "file.txt"); echo "${PIPESTATUS[1]}"  

$> OUT=$(wget -q "http://budueba.com/net" | tee -a "file.txt"); echo "${PIPESTATUS[0]}" 
0 

$> OUT=$(wget -q "http://budueba.com/net" | tee -a "file.txt"); echo "${PIPESTATUS[-1]}" 
0 

Vì vậy, câu hỏi của tôi là - làm thế nào tôi có thể nhận wget 's mã thoát qua tee và subshell?

Nếu có thể hữu ích, phiên bản bash của tôi là 4.2.20.

Trả lời

13

Bằng cách sử dụng $(), bạn đang (tạo hiệu quả) tạo một vỏ bọc con. Do đó, cá thể PIPESTATUS bạn cần xem chỉ khả dụng bên trong vỏ con của bạn (ví dụ: bên trong $()), vì biến môi trường không lan truyền từ các quy trình con đến cha mẹ.

Bạn có thể làm một cái gì đó như thế này:

OUT=$(wget -q "http://budueba.com/net" | tee -a "file.txt"; exit ${PIPESTATUS[0]}); 
    echo $? # prints exit code of wget. 

Bạn có thể đạt được một hành vi tương tự bằng cách sử dụng như sau:

OUT=$(wget -q "http://budueba.com/net") 
    rc=$? # safe exit code for later 
    echo "$OUT" | tee -a "file.txt" 
+0

Nhưng là nó có thể xuất khẩu tất cả {PIPESTATUS} 'mảng' $ lên vào shell mẹ? –

+1

Đó không phải là cách hoạt động của ['export'] (http://www.gnu.org/software/bash/manual/bashref.html#Environment) - nó xuất các biến làm biến môi trường cho các tiến trình * child * (từ bố mẹ). –

+0

Đây là một [giải pháp để đưa toàn bộ mảng '$ {PIPESTATUS [@]}' vào tập lệnh gốc] (https://stackoverflow.com/questions/41716616/get-exit-codes-of-a-pipe- khi-đầu ra-được-giao-để-biến-lệnh-thay thế/44314883 # 44314883). Nó liên quan đến việc thêm nó vào cuối biến được tạo ra và sau đó kéo nó vào một mảng mới. –

0

Sao chép mảng PIPESTATUS đầu tiên. Bất kỳ lần đọc nào phá hủy trạng thái hiện tại.

declare -a PSA 
cmd1 | cmd2 | cmd3 
PSA=("${PIPESTATUS[@]}") 

Tôi đã sử dụng fifos để giải quyết vấn đề phụ shell/PIPESTATUS. Xem bash pipestatus in backticked command?
Tôi cũng thấy những hữu ích: bash script: how to save return value of first command in a pipeline?
https://unix.stackexchange.com/questions/14270/get-exit-status-of-process-thats-piped-to-another/70675#70675

3

Cẩn thận với điều này khi sử dụng local biến:

local OUT=$(command; exit 1) 
echo $? # 0 

OUT=$(command; exit 1) 
echo $? # 1 
+3

Khai báo 'local OUT' sau đó gán' OUT = 'trên một dòng mới đặt đúng biến mã thoát' $? 'Nếu bạn không muốn phạm vi creep. –

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