ความแตกต่างระหว่างวิธีการทับทิมต่อไปนี้คืออะไร?
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 จะเรียกใช้กระบวนการอื่นและส่งกลับผลลัพธ์ของกระบวนการนั้นไปยังกระบวนการปัจจุบัน