Tự động nhập đầu vào trong dòng lệnh


142

Tôi đang chạy một tập lệnh mà nó yêu cầu nhập 'y' trên mỗi thao tác, tôi đang tìm kiếm một giải pháp như $ ./script < echo 'yyyyyyyyyyyyyy'vượt qua tất cả các đầu vào của mình trong một lần.


Đôi khi -ftùy chọn hoạt động tốt với các lệnh nhất định.
iammilind

Câu trả lời:


258

Có một lệnh được tạo riêng cho trường hợp đó: yes

$ yes | ./script

Những gì nó làm là kết nối đầu ra của yesđầu vào ./script. Vì vậy, khi ./scriptyêu cầu đầu vào của người dùng, thay vào đó, nó sẽ nhận được đầu ra yes. Đầu ra của yeslà một dòng vô tận ytheo sau bởi một dòng mới. Vì vậy, về cơ bản như thể người dùng đang nhập ycho mọi câu hỏi ./script.

Nếu bạn muốn nói không ( n) thay vì có ( y) bạn có thể làm như thế này:

$ yes n | ./script

Lưu ý rằng một số công cụ có một tùy chọn để luôn luôn yestrả lời. Xem ở đây ví dụ: Bỏ qua lời nhắc có / không trong 'apt-get nâng cấp'


Các phương pháp khác để nhập dữ liệu:

Nếu bạn biết chính xác có bao nhiêu ykịch bản của bạn đang mong đợi, bạn có thể làm nó như thế này:

$ printf 'y\ny\ny\n' | ./script

Các dòng mới ( \n) là các phím enter.

Sử dụng printfthay vì yesbạn có quyền kiểm soát chi tiết hơn của đầu vào:

$ printf 'yes\nno\nmaybe\n' | ./script

Lưu ý rằng trong một số trường hợp hiếm hoi, lệnh không yêu cầu người dùng nhấn enter sau ký tự. trong trường hợp đó hãy bỏ dòng mới ra:

$ printf 'yyy' | ./script

Để hoàn thiện, bạn cũng có thể sử dụng tài liệu ở đây :

$ ./script << EOF
y
y
y
EOF

Hoặc nếu shell của bạn hỗ trợ nó một chuỗi ở đây :

$ ./script <<< "y
y
y
"

Hoặc bạn có thể tạo một tệp với một đầu vào trên mỗi dòng:

$ ./script < inputfile

Nếu lệnh đủ phức tạp và các phương thức trên không còn đủ thì bạn có thể sử dụng mong đợi .

Dưới đây là một ví dụ về một kịch bản kỳ vọng siêu đơn giản:

spawn ./script
expect "are you sure?"
send "yes\r"
expect "are you really sure?"
send "YES!\r"
expect eof

Kỹ thuật nitpick:

Lệnh gọi giả định mà bạn đưa ra trong câu hỏi của bạn không hoạt động:

$ ./script < echo 'yyyyyyyyyyyyyy'
bash: echo: No such file or directory

Điều này là do ngữ pháp shell cho phép toán tử chuyển hướng ở bất cứ đâu trong dòng lệnh. Về phần vỏ có liên quan đến dòng lệnh giả định của bạn giống như dòng này:

$ ./script 'yyyyyyyyyyyyyy' < echo
bash: echo: No such file or directory

Điều đó có nghĩa là ./scriptsẽ được gọi với đối số 'yyyyyyyyyyyyyy'và stdin sẽ nhận đầu vào từ một tệp có tên echo. Và bash phàn nàn vì tập tin không tồn tại.


1
Tôi nhận được một cannot enable tty mode on non tty input. Bạn có biết một cách giải quyết cho điều đó?
bmpasini

Khi tôi thử printfmẹo với một runtệp mà tôi cần để tự động hóa quá trình cài đặt, tất cả những gì xảy ra là tôi nhận được thông báo lỗi Warning: Tried to connect to session manager, None of the authentication protocols specified are supportedvà tập lệnh sẽ mở trong một thiết bị đầu cuối mới và yêu cầu tôi nhập thủ công như bình thường. Điều này đang xảy ra trên Debian bằng cách này. Bất kỳ đề xuất?
DavidB

cần thêm chi tiết. quá lớn cho ý kiến. xin hỏi một câu hỏi mới với tất cả các chi tiết bạn có thể đặt một liên kết ở đây.
lesmana

không có gì hoạt động với 'phá hủy mơ hồ' trên centos
vẽ

Xấu dễ! Hoạt động trên nhập dữ liệu Google Cloud Beta SQL! Nhiều đánh giá cao!
G_Style

11

Sử dụng lệnh yes:

yes | script

Trích từ trang người đàn ông:

NAME
       yes - output a string repeatedly until killed

SYNOPSIS
       yes [STRING]...
       yes OPTION

DESCRIPTION
       Repeatedly output a line with all specified STRING(s), or 'y'.

9

