ทำให้ bash ใช้คำสั่ง `time 'จากภายนอกแทนที่จะใช้เชลล์ในตัว


27

ฉันจะทำให้ bash ใช้ time binary (/ usr / bin / time) เป็นค่าเริ่มต้นแทนที่จะเป็นคีย์เวิร์ดเชลล์ได้อย่างไร?

which timeการส่ง/usr/bin/time
type timeคืนการtime is a shell keyword
รันtimeกำลังดำเนินการคำหลักเชลล์:

$ time

real    0m0.000s
user    0m0.000s
sys     0m0.000s
$ /usr/bin/time
Usage: /usr/bin/time [-apvV] [-f format] [-o file] [--append] [--verbose]
   [--portability] [--format=format] [--output=file] [--version]
   [--quiet] [--help] command [arg...]

enable -n time ผลตอบแทน bash: enable: time: not a shell builtin

คำตอบ:


30

คุณสามารถใช้commandเชลล์บิวด์อินเพื่อข้ามขั้นตอนการค้นหาปกติและรันคำสั่งที่กำหนดเป็นคำสั่งภายนอกโดยไม่คำนึงถึงความเป็นไปได้อื่น ๆ (เชลล์บิวด์อินชื่อแทน ฯลฯ ) สิ่งนี้มักจะทำในสคริปต์ที่ต้องพกพาข้ามระบบแม้ว่าอาจจะมากกว่าการใช้ชวเลข\(เหมือนในหรือ\rmมากกว่าcommand rmหรือrmโดยเฉพาะอย่างยิ่งในช่วงหลังอาจเป็นชื่อแทนสิ่งที่ไม่รู้จักrm -i)

$ time

real    0m0.000s
user    0m0.000s
sys 0m0.000s
$ command time
Usage: time [-apvV] [-f format] [-o file] [--append] [--verbose]
       [--portability] [--format=format] [--output=file] [--version]
       [--quiet] [--help] command [arg...]
$ 

สามารถใช้กับนามแฝงได้เช่น:

$ alias time='command time'
$ time
Usage: time [-apvV] [-f format] [-o file] [--append] [--verbose]
       [--portability] [--format=format] [--output=file] [--version]
       [--quiet] [--help] command [arg...]
$ 

ข้อดีของการทำเช่นalias time=/usr/bin/timeนี้คือคุณไม่ได้ระบุเส้นทางแบบเต็มไปยังtimeไบนารี แต่แทนที่จะกลับไปที่กลไกการค้นหาเส้นทางแบบปกติ

aliasคำสั่งตัวเองสามารถไปลงเช่น ~ / .bashrc หรือ /etc/bash.bashrc (หลังเป็นระดับโลกสำหรับผู้ใช้ทั้งหมดในระบบ)

สำหรับกรณีตรงข้าม (บังคับให้ใช้เชลล์ในตัวในกรณีที่มีการกำหนดนามแฝง) คุณจะต้องใช้สิ่งที่คล้ายbuiltin timeกันซึ่งจะแทนที่ขั้นตอนการค้นหาตามปกติอีกครั้งและเรียกใช้เชลล์ในตัวที่มีชื่อ หน้าคนทุบตีกล่าวถึงว่านี่มักจะใช้เพื่อให้การcdทำงานที่กำหนดเองด้วยฟังก์ชั่นที่มีชื่อcdซึ่งจะใช้ builtin cdในการทำสิ่งที่จริง


type -a <cmd>นอกจากนี้คุณยังสามารถสอบถามที่คำสั่งโดยเฉพาะอย่างยิ่งจะมาจากการใช้คำสั่ง
slm

12
commandไม่บายพาส builtins (ยกเว้นzshเมื่อไม่ทำการจำลอง shell อื่น ๆ ) มันข้ามหน้าที่และนั่นคือเหตุผลหลักสำหรับการดำรงอยู่ของมัน บทบาทที่สองคือการลบพิเศษในbuiltins พิเศษ มันจะข้ามนามแฝงและคำหลักเพียงเพราะสิ่งเหล่านั้นจะถูกขยายในตำแหน่งแรกเท่านั้น (ในzshตัวอย่างเช่นมันจะไม่ข้ามนามแฝงทั่วโลก) ไม่มีtimeทุบตีในตัว เป็นคำหลักที่ให้คุณสามารถทำเช่นtime time { foo; bar; }
Stéphane Chazelas

1
@StephaneChazelas โดยทั้งหมดรู้สึกฟรีเพื่อแก้ไขที่เป็นคำตอบเพื่อให้คำอธิบายที่แม่นยำยิ่งขึ้น commandทำงานในกรณีนี้โดยเฉพาะอย่างยิ่ง แต่เห็นได้ชัดว่าคำตอบที่ถูกต้องดีกว่าคำตอบครึ่งทางขวา
CVn

1
ส่วนสุดท้ายของคำตอบของคุณผิด เวลาไม่ใช่เชลล์บิวด์อิน แต่เป็นคีย์เวิร์ดของเชลล์ builtin timeไม่ทำงาน
Teresa e Junior

คล้ายกับคำสั่งจะเป็นเพียงพูดมัน'time' echo test
mxmlnkn

9

มีช็อตคัตในคำสั่ง bash to sestestep โดยไม่ต้องระบุพา ธ หรือใช้บิวด์อินอื่นเช่นcommand: Escape ด้วย backslash

=^_^= izkata@Izein:~$ time

real    0m0.000s
user    0m0.000s
sys     0m0.000s
=^_^= izkata@Izein:~$ \time
Usage: time [-apvV] [-f format] [-o file] [--append] [--verbose]
       [--portability] [--format=format] [--output=file] [--version]
       [--quiet] [--help] command [arg...]

โดยส่วนตัวแล้วฉันพบว่าสิ่งนี้สามารถอ่านได้และปลอดภัยกว่าเนื่องจากเป็นไปได้:

=^_^= izkata@Izein:~$ alias command=echo
=^_^= izkata@Izein:~$ command time
time

8
โปรดทราบว่ารูปแบบใด ๆ ของข้อความหรืออะไรที่ทำให้มันไม่ได้โทเค็นtimeจะทำ: ti\me, 'time', ti""me, ti${-##*}me, ${-+time}... ที่นำไปใช้กับคำหลักเปลือกใด ๆ
Stéphane Chazelas

สุดยอด PS1 ที่ฉันเคยเห็น
maxywb

1
@maxywb มันไม่ใช่แค่การตกแต่ง - หากคำสั่งสุดท้ายล้มเหลวใบหน้าที่มีความสุขจะเปลี่ยนเป็นสีแดง(x_x)
Izkata

4

โซลูชันทั่วไปสำหรับบิวด์อิน (ตัวอย่างเช่นการทดสอบ) คือ[1] :

  • ใช้env(ทุกเชลล์)

    $ env test
    external test
  • ปิดการใช้งาน builtin (เฉพาะ bash และ zsh):

    $ test 1 = 1 && echo "yes"
    yes
    $ enable -n test        ### for bash. Re-enable with "enable test".
    $ disable test          ### for zsh. Re-enable with "enable test".
    $ test
    external test
  • ใช้เครื่องหมายทับ/เพื่อเรียกคำสั่ง (เชลล์ทั้งหมด):

    $ test 1 = 1 && echo "yes"
    yes 
    $ ~/bin/test
    external test
  • ทำนามแฝง (ล้มเหลวภายในสคริปต์ทุบตียกเว้นหากshopt -s expand_aliasesใช้):

    $ alias test='~/bin/test'             ### remove with 'unalias test'.
    $ test
    external test

แต่เวลาไม่ได้เป็นในตัว

คำtimeนี้เป็น "คำสงวน" ไม่ใช่คำสั่งและไม่มีในตัว ที่เปิดใช้งานโซลูชันนี้:

  • อ้างคำพูด สิ่งนี้ไม่ทำงานกับบิวด์อิน
    การอ้างอิงหลายรูปแบบ: \time "time" 'time' ti\me ti"me"ฯลฯ

    $  time
    
    real    0m0.000s
    user    0m0.000s
    sys     0m0.000s
    
    $ \time
    Usage: /usr/bin/time [-apvV] [-f format] [-o file] [--append] [--verbose]
           [--portability] [--format=format] [--output=file] [--version]
           [--quiet] [--help] command [arg...]

    สิ่งนี้มีประโยชน์ในการข้ามนามแฝง แม้ว่าtestจะเป็นนามแฝงแล้วก็ตาม\testก็จะดำเนินการคำสั่ง PATHed (หรือ builtin หากยังไม่ได้ปิดการใช้งาน)

  • ใช้commandบิวอิน (ซึ่งไม่สามารถใช้งานได้กับบิวด์อิน):

    $ command time
  • ดังกล่าวข้างต้นสำหรับตัว -ins ใช้/งานทับใด ๆ:

    $ /usr/bin/time
  • ดังที่กล่าวมาสำหรับบิวด์อิน alias ยังทำงานได้ที่นี่

    $ alias time='command time'
    $ alias time='/usr/bin/time'

[1] ให้สมมติว่ามีความสามารถในการประมวลผลภายนอกในการ~/bin/testพิมพ์ "การทดสอบภายนอก" และเพิ่มเติม: สมมติว่า~/binเป็นล่วงหน้า/binใน PATH ที่ใช้งานอยู่



2

คุณสามารถใช้enableคำสั่งเพื่อปิดการใช้งานบิวด์อินบางอย่าง

$ enable -n kill

อย่างไรก็ตามtimeเป็นคำหลักดังนั้นสิ่งนี้จะไม่ทำงาน

$ builtin time
bash: builtin: time: not a shell builtin

ดังนั้นคุณเหลือที่จะสร้างนามแฝงเพื่อแทนที่:

$ alias time=/usr/bin/time

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