2009-09-28 35 views
5

Tôi có một chương trình đọc từ đầu vào tiêu chuẩn khi được gọi từ dòng lệnh. Thông thường người dùng sẽ nhập một số thông tin, nhấn C-d trên một dòng mới để báo hiệu kết thúc tệp, và chương trình sẽ xử lý tệp. Sau đó, người dùng một lần nữa sẽ được nhắc nhở, sẽ nhập một số văn bản hơn, và một lần nữa nhấn C-d để báo hiệu kết thúc của tập tin thứ hai.gửi nhiều tập tin từ tập lệnh shell qua đầu vào tiêu chuẩn

Tôi đang tìm cách viết tập lệnh shell sẽ gọi chương trình này và tự động gửi hai tệp. Tôi muốn làm điều gì đó như thế này:

$ myprogram < file1.txt < file2.txt 

HOẶC

$ myprogam <file1.txt file2.txt 

Bất kỳ lời đề nghị? Tôi đang sử dụng bash shell trong Linux.

+0

Người dùng cho biết kết thúc của tất cả các tệp như thế nào? Hai control-D liên tiếp? Thiết kế chuẩn cho các chương trình Unix là "đọc các tập tin có tên trên dòng lệnh; nếu không có các tệp như vậy, hãy xử lý đầu vào tiêu chuẩn". Nếu bạn chấp nhận thiết kế đó, không có vấn đề gì; bạn chỉ cần gọi 'myprogram file1.txt file2.txt'. –

Trả lời

3

Rõ ràng, bạn có thể sử dụng cat để gửi hai tập tin vào một đầu vào tiêu chuẩn chương trình, nhưng điều này có lẽ không phải những gì bạn muốn:

$ cat file1.txt file2.txt | myprogram 

Trong trường hợp trên myprogram sẽ không thể để cho biết nơi file1.txt đầu và file2.txt bắt đầu, trừ khi chúng có định dạng cụ thể và nó đang xem luồng cho một số định dạng nhất định biểu thị kết thúc hoặc bắt đầu của một tệp.

Không có cách nào chuẩn cho nhiều luồng được gửi vào đầu vào chuẩn. Về cơ bản, chỉ có một luồng duy nhất đi vào đầu vào tiêu chuẩn.

Có thể bạn sẽ cấu trúc tập lệnh của mình để nó chấp nhận nhiều đối số trên dòng lệnh và được mở bên trong và xử lý chúng cùng một lúc. Đó là, bạn sẽ gọi nó là như vậy:

$ myprogram file1.txt file2.txt 
+0

có thể có cách để nói: $ cat file1.txt "EOF" file2.txt và sau đó nó sẽ biết đó là hai tệp riêng biệt? –

+0

Không, không có cách nào để gửi EOF như thế; nhìn nhận xét của tôi cho câu trả lời của Pavel Shved. –

0

Jonathan Leffler nói trong comment của mình, rằng giải pháp của tôi là không chính xác. Có thể nó là. Tôi thực sự chưa kiểm tra kỹ. Nhưng hãy để nó ở đây chỉ để cho thông tin rằng đó là một câu trả lời sai, ít nhất.


Bash có thể lặp lại ký tự điều khiển bằng lệnh echo. EOFC-d, như bạn đã lưu ý, vì vậy hãy sử dụng một subshell:

$ (cat file1.txt ; echo -e '\cD' ; cat file2.txt) | myprogram 

này sẽ thực hiện các lệnh trong ngoặc đơn và ống đầu ra của tất cả chúng như thể nó là một chương trình riêng biệt.

Nếu bạn không chắc chắn rằng nó ống một cách chính xác, hãy thử điều này:

$ (echo "Hello" ; echo -e '\cD' ; echo "bash") | tee 
+1

Điều khiển-D bị chặn bởi trình điều khiển thiết bị đầu cuối và làm cho nó gửi bất kỳ dữ liệu đang chờ xử lý nào - không có ký tự nào nếu không có dữ liệu nào đang chờ xử lý. Do đó, chương trình nhận được một số không đọc byte, cho biết EOF. Echo các ký tự điều khiển chữ D xuống đường ống không mô phỏng điều này - không có trình điều khiển đầu cuối để hỗ trợ. Đó là nơi 'kỳ vọng' xuất hiện - nó sử dụng các tses giả để mô phỏng các thiết bị đầu cuối. –

2

Liệu nó có phải là 1 gọi? Nếu không:

for file in file1 file2 file3; do myprogram < $file; done 
0

Tôi đã viết một chương trình Python đơn giản để mô phỏng hành vi của chương trình bạn mô tả. Ở mức tối thiểu, điều này đặt tất cả chúng ta vào vị trí nói về cùng một thứ thay vì giả định cách chương trình của bạn hoạt động. (Tất nhiên, nếu chương trình của bạn không thực sự hoạt động theo cách tôi mô tả ở đây, hãy sửa tôi.)

#!/usr/bin/python 

def read_a_file(): 
    print('Type the contents of a file now.') 
    while True: 
     try: 
      s = raw_input('>') 
     except EOFError: 
      break 

read_a_file() 
read_a_file() 
print('We have now read two files. Quitting.') 

Bạn có thể chạy kịch bản này, gõ nội dung của file đầu tiên, nhấn tổ hợp phím CTRL-D, gõ nội dung của file thứ hai, nhấn Ctrl-D, và thoát khỏi chương trình. Đây dường như là hành vi bạn mô tả.

Suy nghĩ đầu tiên của tôi là sử dụng mong đợi, như sự hỗn loạn được đề xuất. Tuy nhiên, tôi không thể tìm thấy bất kỳ sự hỗ trợ nào trong việc mong đợi đường ống nội dung của một tệp đến một quy trình. (Tôi cho rằng nội dung của các tệp khác nhau mỗi lần. Nếu chúng giống nhau, thì mong đợi sẽ hoạt động, chỉ bằng cách đặt nội dung của tệp vào kịch bản mong đợi.)

Tôi nên lưu ý rằng tôi không có nghĩa là một chuyên gia kỳ vọng; có thể có một cách để làm điều này không rõ ràng với tôi.

Suy nghĩ thứ hai của tôi là viết một tập lệnh Python đã khởi chạy chương trình của bạn và cho nó nội dung của các tệp và các ký tự EOF. Tuy nhiên, nhận xét của Jonathan Leffler khiến tôi nghĩ rằng các nhân vật EOF lặp lại sẽ không hoạt động.

Suy nghĩ thứ ba của tôi khá là kludgy. Bạn có thể viết một kịch bản để tạo ra một kịch bản mong đợi bằng cách cắm nội dung của các tệp vào kịch bản mong đợi và sau đó thực thi kịch bản mong đợi. Tôi nghi ngờ rằng sẽ làm việc.

Các vấn đề liên quan