`\ time ',` t \ ime` และ `\ cd` จริง ๆ ทำอะไร? (สนุกกับแบ็กสแลชในเปลือกหอย)


9

ขณะที่คุยมากกว่าความแตกต่างระหว่าง/usr/bin/timeและเปลือก (ทุบตีและ zsh) ในตัวtimeใครบางคนบอกว่าหนึ่งสามารถใช้เป็นชวเลขที่จะได้รับ\time/usr/bin/time

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

  • ทำไมถึงt\imeทำงานเช่นกัน?
  • ทำไมถึง\cdเปลี่ยนได/usr/bin/cdเร็กตอรี่ถึงแม้ว่า¹จะไม่เป็นเช่นนั้น?

ดังนั้นเห็นได้ชัดว่าจะไม่เทียบเท่ากับ\foo $(which foo)คำถามคือตอนนี้:

พฤติกรรมที่สังเกตได้ของ\fooทั้งใน bash และ zsh ในทุก ๆ ด้านที่ครอบคลุมโดยนิยาม POSIX ของเชลล์และถ้าเป็นเช่นนั้นทำไมมันมีพฤติกรรมเหมือนมัน?


เชิงอรรถ 1: /usr/bin/cdคือบนระบบของฉัน

#!/bin/sh
builtin cd "$@"

โปรดดูunix.stackexchange.com/questions/12762/…โปรดทราบว่า \ command มีการบันทึกการทำงาน tcsh โดยเฉพาะซึ่งระบุว่าจะละเว้นนามแฝงสำหรับคำสั่ง
simpleuser

คำตอบ:


14

t\imeหรือ\cd(หรือ"tim"eหรือ'cd'หรือ${-##*}timeหรือ${-+time}และทุกชุดอื่น ๆ ของข้อความและการขยายคุณอาจจะคิดว่าในที่สุดจะแก้timeหรือcd) เป็นว่าวิธีการที่จะเขียนอีกและcdtime

อย่างไรก็ตามในที่สุดก็จะแก้ไขcdหรือtimeในเวลาต่อมาของการแยกวิเคราะห์ไวยากรณ์และเปลือก โดยเฉพาะอย่างยิ่งที่เกิดขึ้นนานหลังจากการรับรู้คำหลักของเชลล์และการทดแทนนามแฝงเกิดขึ้น

ดังนั้นในขณะที่เชลล์กำลังค้นหาคำหลักในภาษาของมันก็ไม่ได้รับการยอมรับti\meว่าเป็นtimeคำหลักของเชลล์ ดังนั้น:

ti\me echo test

จะรับรู้โดยเชลล์เป็นคำสั่งง่าย ๆ ซึ่งตรงข้ามกับtimeคำหลักตามด้วยคำสั่งง่ายๆ

จากนั้นการti\meประมวลผลการอ้างอิงจะดำเนินการ (นี่คือเครื่องหมายแบ็กสแลชคือการอ้างอิงmอักขระที่ไม่จำเป็นต้องมีการอ้างอิงอักขระการถอดข้อความออกคุณจะได้รับtime) และtime คำสั่งจะค้นหาเหมือนคำสั่งอื่น ๆ (ในรายการบิวด์อิน ฟังก์ชั่นและไฟล์ที่เรียกใช้งาน$PATHได้ส่วนใหญ่จะอยู่/bin/timeที่นี่)

สำหรับcdไม่มีcdคำหลักในภาษาของเชลล์เพียงcdคำสั่ง builtin (ซึ่งมีความสำคัญกว่าของคุณ/usr/bin/cd) อย่างไรก็ตามหากคุณกำหนดนามแฝงสำหรับcd(เช่นalias cd=pushd) ให้เหมือนกันอีกครั้ง เนื่องจากการแทนที่สมนามเสร็จสิ้นก่อนที่จะทำการลบเครื่องหมายอัญประกาศถ้าคุณมีนามแฝงcdและไม่ใช่อันเดียว\cd(โปรดทราบว่ามีเชลล์จำนวนไม่มากที่อนุญาตสมนามที่มีแบ็กสแลชอยู่) จากนั้นจึงเขียนโดย:

\cd dir

คุณกำลังทำให้แน่ใจว่าcdชื่อแทนของคุณจะไม่ถูกแทนที่

ในระยะสั้นอ้างชื่อคำสั่งหรือส่วนหนึ่งส่วนใด ๆ ป้องกันไม่ให้มันจากการถูกมองว่าเป็นคำหลักเปลือก (คำหลักเป็นสิ่งที่ชอบwhile, for, if, {... timeเป็นคำหลักในบางหอยเท่านั้น) และทะลุนามแฝงคุณอาจจะต้องให้มัน .

มันไม่ได้ แต่บังคับคำสั่งที่จะมีมติให้แฟ้มที่ปฏิบัติการใน$PATHคำสั่งยังคงสืบค้นแรกในฟังก์ชั่น (ซึ่งคุณสามารถหลีกเลี่ยงโดยการทำcommand time cmd...) และbuiltins (ซึ่งคุณสามารถหลีกเลี่ยงโดยการทำenv time cmd...แต่ผมไม่ทราบว่าของ เชลล์ที่มีtimeคำสั่งbuiltin )

โปรดทราบว่าการอ้างถึงสามารถมีอิทธิพลต่อพฤติกรรมของบิวด์อินพิเศษของตระกูลtypeset/ declare/ export/ local... ในเชลล์บางตัว ดูคำพูดจำเป็นสำหรับการกำหนดตัวแปรท้องถิ่นหรือไม่? สำหรับรายละเอียด


ดังนั้นความแตกต่างระหว่างtimeและcdสิ่งที่นำไปสู่ความแตกต่างในพฤติกรรมที่สังเกตได้timeคือคำหลักและcdเป็นคำสั่ง builtin ?
Jonas Schäfer

1
@ JonasWielicki มันtimeเป็นคำหลักและนั่นcdไม่ใช่ (และถ้าคุณมีนามแฝงสำหรับcdหรือtimeนั่นจะเป็นเรื่องอื่น) สิ่งนั้นcdถูกสร้างขึ้นในหรือไม่ไม่มีอุบัติการณ์ในจุดนี้ เชลล์บางตัวมีบิวอินไม่กี่ตัวที่อยู่กึ่งกลางระหว่างคีย์เวิร์ดและบิวด์อินเนื่องจากการแยกวิเคราะห์จะทำแตกต่างจากบิวด์อื่น ๆ นั่นคือกรณีของexport/ /typeset declareฉันควรจะเพิ่มบันทึกเกี่ยวกับมันในคำตอบนี้
Stéphane Chazelas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.