ใช้ไฟล์ HERE และเปลี่ยนเส้นทางผลลัพธ์ของคำสั่ง


11

ฉันมีรหัสต่อไปนี้ในสคริปต์ชุด:

mpirun -np 6 ./laplace <<END
100
100
100
0.01
100
3
2
1
END
| tail -n 1 > output

แต่มันไม่ทำงาน สิ่งที่ฉันต้องการให้ทำคือใช้ไฟล์ HERE เป็นอินพุตไปยังคำสั่ง mpirun จากนั้นไพพ์เอาต์พุตไปยังคำสั่ง tail อย่างไรก็ตามฉันคิดว่าสิ่งที่ไฟล์ HERE และส่วนท้ายของเอาต์พุตกำลังสับสน

ฉันควรเขียนสิ่งนี้อย่างไรเพื่อให้เป็นไปตามที่ฉันต้องการ?

คำตอบ:


12

สิ่งที่คุณเขียนในบรรทัดแรกดูเหมือนว่าคำสั่งทั้งหมด (รายการ“ (คำสั่งผสม)” ในคำศัพท์เชลล์) ดังนั้นเชลล์จึงถือว่าเป็นคำสั่งที่สมบูรณ์ เนื่องจากมีเครื่องหมายเริ่มต้นที่นี่เอกสาร ( <<END) เชลล์จึงอ่านเนื้อหาเอกสารที่นี่แล้วเริ่มคำสั่งใหม่ หากคุณต้องการวาง here-document ไว้ตรงกลางของรายการคุณต้องระบุเชลล์ที่รายการนั้นยังไม่เสร็จสิ้น นี่คือสองวิธี

mpirun -np 6 ./laplace <<END |

END
tail -n 1 > output
{ mpirun -np 6 ./laplace <<END

END
} | tail -n 1 > output

หรือแน่นอนคุณสามารถตรวจสอบให้แน่ใจว่าคำสั่งนั้นพอดีในบรรทัดแรก

mpirun -np 6 ./laplace <<END | tail -n 1 > output

END

กฎที่ต้องจำคือเนื้อหาของเอกสารที่นี่เริ่มต้นหลังจากบรรทัดใหม่ที่ไม่ได้ประกาศบรรทัดแรกหลังจาก<<ENDตัวบ่งชี้ ตัวอย่างเช่นต่อไปนี้เป็นอีกวิธีหนึ่งในการเขียนสคริปต์นี้:

mpirun -np 6 ./laplace <<END \
| tail -n $(

END
             echo 1) > output

อันสุดท้าย! "obfuscated" .. คุณไม่ได้ล้อเล่น! :) .. ฉันสะดุดความคิดที่ยากขึ้นบรรทัดใหม่ แต่จริงๆแล้วก็แบ่งบล็อกที่มีวงเล็บเหลี่ยมแบบนั้นออกมาในแบบ bizzare .. นี่คือการออกแบบหรือเป็นความบังเอิญที่บังเอิญ? (เช่นมีการใช้งานจริงสำหรับสิ่งนี้หรือไม่?) และคุณยังสามารถใส่คำสั่งแบบแยกคำสั่งแบบโคลอนหลายคำสั่งในบรรทัด "soft" บรรทัดแรกได้
Peter.O

@ เฟรด: เป็นเพียงความบังเอิญเท่านั้น จะต้องมีกฎบางอย่างที่ heredoc เริ่มต้นและหยุด นี่คือกฎคือ heredoc นั้นเหมือนกับโทเค็นเดียวที่แนบกับโทเค็น newline ถัดไปหลังจาก<<ENDบิต แบ็กสแลช - ขึ้นบรรทัดใหม่จะยกเลิกการขึ้นบรรทัดใหม่
Gilles 'ดังนั้น - หยุดความชั่วร้าย'

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