Một số thứ ( apt-getví dụ) chấp nhận các cờ đặc biệt để chạy ở chế độ im lặng (và chấp nhận mặc định). Trong apt-gettrường hợp của bạn, bạn chỉ cần truyền cho nó một -ylá cờ. Điều này hoàn toàn phụ thuộc vào kịch bản của bạn mặc dù.

Nếu bạn cần những thứ phức tạp hơn, bạn có thể gói kịch bản của mình trong một kịch bản mong đợi. mong đợi cho phép bạn đọc đầu ra và gửi đầu vào để bạn có thể thực hiện những điều khá phức tạp mà các kịch bản khác không cho phép. Đây là một trong những ví dụ từ trang Wikipedia của nó :

# Assume $remote_server, $my_user_id, $my_password, and $my_command were read in earlier
# in the script.
# Open a telnet session to a remote server, and wait for a username prompt.
spawn telnet $remote_server
expect "username:"
# Send the username, and then wait for a password prompt.
send "$my_user_id\r"
expect "password:"
# Send the password, and then wait for a shell prompt.
send "$my_password\r"
expect "%"
# Send the prebuilt command, and then wait for another shell prompt.
send "$my_command\r"
expect "%"
# Capture the results of the command into a variable. This can be displayed, or written to disk.
set results $expect_out(buffer)
# Exit the telnet session, and wait for a special end-of-file character.
send "exit\r"
expect eof

Điều này không thể được sử dụng nó với một .shkịch bản shell, phải không? Hay là có một cách?
Shaya

7

Trong kịch bản shell, bạn cũng có thể sử dụng thủ thuật sinh sản, mong đợi và gửi sau đây

spawn script.sh
expect "Are you sure you want to continue connecting (yes/no)?"
send "yes"

Tuy nhiên, trong scenerio ở trên, bạn sẽ phải đưa ra cụm từ mà bạn đang mong đợi nhận được trong khi bạn thực thi tập lệnh để có thêm ví dụ đi đến liên kết sau

Mong đợi trong Bash


2

Được rồi, đây có thể không phải là một giải pháp rất thanh lịch nhưng nếu bạn viết các tùy chọn của mình trong một tệp riêng biệt và sau đó chuyển nó làm đầu vào cho tập lệnh, nó cũng sẽ hoạt động. Vì vậy, nếu bạn tạo một tệp mới với tất cả các tùy chọn của mình (gọi tệp này là 'tùy chọn.in'), thì bạn có thể dễ dàng chạy tập lệnh của mình ./script.sh < options.invà chỉnh sửa / tạo các tệp tùy chọn khác nhau nếu phù hợp.


Tôi nên viết options.intập tin như thế nào? Bạn có thể đưa ra một ví dụ không?
Shaya

0

Tôi đã viết một tập lệnh bash với Dialog và cũng cần điều này xảy ra tự động. Tôi đã làm điều này và nó làm việc như một lá bùa.

# -Wy force signaturewipe (if exists)
echo "y" | sudo lvcreate -W y -n $lvName -L "$lvSize"G /dev/"$svg" >> $nfsUtilLog

-1

Bạn có thể cung cấp đầu vào của người dùng cho tập lệnh của mình cat, từ tệp văn bản, được chuyển sang tập lệnh của bạn bashnhư sau:

cat input.txt | bash your_script.sh

Chỉ cần đặt đầu vào người dùng mong muốn của bạn vào tệp input.txt của bạn, bất kỳ câu trả lời nào bạn muốn - y, n, chữ số, chuỗi, v.v.



@muru Đối với tôi, giải pháp bạn đề cập không hiệu quả, vì vậy tôi phải tự phát minh ra.
WebCome

Không có khả năng. Cả hai bạn mô tả cùng một điều.
muru

@muru Ý tưởng tương tự về việc cung cấp câu trả lời từ tệp (có thể được thực hiện theo nhiều cách) không giống nhau, và hơn nữa nó đã hoàn thành một cách hoàn toàn khác. Bạn sẽ có thể nhìn thấy nó. Nếu giải pháp bạn chỉ ra sẽ có hiệu quả với tôi, tôi sẽ không dành thời gian để sáng tạo lại bánh xe ngày hôm nay. Bạn có thể sử dụng bất cứ điều gì làm việc cho bạn.
WebCome

@muru Tôi tin rằng có một sự khác biệt giữa hai điều này, một số trong đó được mô tả trong các câu trả lời nói ở đây là Askubfox.com/questions/172982/ . Đối với tôi, ví dụ, mã của tôi nếu đầu ra được chuyển hướng đến tệp có vẻ rõ ràng hơn như một luồng tự nhiên từ trái sang phải. Rốt cuộc, việc hạ thấp các giải pháp hoạt động tốt như bạn không kích thích mọi người chia sẻ giải pháp của họ ở đây. Tôi tin rằng nói là đủ để loại bỏ downvote.
WebCome
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.