No bash, de dentro do PROMPT_COMMAND, existe uma maneira de saber se o usuário pressionou 'return' e não inseriu um comando?
12
Verifique se o número do histórico foi incrementado. Um prompt cancelado ou um prompt em que o usuário acabou de pressionar Enternão aumentará o número do histórico.
O número do histórico está disponível na variável HISTCMD
, mas não está disponível em PROMPT_COMMAND
(porque o que você deseja é, de fato, o número do histórico do comando anterior; o comando que se executa por PROMPT_COMMAND
si mesmo não tem número do 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ê ativou o esmagamento de duplicatas no histórico ( HISTCONTROL=ignoredups
ou HISTCONTROL=erasedups
), isso reportará por engano um comando vazio após executar dois comandos idênticos sucessivamente.
${HISTCMD_previous%%$'[\t ]'*}
bit estava ausente$'…'
e acabou truncando após`,
t` ou espaço em vez de após tab ou espaço, mas o bash imprime uma tab.Existe uma solução alternativa, mas ela tem alguns requisitos:
Você precisa definir
$HISTCONTROL
para salvar TODOS os comandos, também duplicatas e espaços. Então defina:Agora defina uma função para chamar como
$PROMPT_COMMAND
:Agora, defina a
$PROMPT_COMMAND
variável:Veja a saída:
fonte
last
é preservada de uma chamadaisnewline
para a próxima (escolha apenas um nome menos genéricoprompt_command__isnewline__last
para evitar conflitos).HISTCONTROL="" function last_was_blank { local last_command="$(history 1)" if [[ "$last_was_blank_PREVIOUS_LINE" = "$last_command" ]] ; then echo "true" else echo "false" fi export last_was_blank_PREVIOUS_LINE="$last_command" } PROMPT_COMMAND=last_was_blank
Não sei como, por si só . Mas você pode obter o mesmo efeito usando
Isso fará com
some_command_or_function
que seja chamado sempre que você executar um comando. O mais complicado é que não será chamado se você apenas pressionar Enter- a menos que você tenha um PROMPT_COMMAND definido; nesse caso, pressionar Enterinvoca o PROMPT_COMMAND, que, por sua vez, aciona a armadilha.Talvez a maneira mais simples de obter o resultado desejado seja definir uma função de interceptação de depuração em vez de usar um PROMPT_COMMAND. Mas não sei dizer, porque não sei qual resultado você deseja. Se você deseja que algo aconteça quando você apenas pressiona Enter, e algo diferente / adicional aconteça ao digitar um comando, (AFAIK), você precisa usar uma interceptação de depuração e um PROMPT_COMMAND. Veja esta resposta e esta como uma maneira de fazer com que os dois mecanismos funcionem bem juntos.
fonte
(Isso teria sido um comentário para a resposta aceita se eu tivesse permissão para adicionar comentários ...) @schlimmen, você pode definir
HISTTIMEFORMAT
algo como issoHISTTIMEFORMAT='%F %T '
e depois salvar e compararhistory 1
. Isso ocorre porque, com as cópias apagadas, pelo menos o registro de data e hora do último comando (possivelmente repetido) muda sempre - e, comHISSTIMEFORMAT
o ajuste apropriado,history 1
exibirá o registro de data e hora (diferente defc
) e, portanto, difere mesmo entre os comandos repetidos.fonte