Các hàm có chạy như các tiến trình con trong Bash không?


28

Trong Hướng dẫn Bash-Scripting nâng cao , trong ví dụ 27-4 , dòng thứ 7 từ dưới lên, tôi đã đọc điều này:

Một chức năng chạy như là một quá trình phụ.

Tôi đã làm một bài kiểm tra ở Bash và dường như tuyên bố trên là sai.

Tìm kiếm trên trang web này, Bash Man và công cụ tìm kiếm của tôi không mang lại bất kỳ ánh sáng nào.

Bạn có câu trả lời và muốn giải thích?


12
Như đã lưu ý, hướng dẫn đó là sai lệch trong cực đoan. Tôi đề nghị Hướng dẫn Wooledge Bash thay thế.
tự đại diện

Câu trả lời:


36

Hướng dẫn Bash-Scripting nâng cao không phải lúc nào cũng đáng tin cậy và các tập lệnh mẫu của nó chứa các thực tiễn lỗi thời như sử dụng các backticks không được dùng một cách hiệu quả để thay thế lệnh, `command`thay vì $(command).

Trong trường hợp cụ thể này, nó rõ ràng không chính xác.

Phần về Hàm Shell trong hướng dẫn Bash (chính tắc) nói rõ rằng

Các hàm Shell được thực thi trong bối cảnh shell hiện tại; không có quá trình mới được tạo ra để giải thích chúng.


10
"Hướng dẫn Bash-Scripting nâng cao thường không đáng tin cậy" Rất đúng.
John1024

1
Bạn có thể cung cấp tài liệu tham khảo để hỗ trợ câu đầu tiên của bạn?
Will Vousden

5
@WillVousden một tài liệu tham khảo trông như thế nào ở đây? Một loạt các ví dụ về sự thiếu hụt kỹ thuật của hướng dẫn? Một tài liệu mà các chuyên gia trong cộng đồng bash trước đây đã lưu ý rằng nó không đáng tin cậy? Nó có giúp ích gì không nếu một thành viên stackoverflow có huy hiệu vàng trong bash chỉ đồng ý trong một bình luận? : p
kojiro

3
@WillVousden Tôi không nghĩ những gì bạn muốn tồn tại ở dạng đáng tin cậy. Mendel Cooper đã cập nhật và sửa các vấn đề với hướng dẫn trong quá khứ, nhưng không có trình theo dõi lỗi công khai hoặc danh sách lỗi. (Có lẽ đó là tuyên bố gây tổn hại nhất mà tôi có thể đưa ra.) Vì vậy, khi chúng tôi tìm thấy một lỗ hổng (nhận thức hoặc thực tế), tất cả những gì chúng tôi có thể làm là gửi email cho tác giả và hy vọng điều tốt nhất.
kojiro

3
@WillVousden, ... nếu bạn muốn có lịch sử về sự đồng thuận trong kênh freenode #bash trong bao lâu thì nên tránh ABS, xem Wooledge.org/~greybot/meta/abs - trường thứ hai trong mỗi dòng là dấu thời gian và đầu tiên là tên người dùng; Tôi sẽ hy vọng rằng sự khẳng định rằng tên người dùng trong câu hỏi là những cá nhân rất được tôn trọng.
Charles Duffy

32

Các hàm giằng xoăn sẽ chạy trong quy trình shell gọi, trừ khi chúng cần lớp con riêng của chúng, đó là:

  • khi bạn chạy chúng trong nền với &
  • khi bạn chạy chúng như một liên kết trong một đường ống

Chuyển hướng hoặc thêm env. các biến sẽ không buộc một subshell mới:

hw(){
    echo hello world from $BASHPID
    echo var=$var
} 
var=42 hw >&2
echo $BASHPID  #unexports var=42 and restores stdout here

Nếu bạn xác định hàm bằng dấu ngoặc đơn thay vì curlies:

hw()(
  echo hello world from $BASHPID
)
hw 
echo $BASHPID

nó sẽ luôn chạy trong một tiến trình mới.

Thay thế lệnh $() cũng luôn tạo các tiến trình trong bash (nhưng không phải bằng ksh nếu bạn chạy nội trang bên trong nó).


Tôi không biết f() (...)là được phép. Có bất kỳ định nghĩa khác ngoài {...}(...)? Ở Bash, tôi chưa thích người khác.
Tomasz

1
@tomas Bạn có thể sử dụng function hw { echo hello world; } cú pháp (không cần ()nếu bạn gõ functionvà bạn có thể chỉ định chuyển hướng ngay sau trận chung kết }hoặc )như trong hw(){ echo error; } >&2. Đó là về nó.
PSkocik

2
Đây là câu trả lời tôi nghĩ ngay lập tức, và nó hoàn toàn chính xác. Nó nên được bình chọn là câu trả lời chính xác. f()(...)luôn luôn thực thi một shell riêng, trong khi f(){...}không.
rexkogitans

11
Các hàm bash NB chấp nhận bất kỳ lệnh ghép nào, do đó, cũng foo() [[ x = x ]]là một định nghĩa hàm hợp lệ. Tuy nhiên, nếu bạn nhìn vào chức năng với type foobạn sẽ thấy rằng đây vẫn là đường cú pháp foo() { [[ x = x ]]; }. Điều tương tự cũng đúng với các hàm subshell: bar() ( : )trở thành bar() { ( : ); }.
kojiro

1
@kojiro đẹp +1. không biết điều đó
PSkocik

9

Lệnh trong câu hỏi từ ví dụ đó trông giống như:

echo ${arrayZ[@]/%e/$(replacement)}

Ví dụ sau nêu:

#    $( ... ) is command substitution.
#    A function runs as a sub-process.

Có thể làm từ thiện cho Hướng dẫn ABS, điều họ dường như muốn viết là hàm chạy bên trong thay thế lệnh và lệnh bên trong thay thế lệnh chạy trong một lớp con .


Điều đó rất sai lệch. Cảm ơn bạn đã giải thích.
Tomasz

5
@tomas "rất sai lệch." Vâng, rât nhiêu. Trái ngược với Hướng dẫn ABS, Wiki của Greg là một nguồn thông tin bash nâng cao tuyệt vời.
John1024

1
Chúc mừng. Ý kiến ​​của bạn về điều này là gì: wiki.bash-hackers.org/start ?
Tomasz

@tomas Tôi không có kiến ​​thức đầu tiên về cái đó.
John1024

2
@tomas, ... ý kiến ​​của riêng tôi đối với wiki bash-hacker là nó là một nguồn tuyệt vời. Tôi chưa từng trải qua nó một cách toàn diện như tôi có wiki Wooledge, nhưng nó có xu hướng được viết chính xác và chính xác.
Charles Duffy
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.