Согласно руководству 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. Только путем наблюдения переменной, я изменяю его.
Ответ на третий вопрос: конечно, это может использоваться обоснованно в пути в руководстве 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
Теперь, когда 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, в заключительном абзаце того раздела это говорит
, Если существует название команды, оставленное после расширения, доходы выполнения, как описано ниже. Иначе, выходы команды .
..., который предлагает иначе, и переменные присвоения, команды также.
изобретательное использование за $BASH_COMMAND
Недавно нашло этот впечатляющее использование $BASH_COMMAND в реализации подобной макросу функциональности.
Это - базовый прием псевдонима и заменяет использование прерывания ОТЛАДКИ. При чтении части в предыдущем сообщении о прерывании ОТЛАДКИ you’ll распознают переменную $BASH_COMMAND. В том сообщении я сказал, что оно было установлено на текст команды перед каждым вызовом к прерыванию ОТЛАДКИ. Ну, это оказывается набором it’s перед выполнением каждой команды, прерывания ОТЛАДКИ или не (например, выполненной команды вЂecho “this = $BASH_COMMANDӠдля наблюдения что I’m, говорящий о). Путем присвоения ему переменной (только для той строки) мы получаем BASH_COMMAND в наиболее удаленном объеме команды, которая будет содержать всю команду.
автор предыдущая статья также предоставляет некоторый хороший фон при реализации техники с помощью ОТЛАДКИ trap
. Эти trap
устраняется в улучшенной версии.
На вид общее использование для прерывания... отлаживает, должен улучшить заголовки, которые появляются в 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$