Lặp lại đầu ra của một lệnh trong bash mà không có một mạng con


9

Tôi muốn lặp qua đầu ra của lệnh mà không tạo shell phụ hoặc sử dụng tệp tạm thời.

Phiên bản ban đầu của tập lệnh của tôi trông như thế này, nhưng điều này không hoạt động vì nó tạo ra một lớp con và exitlệnh chấm dứt lớp con thay vì tập lệnh chính được yêu cầu. Nó là một phần của tập lệnh lớn hơn nhiều để định cấu hình định tuyến chính sách và sẽ tạm dừng thực thi nếu phát hiện một điều kiện sẽ khiến việc định tuyến bị lỗi.

sysctl -a 2>/dev/null | grep '\.rp_filter' | while read -r -a RPSTAT ; do

  if [[ "0" != "${RPSTAT[2]}" ]] ; then
    echo >&2 "RP Filter must be disabled on all interfaces!"
    echo >&2 "The RP filter feature is incompatible with policy routing"
    exit 1
  fi
done

Vì vậy, một trong những lựa chọn thay thế được đề xuất là sử dụng một lệnh như thế này để tránh lớp vỏ con.

while read BLAH ; do echo $BLAH; done </root/regularfile

Vì vậy, dường như tôi cũng có thể sử dụng một lệnh như thế này để tránh lớp con và vẫn nhận được đầu ra từ chương trình tôi muốn.

while read BLAH ; do echo $BLAH; done <(sysctl -a 2>/dev/null | grep '\.rp_filter')

Thật không may, sử dụng lệnh đó dẫn đến lỗi này.

-bash: syntax error near unexpected token `<(sysct ...

Tôi thực sự bối rối vì điều này không hoạt động.

cat <(sysctl -a 2>/dev/null | grep '\.rp_filter')

Tôi có thể lưu đầu ra của lệnh đó vào một tệp tạm thời và sử dụng chuyển hướng trên tệp tạm thời, nhưng tôi muốn tránh làm điều đó.

Vậy tại sao việc chuyển hướng lại gây ra lỗi cho tôi và tôi có bất kỳ tùy chọn nào khác sau đó tạo một tệp tạm thời không?


Câu trả lời:


13

Bạn đã bỏ lỡ a <. Nên là:

while read BLAH ; do echo $BLAH; done < <(sysctl -a 2>/dev/null | grep '\.rp_filter')

Hãy nghĩ về <(sysctl -a 2>/dev/null | grep '\.rp_filter')việc là một tập tin.


Cảm ơn rất nhiều. Chỉ cần chỉnh sửa của tôi, tôi có thể chỉ cho tôi một trang nam, trợ giúp hoặc trang web, tài liệu này không? Tôi không thể khiến Google chỉ cho tôi bất cứ điều gì hữu ích trong khi cố gắng tìm kiếm điều này.
Zoredache

2
Google "thay thế quá trình". ví dụ: tldp.org/LDP/abs/html/abs-guide.html#PROCESS-SUB
dogbane

Cần lưu ý rằng sự thay thế <() sử dụng các mô tả tệp và trên một số hệ điều hành sẽ tạo và sử dụng các tệp tạm thời trong suốt.
ewindisch

@Zoredache: Đơn giản chỉ cần tìm kiếm <(trong hướng dẫn sử dụng bash (nó nằm dưới quy trình thay thế của quy trình).
Gilles 'SO- ngừng trở nên xấu xa'

@ewindisch, nếu một công cụ trong suốt tạo ra một tempfile vẫn ổn, tôi chỉ không muốn tự tạo một công cụ, khi tôi khá chắc chắn rằng mình không cần.
Zoredache

0

Đối với một vài lựa chọn thay thế nếu có ai đến đây một lần nữa ...

Tùy thuộc vào shell, có lẽ bạn có thể sử dụng set -o errexitđể có lối thoát shell cha khi một lệnh (bao gồm cả lớp con) thoát ra khác không mà không bị kẹt trong một ifkhối hoặc dấu &&hoặc ||, như trong

/bin/false || echo "ignoring error"

Hoặc, bạn có thể có tín hiệu con phụ huynh sử dụng kill và biến môi trường $ PPID, nếu có.

Hoặc bạn có thể di chuyển khối while vào một hàm và trả về 0/1 (trả về 0 rõ ràng sau khối while) và chỉ cần thực hiện đường ống của bạn như thế nào sysctl | grep | function || exit. Tôi cho rằng bạn cũng có thể đặt lợi nhuận trong khối nội tuyến, nhưng các chức năng là bạn của bạn. ;)

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.