Làm cho bash sử dụng lệnh `time` bên ngoài thay vì shell tích hợp


27

Làm cách nào để tạo bash sử dụng nhị phân thời gian (/ usr / bin / time) theo mặc định thay vì từ khóa shell?

which timetrả về trả /usr/bin/time
type timevề time is a shell keyword
Chạy timeđang rõ ràng đang thực hiện từ khóa shell:

$ 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 trả lại bash: enable: time: not a shell builtin

Câu trả lời:


30

Bạn có thể sử dụng commandshell tích hợp để bỏ qua quá trình tra cứu thông thường và chạy lệnh đã cho dưới dạng lệnh bên ngoài bất kể mọi khả năng khác (shell dựng sẵn, bí danh, v.v.). Điều này thường được thực hiện trong các tập lệnh cần có khả năng di động trên các hệ thống, mặc dù có lẽ phổ biến hơn bằng cách sử dụng tốc ký \(như \rmthay vì command rmhoặc rm, đặc biệt là phần sau có thể được đặt bí danh cho một cái gì đó không được biết đến như thế 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...]
$ 

Điều này có thể được sử dụng với một bí danh, như vậy:

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

Ưu điểm của việc này hơn alias time=/usr/bin/timelà bạn không chỉ định đường dẫn đầy đủ đến timenhị phân, mà thay vào đó, quay lại cơ chế tìm kiếm đường dẫn thông thường.

Bản aliasthân lệnh có thể đi vào ví dụ ~ / .bashrc hoặc /etc/bash.bashrc (lệnh sau là toàn cục cho tất cả người dùng trên hệ thống).

Đối với trường hợp ngược lại (buộc sử dụng shell được tích hợp trong trường hợp có một bí danh được xác định), bạn sẽ sử dụng một cái gì đó giống như builtin time, một lần nữa ghi đè lên quá trình tìm kiếm thông thường và chạy shell được tích hợp sẵn. Trang bash man đề cập rằng điều này thường được sử dụng để cung cấp cdchức năng tùy chỉnh với một chức năng có tên cd, lần lượt sử dụng nội dung dựng sẵn cdđể thực hiện điều thực.


Bạn cũng có thể hỏi nơi một lệnh cụ thể đến từ việc sử dụng lệnh type -a <cmd>.
slm

12
commandkhông bỏ qua các nội trang (trừ zshkhi không mô phỏng các trình bao khác). Nó bỏ qua các chức năng và đó là lý do chính cho sự tồn tại của nó. Vai trò thứ hai của nó là loại bỏ sự đặc biệt trong các nội trang đặc biệt . Nó bỏ qua các bí danh và từ khóa chỉ vì chúng chỉ được mở rộng ở vị trí đầu tiên ( zshví dụ, nó không bỏ qua các bí danh toàn cầu). Không có timebash dựng sẵn. timelà một từ khóa để bạn có thể làm ví dụ time { foo; bar; }.
Stéphane Chazelas

1
@StephaneChazelas Bằng mọi cách, hãy thoải mái chỉnh sửa nó thành câu trả lời để cung cấp một mô tả chính xác hơn. commandhoạt động trong trường hợp cụ thể này, như được minh họa, nhưng rõ ràng một câu trả lời đúng là tốt hơn một nửa đúng.
một CVn

1
Phần cuối của câu trả lời của bạn là sai. thời gian không phải là một vỏ dựng sẵn, mà là một từ khóa shell. builtin timekhông hoạt động.
Teresa e Junior

tương tự như lệnh sẽ chỉ trích dẫn nó:'time' echo test
mxmlnkn

9

Có một lối tắt trong bash để sidestep từ khóa, mà không phải chỉ định một đường dẫn hoặc sử dụng một nội dung khác như command: Thoát khỏi nó bằng dấu gạch chéo ngược.

=^_^= 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...]

Cá nhân, tôi thấy điều này dễ đọc hơn và an toàn hơn, vì điều này là có thể:

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

8
Lưu ý rằng bất kỳ hình thức trích dẫn hoặc bất cứ điều gì mà làm cho nó không token timesẽ làm: ti\me, 'time', ti""me, ti${-##*}me, ${-+time}... Đó là áp dụng cho bất kỳ từ khoá vỏ.
Stéphane Chazelas

PS1 tốt nhất tôi từng thấy.
maxywb

1
@maxwb Ngoài ra, nó không chỉ là trang trí - nếu lệnh cuối cùng thất bại, khuôn mặt hạnh phúc biến thành màu đỏ(x_x)
Izkata

4

Các giải pháp chung cho tích hợp (ví dụ kiểm tra) là [1] :

  • sử dụng env(tất cả các vỏ)

    $ env test
    external test
  • vô hiệu hóa nội dung (chỉ bash và 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
  • sử dụng bất kỳ dấu gạch chéo / để gọi lệnh (tất cả shell):

    $ test 1 = 1 && echo "yes"
    yes 
    $ ~/bin/test
    external test
  • tạo bí danh (thất bại trong tập lệnh bash, trừ khi shopt -s expand_aliases được sử dụng):

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

Nhưng thời gian không phải là một nội dung.

Từ time này là "từ dành riêng", không phải là lệnh và cũng không phải là tích hợp. Điều đó cho phép các giải pháp này:

  • Trích dẫn từ. Điều này không hoạt động với tích hợp.
    Nhiều hình thức trích dẫn công việc: \time "time" 'time' ti\me ti"me" vv

    $  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...]

    Điều này rất hữu ích để bỏ qua một bí danh. Ngay cả khi testđược đặt bí danh, \testsẽ thực thi lệnh PATHed (hoặc nội dung dựng sẵn nếu nó chưa bị vô hiệu hóa).

  • Sử dụng nội dung command(điều này không hoạt động với phần dựng sẵn):

    $ command time
  • Như trên đối với phần dựng sẵn, sử dụng bất kỳ dấu gạch chéo nào /:

    $ /usr/bin/time
  • Như trên để xây dựng, một bí danh cũng hoạt động ở đây:

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

[1] Giả sử có một thực thi bên ngoài trong ~/bin/testđó in "kiểm tra bên ngoài". Và hơn nữa: giả sử rằng ~/binđi trước /bintrong PATH hoạt động.



2

Bạn có thể sử dụng enablelệnh để vô hiệu hóa một số tích hợp nhất định.

$ enable -n kill

Tuy nhiên timelà một từ khóa vì vậy điều này sẽ không hoạt động.

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

Vì vậy, bạn còn lại với việc tạo bí danh để ghi đè lên nó:

$ alias time=/usr/bin/time

không thời gian là một từ khóa shell, không phải là một vỏ dựng sẵn. Tôi vừa mới chỉnh sửa câu hỏi của mình để nói rằng enable -n không hoạt động khi tôi thấy bạn đã trả lời.
David Holdeman
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.