การส่งผ่านข้อโต้แย้งไปยังโปรแกรมโต้ตอบแบบไม่โต้ตอบ


115

ฉันมีสคริปต์ทุบตีที่ใช้readคำสั่งเพื่ออ่านอาร์กิวเมนต์ของคำสั่งแบบโต้ตอบตัวอย่างเช่นตัวเลือกใช่ / ไม่ใช่ มีวิธีเรียกสคริปต์นี้ในสคริปต์ที่ไม่ใช่แบบโต้ตอบที่ส่งผ่านค่าตัวเลือกเริ่มต้นเป็นอาร์กิวเมนต์หรือไม่

ไม่ใช่แค่ตัวเลือกเดียวที่ฉันต้องส่งผ่านไปยังสคริปต์โต้ตอบ


2
หากอ่านจาก stdin คุณสามารถไพพ์อินพุตของคุณ
lc

4
เนื่องจากคำถามนี้มีคำซ้ำหลายรายการจึงควรชี้ให้เห็นว่าไม่สำคัญว่าโปรแกรมโต้ตอบจะเขียนด้วยภาษาใด อาจเป็นโปรแกรม C ที่อ่านอินพุตมาตรฐานหรือแอปพลิเคชัน Erlang หรืออะไรก็ได้ มีบางอย่างที่ทำงานจากบรรทัดคำสั่งและต้องการการป้อนข้อมูลแบบโต้ตอบอย่างน่ารังเกียจและคุณต้องการทำให้เป็นอัตโนมัติ
tripleee

แน่นอนว่าหากคุณสามารถควบคุมแอปพลิเคชันที่น่ารังเกียจได้ให้เขียนใหม่เพื่อให้สามารถอ่านคำตอบได้โดยไม่ตั้งใจ (ผ่านไฟล์การกำหนดค่าตัวเลือกบรรทัดคำสั่งหรืออะไรก็ตาม) สิ่งนี้มีความน่าเชื่อถือและมีประสิทธิภาพมากขึ้นเมื่อเทียบกับการเปลี่ยนลำดับหรือถ้อยคำของคำถามเชิงโต้ตอบ
tripleee

คำตอบ:


46

สำหรับงานที่ซับซ้อนมากขึ้นมีexpect( http://en.wikipedia.org/wiki/Expect ) โดยพื้นฐานแล้วจะจำลองผู้ใช้คุณสามารถโค้ดสคริปต์ว่าจะตอบสนองต่อผลลัพธ์ของโปรแกรมเฉพาะและสิ่งที่เกี่ยวข้องได้อย่างไร

นอกจากนี้ยังใช้งานได้ในกรณีเช่นนี้sshที่ห้ามไม่ให้ส่งรหัสผ่านไปยังรหัสผ่าน


8
... แม้ว่าวิธีแก้ปัญหาที่เหมาะสมในกรณี SSH คือการเปลี่ยนไปใช้การพิสูจน์ตัวตนด้วยคีย์สาธารณะ
tripleee

154

หลายวิธี

ส่งข้อมูลของคุณ

echo "yes
no
maybe" | your_program

เปลี่ยนเส้นทางจากไฟล์

your_program < answers.txt

ใช้เอกสารที่นี่ (สามารถอ่านได้มาก)

your_program << ANSWERS
yes
no
maybe
ANSWERS

ใช้สตริงที่นี่

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

5
มันชี้ให้เห็นว่าสิ่งนี้ใช้ได้เฉพาะเมื่อโปรแกรมอ่านอินพุตมาตรฐาน บางโปรแกรมไม่สามารถอ่านเช่นรหัสผ่านแบบโต้ตอบได้แม้ว่าอินพุตมาตรฐานจะเป็นไพพ์ก็ตาม สำหรับรหัสผ่านสิ่งนี้เหมาะสมสำหรับเหตุผลด้านความปลอดภัย แม้ว่าโปรแกรมโต้ตอบบางโปรแกรมจะได้รับการออกแบบมาไม่ดีก็ตาม
tripleee

@tripleee ตามสิ่งที่คุณพูดสคริปต์อ่านรหัสผ่านที่ไม่ได้รับผลกระทบจาก stdin อย่างไร ฉันรู้ว่าคุณสามารถใช้readเพื่อจับ stdin คุณสามารถใช้ฟังก์ชันอะไรทำตามที่คุณอธิบายไว้
flow2k

ในกรณีนี้คุณต้องดูว่าโปรแกรมที่คุณพยายามโต้ตอบมีวิธีพิเศษในการส่งอินพุตไปให้หรือไม่ (เช่น sshpass, ssh-agent) หรือใช้คาดว่าจะเขียนสคริปต์การโต้ตอบ
glenn jackman

2
สิ่งที่โปรแกรมเช่น Expect ทำคือเรียกใช้ไคลเอนต์ภายใต้ pseudo-tty ซึ่งดูเหมือนว่าไคลเอ็นต์มีผู้ใช้ที่มีเทอร์มินัลและคีย์บอร์ดอยู่ที่ปลายอีกด้านหนึ่ง คุณไม่สามารถทำได้ด้วยท่อธรรมดา
tripleee

ประกาศสำคัญ ไม่ได้ผลถ้าเราเพิ่มช่องว่างให้กับคำสั่งที่ให้มา
71GA

13

คุณสามารถใส่ข้อมูลลงในไฟล์และกำหนดทิศทางใหม่ได้ดังนี้:

$ cat file.sh
#!/bin/bash

read x
read y
echo $x
echo $y

ข้อมูลสำหรับสคริปต์:

$ cat data.txt
2
3

การเรียกใช้สคริปต์:

$ file.sh < data.txt
2
3

7

แค่อยากจะเพิ่มอีกหนึ่งวิธี พบได้จากที่อื่นและค่อนข้างเรียบง่าย สมมติว่าฉันต้องการส่งใช่สำหรับพรอมต์ทั้งหมดที่บรรทัดคำสั่งสำหรับคำสั่ง "execute_command" จากนั้นฉันก็แค่ไพพ์ใช่มัน

yes | execute_command

สิ่งนี้จะใช้ใช่เป็นคำตอบสำหรับการแจ้งเตือนใช่ / ไม่ใช่ทั้งหมด


2

คุณยังสามารถใช้ printf เพื่อไพพ์อินพุตไปยังสคริปต์ของคุณ

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

นั่นคือสิ่งที่ช่วยฉัน ขอบคุณ @spanchan.
sk001

0

anothe ralternative ได้

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

คำสั่ง tee จะพิมพ์อินพุตที่ได้รับไปยังหน้าจอและบันทึกลงในไฟล์ในเวลาเดียวกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.