узнать, была ли последняя команда пустой в PROMPT_COMMAND

Семантически, те две формы эквивалентны в Bash.

Из страницы справочника:

Функции Shell объявляются следующим образом:

name () compound-command [redirection]
function name [()] compound-command [redirection]

Это определяет названную функцию name. Функция зарезервированного слова является дополнительной. Если функциональное зарезервированное слово предоставляется, круглые скобки дополнительные.

Править: Я просто заметил, что этот вопрос отмечен posix. В POSIX sh, function ключевое слово не используется (хотя оно резервируется).

11
09.04.2018, 16:57
4 ответа

Проверьте, увеличивался ли номер истории. Отмененная подсказка или подсказка, в которой пользователь только что нажал Enter , не увеличивают номер истории.

Номер истории доступен в переменной HISTCMD , но недоступен в PROMPT_COMMAND (потому что то, что вы хотите, это фактически номер истории предыдущей команды; команда, которая выполняет PROMPT_COMMAND сама не имеет номера истории). Вы можете получить число из вывода fc .

prompt_command () {
  HISTCMD_previous=$(fc -l -1); HISTCMD_previous=${HISTCMD_previous%%$'[\t ]'*}
  if [[ -z $HISTCMD_before_last ]]; then
    # initial prompt
  elif [[ $HISTCMD_before_last = "$HISTCMD_previous" ]]; then
    # cancelled prompt
  else
    # a command was run
  fi
  HISTCMD_before_last=$HISTCMD_previous
}
PROMPT_COMMAND='prompt_command'

Обратите внимание, что если вы включили сжатие дубликатов в истории ( HISTCONTROL = ignoredups или HISTCONTROL = erasedups ), это будет ошибочно сообщать о пустой команде после выполнения двух одинаковых команды подряд.

7
27.01.2020, 19:59

Существует обходной путь, но к нему предъявляются некоторые требования:

Вам нужно установить $ HISTCONTROL , чтобы сохранять ВСЕ команды, а также дубликаты и пробелы. Итак, установите:

HISTCONTROL=

Теперь определите функцию для вызова как $ PROMPT_COMMAND :

isnewline () {
  # read the last history number
  prompt_command__isnewline__last="$prompt_command__isnewline__curr"
  # get the current history number
  prompt_command__isnewline__curr="$(history 1 | grep -oP '^\ +\K[0-9]+')"
  [ "$prompt_command__isnewline__curr" = "$prompt_command__isnewline__last" ] && \
    echo "User hit return"
}

Теперь установите переменную $ PROMPT_COMMAND :

PROMPT_COMMAND="isnewline"

См. Вывод:

user@host:~$ true
user@host:~$ <return>
User hit return
user@host:~$ <space><return>
user@host:~$ 
4
27.01.2020, 19:59

Я не знаю, как это сделать, как таковой . Но вы можете получить тот же эффект, используя

trap some_command_or_function debug

. Это приведет к вызову some_command_or_function каждый раз, когда вы запускаете команду. Сложность в том, что он не будет вызван, если вы просто нажмете , введите - , если только у вас не определена PROMPT_COMMAND, в этом случае нажмите Enter вызывает PROMPT_COMMAND, который, в свою очередь, запускает ловушку.

Возможно, самый простой способ достичь желаемого результата - это определить функцию ловушки отладки вместо использования PROMPT_COMMAND. Но я не могу сказать, потому что не знаю, какого результата вы хотите. Если вы хотите, чтобы что-то произошло, когда вы просто нажмете , введите , и что-то другое / дополнительное произойдет при вводе команды, затем (AFAIK) вам нужно использовать ловушку отладки и PROMPT_COMMAND. См. этот ответ , чтобы узнать, как заставить эти два механизма хорошо взаимодействовать друг с другом.

0
27.01.2020, 19:59

(Это был бы комментарий к принятому ответу, если бы мне было разрешено добавлять комментарии... )@schlimmen, вы можете установить HISTTIMEFORMATна что-то вроде HISTTIMEFORMAT='%F %T ', а затем сохранить и сравнить history 1. Это связано с тем, что при стирании по крайней мере метка времени (возможно повторяемой )последней команды меняется каждый раз ---, а при соответствующей установке HISSTIMEFORMAThistory 1будет отображать метку времени (, в отличие от fc), и таким образом различаются даже между повторяющимися командами.

0
27.01.2020, 19:59

Теги

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