Truyền văn bản cho chương trình mong đợi một tập tin


30

Liên quan đến một câu hỏi tôi đã hỏi về Stack Overflow: Truyền nhiều dòng mã cho wsadmin.sh? .

Tôi có, như một chuỗi, một vài dòng đầu vào mà tôi cần đưa vào một lệnh. Lệnh, tuy nhiên, chỉ chấp nhận một tệp đầy đủ đầu vào.

Có cách nào để tôi có thể lưu trữ các dòng trong một tệp hoặc ống tạm thời mà không bao giờ thực sự được ghi vào đĩa và sau đó đưa trực tiếp vào chương trình không?

Làm thế nào để tôi có được việc lấy đường ống, cho đầu vào vào nó, chuyển đường ống đó đến lệnh và sau đó thoát khỏi đường ống?


2
Bạn có thể thêm một ví dụ về lệnh bạn đang sử dụng không và nó được gọi như thế nào?
Đột phá

2
Điều đó có nghĩa là chương trình không chấp nhận stdin?
Léo Lam

Tôi đồng ý với cả hai người bình luận ở trên. Không thể đề xuất bất cứ điều gì có thể hoạt động mà không biết thông số kỹ thuật của chương trình.
Larssend

Câu trả lời:


27

Một giải pháp khác là sử dụng Thay thế quy trình trong Bash. Nếu hệ thống của bạn có tên ống, bạn có thể sử dụng tính năng này.

Nó được sử dụng như thế này:

program_expecting_a_file <(list)

trong đó listlà một chuỗi các lệnh shell (thực sự là các đường ống; chi tiết đầy đủ ở đây ). listsẽ được thực hiện và đầu ra của nó sẽ được kết nối với đường ống. Tên của đường ống sau đó được chuyển đến chương trình của bạn.

