Intereting Posts
Может ли Apt удалить пакеты, которые необходимы программному обеспечению, которое пользователи установили из источника? Поле имени пользователя изменено на passwd Недопустимая файловая система ZFS не имеет данных Копирование одного файла в несколько каталогов ZSH: `ls * (.)` Перечисляет только обычные файлы, но `ls * (/)` не перечисляет только каталоги Почему scp говорит «Нет такого файла»? Разрешения локального каталога Linux как вопросительные знаки для не-root Инструмент командной строки для «cat» попарно расширяет все строки в файле Цвет git grep отличается от пользовательских цветов grep Сценарий оболочки для команды kill Маршрутизация для нескольких восходящих линий / поставщиков VMware на хосте Linux вызывает регулярные зависания Можно ли изменить палитру по умолчанию для терминала xterm-256color? поиск и подглаживание (и подстановочные знаки) Перезагрузите систему в настройки UEFI

Различия между зарезервированным словом и командой `time` на встроенной оболочке оболочки, функции, конвейере и списке команд?

В Справочном руководстве Bash,

Использование time в качестве зарезервированного слова позволяет синхронизировать встроенные оболочки, функции оболочки и конвейеры . Внешняя команда времени не может легко это сделать.

  1. Не могли бы вы объяснить, почему цитата говорит об этом?

    Это из-за разницы между зарезервированным словом и командой, не ограничиваясь только случаем time ? Например, как оболочка bash анализирует или интерпретирует их по-разному?

    Или это ограничивается только случаем time ?

  2. В следующих примерах,

    почему внешнее time работает над встроенной оболочкой и конвейером, в то время как цитата говорит, что «не может легко это сделать»?

    Внешнее time на встроенной оболочке :

     $ /usr/bin/time echo hello hello 0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 1676maxresident)k 0inputs+0outputs (0major+78minor)pagefaults 0swaps 

    Внешнее time на трубопроводе :

     $ /usr/bin/time sleep 10 | sleep 5 0.00user 0.00system 0:10.00elapsed 0%CPU (0avgtext+0avgdata 1776maxresident)k 0inputs+0outputs (0major+79minor)pagefaults 0swaps 
  3. В следующем примере, почему нарушается внешнее time на функции оболочки ? Что означает его ошибка?

     $ function mytest () { sleep 10; } $ /usr/bin/time mytest /usr/bin/time: cannot run mytest: No such file or directory Command exited with non-zero status 127 0.00user 0.00system 0:00.03elapsed 0%CPU (0avgtext+0avgdata 1252maxresident)k 32inputs+0outputs (0major+30minor)pagefaults 0swaps 
  4. Кажется, что цитата относится не только к встроенным тайм-оболочкам, функциям оболочки и конвейерам, но также к выбору времени для группы команд :

     $ time { echo hello; sleep 3; echo tim; } hello tim real 0m3.002s user 0m0.000s sys 0m0.000s $ /usr/bin/time { echo hello; sleep 3; echo tim; } bash: syntax error near unexpected token `}' 

    Почему оболочка говорит «bash: синтаксическая ошибка около неожиданного токена» в случае команды /usr/bin/time ?

    В bash time является зарезервированным словом , поэтому оболочка может анализировать его по-своему и применять для него правила.

    Вот код показывает, как строка bash parse начинается с зарезервированного слова времени :

     static int time_command_acceptable () { #if defined (COMMAND_TIMING) int i; if (posixly_correct && shell_compatibility_level > 41) { /* Quick check of the rest of the line to find the next token. If it begins with a `-', Posix says to not return `time' as the token. This was interp 267. */ i = shell_input_line_index; while (i < shell_input_line_len && (shell_input_line[i] == ' ' || shell_input_line[i] == '\t')) i++; if (shell_input_line[i] == '-') return 0; } switch (last_read_token) { case 0: case ';': case '\n': case AND_AND: case OR_OR: case '&': case WHILE: case DO: case UNTIL: case IF: case THEN: case ELIF: case ELSE: case '{': /* } */ case '(': /* )( */ case ')': /* only valid in case statement */ case BANG: /* ! time pipeline */ case TIME: /* time time pipeline */ case TIMEOPT: /* time -p time pipeline */ case TIMEIGN: /* time -p -- ... */ return 1; default: return 0; } #else return 0; #endif /* COMMAND_TIMING */ } 

    Понимаете, за time может следовать большинство других зарезервированных слов.

    В случае внешней команды было применено нормальное правило, { считалось вводом /usr/bin/time . } является недействительным токеном, а bash вызывает ошибку.


    В:

     /usr/bin/time echo hello 

    внешнее time не вызывало встроенное echo сообщение оболочки, а внешнюю команду echo .

    strace проверяет, что:

     $ strace -fe execve /usr/bin/time echo 1 execve("/usr/bin/time", ["/usr/bin/time", "echo", "1"], [/* 64 vars */]) = 0 Process 25161 attached .... [pid 25161] execve("/usr/bin/echo", ["echo", "1"], [/* 64 vars */]) = -1 ENOENT (No such file or directory) [pid 25161] execve("/bin/echo", ["echo", "1"], [/* 64 vars */]) = 0 1 [pid 25161] +++ exited with 0 +++ .... 

    Здесь внешнее time PATH переменную PATH чтобы найти исполняемую команду. Это также объясняет, что в случае использования функции у вас нет такого файла или каталога , mytest в вашем PATH нет команды с именем mytest .

    В 2. вы можете видеть, что результат неправильный, особенно для второго случая: /usr/bin/time times первая команда конвейера (10 с). Затем вывод команды /usr/bin/time sleep 10 передается в sleep 5 . Это оболочка, которая разбивает вашу командную строку таким образом: для нее /usr/bin/time точно так же, как любая другая команда.

    В 3. функции оболочки внутренние для процесса оболочки: /usr/bin/time вызывается с аргументом mytest , он ищет эту команду в пути и ничего не находит. /usr/bin/time вызывается оболочкой, но не является ее частью.