กำ rake exec หมายถึงอะไร?


351

อะไรbundle exec rake db:migrateหมายถึง? หรือbundle exec rake <command>โดยทั่วไป?

ฉันเข้าใจว่าbundleจะดูแลสิ่งต่าง ๆ ใน Gemfile ฉันรู้ว่าคำว่า "exec" หมายถึงอะไร ฉันเข้าใจว่าrakeรักษาสิ่งต่าง ๆ ไว้ในสคริปต์ที่คุณสามารถทำได้และฉันรู้ว่านั่นdb:migrateเป็นหนึ่งในนั้น ฉันแค่ไม่รู้ว่าคำเหล่านี้ทำอะไรกัน เหตุใดจึงควรbundleใช้เพื่อดำเนินการrakeเพื่อโยกย้ายฐานข้อมูล

คำตอบ:


468

bundle execเป็นคำสั่งBundlerเพื่อรันสคริปต์ในบริบทของบันเดิลปัจจุบัน (อันหนึ่งจากGemfileของไดเรกทอรีของคุณ) rake db:migrateเป็นสคริปต์ที่dbเป็นเนมสเปซและโอนย้ายเป็นชื่อภารกิจที่กำหนดไว้

ดังนั้นbundle exec rake db:migrateรันสคริปต์ rake ด้วยคำสั่งdb:migrateในบริบทของบันเดิลปัจจุบัน

ในฐานะที่เป็น "ทำไม" ฉันจะพูดจากหน้า Bundler :

ในบางกรณีการเรียกใช้ไฟล์ปฏิบัติการที่ไม่มีbundle execอาจทำงานได้หากมีการติดตั้งโปรแกรมปฏิบัติการในระบบของคุณและไม่ดึงอัญมณีใด ๆ ที่ขัดแย้งกับชุดข้อมูลของคุณ

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


7
หมายความว่าเราควรรันชุดคำสั่ง exec เสมอฉันใช้ ruby ​​version manager ติดตั้ง ruby ​​และ ruby ​​บนราง
Pradeep Sharma

11
@Edmund "bundle" เป็นคำภาษาอังกฤษหมายถึงกลุ่มของสิ่งที่คล้ายกันซึ่งมักจะผูกติดกันอย่างเรียบร้อย โดยเฉพาะในคำถามนี้มันหมายถึงกลุ่มของ Gems (ไลบรารีรหัส ruby ​​ที่มีในตัวเอง) Bundlerเป็นชื่อของซอฟต์แวร์ที่เราใช้ในการจัดการ Gems และbundleเป็นคำสั่งที่ Bundler ใช้
ghoppe

2
ฉันประทับใจว่าเมื่อใดก็ตามที่เราไปยังโฟลเดอร์ที่มี Gemfile เชลล์จะใช้เวอร์ชันที่ระบุใน Gemfile โดยอัตโนมัติ (เช่นรุ่น Ruby) จากข้อสันนิษฐานนั้นฉันคิดว่า rake db: migrate จะทำงานได้ดีเสมอโดยไม่ต้องใช้ชุดบันเดิล CMIIW
Pahlevi Fikri Auliya

1
@PahleviFikriAuliya ที่เป็นจริงหากคุณมี.ruby-gemsetไฟล์ในโปรเจ็กต์รูทของคุณ นอกจากนี้ยังมี.ruby-versionไฟล์ที่ตั้งค่ารุ่นทับทิมของคุณหากใช้ RVM
ปลาดุก

1
หน้าที่เชื่อมโยงไม่ได้กล่าวถึงคำพูดที่คุณระบุอีกต่อไป โปรดแก้ไขขอบคุณ
Gaurang Tandon

153

คุณกำลังเรียกใช้bundle execโปรแกรม ผู้สร้างของโปรแกรมเขียนเมื่ออัญมณีบางรุ่นมีวางจำหน่าย โปรแกรม Gemfile ระบุเวอร์ชันของอัญมณีที่ผู้สร้างตัดสินใจใช้ นั่นคือสคริปต์ถูกสร้างขึ้นเพื่อให้ทำงานอย่างถูกต้องกับรุ่นอัญมณี

Gemfile ทั่วทั้งระบบของคุณอาจแตกต่างจาก Gemfile นี้ คุณอาจมีอัญมณีที่ใหม่กว่าหรือเก่ากว่าซึ่งสคริปต์นี้เล่นได้ไม่ดี ความแตกต่างในรุ่นนี้อาจทำให้คุณมีข้อผิดพลาดแปลก ๆ

bundle execช่วยคุณหลีกเลี่ยงข้อผิดพลาดเหล่านี้ มันรันสคริปต์โดยใช้อัญมณีที่ระบุใน Gemfile ของสคริปต์มากกว่า Gemfile ทั้งระบบ มันดำเนินการบางรุ่นอัญมณีด้วยความมหัศจรรย์ของนามแฝงเปลือก

ดูข้อมูลเพิ่มเติมเกี่ยวกับหน้าคน

นี่คือตัวอย่าง Gemfile:

source 'http://rubygems.org'

gem 'rails', '2.8.3'

