ป้อนข้อความโดยอัตโนมัติจากสคริปต์ทุบตีโดยไม่ต้องใช้ EOF


10

ฉันใช้ Ubuntu Linux myprogramสมมติว่ามีโปรแกรมที่เรียกว่า โปรแกรมนี้ให้ผู้ใช้ป้อนข้อมูล Enterโดยเฉพาะผู้ใช้ต้องพิมพ์เป็นจำนวนเต็มเมื่อได้รับแจ้งและกด ฉันต้องการทำให้กระบวนการนี้เป็นแบบอัตโนมัติโดยใช้สคริปต์ทุบตี โดยเฉพาะอย่างยิ่งฉันต้องการที่จะดำเนินการmyprogramพูด 100 ครั้ง (ใช้เคาน์เตอร์iที่ไปจาก1ไป100) ในการดำเนินการแต่ละครั้งmyprogramฉันต้องการป้อนค่าปัจจุบันของiเมื่อได้รับแจ้ง

(โดยวิธีการmyprogramใช้ตัวเลือก / สวิทช์-optionsซึ่งทั้งหมดจะคงที่และระบุไว้ในสคริปต์ทุบตี)

โครงกระดูกที่ไม่สมบูรณ์ของสคริปต์ทุบตีนี้อาจเป็น:

#!/bin/bash
for i in {1..100}
do
   myprogram -options
done

ตอนนี้ฉันต้องการแก้ไขโค้ดด้านบนเพื่อให้iป้อนค่าปัจจุบันของเมื่อได้รับแจ้งจากโปรแกรม วิธีที่ดีที่สุดในการทำเช่นนี้คืออะไร?

เว็บไซต์ของซอฟต์แวร์ที่ฉันใช้แนะนำให้ใช้<<EOFที่ท้ายmyprogram -optionsบรรทัด ฉันคิดว่าสิ่งนี้บอกให้ทุบตีดูที่ "จุดสิ้นสุดของไฟล์" สำหรับอินพุตที่จะใช้ แต่ถ้าฉันไม่ต้องการวางอินพุตที่ท้ายไฟล์ล่ะ เกิดอะไรขึ้นถ้าผมอยากจะใส่มันทันทีหลังจากที่<<หรือ<?

เหตุผลก็คือสิ่งต่าง ๆ จะมีความซับซ้อนมากขึ้น ตัวอย่างเช่นฉันอาจแนะนำตัวนับจำนวนเต็มที่jเปลี่ยนแปลงในวิธีที่ไม่เป็นเชิงเส้นหรือไม่ต่อเนื่อง จากนั้นผมก็อยากจะกินค่าปัจจุบันของjไปmyprogramในแต่ละซ้ำ แต่ค่าของjอาจมีการเปลี่ยนแปลงระหว่างการโทรไปและจุดสิ้นสุดของแฟ้ม myprogram -optionsEOF

คุณมีข้อเสนอแนะใด?


ตรวจสอบบล็อกนี้ - การใช้งานโปรแกรมแบบโต้ตอบ
Suresh

คำตอบ:


14

สำหรับโปรแกรมเกือบทั้งหมดทั้งecho $i | myprogram -optionsและmyprogram -options <<<$iควรทำงานโดยป้อนโปรแกรม$iผ่านอินพุตมาตรฐาน

<fooจะใช้เนื้อหาของไฟล์ที่ชื่อว่าfooเป็น stdin

<<fooจะใช้ข้อความระหว่างบรรทัดนั้นกับบรรทัดที่ประกอบด้วยfooอินพุตมาตรฐานเท่านั้น นี่คือเอกสารที่นี่ (heredoc) ตามที่ Gilles พูด; EOFไม่ได้หมายถึงจุดสิ้นสุดของไฟล์มันเป็นเพียงตัวกำจัด heredoc ทั่วไป (เราใช้ "foo" แทนในตัวอย่างนี้)

<<<fooจะใช้สตริง "foo" เป็นอินพุตมาตรฐาน คุณยังสามารถระบุตัวแปร$fooและเชลล์จะใช้เนื้อหาเป็น stdin ดังที่ฉันได้แสดงไว้ด้านบน สิ่งนี้เรียกว่าherestringเนื่องจากใช้สตริงสั้น ๆ ในทางตรงกันข้ามกับบล็อกทั้งหมดใน heredoc Herestrings ทำงานในทุบตี /bin/shแต่ไม่ได้อยู่ใน


9

ไวยากรณ์ที่แนะนำโดยเว็บไซต์นี้จะเรียกว่าที่นี่เอกสาร อินพุตไปยังโปรแกรมไฟล์เริ่มต้นทันทีด้านล่างบรรทัดที่มี<<EOFและจะไม่ถูกยกเลิกในตอนท้ายของสคริปต์ แต่โดยบรรทัดที่มีข้อความทั้งหมดEOF(ระวังอย่าให้มีพื้นที่ว่างเพิ่มเติม) อย่างไรก็ตามคุณสามารถใช้เครื่องหมายสิ้นสุดใด ๆ ที่ไม่มีอักขระพิเศษของเชลล์: EOFไม่ใช่คำหลักมันเป็นแบบดั้งเดิมเท่านั้น

