Dash tương đương với tự chuyển hướng đầu ra tập lệnh


9

Trong Bash, bạn có thể chuyển hướng tất cả đầu ra xuất chuẩn trong tương lai của tập lệnh hiện đang chạy . Ví dụ với tập lệnh này,

exec > >(logger -t my-awesome-script)
echo 1
echo 2
echo 3

Điều này sẽ kết thúc trong syslog:

Oct 26 01:03:16 mybox my-awesome-script[72754]: 1
Oct 26 01:03:16 mybox my-awesome-script[72754]: 2
Oct 26 01:03:16 mybox my-awesome-script[72754]: 3

Nhưng đây là đặc thù của Bash và người thực hiện trần trụi với chuyển hướng dường như không hoạt động trong Dash.

Syntax error: redirection unexpected

Làm cách nào tôi có thể làm cho nó hoạt động trong Dash, hoặc có thể trong cả hai shell?


Bạn có thể làm rõ những gì bạn cần chính xác? Bạn có thể chuyển hướng với >trong dấu gạch ngang. Tôi nhận ra bạn dường như đang yêu cầu một cái gì đó khác nhưng tôi không thể nói nó là gì.
terdon

@terdon Mình đã mở rộng giải thích.
Alex B

Câu trả lời:


6

Bạn chỉ có thể làm:

{ commands
....
} | logger -t my_awesome_script

Bạn có thể làm điều đó với bất kỳ vỏ.

Nếu bạn không thích giao diện của nó, có thể làm cho tập lệnh tự bao bọc trong một hàm.

#!/bin/sh
run() if     [ "$run" != "$$" ] || return
      then   sh -c 'run=$$ exec "$0" "$@"' "$0" "$@" |
             logger -t my-awesome-script
      fi
#script-body
run "$@" || do stuff

Dòng cuối cùng phải được run ${1+"$@"} || do stuffgiữ lại để các đối số được giữ lại.
Adam Katz

@AdamKatz - điểm tốt, ${1+"$@"}thực hiện không có gì "$@" không. Dù sao nó cũng có vấn đề khác.
mikeerv

"$@"sẽ vượt qua ""khi không có đối số trong khi ${1+"$@"}sẽ truyền một chuỗi trống khi không có đối số. Điều này rất quan trọng đối với nhiều chương trình, vì chúng phân tích ""thành một đối số trống trong khi một chuỗi trống (không trích dẫn) sẽ không được hiểu là một đối số.
Adam Katz

@AdamKatz - một vỏ Bourne rất cũ có thể (và tôi không mong đợi tìm thấy dashtrên một hệ thống như vậy) , nhưng mặt khác "$@"là duy nhất trong trường hợp zero-args không thay thế cho đối số null cho shell POSIX.
mikeerv

1
@AdamKatz - đó thực sự là một lỗi ngay cả trong bsh cũ và không bao giờ nên hoạt động như vậy. Cuối cùng nó đã được sửa, nhưng tôi không biết liệu nó có còn cần thiết trong Solaris 10 hay không. Bạn nói đúng về $ * - nó không thể hiện cùng một tính chất gọn gàng của sự mở rộng - tính độc đáo của nó liên quan đến nội dung thay đổi của bản mở rộng của nó, mặc dù nó sẽ luôn là một cái gì đó "${@+is especially cool $@}" . Nhưng thực tế không khác lắm so với ${1+”$@"}cách giải quyết cũ . Nếu bạn có một ksh93:"${1+quoted" not quoted "quoted again}"
mikeerv 2/2/2016

5

Quá trình thay thế dễ dàng được mô phỏng với các đường ống được đặt tên.

mkfifo logger_input
logger -t my_awesome_script < logger_input &
exec > logger_input
echo 1
echo 2
echo 3

Trong thực tế, các đường ống được đặt tên là một trong những cơ chế (thực thể khác /dev/fd) mà quá trình thay thế có thể được thực hiện bash.


Linh hoạt nhất theo quan điểm của tôi: Tôi có thể sử dụng tee để chuyển hướng đến một số luồng liên tục. Chỉ có một điều: đừng quên xóa logger_input đã tạo ở cuối tập lệnh.
lauhub

2

Tôi không nghĩ rằng điều này là có thể trong dash. Theo như tôi có thể nói từ mantrang của nó , nó không hỗ trợ thay thế quá trình.

Như một giải pháp thay thế, bạn có thể thử những gì mikserv đề xuất hoặc bạn có thể chuyển hướng mọi thứ đến một tệp, và sau khi tập lệnh của bạn kết thúc (có lẽ đây là trong một tập lệnh), hãy thêm nội dung của tệp đó vào logger:

$ exec > ~/foo/foo.txt
$ ls
$ echo something
$ cat foo/foo.txt | sudo logger -t my-awesome-script

Trong thực tế, thay thế quá trình - hoặc những gì các shell khác gọi thay thế quá trình - dễ dàng hơn trong dashcác shell khác. Quá trình thay thế chỉ là một đối số chỉ ra một /dev/fd/[num]liên kết đến một đường ống ẩn danh. dashthực hiện ở đây - các tài liệu với các đường dẫn ẩn danh thay vì tạo các tệp tạm thời như hầu hết các trình bao khác. Vì vậy, cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\nkhông chỉ tương đương về chức năng, bạn thậm chí có thể tự đặt tên cho fd. Tuy nhiên, quan điểm của bạn được thực hiện tốt khi đi theo một cách khác - bạn cần mở một fd mới với execvà làm nền cho một quá trình đọc nó.
mikeerv

2
@mikeerv: Theo nghĩa nào thì cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\n"dễ" hơn cat <(get output)?
ruakh

@mikeerv: Nó bao gồm rất nhiều quy tắc cần nhớ; có lẽ bạn chỉ đơn giản là đã quen với chúng mà bạn không nhận thấy.
ruakh

@ruakh - tốt, chắc chắn rồi < >chuyển hướng vỏ. về cơ bản nếu bạn chỉ làm hai trong số đó thì bạn cũng có thể chồng lên các dòng sau. Nhưng vâng, bạn có một điểm - tôi thích ở đây tài liệu. Tuy nhiên, nhiều như tôi có thể yêu cầu ghi nhớ, nó dễ dàng hơn khi chúng hoạt động phổ biến. Sau đó, một lần nữa, rất nhiều người không sử dụng nhiều cho các loại đạn khác và vì vậy nó không có gì khác biệt đối với họ. Tôi chỉ không nằm trong số đó.
mikeerv

1
@mikeerv: Không chỉ heredocs, mà còn /dev/fd/3(ở dạng chính xác đó) và các chi tiết về những gì xảy ra với khoảng trắng. . . và đối với vấn đề đó, thực tế là toàn bộ cách tiếp cận này hoạt động hoàn toàn trong Dash, khi nó không hoạt động trong các hệ vỏ khác có tất cả các thành phần, có nghĩa là cách tiếp cận tổng thể là một quy tắc đặc biệt cần nhớ. (Điều này nhắc nhở tôi về những nỗ lực tạo ra một tiếng Anh đơn giản với ít từ vựng hơn, họ cắt bỏ những từ như vẫn tồn tại , nhưng họ bỏ qua những thành ngữ khó hiểu như tiếp tục .)
ruakh
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.