Làm thế nào tôi có thể gửi các ký tự đến một lệnh như thể chúng đến từ một tệp?
Ví dụ tôi đã thử:
wc < "apple pear orange"
-bash: apple pear orange: No such file or directory
Làm thế nào tôi có thể gửi các ký tự đến một lệnh như thể chúng đến từ một tệp?
Ví dụ tôi đã thử:
wc < "apple pear orange"
-bash: apple pear orange: No such file or directory
Câu trả lời:
Trong các shell hỗ trợ ở đây các chuỗi , bao gồm bash
, zsh
và ksh93
, bạn có thể sử dụng
wc <<< "apple pear orange"
Hai cách tiếp cận khác (cho phép nhập nhiều dòng mà không cần nỗ lực thêm):
Sử dụng "tài liệu ở đây":
$ wc << EOF táo lê cam EOF 1 3 18 $
Các EOF
chuỗi là một dấu phân cách. Bạn có thể sử dụng bất kỳ chuỗi nào; EOF
chỉ là một sự lựa chọn thông thường.
Sử dụng tty làm đầu vào:
$ wc táo lê cam Ctrl+D 1 3 18 $
Điều này có nhược điểm là chương trình bắt đầu chạy và bắt đầu đọc đầu vào, ngay khi bạn nhập tên của nó. Điều này có thể gây bối rối; ví dụ:
$ grep v Con cáo nâu nhanh (đánh máy) nhảy qua (đánh máy) nhảy qua (Đây là đầu ra từ grep!) Con chó lười. (đã gõ) Ctrl + D (Không có đầu ra ở đây) $
<<<
mẫu cũng cho phép nhập nhiều dòng mà không cần nỗ lực thêm, vì "
chuỗi ký tự có thể chứa dòng mới. Tất nhiên, << EOF
biểu mẫu (cú pháp tài liệu gốc ở đây) dễ đọc hơn nếu bạn có đầu vào nhiều dòng.
<<<
word
- tất nhiên, trong ngữ cảnh của shell, a word
có thể là một chuỗi được trích dẫn, chứa khoảng trắng và dòng mới! Ôi! Điều đó quá rõ ràng đến nỗi không cần phải nói (và trên thực tế, tôi không thấy nó được đề cập trong trang người đàn ông nào cả). :-( Cảm ơn bạn đã chỉ ra điều này cho tôi!
word
được định nghĩa trong trang này là "Một chuỗi các ký tự được coi là một đơn vị theo vỏ" (còn gọi là "mã thông báo") và bạn cần biết rằng các chuỗi được trích dẫn được coi là "một đơn vị" theo nghĩa liên quan (sau xử lý dấu gạch chéo ngược, mở rộng biến, v.v. "Nhưng thực sự đó là toàn bộ mục đích của trích dẫn kép trong shell. (Dấu ngoặc đơn cũng bảo vệ khỏi sự mở rộng.) Mô hình xử lý của shell được suy nghĩ rất kỹ, và bất cứ điều gì ngoài đơn giản.
Mặc dù có một số giải pháp hợp lệ ở đây, đôi khi một cú pháp khác có thể hữu ích, là chạy một lệnh trong <()
. Điều này sẽ cho phép bạn tạo nhiều hơn 1 đối tượng mô tả tệp trên một dòng lệnh.
Điều này có thể hữu ích khi bạn đang làm một cái gì đó như so sánh các chuỗi văn bản dài hoặc nếu bạn muốn tìm một số nội dung không có trong một tệp.
Ví dụ: so sánh các tệp máy chủ trên hai nút mà không phải sao chép tệp máy chủ vào localhost:
diff -Naur <(cat /etc/hosts) <(ssh -q otherhost 'cat /etc/hosts')
Các <
chuyển hướng một tập tin vào STDIN, và ()
tạo ra một subshell để chạy các lệnh giữa dấu ngoặc. Đó là STDOUT từ lớp con được truyền đến STDIN của lệnh đang được chạy.
Đó là một cách dễ dàng hơn để tạo nhiều hơn 1 "tệp" đầu vào cho một lệnh hơn là cố gắng sử dụng nhiều tài liệu ở đây hoặc cố gắng lặp lại nhiều lệnh thành một đường dẫn đến lệnh cuối cùng.
<fileorpathname
chuyển hướng stdin, nhưng <(subcmd)
không; nó thay thế một tên mà khi / nếu được mở bởi chương trình có thể đọc thiết bị xuất chuẩn từ subcmd. < <(subcmd)
(không gian cần thiết) không chuyển hướng stdin từ tệp đó, gần giống như subcmd |
. Bạn diff
có thể đọc một trong những đầu vào của nó từ stdin bằng cách chỉ định một đối số -
nhưng không phải cả hai.
cmd <(cmd2 ...)
và cmd < <(cmd2 ...)
. Cái trước cho phép dữ liệu dẫn xuất (đầu ra của cmd2) được sử dụng để đặt tên tệp. Cái sau tương đương với cmd2 ... | cmd
. Các lệnh phải được viết để chấp nhận đầu vào stdin một cách rõ ràng và nhiều lệnh thì không. Điều này đặc biệt đúng với các kịch bản shell.
Bạn có thể muốn sử dụng một cái gì đó tương tự như mong đợi. Sau đây là một ví dụ đơn giản về việc mở một phiên telnet từ xa, chờ lời nhắc, gửi một số dữ liệu, chờ phản hồi, ngủ và thoát.
#!/usr/bin/expect
spawn telnet localhost 8555
expect "Escape character is '^]'."
send "Hello World\n"
expect "Connection closed by foreign host."
sleep 1