Có tuân thủ POSIX để sử dụng hàm shell trong đường ống không?


1

Có thể sử dụng một chức năng vỏ trong một đường ống?

Nói rằng tôi có một chức năng mà hành động như thế grep, được gọi mygrep. Có cách nào không, chỉ sử dụng các tính năng vỏ POSIX, để có thể gọi mygrepnhư thế này:

if ps | mygrep foo ; then
   echo "process foo is running"
fi

Hoặc là đường ống giới hạn chỉ các lệnh bên ngoài?


1
Điều gì khiến bạn không cố gắng?
Kamil Maciorowski

1
@KamilMaciorowski: Có lẽ sự không chắc chắn trong việc nó hoạt động do là một tính năng POSIX tiêu chuẩn hay nó hoạt động do là một trong những tiện ích mở rộng hàng triệu ksh / bash / zsh. Khi OP đề cập đến "chỉ sử dụng ...", đó là tốt nhất để giả định "Có lẽ để làm việc?"
grawity

@grawity Một phỏng đoán hợp lý, tôi nhận được quan điểm của bạn. Nếu vậy, cung cấp kết quả của các thử nghiệm riêng trong vài vỏ sẽ là một nỗ lực nghiên cứu tốt.
Kamil Maciorowski

@grawity Câu trả lời của tôi bây giờ giải quyết vấn đề này. Cảm ơn bạn.
Kamil Maciorowski

Câu trả lời:


4

Vâng. Xem tài liệu này .

1. Giới thiệu

Khối lượng Shell và Tiện ích của POSIX.1-2017 mô tả các lệnh và tiện ích được cung cấp cho các chương trình ứng dụng bởi các hệ thống tuân thủ POSIX.

Từ 2.9.2 Đường ống :

Đường ống là một chuỗi gồm một hoặc nhiều lệnh được phân tách bởi toán tử điều khiển '|'.

Từ lệnh 2.9.5 Định nghĩa hàm :

Hàm là tên do người dùng định nghĩa được sử dụng như một lệnh đơn giản [...]

Định dạng của lệnh định nghĩa hàm như sau:

fname ( ) compound-command [io-redirect ...]

Từ 2.9 Lệnh Shell :

Một lệnh là một trong những điều sau đây:

  • Lệnh đơn giản [...]
  • [...]

Vì vậy, |tách các lệnh; một lệnh có thể là một lệnh đơn giản; Tên hàm được sử dụng như một lệnh đơn giản. Câu trả lời cho câu hỏi của bạn là: có, cú pháp này

some_command | some_function

được định nghĩa bởi POSIX.


Đó là khá dễ dàng để thử (thử nghiệm với shcung cấp bởi dashtrong Debian 9):

mygrep() { grep "$@"; }

if ps | mygrep foo ; then
   echo "process foo is running"
fi

if ps | mygrep ps ; then
   echo "process ps is running"
fi

( ps | mygrep foocũng sẽ phát hiện một quy trình foobar, nếu có. Tôi hiểu vấn đề này nằm ngoài phạm vi câu hỏi của bạn và chúng tôi có thể bỏ qua nó).

Trong ví dụ mygrepnày là tầm thường. Nó trả về trạng thái thoát của lệnh cuối cùng (và duy nhất). Trong khi xây dựng các hàm với logic phức tạp hơn, bạn có thể cần dựng sẵn đặc biệt returnđể trả về trạng thái thoát mong muốn.

Cũng lưu ý đầu ra từ grepkhông bị triệt tiêu. Không chỉ có chức năng vỏ có thể được sử dụng trong đường ống, đầu ra của nó cũng có thể được chuyển hướng. Thí dụ:

if ps | mygrep ps >/dev/null ; then
   echo "process ps is running"
fi

thay thế bằng bình luận dưới đây. SE đã hành động kỳ lạ và có vẻ như bình luận của tôi đã không được lưu.
Tim Bird

Tôi xấu hổ vì tôi đã không thử điều này bản thân mình. Tôi nghĩ rằng việc xử lý stdin sẽ liên quan nhiều hơn, nhưng nhìn chung có vẻ như rõ ràng nó chỉ "đi" đến chức năng (nếu đó là cách để đặt nó). Rằng bạn có thể chuyển hướng đầu ra chức năng cũng rất thú vị. Cảm ơn!
Tim Bird

-2

Bạn phải sử dụng biểu mẫu oneliner hoặc đóng gói biểu thức của bạn thành $ {}. Ở dạng đó bạn đã viết dưới dạng bash script thì không thể.


1
Tôi thực sự không hiểu ý của bạn. Bạn có thể gửi một ví dụ? một đoạn mã làm việc? Theo như tôi biết ${}làm việc với các biến và làm cho mọi thứ echo "${variable}_suffix"có thể.
Kamil Maciorowski

ngay trên ví dụ mygrep () {grep "$ @"; }
Yurij
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.