ความแตกต่างระหว่างวิธีการทับทิมต่อไปนี้คืออะไร?
exec, systemและ%x()หรือBackticks
ฉันรู้ว่ามันถูกใช้เพื่อรันคำสั่งเทอร์มินัลผ่านทางการเขียนโปรแกรมผ่าน Ruby แต่ฉันต้องการรู้ว่าทำไมมีสามวิธีที่แตกต่างกันในการทำเช่นนี้
ความแตกต่างระหว่างวิธีการทับทิมต่อไปนี้คืออะไร?
exec, systemและ%x()หรือBackticks
ฉันรู้ว่ามันถูกใช้เพื่อรันคำสั่งเทอร์มินัลผ่านทางการเขียนโปรแกรมผ่าน Ruby แต่ฉันต้องการรู้ว่าทำไมมีสามวิธีที่แตกต่างกันในการทำเช่นนี้
คำตอบ:
ระบบ
systemวิธีการเรียกโปรแกรมระบบ คุณต้องให้คำสั่งเป็นอาร์กิวเมนต์สตริงกับวิธีนี้ ตัวอย่างเช่น:
>> system("date")
Wed Sep 4 22:03:44 CEST 2013
=> true
โปรแกรมเรียกจะใช้ในปัจจุบันSTDIN, STDOUTและSTDERRวัตถุของโปรแกรมทับทิมของคุณ ในความเป็นจริงค่าตอบแทนที่เกิดขึ้นจริงเป็นอย่างใดอย่างหนึ่งtrue, หรือfalse nilในตัวอย่างวันที่ถูกตีพิมพ์ผ่านวัตถุ IO STDINของ เมธอดจะส่งคืนtrueหากกระบวนการออกจากสถานะเป็นศูนย์falseหากกระบวนการออกจากสถานะไม่เป็นศูนย์และnilหากการดำเนินการล้มเหลว
ผลข้างเคียงก็คือตัวแปรทั่วโลก$?ถูกตั้งค่าเป็นProcess::Statusวัตถุ วัตถุนี้จะมีข้อมูลเกี่ยวกับการเรียกตัวเองรวมถึงตัวระบุกระบวนการ (PID) ของกระบวนการที่เรียกใช้และสถานะการออก
>> system("date")
Wed Sep 4 22:11:02 CEST 2013
=> true
>> $?
=> #<Process::Status: pid 15470 exit 0>
backticks
Backticks (``) เรียกโปรแกรมระบบและส่งคืนผลลัพธ์ ซึ่งแตกต่างจากวิธีแรกคำสั่งไม่ได้ให้ผ่านสตริง แต่โดยการวางไว้ในคู่ backticks
>> `date`
=> Wed Sep 4 22:22:51 CEST 2013
ตัวแปรโกลบอล$?ถูกตั้งค่าผ่าน backticks ด้วย ด้วย backticks คุณยังสามารถใช้การแก้ไขสตริงด้วย
% x ()
การใช้%xเป็นทางเลือกของสไตล์ backticks มันจะส่งคืนผลลัพธ์เช่นกัน เช่นเดียวกับญาติ%wและ%q(ในกลุ่มอื่น ๆ ) ตัวคั่นใด ๆ จะพอเพียงตราบเท่าที่ตัวคั่นลักษณะวงเล็บเหลี่ยมตรงกัน วิธีนี้%x(date), %x{date}และ%x-date-มีความหมายเหมือนกันทั้งหมด เช่นเดียวกับ backticks %xสามารถใช้การแก้ไขสตริงได้
exec
โดยใช้Kernel#execกระบวนการปัจจุบัน (สคริปต์ทับทิมของคุณ) execจะถูกแทนที่ด้วยกระบวนการเรียกใช้ผ่าน วิธีการสามารถใช้สตริงเป็นอาร์กิวเมนต์ ในกรณีนี้สตริงจะขึ้นอยู่กับการขยายตัวของเชลล์ เมื่อใช้มากกว่าหนึ่งอาร์กิวเมนต์อาร์กิวเมนต์แรกจะถูกใช้เพื่อเรียกใช้งานโปรแกรมและต่อไปนี้ถูกจัดเตรียมไว้เป็นอาร์กิวเมนต์ของโปรแกรมที่จะเรียกใช้
Open3.popen3
บางครั้งข้อมูลที่ต้องการถูกเขียนไปยังอินพุตมาตรฐานหรือข้อผิดพลาดมาตรฐานและคุณต้องควบคุมสิ่งเหล่านั้นด้วย Open3.popen3มาที่นี่มีประโยชน์:
require 'open3'
Open3.popen3("curl http://example.com") do |stdin, stdout, stderr, thread|
pid = thread.pid
puts stdout.read.chomp
end
STDIN, STDOUT, STDERRพิจารณาOpen3.popen3แทน; เช่นดูstackoverflow.com/a/10922097/258662
พวกเขาทำสิ่งต่าง ๆ execแทนที่กระบวนการปัจจุบันด้วยกระบวนการใหม่และไม่กลับมา systemเรียกใช้กระบวนการอื่นและส่งคืนค่าการออกเป็นกระบวนการปัจจุบัน การใช้ backticks จะเรียกใช้กระบวนการอื่นและส่งกลับผลลัพธ์ของกระบวนการนั้นไปยังกระบวนการปัจจุบัน