Согласно руководству по Bash , переменная окружения BASH_COMMAND
содержит
Команда, выполняемая в настоящее время или готовящаяся к исполнению, если только оболочка не выполняет команду в результате прерывания, и в этом случае это команда, выполняющаяся во время прерывания.
Если оставить в стороне этот случай с ловушкой, если я правильно понимаю, это означает, что когда я выполняю команду, переменная BASH_COMMAND
содержит эту команду. Не совсем ясно, является ли эта переменная неустановленной после выполнения команды (т. Е. Доступна ли она только во время выполнения команды, но не после), хотя можно утверждать, что, поскольку она является «командой , выполняемой в настоящее время или готовой к выполнению» , это не команда, которая была только что выполнена.
Но давайте проверим:
$ set | grep BASH_COMMAND=
$
Пустой. Я бы ожидал увидеть BASH_COMMAND='set | grep BASH_COMMAND='
или, может быть, просто BASH_COMMAND='set'
, но пусто удивил меня.
Давайте попробуем что-то еще:
$ echo $BASH_COMMAND
echo $BASH_COMMAND
$
Ну, это имеет смысл. Я выполняю команду, echo $BASH_COMMAND
и поэтому переменная BASH_COMMAND
содержит строку echo $BASH_COMMAND
. Почему это сработало на этот раз, но не раньше?
Давайте сделаем set
это снова:
$ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
Так что ждите. Он был установлен, когда я выполнил эту echo
команду, и впоследствии он не был сброшен. Но когда я set
снова выполнил , BASH_COMMAND
не было установлено set
команды. Независимо от того, как часто я выполняю set
команду здесь, результат остается неизменным. Итак, установлена ли переменная при выполнении echo
, но не при выполнении set
? Посмотрим.
$ echo Hello AskUbuntu
Hello AskUbuntu
$ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
Какая? Таким образом, переменная была установлена, когда я выполнял echo $BASH_COMMAND
, но не когда я выполнял echo Hello AskUbuntu
? Где разница сейчас? Переменная устанавливается только тогда, когда текущая команда сама заставляет оболочку вычислять переменную? Давайте попробуем что-то другое. Может быть, на этот раз какая-то внешняя команда, а не встроенная команда bash, для разнообразия.
$ /bin/echo $BASH_COMMAND
/bin/echo $BASH_COMMAND
$ set | grep BASH_COMMAND=
BASH_COMMAND='/bin/echo $BASH_COMMAND'
$
Хм, ладно ... опять переменная была установлена. Так верна ли моя нынешняя догадка? Переменная устанавливается только тогда, когда она должна быть оценена? Зачем? Зачем? По причинам производительности? Давайте сделаем еще одну попытку. Мы попытаемся выполнить поиск grep для $BASH_COMMAND
файла и, поскольку он $BASH_COMMAND
должен содержать grep
команду, grep
должен выполнить grep для этой grep
команды (т. Е. Для себя). Итак, давайте сделаем соответствующий файл:
$ echo -e "1 foo\n2 grep\n3 bar\n4 grep \$BASH_COMMAND tmp" > tmp
$ grep $BASH_COMMAND tmp
grep: $BASH_COMMAND: No such file or directory
tmp:2 grep <-- here, the word "grep" is RED
tmp:4 grep $BASH_COMMAND tmp <-- here, the word "grep" is RED
tmp:2 grep <-- here, the word "grep" is RED
tmp:4 grep $BASH_COMMAND tmp <-- here, the word "grep" is RED
$ set | grep BASH_COMMAND=
BASH_COMMAND='grep --color=auto $BASH_COMMAND tmp'
$
Ок, интересно. Команда grep $BASH_COMMAND tmp
была расширена до grep grep $BASH_COMMAND tmp tmp
(переменная раскрывается только один раз, конечно), и поэтому я нашел grep
, один раз в файле, $BASH_COMMAND
который не существует, и два раза в файле tmp
.
Q1: верно ли мое текущее предположение, что:
BASH_COMMAND
устанавливается только тогда, когда команда пытается его реально оценить; а также- оно не сбрасывается после выполнения команды, хотя описание может заставить нас поверить в это?
Q2: если да, то почему? Спектакль? Если нет, как еще можно объяснить поведение в приведенной выше последовательности команд?
Q3: Наконец, есть ли сценарий, в котором эта переменная могла бы реально использоваться осмысленно? Я на самом деле пытался использовать его внутри $PROMPT_COMMAND
для анализа выполняемой команды (и делать что-то в зависимости от этого), но я не могу, потому что, как только внутри $PROMPT_COMMAND
, я выполняю команду, чтобы посмотреть на переменную $BASH_COMMAND
, переменную получает наборы для этой команды. Даже когда я делаю MYVARIABLE=$BASH_COMMAND
прямо в начале моего $PROMPT_COMMAND
, тогда MYVARIABLE
содержит строку MYVARIABLE=$BASH_COMMAND
, потому что назначение тоже команда. (Этот вопрос не о том, как я могу получить текущую команду в ходе $PROMPT_COMMAND
выполнения. Я знаю, что есть и другие способы.)
Это немного похоже на принцип неопределенности Гейзенберга. Просто наблюдая за переменной, я меняю ее.
bash
-гуру.