#!/bin/bash
for i in {1..100}
do
   myprogram -options <<EOF
$i
EOF
   for j in {1..42}; do
     myprogram2 <<EOF
$i
$j
EOF
   done
done

ในคำอื่น ๆ EOF ในบริบทนี้หมายถึงการสิ้นสุดของแฟ้มเครื่องหมายไม่สิ้นสุดจริงของไฟล์สคริปต์ ข้อความ "EOF" เป็นข้อความที่กำหนดเอง - สิ่งที่คุณใช้ทันทีหลังจากตัวอักษร << ตัวจะแสดงจุดสิ้นสุดของเอกสารที่นี่ตอนนี้ ฉันมักจะใช้EOFเพราะมันโดดเด่นและไม่น่าเป็นไปได้มากที่จะอยู่ในเอกสารนี้ถ้าเช่นฉันกำลังสร้างเชลล์สคริปต์ (ซึ่งฉันทำค่อนข้างบ่อย)
cas

ที่เป็นตัวหนา EOF ควรจะ <ขีด> <ขีด> EOF <ขีด> <ขีด>
CAS

การใช้ที่นี่เอกสารเช่นนี้ผมได้เปลี่ยนบ่อยเครื่องหมายสิ้นสุดกับสิ่งที่มีความหมายมากขึ้น (และโอกาสน้อยที่จะ "สุ่ม" จับคู่) END_OF_WHATEVER_FUNCTIONเช่น บางครั้งการพยายามที่จะ "ประหยัด" พื้นที่ / ขนาดนั้นเป็นความพยายามอย่างมากเพราะมันทำให้เกิดความคลุมเครือในสิ่งที่เกิดขึ้นจริง
killermist

คุณจะsleepอ่านคำสั่งในสคริปต์ได้อย่างไร?
boltup_im_coding

@ ไม่คาดคิด 62 ฉันไม่เข้าใจสิ่งที่คุณถาม คุณควรถามคำถามใหม่ในเว็บไซต์นี้ ให้แน่ใจว่าได้ให้บริบทเพียงพอ
Gilles 'หยุดความชั่วร้าย'

3

ที่นี่เอกสารตามที่กล่าวถึงโดยทั้งเควินและกิลส์ข้างต้นหรือท่อง่ายจะทำงานในหลายกรณี

สำหรับสถานการณ์ที่มีความซับซ้อนมากขึ้นคุณอาจต้องการดูในสิ่งที่คาดหวังหรือสิ่งที่คล้ายกัน (เช่นโมดูล CPAN ที่คาดการณ์ :: Simple คือการใช้งาน perl ที่ง่ายมาก) ส่วนตัวฉันชอบโมดูล Perl (คาดว่าตัวเองเป็น tcl) แต่มีการใช้งานสำหรับภาษาสคริปต์ทั่วไปจำนวนมาก มันเป็นไปได้ที่จะเขียนมากการดำเนินการแบบดั้งเดิมของความคิดในการดวลจุดโทษหรือทุบตีใช้ในขณะที่อ่าน

แนวคิดทั่วไปเกี่ยวกับความคาดหวังและเครื่องมือที่คล้ายกันคือการรอสตริงหรือรูปแบบที่ระบุในผลลัพธ์ของโปรแกรมจากนั้นป้อนสิ่งที่คุณต้องการป้อนเข้า

ตัวอย่างทั่วไปที่ใช้คือทำการล็อกอินโดยอัตโนมัติโดย "คาดหวัง" (เช่นรอ) สตริง "ogin:" ส่งชื่อล็อกอินจากนั้นคาดว่าสตริง "คำ:" และส่งรหัสผ่าน

หนึ่งตัวเลือกสุดท้ายหากคุณมีแหล่งที่มาของ myprogram คือเพียงปรับเปลี่ยนเพื่อรับอินพุตที่คุณต้องการให้เป็นตัวเลือกบรรทัดคำสั่ง นี่อาจเป็นงานที่ต้องทำล่วงหน้ามากขึ้น แต่จะทำให้ยุ่งยากน้อยลงกว่าที่ทำไปโดยใช้ข้อมูลที่คาดไว้หรือการบีบอัดข้อมูลลงในโปรแกรมที่ไม่ได้ออกแบบมาให้ใช้แบบนั้น

... และอย่าลืมส่งแพตช์ของคุณไปที่ myprogram back up up :) แม้ว่าพวกเขาจะไม่ชอบวิธีที่คุณเขียนมันพวกเขาอาจชอบไอเดียที่จะเพิ่มคุณสมบัติด้วยตัวเอง นักพัฒนาซอฟต์แวร์ต้นน้ำมักจะชื่นชมผู้ที่ออกไปจากก้นและสนับสนุนมากกว่าที่จะเรียกร้องหรือบ่น

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