Обсуждая различия между /usr/bin/time
встроенной оболочкой (bash и 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 "$@"
shell
quoting
posix
time-utility
Йонас Шефер
источник
источник
Ответы:
t\ime
или\cd
(или"tim"e
или'cd'
или${-##*}time
или${-+time}
и любая другая комбинация цитирования и расширений, о которой вы могли бы подумать, что в конечном итоге разрешитtime
илиcd
), такова: другой способ написатьcd
иtime
.Тем не менее, это в конечном итоге приведет к
cd
илиtime
к более позднему времени синтаксического анализа и интерпретации оболочки. В частности, это происходит спустя долгое время после распознавания ключевых слов оболочки и замены псевдонимов .Таким образом, в то время как оболочка ищет ключевые слова на своем языке, она не распознается
ti\me
какtime
ключевое слово оболочки. Итак:будет распознаваться оболочкой как простая команда, а не как
time
ключевое слово, за которым следует простая команда.Затем
ti\me
будет обработано цитирование (здесь обратная косая черта заключает в кавычкиm
символ, который в любом случае не нужно заключать в кавычки, символ цитирования удаляетсяtime
), иtime
команда будет выглядеть как любая другая команда (в списке встроенных функций). , функции и исполняемые файлы в$PATH
. Скорее всего, что будет/bin/time
здесь)Ведь в языке оболочки
cd
нетcd
ключевого слова, толькоcd
встроенная команда (которая имеет приоритет над вашей/usr/bin/cd
). Однако, если вы определите псевдоним дляcd
(какalias cd=pushd
), то же самое снова. Поскольку подстановка псевдонимов выполняется очень рано, перед удалением кавычек, если у вас есть псевдоним для,cd
а не один для\cd
(обратите внимание, что не многие оболочки допускают псевдонимы с обратными косыми чертами в них), то пишите:вы убедитесь, что ваш
cd
псевдоним не заменен.Короче говоря, со ссылкой на имя команды или какую - либо его часть не мешает ему быть рассматриваются в качестве ключевого слова оболочки (ключевых слов быть вещи , как
while
,for
,if
,{
...time
это ключевое слово в некоторых только оболочках), и обходят псевдоним , вы можете иметь для него ,Однако это не заставляет эту команду преобразовываться в исполняемый файл
$PATH
, команда по-прежнему ищется первой среди функций (которые вы можете обойти, выполняяcommand time cmd...
) и встроенных функций (которые вы можете обойти, выполняяenv time cmd...
, хотя я не знаю, оболочка, которая имеет встроеннуюtime
команду).Обратите внимание, что цитирование может также влиять на поведение специальных встроенных элементов семейства
typeset
/declare
/export
/local
... в некоторых оболочках. См. Нужны ли кавычки для назначения локальной переменной? для деталей.источник
time
иcd
что приводит к разнице в наблюдаемом поведении в том, чтоtime
это ключевое слово иcd
является встроенной командой ?time
ключевое слово, а этоcd
не так. (и если бы у вас был псевдоним дляcd
илиtime
, это было бы другое дело). Этоcd
встроено или нет, на данный момент не имеет никакого значения (что касается влияния цитирования). Однако некоторые оболочки имеют несколько встроенных функций, которые находятся на полпути между ключевыми словами и встроенными функциями, поскольку их синтаксический анализ выполняется не так, как другие встроенные функции. Это случайexport
/typeset
/declare
. Я, вероятно, должен добавить примечание об этом в этом ответе.