Como posso corrigir permanentemente um erro de digitação no meu último comando bash?

1

Não é incomum que eu faça um erro de digitação ao digitar comandos no meu shell interativo bash. Gostaria de poder corrigir o erro de digitação no meu histórico bash para que o comando incorreto não o polua e me leve a executá-lo acidentalmente mais tarde. Em particular, gostaria de editar o último comando.

Existem bastante a número of perguntas perguntando sobre como impedir editar acidentalmente o histórico bash. Eu quero o oposto: eu quero explicitamente editar o histórico.

Com base em algumas das explicações das perguntas mencionadas, tentei fazer:

$ echo foo

pressionando Up , mudando para:

$ echo foobar

pressionando Down , mas isso não faz nada, e se eu pressionar Enter , ele executará o comando modificado e deixará os dois

echo foo
echo foobar

na minha história.

Estou ciente de que posso excluir manualmente as entradas do histórico com history -d , mas não criei uma boa maneira de usá-lo convenientemente. Eu não quero fazer uma função de shell para excluir incondicionalmente a última entrada do histórico, porque eu ainda quero ser capaz de usar Up para carregar a última entrada para que eu possa corrigi-la. Eu poderia fazer a correção e, em seguida, excluir a entrada do histórico de penúltimo para o último, mas isso é desajeitado e é particularmente irritante para um comando de longa duração, já que eu precisaria me lembrar de executar etapas extras mais tarde ou suspender temporariamente faça essas etapas e continue.

O que eu quero:

  • Idealmente, o que eu gostaria de poder fazer é pressionar Up , fazer uma correção no comando anterior e pressionar alguns atalhos de teclado especiais ou adicionar algum símbolo mágico ao comando Linha para fazer com que substitua a entrada do histórico quando executada.

  • Também é aceitável pressionar outra sequência de teclas para recuperar e editar um comando do histórico (semelhante ao Ctrl + R) que substitui a entrada do histórico quando executado.

  • Uma função shell robusta que remove a segunda entrada do histórico seria tolerável, mas não ideal.

Eu imagino que certamente outras pessoas também cometeram erros de digitação e estão igualmente irritadas quando tais comandos poluem sua história. O que as outras pessoas fazem?

    
por jamesdlin 17.07.2018 / 04:40

2 respostas

0

O HSTR parecia atraente, mas acabou sendo pesado demais para o meu gosto.

Em vez disso, escrevi minha própria função bash:

# Removes the last command from the history that matches the given search
# string and re-executes it using the given replacement string.
#
# Usage:
#   historysub SEARCH [REPLACEMENT]
#   historysub -d SEARCH
#
#   REPLACEMENT may be omitted to remove SEARCH from the executed command.
#
#   -d removes the last command matching SEARCH from the history without
#   executing a new command.
historysub()
{
  local delete=0
  local usage=0
  local OPTIND=1
  while getopts ":hd" option; do
    case "${option}" in
      d) delete=1 ;;
      h) usage=1 ;;
      ?) usage=2 ;;
    esac
  done
  shift $((OPTIND - 1))

  local search="${1}"
  local replacement="${2}"

  usage_text=
  usage_text+="Usage: ${FUNCNAME[0]} SEARCH [REPLACEMENT]\n"
  usage_text+="       ${FUNCNAME[0]} -d SEARCH\n"

  if (( usage )); then
    echo -e "${usage_text}"
    return $(( usage - 1 ))
  fi

  if [[ -z "${search}" ]]; then
    echo -e "${usage_text}" >&2
    return 1
  fi

  # Find the last matching history entry (excluding ourself).
  local hist_info
  hist_info=$(HISTTIMEFORMAT="" history | grep -F -- "${search}" | grep -vF -- "${FUNCNAME[0]}" | tail -n 1)
  if [[ -z "${hist_info}" ]]; then
    echo "${FUNCNAME[0]}: \"${search}\" not found." >&2
    return 1
  fi

  local re='^[ \t]*([0-9]+)[ \t]+(.+)$'
  local hist_num hist_cmd
  hist_num=$(sed -E "s/${re}//" <<< "${hist_info}")
  hist_cmd=$(sed -E "s/${re}//" <<< "${hist_info}")

  history -d "${hist_num}"
  if (( delete )); then
    echo "Removed: ${hist_cmd}"
    return 0
  fi

  local cmd="${hist_cmd/${search}/${replacement}}"
  echo "${cmd}"

  # Add the new command to the history.
  history -s ${cmd}
  ${cmd}
}

Agora, posso executar historysub TYPO CORRECTION para executar novamente um comando com uma correção. Não é tão bom quanto poder editar o comando antigo de forma interativa, mas acho que deve ser bom o suficiente para as minhas necessidades.

    
por 06.10.2018 / 21:20
2

Opção nº 1 - manualmente

Eu simplesmente abriria o arquivo ~/.bash_history em um editor como vim e faria as alterações necessárias nesse arquivo e salvaria.

$ vim ~/.bash_history

Antes de editá-lo, certifique-se de que seu histórico atual de terminais também esteja comprometido com este arquivo:

$ history -a

Tenha em mente que seu arquivo de histórico está localizado para onde essa variável de ambiente está apontando:

$ echo $HISTFILE
/Users/user1/.bash_history

Opção # 2 - HSTR

Existe uma ferramenta CLI chamada HSTR que você pode usar para gerenciar seu arquivo ~/.bash_history de uma maneira mais sistemática. O site principal do HSTR continha vídeos e detalhes sobre como usá-lo.

Ele também menciona essa sinopse:

HSTR can also manage your command history (for instance you can remove commands that are obsolete or contain a sensitive information) or bookmark your favorite commands.

Consulte a documentação completa para saber mais sobre isso: DOCUMENTAÇÃO DO HSTR .

Referências

por 17.07.2018 / 04:45