Для чего $BASH_COMMAND является переменной пользой?

Согласно руководству 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? Где различие теперь? Переменная только установлена, когда сама текущая команда на самом деле вынуждает оболочку оценить переменную? Давайте попробуем что-то другое. Возможно, некоторая внешняя команда на этот раз, не встроенный удар, для разнообразия.

$ /bin/echo $BASH_COMMAND
/bin/echo $BASH_COMMAND
$ set | grep BASH_COMMAND=
BASH_COMMAND='/bin/echo $BASH_COMMAND'
$

Хм, хорошо... снова, переменная была установлена. Таким образом, мое текущее предположение корректно? Переменная только установлена, когда она должна быть оценена? Почему? Почему? По причинам производительности? Давайте сделаем еще одну попытку. Мы попробуем к grep за $BASH_COMMAND в файле, и с тех пор $BASH_COMMAND должен затем содержать a 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, потому что присвоение является командой также. (Этот вопрос не о том, как я мог получить текущую команду в a $PROMPT_COMMAND выполнение. Существуют другие пути, я знаю.)

Это немного похоже с принципом неуверенности Heisenberg's. Только путем наблюдения переменной, я изменяю его.

25
задан 20 August 2014 в 22:24

4 ответа

Ответ на третий вопрос: конечно, это может использоваться обоснованно в пути в руководстве Bash, ясно подсказывает †“в прерывании, например:

$ trap 'echo ‘$BASH_COMMAND’ failed with error code $?' ERR
$ fgfdjsa
fgfdjsa: command not found
‘fgfdjsa’ failed with error code 127
$ cat /etc/fgfdjsa
cat: /etc/fgfdjsa: No such file or directory
‘cat /etc/fgfdjsa’ failed with error code 1
15
ответ дан 16 November 2019 в 11:50

Теперь, когда Q3 ответили (правильно, по-моему: BASH_COMMAND полезно в прерываниях и едва где-либо еще), давайте дадим Q1 и Q2 выстрел.

ответ на Q1: правильность Вашего предположения неразрешима. Истина ни одного из пунктов маркированного списка может быть установлена, поскольку они спрашивают о неуказанном поведении. Его спецификацией значение BASH_COMMAND установлено к тексту команды на время выполнения той команды. Спецификация не указывает, чем ее значение должно быть в любой другой ситуации, т.е. когда никакая команда не выполняется. Это могло иметь любое значение или ни один вообще.

ответ на Q2, "Если не, как еще может поведение в вышеупомянутой последовательности команды быть объясненным?" тогда следует логически (если несколько педантично): это объяснено тем, что значение BASH_COMMAND не определено. Так как его значение не определено, это может иметь любое значение, которое является точно, что показывает последовательность.

Постскриптум

существует одна точка, где я думаю, что Вы действительно поражаете мягкое место в спецификации. Это - где Вы говорите:

, Даже когда я делаю $BASH_COMMAND MYVARIABLE= правильно в начале своего $PROMPT_COMMAND, тогда MYVARIABLE содержит строку $BASH_COMMAND MYVARIABLE=, , потому что присвоение является командой также .

способ, которым я прочитал страницу справочника удара, бит курсивом, не верен. Раздел SIMPLE COMMAND EXPANSION объясняет, как сначала переменные присвоения на командной строке обойдены, и затем

, Если никакое название команды не заканчивается [другими словами, были только переменные присвоения], переменные присвоения влияют на текущую среду оболочки.

Это намекает мне, что переменные присвоения не являются командами (и поэтому освободите от разоблачения в BASH_COMMAND), как на других языках программирования. Это тогда также объяснило бы, почему нет строки BASH_COMMAND=set в выводе set, set по существу быть синтаксическим 'маркером' для переменного присвоения.

OTOH, в заключительном абзаце того раздела это говорит

, Если существует название команды, оставленное после расширения, доходы выполнения, как описано ниже. Иначе, выходы команды .

..., который предлагает иначе, и переменные присвоения, команды также.

6
ответ дан 16 November 2019 в 11:50

изобретательное использование за $BASH_COMMAND

Недавно нашло этот впечатляющее использование $BASH_COMMAND в реализации подобной макросу функциональности.

Это - базовый прием псевдонима и заменяет использование прерывания ОТЛАДКИ. При чтении части в предыдущем сообщении о прерывании ОТЛАДКИ you’ll распознают переменную $BASH_COMMAND. В том сообщении я сказал, что оно было установлено на текст команды перед каждым вызовом к прерыванию ОТЛАДКИ. Ну, это оказывается набором it’s перед выполнением каждой команды, прерывания ОТЛАДКИ или не (например, выполненной команды ‘echo “this = $BASH_COMMANDӠ˜ для наблюдения что I’m, говорящий о). Путем присвоения ему переменной (только для той строки) мы получаем BASH_COMMAND в наиболее удаленном объеме команды, которая будет содержать всю команду.

автор предыдущая статья также предоставляет некоторый хороший фон при реализации техники с помощью ОТЛАДКИ trap. Эти trap устраняется в улучшенной версии.

2
ответ дан 16 November 2019 в 11:50

На вид общее использование для прерывания... отлаживает, должен улучшить заголовки, которые появляются в windowlist (^A"), когда Вы используете "экран".

я пытался сделать "экран", "windowlist" более применимым, таким образом, я начал находить, что статьи, ссылающиеся "на прерывание..., отлаживают".

я нашел, что метод с помощью PROMPT_COMMAND для отправки "пустой последовательности заголовка" не работал так хорошо, таким образом, я вернулся к прерыванию... отлаживают метод.

Вот то, как Вы делаете это:

1 Говорят, "экран" для поиска escape-последовательности (включите его) путем помещения "shelltitle '$ |bash'": в "$HOME/.screenrc".

2 Выключают распространение прерывания отладки в подоболочки. Это важно, потому что, если это включено, все испачкано, используйте: "набор +o functrace".

3 Отправляют escape-последовательность заголовка за "экраном" для интерпретации: захватите 'printf "\ek$ (дата + %Y%m%d%H%M%S) $ (whoami) $ (имя хоста): $ (pwd) $ {BASH_COMMAND }\\e \"' "ОТЛАДКА"

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

, Посмотрите следующий "windowlist" (5 экранов):

Цифровые Флаги Имени

1 bash:20161115232035 mcb@ken007:/home/mcb/ken007 RSYNCCMD = "sudo rsync" myrsync.sh-R-r "$ {1}" "$ {BACKUPDIR} $ {2: + "/$ {2} "}" bash:20161115230434 mcb@ken007:/home/mcb/ken007 ls за 2$ - кошка color=auto - la 3$ bash:20161115230504 mcb@ken007:/home/mcb/ken007 bin/psg.sh $ bash:20161115222450 mcb@ken007:/home/mcb/ken007 mycommoncleanup bash:20161115222415 mcb@ken007:/home/mcb/ken007 ssh ken009 за 5$ за 4$

0
ответ дан 16 November 2019 в 11:50

Другие вопросы по тегам:

Похожие вопросы: