Truyền đối số cho một chương trình tương tác không tương tác


113

Tôi có một tập lệnh bash sử dụng readlệnh để đọc các đối số cho các lệnh một cách tương tác, ví dụ: tùy chọn có / không. Có cách nào để gọi tập lệnh này trong một tập lệnh không tương tác chuyển các giá trị tùy chọn mặc định làm đối số không?

Đó không chỉ là một lựa chọn mà tôi phải chuyển cho tập lệnh tương tác.


2
Nếu nó đang đọc từ stdin, bạn có thể nhập vào đầu vào của mình
lc.

4
Vì câu hỏi này có nhiều điểm trùng lặp, nên cần chỉ ra rằng chương trình tương tác được viết bằng ngôn ngữ nào không quan trọng. Nó có thể là một chương trình C đọc đầu vào chuẩn, hoặc một ứng dụng Erlang, hoặc bất cứ thứ gì. Có một thứ gì đó chạy từ dòng lệnh và đòi hỏi đầu vào tương tác một cách đáng ghét, và bạn muốn tự động hóa nó.
tripleee

Tất nhiên, nếu bạn có quyền kiểm soát ứng dụng đáng ghét, hãy viết lại nó để nó có thể đọc câu trả lời một cách phi thực tế (thông qua tệp cấu hình, tùy chọn dòng lệnh hoặc bất cứ điều gì). Điều này đáng tin cậy và mạnh mẽ hơn nhiều so với việc thay đổi thứ tự hoặc từ ngữ của các câu hỏi tương tác.
tripleee

Câu trả lời:


46

Đối với các tác vụ phức tạp hơn có expect( http://en.wikipedia.org/wiki/Expect ). Về cơ bản, nó mô phỏng một người dùng, bạn có thể viết một tập lệnh để phản ứng với kết quả đầu ra của chương trình cụ thể và những thứ liên quan.

Điều này cũng hoạt động trong các trường hợp như sshvậy cấm đường ống mật khẩu vào nó.


8
... Mặc dù giải pháp thích hợp trong trường hợp SSH là chuyển sang xác thực khóa công khai.
tripleee

154

Nhiều cách

ghi đầu vào của bạn

echo "yes
no
maybe" | your_program

chuyển hướng từ một tệp

your_program < answers.txt

sử dụng tài liệu tại đây ( tài liệu này có thể rất dễ đọc)

your_program << ANSWERS
yes
no
maybe
ANSWERS

sử dụng một chuỗi ở đây

your_program <<< $'yes\nno\nmaybe\n'

5
Nó chỉ ra rằng điều này chỉ hoạt động nếu chương trình đọc đầu vào chuẩn. Một số chương trình không thể đọc tương tác, ví dụ như mật khẩu, ngay cả khi đầu vào chuẩn là một đường ống. Đối với mật khẩu, điều này có ý nghĩa vì lý do bảo mật; mặc dù một số chương trình tương tác được thiết kế đơn giản.
tripleee

@tripleee Cùng với những gì bạn đã nói, làm cách nào để script đọc mật khẩu mà không bị ảnh hưởng bởi stdin? Tôi biết bạn có thể sử dụng readđể lấy stdin, bạn có thể sử dụng chức năng nào để làm những gì bạn mô tả?
flow2k 17/10/17

Trong trường hợp đó, bạn cần xem liệu chương trình mà bạn đang cố gắng tương tác có cách đặc biệt nào để gửi dữ liệu đầu vào đến nó hay không (ví dụ: sshpass, ssh-agent) hay sử dụng mong đợi để tạo kịch bản cho tương tác.
glenn Jackman

2
Những gì các chương trình như Expect làm là chạy máy khách dưới một tty giả, nơi nó trông máy khách giống như có một người dùng với một thiết bị đầu cuối và một bàn phím ở đầu kia. Bạn không thể làm điều đó với một đường ống thông thường.
tripleee

Thông báo quan trọng. Điều này không hoạt động nếu chúng ta thêm dấu cách vào các lệnh được cung cấp.
71GA

13

Bạn có thể đưa dữ liệu vào một tệp và chuyển hướng lại nó như sau:

$ cat file.sh
#!/bin/bash

read x
read y
echo $x
echo $y

Dữ liệu cho tập lệnh:

$ cat data.txt
2
3

Thực thi script:

$ file.sh < data.txt
2
3

7

Chỉ muốn thêm một cách nữa. Tìm thấy nó ở nơi khác, và khá đơn giản. Giả sử tôi muốn chuyển yes cho tất cả các lời nhắc tại dòng lệnh cho một lệnh "execute_command", Sau đó, tôi chỉ cần đặt câu hỏi yes cho nó.

yes | execute_command

Điều này sẽ sử dụng có làm câu trả lời cho tất cả các lời nhắc có / không.


1

Bạn cũng có thể sử dụng printf để chuyển đầu vào vào tập lệnh của mình.

var=val
printf "yes\nno\nmaybe\n$var\n" | ./your_script.sh

0

anothe ralternative có thể là

echo "something" | tee /path/to/file

Lệnh tee in thông tin đầu vào mà nó nhận được ra màn hình và lưu vào tệp cùng lúc.

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.