informa se o último comando estava vazio em PROMPT_COMMAND

11

No bash, a partir do interior do PROMPT_COMMAND, existe uma maneira de saber se o usuário apenas pressionou 'return' e não inseriu um comando?

    
por user 02.09.2015 / 04:19

4 respostas

7

Verifique se o número do histórico foi incrementado. Um aviso cancelado ou um prompt no qual o usuário pressionou Enter não aumentará o número do histórico.

O número do histórico está disponível na variável HISTCMD , mas isso não está disponível em PROMPT_COMMAND (porque o que você quer é o número do histórico do comando anterior; o comando que executa PROMPT_COMMAND tem nenhum número de histórico). Você pode obter o número da saída de 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'

Observe que, se você tiver ativado a compactação de duplicatas no histórico ( HISTCONTROL=ignoredups ou HISTCONTROL=erasedups ), isso informará erroneamente um comando vazio depois de executar dois comandos idênticos sucessivamente.

    
por 03.09.2015 / 03:02
4

Existe uma solução alternativa, mas tem alguns requisitos:

Você precisa definir $HISTCONTROL para salvar TODOS os comandos, também duplicatas e espaços. Então defina:

HISTCONTROL=

Agora defina uma função para chamar como $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"
}

Agora, defina a variável $PROMPT_COMMAND :

PROMPT_COMMAND="isnewline"

Veja a saída:

user@host:~$ true
user@host:~$ <return>
User hit return
user@host:~$ <space><return>
user@host:~$ 
    
por 02.09.2015 / 08:59
0

Eu não sei de uma maneira de fazer isso, per se . Mas você pode obter o mesmo efeito usando

trap some_command_or_function debug

Isso fará com que some_command_or_function seja chamado sempre que você executar um comando. O mais complicado é que ele não será chamado se você apertar Enter - a menos que você tenha um PROMPT_COMMAND definido, Nesse caso, pressionar Enter invoca o PROMPT_COMMAND, que, por sua vez, desencadeia a armadilha.

Talvez a maneira mais simples de alcançar o resultado desejado é definir uma função de depuração de depuração em vez de usar um PROMPT_COMMAND. Mas eu não sei, porque eu não sei o resultado que você quer. Se você quer que algo aconteça quando você apertar Enter , e algo diferente / adicional acontecer quando você digita um comando, então (AFAIK) você precisa usar uma armadilha de depuração e um PROMPT_COMMAND. Veja esta resposta para que os dois mecanismos funcionem bem juntos.

    
por 02.09.2015 / 08:15
0

(Este teria sido um comentário para a resposta aceita se eu tivesse permissão para adicionar comentários ...) @schlimmen, você pode definir HISTTIMEFORMAT para algo como HISTTIMEFORMAT='%F %T ' e depois salvar e comparar history 1 . É porque com os apagamentos, pelo menos, o timestamp do último comando (possivelmente repetido) muda sempre - e com HISSTIMEFORMAT apropriadamente definido, history 1 exibirá o timestamp (diferente de fc ) e, portanto, diferirá até mesmo entre o comandos repetidos.

    
por 09.04.2018 / 15:18

Tags