Зробіть bash використовувати зовнішню команду `time`, а не вбудовану оболонку


27

Як я можу змусити bash використовувати бінарний час (/ usr / bin / time) за замовчуванням замість ключового слова shell?

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, що знову переосмислює звичайний процес пошуку та запускає вбудовану оболонку. Сторінка bash man згадує, що це часто використовується для надання користувальницької cdфункції з функцією, названою cd, яка, в свою чергу, використовує вбудований, cdщоб зробити справжню справу.


Ви також можете запитати, звідки походить певна команда за допомогою команди type -a <cmd>.
slm

12
commandне обходить вбудовані (за винятком випадків, zshколи не імітують інші оболонки). Він обходить функції, і це головна причина його існування. Друга його роль полягає у видаленні спеціального в спеціальних вбудованих . Він обходить псевдоніми та ключові слова лише тому, що вони розширені лише на першій позиції ( zshнаприклад, це не обходить глобальні псевдоніми). Немає timeбашти вбудованого. timeце ключове слово, так що ви можете це зробити, наприклад time { foo; bar; }.
Стефан Шазелас

1
@StephaneChazelas Очевидно, сміливо редагуйте це у відповідь, щоб дати більш точний опис. commandпрацює в даному конкретному випадку, як приклад, але, очевидно, правильна відповідь є кращою, ніж напівправильна.
CVn

1
Остання частина вашої відповіді неправильна. час - це не вбудована оболонка, а скоріше ключове слово оболонки. builtin timeне працює.
Teresa e Junior

подібне до команди було б просто цитувати його:'time' echo test
mxmlnkn

9

Існує ярлик у ключових словах bash to sidepep, без необхідності вказувати шлях або використовувати інший вбудований на зразок command: Escape it with 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}... Це відноситься до будь-якого ключового слова оболонки.
Стефан Шазелас

Найкращий PS1, який я бачив ще.
maxywb

1
@maxywb Крім того, це не просто декоративно - якщо остання команда не вдалася, щасливе обличчя перетворюється на червоне(x_x)
Izkata

4

Загальні рішення для вбудованих модулів (наприклад, тест) [1] :

  • використання env(усі оболонки)

    $ env test
    external test
  • вимкнути вбудований (лише 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
  • зробити псевдонім (не вдається всередині bash-скрипту, за винятком випадків, коли 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 (або вбудований, якщо він не був відключений).

  • Використовуйте вбудований command(це не працює із вбудованими модулями):

    $ command time
  • Як зазначено вище для вбудованих модулів, використовуючи будь-які нахили /:

    $ /usr/bin/time
  • Як зазначено вище для вбудованих програм, тут також працює псевдонім:

    $ 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

ніпе. час - це ключове слово оболонки, а не вбудована оболонка. Я збирався редагувати своє запитання, щоб сказати, що enable -n не працює, коли я побачив, що ти відповів.
Девід Холдеман
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.