หากคุณต้องการเรียกใช้คำสั่งภายนอกจาก Ruby…
…เช่น wkhtmltopdf เพื่อแปลงไฟล์ HTML เป็น PDF
มีวิธี Ruby สองสามวิธีที่คุณสามารถใช้ได้
ขึ้นอยู่กับวิธีการที่คุณใช้ คุณจะได้ผลลัพธ์ที่แตกต่างกัน .
มาสำรวจวิธีการเหล่านี้กัน!
วิธีการระบบทับทิม
วิธีการของระบบ Ruby เป็นวิธีที่ง่ายที่สุดในการรันคำสั่งภายนอก
หน้าตาเป็นแบบนี้ :
system("ls")
ขอให้สังเกตว่า system
จะพิมพ์เอาต์พุตคำสั่งตามที่เกิดขึ้น
นอกจากนี้ระบบจะทำให้โปรแกรม Ruby ของคุณ รอจนกว่าคำสั่งจะเสร็จสิ้น .
ลองสิ่งนี้:
system("sleep 2")
มีวิธีเรียกใช้คำสั่งในเบื้องหลังดังที่เราเห็นในภายหลัง
ระบบสามารถคืนค่า 3 ค่าที่เป็นไปได้ :
true
ถ้าคำสั่งทำงานfalse
หากคำสั่งส่งคืนรหัสข้อผิดพลาดnil
หากการดำเนินการคำสั่งล้มเหลว (ไม่พบคำสั่ง)
คุณสามารถรับรหัสสถานะการออก ของคำสั่งภายนอกล่าสุดที่คุณรันด้วย $?
ตัวแปรระดับโลก รหัสสถานะนี้สามารถให้ข้อมูลเพิ่มเติมเกี่ยวกับสาเหตุที่คำสั่งล้มเหลวได้
การขยายเชลล์คืออะไร
เมื่อคุณเรียกใช้คำสั่งภายนอกด้วย system
คุณจะได้รับเอฟเฟกต์ “การขยายเชลล์”
การขยายเชลล์คือเมื่อเชลล์ (sh/bash/zsh) ใช้อักขระพิเศษบางตัว (*
, ?
และ [
) จากคำสั่งของคุณ &ขยายเป็นรายการไฟล์ .
ตัวอย่าง:
system("echo *")
นี่จะพิมพ์ทุกไฟล์ &โฟลเดอร์ในไดเร็กทอรีปัจจุบัน
*
จะถูกแทนที่ด้วยรายการไฟล์ก่อนที่คำสั่งจะรัน
หากคุณต้องการใช้อักขระพิเศษเหล่านี้เนื่องจาก ส่งอาร์กิวเมนต์เป็นอาร์กิวเมนต์ที่ 2 ของ system
.
ชอบสิ่งนี้:
system("echo", "*")
ตอนนี้ผลลัพธ์จะเป็น *
.
วิธีใช้ตัวแปรสภาพแวดล้อม
หากคุณต้องการส่งตัวแปรสภาพแวดล้อมเฉพาะไปยังคำสั่งภายนอก คุณสามารถใช้แฮชเป็นอาร์กิวเมนต์แรกได้ .
นี่คือตัวอย่าง:
system({"rubyguides" => "best"}, "ruby", "-e p ENV['rubyguides']") # "best"
การดำเนินการนี้จะไม่เปลี่ยนสภาพแวดล้อมปัจจุบันของแอปพลิเคชัน Ruby ของคุณ
%x / Kernel#`
หากคุณต้องการรับผลลัพธ์จากคำสั่งที่คุณกำลังเรียกใช้ แทนที่จะแสดง คุณสามารถใช้ %x
หรือ Kernel#`
วิธีการ
พวกเขาทำสิ่งเดียวกัน
นี่คือตัวอย่าง :
`ls`
อีกอันที่มี %x
:
%x|ls|
สองตัวอย่างนี้จะส่งคืน สตริงที่มีเอาต์พุต ของ ls
คำสั่ง
โปรดสังเกตว่าคุณยังต้องรอจนกว่าคำสั่งจะเสร็จสิ้น เว้นแต่คุณจะเรียกใช้ภายในเธรด
วิธีใช้ Fork + Exec เพื่อเรียกใช้คำสั่งภายนอกในกระบวนการแยก
Forking ทำสำเนาของกระบวนการปัจจุบันของคุณ (แอป Ruby ของคุณ) จากนั้นคุณสามารถแทนที่สำเนานั้นด้วยกระบวนการอื่นโดยใช้ exec .
หมายเหตุ :วิธีส้อมไม่พร้อมใช้งานบน Windows
นี่เป็นรูปแบบที่นิยมในโลก Unix
นี่คือวิธีการทำงาน :
fork { exec("ls") }
สิ่งนี้จะเรียกใช้ ls
ในกระบวนการอื่น &แสดงผล
เนื่องจาก คำสั่งนี้กำลังทำงานอยู่ในกระบวนการอื่น มันจะไม่บล็อกแอป Ruby ของคุณไม่ให้ทำงานเหมือนsystem
เมธอดหรือ %x
.
สำคัญ:
หากคุณใช้ exec
ไม่มี fork
คุณจะแทนที่กระบวนการปัจจุบันของคุณ
ซึ่งหมายความว่าโปรแกรม Ruby ของคุณจะสิ้นสุด
วิธีการใช้ Popen Method สำหรับการสื่อสารสองทางกับโปรแกรมภายนอก
หากคุณต้องการ:
- ควบคุมกระบวนการได้มากขึ้น
- การสื่อสารสองทาง
จากนั้น IO.popen
วิธีการคือสิ่งที่คุณต้องการ
ในตัวอย่างต่อไปนี้ ฉันใช้วิธี popen เพื่อเรียกใช้ irb
ประมวลผล จากนั้นส่งข้อมูลบางส่วนไปและอ่านผลลัพธ์
นี่คือตัวอย่าง :
r = IO.popen("irb", "r+") r.write "puts 123 + 1\n" 3.times { puts r.gets } r.write "exit\n"
r
นี้ ตัวแปรเป็นวัตถุ IO ซึ่งหมายความว่า คุณสามารถเขียนและอ่านจากมันได้เหมือนไฟล์ปกติ .
ใช้ popen
ยังหมายความว่าคำสั่งภายนอกของคุณจะทำงานด้วยกระบวนการของมันเอง ดังนั้นคุณจึงไม่ต้องรันบนเธรด
นอกจากนี้ยังมี popen3
วิธีการในไลบรารีมาตรฐาน
ความแตกต่างกับ popen
. ปกติ คือจะแบ่งเอาต์พุตปกติและข้อความแสดงข้อผิดพลาดออกเป็นอ็อบเจ็กต์ IO แยกกัน
บทสรุป
คุณได้เรียนรู้วิธีต่างๆ ในการโต้ตอบกับคำสั่งภายนอกใน Ruby
ระวังสิ่งเหล่านี้!
อย่าส่งข้อมูลใดๆ ของผู้ใช้เข้าสู่คำสั่งเหล่านี้ เว้นแต่คุณต้องการความปลอดภัย ปัญหาในแอป Ruby ของคุณ
หากคุณได้เรียนรู้อะไรใหม่ๆ โปรดแชร์บทความนี้เพื่อให้คนอื่นเห็น
ขอบคุณที่อ่านนะคะ 🙂