ที่นี่bundle execจะรันสคริปต์โดยใช้ rails เวอร์ชัน 2.8.3 และไม่ใช่เวอร์ชั่นอื่น ๆ ที่คุณติดตั้งไว้ทั่วทั้งระบบ


9
ฉันชอบคำตอบนี้ดีกว่าตัวเลือกของ OP: D! ชัดเจนยิ่งขึ้น
mauricioschneider

1
ดังนั้นเพื่อเพิ่มตัวอย่างนี้: ถ้าบุคคลเพียงแค่วิ่งrake db:migrateออกไปbundle execแล้วมันจะดำเนินการโดยใช้ Gemfile systemwide ที่หนึ่งอาจมีชั้นวางที่ 1.5.2 (ล่าสุด)?
Smokin Joe

คำตอบที่ดีกว่ามากพร้อมตัวอย่างที่เป็นรูปธรรม
ahnbizcad

2
ดังนั้นbundle execใช้ app "เฉพาะ" อัญมณีในท้องถิ่นของคุณ Gemfile ของ app ของคุณและbundleใช้ "เครื่องเฉพาะ" gem install a_certain_gemอัญมณีทั่วโลกถ้าคุณไม่ได้ทำ ท้องถิ่น vs ทั่วโลก
ahnbizcad

คำตอบที่ดีกว่าคำตอบที่เลือก
Boon

9

สิ่งนี้เกิดขึ้นมากมายเมื่อ gemfile.lock ของคุณติดตั้งอัญมณีเวอร์ชันต่าง ๆ บนเครื่องของคุณ คุณอาจได้รับคำเตือนหลังจากรัน rake (หรือ rspec หรืออื่น ๆ ) เช่น:

You have already activated rake 10.3.1, but your Gemfile requires rake 10.1.0. Prepending "bundle exec" to your command may solve this.

การจัดเตรียมการbundle execบอกให้ Bundler รันคำสั่งนี้โดยไม่คำนึงถึงส่วนต่างของเวอร์ชัน อย่างไรก็ตามอาจไม่มีปัญหาเสมอไปคุณอาจพบปัญหา

โชคดีที่มีอัญมณีที่สามารถแก้ปัญหานี้ได้: rubygems-bundler

$ gem install rubygems-bundler

$ $ gem regenerate_binstubs

จากนั้นลองใช้ rake, rspec หรืออะไรก็ตาม


ยังเป็นทางออกที่ดีในปี 2020
Brateq

6

มันควรจะกล่าวถึงว่ามีวิธีที่จะละเว้นbundle exec(พวกเขาทั้งหมดระบุไว้ในบทที่ 3.6.1 ของหนังสือ Michael Hartls Ruby on Rails Tutorial )

วิธีที่ง่ายที่สุดคือการใช้ RVM รุ่นที่ทันสมัยเพียงพอ (> = 1.11.x)

หากคุณถูก จำกัด ให้เป็น RVM รุ่นก่อนหน้าคุณสามารถใช้วิธีนี้ได้โดยcalasyr :

$ rvm get head && rvm reload
$ chmod +x $rvm_path/hooks/after_cd_bundler
$ bundle install --binstubs=./bundler_stubs

bundler_stubsไดเรกทอรีควรแล้วยังจะเพิ่มใน.gitignoreไฟล์

ตัวเลือกที่สามคือการใช้rubygems-bundlerอัญมณีหากคุณไม่ได้ใช้ RVM:

$ gem install rubygems-bundler
$ gem regenerate_binstubs

1

เมื่อคุณรันงาน rake โดยตรงหรือรันไฟล์ไบนารีของอัญมณีไม่มีการรับประกันว่าคำสั่งจะทำงานตามที่คาดไว้ เพราะมันอาจเกิดขึ้นได้ว่าคุณได้ติดตั้ง gem ตัวเดียวกันในระบบของคุณซึ่งมีเวอร์ชั่น 1.0 แต่ในโปรเจคของคุณคุณมีเวอร์ชั่นที่สูงกว่าว่า 2.0 ในกรณีนี้คุณไม่สามารถทำนายได้ว่าจะใช้อันไหน

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

ฉันยังเขียนโพสต์เกี่ยวกับโพสต์นี้ซึ่งแสดงให้เห็นว่าเราสามารถหลีกเลี่ยงการใช้โพสต์นี้โดยใช้ bin stubs ได้อย่างไร


1

ฉันไม่ได้ใช้bundle execมากนัก แต่กำลังตั้งค่าตอนนี้

ฉันมีอินสแตนซ์ที่ใช้เรคที่ไม่ถูกต้องและเสียเวลามากในการติดตามปัญหา สิ่งนี้ช่วยให้คุณหลีกเลี่ยงสิ่งนั้นได้

ต่อไปนี้เป็นวิธีตั้งค่า RVM เพื่อให้คุณสามารถใช้งานได้bundle execตามค่าเริ่มต้นภายในไดเรกทอรีโครงการที่ระบุ:

https://thoughtbot.com/blog/use-bundlers-binstubs


0

หมายถึงการใช้เรคที่ Bundler รับรู้และเป็นส่วนหนึ่งของ Gemfile ของคุณเหนือเรคใด ๆ ที่ Bundler ไม่รับรู้และรันงาน db: migrate

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