LƯU Ý: không gian không được phép giữa <(.

(Sự thay thế khác >(list)cũng hoạt động như bạn mong đợi.)

Trong trường hợp cụ thể của bạn, bạn có thể sử dụng

program_expecting_a_file <(echo "$your_strings")

mặc dù bạn có thể thấy giải pháp của @ meuh thanh lịch hơn.

Cập nhật: Rất nhiều ví dụ sử dụng tuyệt vời sẽ được tìm thấy tại Hướng dẫn lập trình Bash nâng cao .


Hai cái còn lại không hoạt động trong những trường hợp tầm thường nhất. Bạn đã vượt qua các bài kiểm tra mà tôi đã ném vào nó cho đến nay. Tôi đã nâng cấp của bạn bây giờ. Tôi sẽ quay lại và đánh dấu điều này là chấp nhận nếu nó làm mọi thứ tôi cần.
ArtOfWarfare 13/07/2015

Bạn làm việc hoàn hảo. Nếu bạn muốn, bạn có thể thêm nó vào câu hỏi liên quan trên StackOverflow và tôi cũng có thể chấp nhận nó ở đó. stackoverflow.com/questions/31374202/
hy

Xin chào @ArtOfWarfare, rất vui khi được giúp đỡ. Có một nhận xét ở đó đã có cùng một giải pháp được đề xuất, vì vậy tôi sẽ không thích hợp để đăng câu trả lời ở đó.
Edward

Bạn đăng giải pháp của bạn trước khi anh ấy làm. Dù sao, tôi đã yêu cầu anh ấy thay đổi nhận xét của mình thành một câu trả lời để tôi có thể chấp nhận nó. Nếu cả hai bạn không đăng câu trả lời trong vòng ~ 24 giờ cho câu hỏi đó, tôi sẽ chỉ tự mình đăng câu trả lời để tôi có thể chấp nhận nó (Tôi không muốn để lại câu hỏi của mình khi xuất hiện câu trả lời khi tôi tìm thấy câu trả lời là gì. chỉ là cách cư xử tệ cho độc giả tương lai / người trả lời tiềm năng của câu hỏi.)
ArtOfWarfare 14/07/2015

Xin chào @ArtOfWarfare, tôi hoàn toàn ổn với những gì bạn đề xuất!
Edward

15

Bạn có thể sử dụng bash tại đây-doc . Ví dụ,

$ cat -n <<<'a
> b'
 1  a
 2  b

Nếu bạn có một cái gì đó trong một biến bash, bạn cũng có thể nội suy nó: vd <<<"path is $PATH".


Nếu lệnh của bạn nhấn mạnh vào tên tệp, bạn có thể cung cấp cho nó /dev/stdin. Ví dụ:

$ sed -f /dev/stdin <<<'s/a/b/'

tạo đầu ra : s/b/b/.


Không rõ câu hỏi liệu lệnh có chấp nhận đầu vào không stdin, và nếu không, điều này sẽ không hoạt động. Tôi hy vọng OP làm rõ.
David Z

1
:( - Điều này có vẻ rất hứa hẹn, nhưng khi tôi thử nó, tôi đã nhận được thông báo lỗi"-f" option must be followed by a file name.
ArtOfWarfare 13/07/2015

Một tài liệu ở đây là dành cho stdin. Nếu lệnh của bạn hoàn toàn cần -fvà một tên tệp, sau đó cung cấp tên tệp /dev/stdin. Xem chỉnh sửa của tôi.
meuh 13/07/2015

Tôi nghĩ rằng sau khi chỉnh sửa, nó hoàn toàn là một lựa chọn khả thi!
Edward

1
+1 cho /dev/stdinđề xuất. Chương trình tôi đang cố gắng gọi chỉ chấp nhận tên tệp, vì vậy tôi đã kết hợp /dev/stdinvới một di sản.
Huw Walters

7

Tùy thuộc vào nội dung trong tập lệnh, bạn thể sử dụng tên tệp đặc biệt - (trừ) viết tắt của stdin

$ mycmd -
Line 1
Line 2
^D

Một phương pháp khác có thể phù hợp với bạn là mở tệp /dev/fd/0một lần nữa là viết tắt của stdin .

Tùy chọn thứ ba có thể là tạo một FIFO (First In First Out). Nó giống như một tập tin, nhưng nó có hai đầu với nó - bạn viết vào một đầu và đọc từ đầu kia.

-- Process 1 --                  -- Process 2 --
$ mkfifo foo
$ cat foo
<waits>                          $ echo hello > foo
hello                            $
$ rm foo

3
Có thể đáng lưu ý rằng chương trình phải được viết để diễn giải -theo cách này - nó không phải là một tính năng của hệ vỏ hoặc hệ điều hành. Mặc dù tất nhiên hầu hết các tiện ích Linux tiêu chuẩn đều tuân theo quy ước này, theo như tôi biết.
David Z

1
Không. Điều này không làm việc cho chương trình. Có một chế độ tương tác, nhưng tôi muốn chuyển các lệnh để thực thi chương trình này từ một chương trình khác và tôi không muốn vào lỗ thỏ expect.
ArtOfWarfare

@ArtOfWarfare Tôi vừa thêm một tùy chọn thứ ba có thể hoạt động.
Majenko

Câu trả lời tốt đẹp! Các tùy chọn thứ hai và thứ ba về cơ bản giống như <()giải pháp, nhưng rõ ràng hơn - có thể rất hữu ích!
Edward

4

Có một tùy chọn khác tương tự như mycmd -giải pháp, nhưng ngay cả đối với các chương trình không xử lý -cụ thể:

$ mycmd /dev/stdin
Line 1
Line 2
^D

/dev/stdin dường như có liên quan đến hệ điều hành và nó hoạt động với tôi trên Debian GNU / Linux, nhưng tôi không chắc nó cũng sẽ hoạt động ở đâu nữa.


1
Điều này có vẻ như nó có thể làm việc, nhưng là ^Dgì?
ArtOfWarfare

^Dlà một ký hiệu phổ biến để nhấn Ctrl-D. ^ D có ngữ nghĩa của "cuối luồng đầu vào" ở đây. Có lẽ nó thường được nhìn thấy trong ^Choặc viết ^Ztắt để nhấn Ctrl-C tương ứng để nhấn Ctrl-Z.
Axel Beckert

1
Điều đó dường như có tác dụng, nhưng làm thế nào tôi có thể lập trình đưa công cụ vào /dev/stdinvà sau đó đóng nó?
ArtOfWarfare 13/07/2015

1
Chỉ cần đặt một cái gì đó vào lệnh đó và nó sẽ hoạt động, tức là cat content | mycmd /dev/stdin. Chỉ cần tưởng tượng các lệnh khác nhau hơn catở đây.
Axel Beckert
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.