How to Disable Editing My History in Bash

How to disable editing my history in bash

Here's my own answer, please correct or provide more details if you can.

When the "vi" option is set in bash ("set -o vi" -- "Use a vi-style command line editing interface"), there are two modes of editing a command from history.

The first mode (let's call it "basic") is when you start editing immediately using Backspace, Del and character keys.

The other mode is the "vi mode", entered when you hit Esc.

If you want to keep your history intact, DO NOT use both modes in the same edit. I don't know how bash works exactly, but you can think of it this way:

  1. Entering the "vi mode" applies any changes done in "basic mode" to the original command, and creates a copy of the command that you can edit further using vi-style commands.
  2. The changes get applied when you hit Enter (execute), Up, Down or j,k (move to another command in history).
  3. The changes do not get applied if you hit Ctrl-C.
  4. Using either basic or vi-style editing ALONE does not affect the original command in history.

Prevent accidental history editing in bash

Each line maintains its own undo list which you can access with C-x C-u or C-_ to undo the most recent change, or M-r to revert all changes since it was last saved.

How to prevent Bash from altering history?

You want the readline setting:

set revert-all-at-newline on

You can either put it in ~/.inputrc (see note below), or put bind 'revert-all-at-newline on' in your ~/.bashrc.

Demo:

$ man bash
$ bind 'set revert-all-at-newline on'
$ man bsh # up arrow and edit
No manual entry for bsh
$ man bash # three up arrows

Further details are in the Bash manpage:

revert-all-at-newline

If set to ‘on’, Readline will undo all changes to history lines before returning when accept-line is executed. By default, history lines may be modified and retain individual undo lists across calls to readline. The default is ‘off’.


Note:

If a new ~/.inputrc file is created for the purpose of setting revert-all-at-newline, be aware that bash will use the readline settings in this file instead of any settings which may be in the file /etc/inputrc. That is, any settings specified in /etc/inputrc will no longer be in effect. Therefore, if the /etc/inputrc file exists, it's a good idea to start ~/.inputrc with the line:

$include /etc/inputrc

.bash_history does not update in Git for Windows (git bash)

I put this in my ~/.bash_profile

PROMPT_COMMAND='history -a'

Preserve bash history in multiple terminal windows

Add the following to your ~/.bashrc:

# Avoid duplicates
HISTCONTROL=ignoredups:erasedups
# When the shell exits, append to the history file instead of overwriting it
shopt -s histappend

# After each command, append to the history file and reread it
PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"

PowerShell's Clear-History doesn't clear history

tl;dr

  • There are two histories to clear:

    • PowerShell's own (Clear-History)
    • Additionally, in consoles (terminals), that of the PSReadLine module that is used for command-line editing by default in PowerShell v5+ ([Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory())
  • In versions 1.2+ of PSReadLine (verify with Get-Module PSReadLine) pressing Alt+F7 performs both calls for you, and therefore fully clears the in-session history.

    • However, it does not clear the saved history that has accumulated up to this point, so even the cleared session's history will resurface in future sessions.

    • To also clear the saved history, you have to manually delete the file in which the saved session is stored ((Get-PSReadlineOption).HistorySavePath), as discussed below, and as wrapped by the Clear-SavedHistory function in the bottom section.


To complement CB.'s helpful answer and JVimes's helpful answer:

  • PowerShell's own history mechanism (Get-History, Clear-History) is host-independent, which is why - somewhat unexpectedly - you also need to clear the hosts's command history separately.

  • As for the console host's own history feature:

    • doskey-style history feature, before module PSReadline shipped with PowerShell (see below):

      • There is no saved history - a history is kept only for the duration of the current session.
      • Alt+F7 must be used to clear the console's history, with no (obvious) programmatic way to do it (in a cmd.exe console window you could use doskey /reinstall, but that doesn't work in PS).
      • CB.'s answer shows you how to simulate this keyboard combination; remember: this must be used in addition to Clear-History.
    • The PSReadline module comes with PowerShell v5 and v5.1 on Windows 10 and will also ship with Windows Server 2016, and also ships with the cross-platform Powershell (Core) v7+ edition; it replaces the doskey-style line-editing and command-history features with more sophisticated functionality; it is also possible to retrofit older Windows editions / PS versions (>= v3) versions with it, using the PowerShell Gallery (PSv3 and PSv4 must first install PowerShellGet).

      • Command history is now saved across sessions, in file

        (Get-PSReadlineOption).HistorySavePath.
      • [Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory() can be used to clear the current session's history (note that v1.2+ also supports Alt+F7 for interactive clearing of the current history).
        • CAVEAT: With PSReadline's default history-saving style, SaveIncrementally, any sensitive commands have already been saved by the time to you call [Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory(), and will reappear in the next session.
        • The only way to handle this is to remove the saved-history file, as demonstrated in JVimes's answer which, however, invariably wipes out the entire history.
        • IF you set up your profile to call Set-PSReadlineOption -HistorySaveStyle SaveAtExit every time a session starts - the setting apparenly does NOT "stick" by itself - you should be able to get away with only calling [Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory() (in addition to Clear-History) without also having to delete the saved-history file, in which case you won't lose your saved history from previous sessions. HOWEVER, AS OF v2.1.0 (the latest as of this writing), SaveAtExit is BROKEN ALTOGETHER - no history is saved at all; see https://github.com/lzybkr/PSReadLine/issues/262

The following advanced function bundles all commands necessary to clear the command history (both for PowerShell itself and the console), both for doskey-style and PSReadline-module PowerShell console windows:

Note:

  • Because it's (currently) the only safe option, PSReadline's saved-history file is deleted as well, which means the entire history, including from previous sessions, is cleared.

  • Therefore, a confirmation prompt is shown by default.

<#
# .SYNOPSIS
# Clears the command history, including the saved-to-file history, if applicable.
#>
function Clear-SavedHistory {
[CmdletBinding(ConfirmImpact='High', SupportsShouldProcess)]
param(
)

# Debugging: For testing you can simulate not having PSReadline loaded with
# Remove-Module PSReadline -Force
$havePSReadline = ($null -ne (Get-Module -EA SilentlyContinue PSReadline))

Write-Verbose "PSReadline present: $havePSReadline"

$target = if ($havePSReadline) { "entire command history, including from previous sessions" } else { "command history" }

if (-not $pscmdlet.ShouldProcess($target))
{
return
}

if ($havePSReadline) {

Clear-Host

# Remove PSReadline's saved-history file.
if (Test-Path (Get-PSReadlineOption).HistorySavePath) {
# Abort, if the file for some reason cannot be removed.
Remove-Item -EA Stop (Get-PSReadlineOption).HistorySavePath
# To be safe, we recreate the file (empty).
$null = New-Item -Type File -Path (Get-PSReadlineOption).HistorySavePath
}

# Clear PowerShell's own history
Clear-History

# Clear PSReadline's *session* history.
# General caveat (doesn't apply here, because we're removing the saved-history file):
# * By default (-HistorySaveStyle SaveIncrementally), if you use
# [Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory(), any sensitive
# commands *have already been saved to the history*, so they'll *reappear in the next session*.
# * Placing `Set-PSReadlineOption -HistorySaveStyle SaveAtExit` in your profile
# SHOULD help that, but as of PSReadline v1.2, this option is BROKEN (saves nothing).
[Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory()

} else { # Without PSReadline, we only have a *session* history.

Clear-Host

# Clear the doskey library's buffer, used pre-PSReadline.
# !! Unfortunately, this requires sending key combination Alt+F7.
# Thanks, https://stackoverflow.com/a/13257933/45375
$null = [system.reflection.assembly]::loadwithpartialname("System.Windows.Forms")
[System.Windows.Forms.SendKeys]::Sendwait('%{F7 2}')

# Clear PowerShell's own history
Clear-History

}

}

How to delete entries from fish shell's command history?

You want history delete. That should ask you for a search term, show you matching entries and ask you for which to delete.



Related Topics



Leave a reply



Submit