2010-06-29 34 views
5

Ví dụ:Return một giá trị duy nhất từ ​​một hàm shell script

#!/bin/sh 

a() { 
R=f 
ls -1 a* 
[ "$?" == "1" ] && { R=t; } 
echo $R 
} 

r=`a` 
echo $r 

$r chứa t hoặc f mà còn là kết quả của lệnh ls.

Tôi có thể viết ls -1 a* >/dev/null 2>/dev/null, nhưng nếu có một tập lệnh phức tạp hơn có thể dẫn đến lỗi.

Có cách nào để trả lại một giá trị từ a() không?

+0

'r = $ (a); echo $ r' có thể được thay thế bằng chỉ' a'. –

Trả lời

4

Hàm vỏ có thể trả về giá trị số. Cân nhắc 0 và 1 chứ không phải là 'f' và 't'

#!/bin/sh 

a() { 
R=0 
ls -1 a* 
[ "$?" == "1" ] && { R=1; } 
return $R 
} 

a 
r=$? 
echo $r 

này vẫn sẽ viết ra từ ls -1 a* mà có thể bạn vẫn muốn vứt bỏ, nhưng giá trị của r sẽ hoặc là 0 hoặc 1 và won không bao gồm đầu ra. Các ví dụ khác về đầu ra chuyển hướng hoặc từ một dòng hoặc toàn bộ khối là tốt, và, như những người khác được đề xuất, bạn nên tìm hiểu các cách khác để kiểm tra điều kiện (nhưng tôi giả định rằng ls là một loại tùy ý ví dụ)

+0

Tại sao không bỏ qua toàn bộ doanh nghiệp sôi nổi bằng '$ R' và chỉ chạy' ls' và sau đó 'return $?'? – Caleb

+0

@Caleb - câu trả lời này là một sửa đổi cho kịch bản gốc của PeterMmm để chứng minh cách thức một hàm shell có thể trả về một giá trị. Tôi chắc chắn rằng toàn bộ chức năng mẫu này có thể được phân phối, nhưng tôi không biết anh ta có thể làm gì trong mã thực sự của mình. –

0
a() { 
ls -1 a* > /dev/null 
[ "$?" == "0" ] && echo t || echo f 

} 

r=`a` 
echo $r 

Cân nhắc sử dụng [-f tên tệp] và các thử nghiệm tệp khác.

1

bạn không phải sử dụng ls để kiểm tra các tệp bắt đầu bằng a. Chỉ cần sử dụng vỏ

a() { 
    shopt -s nullglob 
    ret="f" 
    for file in a* 
    do 
    ret="t" 
    break 
    done 
    echo "$ret" 
} 
+0

Đây là một ví dụ, không phải là câu hỏi của tôi. Làm thế nào tôi có thể tránh để viết ở khắp mọi nơi ">/dev/null 2>/dev/null" khi tôi muốn có một giá trị duy nhất/chuỗi từ một chức năng kịch bản. – PeterMmm

1

Bạn có thể đặt một chuyển hướng vào một danh sách các lệnh:

 
{ 
    command1 
    command2 
} >/dev/null 

Nếu lúc nào đó trong kịch bản mà bạn không muốn bất kỳ đầu ra từ lệnh tiếp theo, bạn có thể chuyển hướng sản lượng của vỏ với exec dựng sẵn:

 
echo interesting 
exec >/dev/null 
echo boring 

Lưu ý rằng điều này kéo dài cho đến khi kết thúc của kịch bản, không chỉ cho đến cuối của một hàm. Điều này sẽ chăm sóc các lệnh sau khi một trong những thú vị nhưng không phải trước đây.

Có cách để hoàn nguyên tác dụng của exec /dev/null, bằng cách sử dụng thao tác mô tả tệp. Mặc dù vậy, tôi không nhất thiết phải giới thiệu nó, bởi vì nó có thể phức tạp để làm việc trong thực tế. Ý tưởng là để di chuyển bất cứ điều gì được kết nối với đầu ra tiêu chuẩn cho một bộ mô tả khác nhau, sau đó chuyển hướng đầu ra tiêu chuẩn sang một tệp khác và cuối cùng chuyển vị trí đầu ra ban đầu trở lại đầu ra tiêu chuẩn.

 
{ 
    exec 3>&1   # duplicate fd 3 to fd 1 (standard output) 
    exec >/dev/null # connect standard output to /dev/null 
    echo boring 
    exec 1>&3   # connect standard output back to what was saved in fd 3 
    echo interesting 
    exec >/dev/null # connect standard output to /dev/null again 
    echo more boring 
} 3>/dev/null  # The braced list must have its fd 3 connected somewhere, 
        # even though nothing will actually be written to it. 
Các vấn đề liên quan