Получить последнюю выполненную команду в bash

#bash #prompt #built-in

Вопрос:

Мне нужно знать, какая была последняя команда, выполненная при настройке моего запроса bash в функции, соответствующей PROMPT_COMMAND. У меня есть следующий код

 function bash_prompt_command () { 
...
    local last_cmd="$(history | tail -n 2 | head -n 1  | tr -s ' ' | cut -d ' ' -f3-)"
    [[ ${last_cmd} =~ .*gits checkout.* ]] amp;amp; ( ... )
...
}
 

Есть ли более быстрый(встроенный способ bash), чтобы узнать, какая команда вызвала команду PROMPT_COMMAND.
Я попытался использовать BASH_COMMAND, но это тоже не возвращает команду, которая фактически вызвала PROMPT_COMMAND.

Комментарии:

1. Насколько я знаю, другого пути нет. Какие проблемы у вас с вашим кодом? Что еще вы хотели бы, чтобы он делал?

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

3. если текущая(последняя) команда-git checkout, я хочу установить PS1 определенным образом.

4. @hardeep, вы подумывали о том, чтобы просто создать функцию для затенения git и изменения поведения при запуске checkout ?

5. Кстати, function funcname() { объединяет синтаксис ksh function funcname { и синтаксис POSIX sh funcname() { таким образом, чтобы он был несовместим как с ksh, так и с POSIX. Выберите один или другой (POSIX, если вы заботитесь о переносимости), не объединяйте их вместе-см. также wiki.bash-hackers.org/scripting/obsolete

Ответ №1:

Общий случай: Сбор всех команд

Вы можете использовать DEBUG ловушку для хранения каждой команды перед ее запуском.

 store_command() {
  declare -g last_command current_command
  last_command=$current_command
  current_command=$BASH_COMMAND
  return 0
}
trap store_command DEBUG
 

…и после этого вы можете проверить "$last_command"


Особый случай: попытка затенить только одну (вспомогательную)команду

Если вы хотите изменить только то, как работает одна команда, вы можете просто скрыть эту команду. Для git checkout :

 git() {
  # if $1 is not checkout, just run real git and pretend we weren't here
  [[ $1 = checkout ]] || { command git "$@"; return; }
  # if $1 _is_ checkout, run real git and do our own thing
  local rc=0
  command git "$@" || rc=$?
  ran_checkout=1 # ...put the extra code you want to run here...
  return "$rc"
}
 

…потенциально используется из чего-то вроде:

 bash_prompt_command() {
  if (( ran_checkout )); then
    ran_checkout=0
    : "do special thing here"
  else
    : "do other thing here"
  fi
}