Chuyển tiếp khai báo hàm trong tập lệnh Bash hoặc Shell?


95

Có một thứ như vậy trong bashhoặc ít nhất là một cái gì đó tương tự (làm việc xung quanh) như khai báo chuyển tiếp, nổi tiếng trong C / C ++, chẳng hạn?

Hoặc có những điều như vậy vì ví dụ như nó luôn được thực hiện trong một lần vượt qua (dòng này sang dòng khác)?

Nếu không có khai báo chuyển tiếp, tôi nên làm gì để làm cho tập lệnh của mình dễ đọc hơn. Nó khá dài và những định nghĩa hàm này ở phần đầu, trộn lẫn với các biến toàn cục, làm cho tập lệnh của tôi trông xấu và khó đọc / khó hiểu)? Tôi đang yêu cầu tìm hiểu một số phương pháp nổi tiếng / tốt nhất cho những trường hợp như vậy.


Ví dụ:

# something like forward declaration
function func

# execution of the function
func

# definition of func
function func
{
    echo 123
}

Câu trả lời:


190

Câu hỏi tuyệt vời. Tôi sử dụng một mẫu như thế này cho hầu hết các tập lệnh của mình:

#!/bin/bash

main() {
    foo
    bar
    baz
}

foo() {
}

bar() {
}

baz() {
}

main "$@"

Bạn có thể đọc mã từ trên xuống dưới, nhưng nó không thực sự bắt đầu thực thi cho đến dòng cuối cùng. Bằng cách vượt qua "$@"để main (), bạn có thể truy cập vào các đối số dòng lệnh $1, $2, et al cũng giống như bạn bình thường.


3
Xin chào, làm thế nào để bạn cấu trúc dữ liệu phải được chia sẻ giữa foo / bar / baz trong ví dụ của bạn? Thường thì tôi chỉ đặt nó ở đầu script. Điều này vẫn xảy ra khi sử dụng các chức năng? Hay tốt hơn là đặt dữ liệu toàn cục vào chính, rồi chuyển nó đến foo / bar / baz làm đối số? Cách thực hành tốt nhất là gì?
bodacydo

4
Tôi thích tranh luận hơn. Ngoài ra, tôi sẽ đặt các biến toàn cục trong mainhoặc trong một hàm ngay sau main(ví dụ: setuphoặc parseArguments). Tôi tránh đặt các biến toàn cục ở trên main- mã không nên đi ra ngoài main.
John Kugelman

Điều này có vẻ khá giống với những gì if _ _ name _ _ == "_ _ main _ _": main()làm trong python
Sergiy Kolodyazhnyy

Điều này cũng rất tuyệt vời khi sử dụng các công cụ như Bats để kiểm tra các tập lệnh của bạn, chia nhỏ mọi thứ thành các chức năng giúp việc kiểm tra các thành phần riêng lẻ dễ dàng hơn nhiều. Xem thêm bài đăng trên blog
dragon788

30

Khi các tập lệnh bash của tôi phát triển quá nhiều, tôi sử dụng cơ chế bao gồm:

Tệp tin allMyFunctions:

foo() {
}

bar() {
}

baz() {
}

Tệp tin main:

#!/bin/bash

. allMyfunctions

foo
bar
baz

27
Cá nhân, khi một kịch bản shell bắt đầu phát triển một tập tin quá khứ, tôi có xu hướng chuyển sang một ngôn ngữ khác nhau ;-)
Joachim Sauer

Sẽ tốt hơn nếu sử dụng source allMyfunctions?
pydoge,

4
@pydoge: sourcekhông tương thích với POSIX. bashđịnh nghĩa sourcenhư một bí danh để .: chúng tương đương về mặt chức năng.
mouviciel
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.