158

Sometimes I forget how the exact syntax of a CMD command looks and then I would like to search my own CMD history. Clearly, within the same session, you can browse it with the up and down arrow keys but what about the history of former CMD sessions? Is there a file, a log the history gets written to or does it all go to digital Nirvana?

Thanks!

2
  • 6
    You can hijack the exit command to automatically save a log before exiting: doskey exit=doskey /history ^>^> C:\path\to\cmdhistory.log $T exit $* but you'll need to figure out how to execute this automatically at each command prompt session startup. PS: Make sure the path of the log file is writable. C:\ is not writable for a non-admin command prompt.
    – ADTC
    Jan 7, 2018 at 5:00
  • 5
    @ADTC: AutoRun should handle 'each startup': superuser.com/a/302553/333316 or stackoverflow.com/a/17405182/2868801 Jun 3, 2018 at 20:40

12 Answers 12

66

No, Windows command prompt history can't be saved when a session ends.

12
  • 3
    for real? how do you know this? Sorry for questioning you, I guess you are right but how can u know unless u programmed the damn thing ;)
    – raoulsson
    Dec 18, 2009 at 0:08
  • 12
    Ok, let me rephrase :-) The Windows command interpreter ("cmd.exe") doesn't provide any support for saving/exporting/keeping history, of, if it does, Microsoft didn't document it and nobody was ever able to find it. You can of course try to work around that, like Sean suggested, but there's (or does appear to be) no built-in support for this.
    – Massimo
    Dec 18, 2009 at 6:17
  • 28
    You can press F7 to see a history list of the current session.
    – jftuga
    Feb 14, 2011 at 13:20
  • 9
    CURRENT session is the keyword here.
    – Massimo
    Aug 24, 2015 at 5:42
  • 10
    You can see / save the history by running doskey.exe /history (that's also where the F7 shortcut comes from, BTW) but there's no way to load it back up in your next session.
    – Coderer
    Feb 19, 2016 at 9:45
91

Not natively but check out: http://mridgers.github.io/clink/ , makes cmd.exe much more productive. Quoting features from the project page:

Powerful Bash-like line editing from GNU's Readline library.
Superior path completion (TAB).
Paste from clipboard (Ctrl-V).
Support for the completion of executables/commands, and environment variables.
Undo/Redo (Ctrl-_ or Ctrl-X, Ctrl-U)
Improved command line history.
Persists across sessions.
Searchable (Ctrl-R and Ctrl-S).
History expansion (e.g. !!, !<string>, and !$).
Scriptable completion using Lua.
7
  • 6
    clink solved everything
    – Still.Tony
    Jan 20, 2015 at 16:27
  • 8
    Any plans to include it by default in Windows? :D Mar 1, 2015 at 22:40
  • Can you set a ~/.inputrc when using clink? (and do you know whether it can be used Console or anything?)
    – Mike H-R
    Apr 20, 2015 at 17:39
  • Apparently, see the doc github.com/mridgers/clink/blob/master/docs/clink.md. Dec 18, 2015 at 9:29
  • ... except aliases. clink hates doskey; forget all of your years-long and carefully-assigned aliases. that's why i stopped to use it. though i miss all the features.
    – user246890
    Jul 3, 2017 at 17:31
26

Massimo is correct that your command prompt history does not persist across sessions. You could manually grab this before closing your prompt by typing doskey /history > history.txt

Or... you could use PowerShell as your CMD prompt, and follow this post to persist your history across sessions.

0
19

You can use clink.

Clink combines the native Windows shell cmd.exe with the powerful command line editing features of the GNU Readline library, which provides rich completion, history, and line-editing capabilities.

Easiest way to install clink is using chocolatey. Once you install chocolatey, you can install clink by typing

choco install clink

Starting from the next time you start cmd.exe, it should store history across sessions.

4
  • 3
    Finally decided to give Chocolatey a shot because of this post. Installation was as easy as of brew in macOS. And now I have a Bash-like command prompt in Windows! Sep 23, 2016 at 7:39
  • 1
    Yes must say Chocolatey is definitely awesome, takes some of the worry about downloading the 'proper' installation file Aug 4, 2020 at 9:12
  • I need to install chrisant996/clink as mentioned here to make it work on Windows 11.
    – 林果皞
    Jan 4, 2022 at 20:42
  • I've read through this post but do not understand how to get clink to keep a global cmdhistory. Depite installing clink, every time I open a cmd window, I cannot get commands from prior sessions. help> Mar 21, 2022 at 20:50
7

It is possible to save the current history to file,

`$ doskey /history > somefile.txt`

But it seems there is no way to load it back as history. It is possible only to use a command line argument to load and execute all lines,

cmd.exe /K somefile.txt

, what can be useful to load a list of doskey macros. This invocation could be included in a shortcut so you don't need to type it everytime; this reference has some additional info on this approach.

There is a similar question on Superuser that bring some alternatives, including clink, as suggested by @RobertBak.

3
  • Hmm, to load it back into history, wouldn't you simply need to save it to a .bat file and run it?
    – Pacerier
    Aug 23, 2015 at 22:10
  • 1
    @Pacerier running the commands again would surely include them back in the history, but it likely would have large side-effects. Imagine that you delete some files through the shell and then recreate them outside the shell through a long and painful process. Reloading the history through your procedure would unexpectedly delete the files again.
    – mMontu
    Aug 24, 2015 at 11:00
  • @Pacerier you realize "run it" does mean executing all those commands, right? It's not simply loading them into history, but actually letting them have some effects on your system.
    – ADTC
    Jan 7, 2018 at 5:07
3

Yes, it's possible

If all you want to do is save your command line history at the end of every session, here's a simple way to do it:

As other answers indicated, doskey allows you to list the command line history for the current session. It also allows you to create macros.

This simple macro will save the command line history when you exit a CMD session:

doskey exit=(echo/ ^& echo **** %date% %time% ****) $g$g %USERPROFILE%\commands.log ^& doskey /history $g$g %USERPROFILE%\commands.log ^& ECHO Command history saved, exiting ^& exit $*

This creates a macro that remaps the EXIT command to copy the command line history into your user profile folder (e.g., C:\Users\yourname\commands.log). Unfortunately, you won't be able to easily go back to any of these entries by pressing the up arrow, but you can examine the file at any point to see what you did in the past.

Autoloading

So that's the easy part. The tricky part is autoloading that doskey macro when you start a new command session. The short and dangerous answer is to just add it to the REGISTRY in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor\AutoRun. Anything you put in this entry will be run when you start a CMD session.

While that will work, it will definitely create unexpected side effects when doing any kind of scripting*.

So here's how I do it:

Create a file called autoexec.bat and store it in your profile folder (e.g., C:\Users\yourname\autoexec.bat). Then change the value of HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor\AutoRun to this:

IF EXIST "%USERPROFILE%\autoexec.bat" (CALL "%USERPROFILE%\autoexec.bat")

So yes, this batch file will run every time a CMD session is opened, but we'll do a trick to make sure it doesn't run in any subprocesses. Here is what you put in the autoexec.bat file:

@echo off
if "%AUTOEXEC%" EQU "1" goto :eof
SET AUTOEXEC=1
echo Loading macros.

rem  remap exit command to save a copy of the command line history to a log before exiting.
DOSKEY exit=(echo/ ^& echo **** %date% %time% ****) $g$g %USERPROFILE%\commands.log ^& doskey /history $g$g %USERPROFILE%\commands.log ^& ECHO Command history saved, exiting ^& exit $*

How does this avoid those unexpected side effects?

All we're doing is creating an environment variable called AUTOEXEC. Then, when any subsequent subprocesses open a command session, they will run into the second line and immediately exit the script! This is because subprocesses automatically inherit the environment variables from the parent process.

But wait, there's more!

This allows you to add as many macros as you want to your command session. For example:

rem  review previous command line entries:
DOSKEY history=notepad %USERPROFILE%\commands.log

rem  copy the current directory to the clipboard
DOSKEY cc=cd^|clip ^& echo %%CD%% copied to clipboard

rem  etc!

Now you've got all the macros you can eat, and you're saving your command line session each time. But remember, if you don't explicitly type exit, the history won't be saved. Closing the window with the mouse won't work here.

Hope this helps!

* because batch subprocesses often open a second copy of CMD which will run this command again and again, from slowing everything down to other unforseen issues.

2

I propose using Cygwin with Windows Terminal. It may not be exactly what you want but it works quite well for me. It also probably has some issues that I haven't discovered just yet.

You can integrate Cygwin with Windows Terminal and use ZSH shell with it to have a working command history that survives closing the terminal window. You can also reverse search the command history with Ctrl+R. Since you're using ZSH, you can also install useful stuff like Oh My Zsh along with plugins like zsh-autosuggestions and zsh-syntax-highlighting to make life easier.

My setup looks like this:

Cygwin with ZSH

  1. Once you have Cygwin installed to C:/cygwin64/ integrate it with Windows Terminal by editing its settings.json file. To do this, open Windows Terminal and press Ctrl+Shift+, (comma). The file should open in your default text/code editor.

  2. Look for the profiles section and add this to the end of the list array:

{
    "colorScheme": "One Half Dark",
    "commandline": "C:/cygwin64/Cygwin.bat",
    "guid": "{00000000-0000-0000-0000-000000000001}",
    "hidden": false,
    "icon": "C:/cygwin64/Cygwin.ico",
    "name": "Cygwin",
    "tabColor": "#3CB371"
}

The section of the file should look something like this when you're done:

    "profiles": 
    {
        "defaults": {},
        "list": 
        [
            {
                "guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
                "hidden": false,
                "name": "Windows PowerShell"
            },
            {
                "guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
                "hidden": false,
                "name": "Command Prompt"
            },
            {
                "guid": "{b453ae62-4e3d-5e58-b989-0a998ec441b8}",
                "hidden": false,
                "name": "Azure Cloud Shell",
                "source": "Windows.Terminal.Azure"
            },
            {
                "guid": "{f9ceaf27-504c-58d7-927c-d1d6a7ac7d3c}",
                "hidden": false,
                "name": "Ubuntu 22.04.1 LTS",
                "source": "CanonicalGroupLimited.Ubuntu22.04LTS_79rhkp1fndgsc"
            },
            {
                "guid": "{17bf3de4-5353-5709-bcf9-835bd952a95e}",
                "hidden": true,
                "name": "Ubuntu-22.04",
                "source": "Windows.Terminal.Wsl"
            },
            {
                "colorScheme": "One Half Dark",
                "commandline": "C:/cygwin64/Cygwin.bat",
                "guid": "{00000000-0000-0000-0000-000000000001}",
                "hidden": false,
                "icon": "C:/cygwin64/Cygwin.ico",
                "name": "Cygwin",
                "tabColor": "#3CB371"
            }
        ]
    },
  1. Save the file and open Windows Terminal and click on the ˅ button and select Cygwin or press the shortcut key associated with that profile

  2. Open the Cygwin installer and make sure you have the following packages installed: lynx, wget, tar, git, vim

  3. Within the Cygwin terminal, install apt-cyg with

lynx -source rawgit.com/transcode-open/apt-cyg/master/apt-cyg > apt-cyg
install apt-cyg /bin
  1. Now install ZSH
apt-cyg install zsh
  1. If you want, you can install Oh My Zsh along with zsh-autosuggestions and zsh-syntax-highlighting plugins. Make sure you set up your ~/.zshrc file so these plugins are enabled.
git clone https://github.com/ohmyzsh/ohmyzsh.git ~/.oh-my-zsh
cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
  1. The final step is to create a new .bat file that will be called when Cygwin terminal is selected within Windows Terminal. Create a new Cygwin-ZSH.bat file at this location: C:/cygwin64/Cygwin-ZSH.bat and then paste the following into it:
@echo off
setlocal enableextensions
set TERM=
cd /d "%~dp0bin" && .\zsh --login -i
  1. Open Windows Terminal's settings.json file and modify the Cygwin profile entry to use the new Cygwin-ZSH.bat file for the Cygwin terminal (See Step 2)
{
    "colorScheme": "One Half Dark",
    "commandline": "C:/cygwin64/Cygwin-ZSH.bat",
    "guid": "{00000000-0000-0000-0000-000000000001}",
    "hidden": false,
    "icon": "C:/cygwin64/Cygwin.ico",
    "name": "Cygwin",
    "tabColor": "#3CB371"
}
  1. If you want, make Cygwin the default profile to use whenever Windows Terminal is launched. To do this, open Windows Terminal, press Ctrl+, (comma) to open the Settings page and under Default profile, select Cygwin

That's it. You should be able to access the commands you typed previously (after the Cygwin profile was installed and set to default) with the history command now.

The first time I launch a Cygwin terminal, it takes a while to load but any new Terminal windows/tabs launched after that were fast to load.


Many thanks to these articles which is where I found out about this:

  1. https://dev.to/vuong/let-s-add-cygwin-into-windows-terminal-and-customize-it-for-development-looks-1hp8
  2. https://medium.com/@alllexsm/how-to-install-z-shell-zsh-on-cygwin-dd9ee380d783
1

Command History: To enable a command history (that can be accessed using the up and down arrow keys) just execute doskey at the command prompt. For example, to create a command history of 100 elements:

doskey /listsize=100

ref:https://users.cs.jmu.edu/bernstdh/web/common/help/ntshell.php

2
  • 4
    That doesn't answer the question at all??
    – Chopper3
    Feb 14, 2011 at 13:27
  • 1
    Not works on Windows 10. Sep 23, 2016 at 7:27
1

clink is nice and the author publishes a chocolatey package on every release, however I would suggest DeepBlueCLI.

You can use https://github.com/sans-blue-team/DeepBlueCLI to set-up Windows Security Event ID 4688.

For PowerShell, DeepBlueCLI also uses module logging (PowerShell event 4013) and script block logging (4104). It does not use transcription.

The added benefit is that it logs the hash of the command line exe in AppLocker event log. Source: https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/manage/component-updates/command-line-process-auditing

Also, because this solution uses the Windows Event Log infrastructure, you can query it through WMI or PowerShell Get-EventLog. With clink, you have to learn another tool in order to detect system- or network-wide patterns of behavior.

1
  • 1
    event 4688 is the key, and that is the central store how Windows record all executed commands. all other tools is just reading looking for this event. thanks. But by default is it not enable: itprotoday.com/strategy/…
    – Peter Teoh
    May 7, 2019 at 1:13
1

you could also install tabby (https://tabby.sh/). or use (Get-PSReadlineOption).HistorySavePath

0

To save command history:

doskey /history > history.dos

To reference commands:

cls & type history.dos | find /v /n ""

This method won't change the command history of current session

To add the current session command history to the last save file:

doskey /history >> history.dos
-1

Windows 10 now includes alternative and better shells ('terminals' as they call them).

  1. Windows Terminal, i think i installed it via the built in store. Once installed just press start and search for Terminal or do Start>Run>wt. This includes persistent command history.
  2. Ubuntu shell, You can install Windows Subsystem for Linux and Ubuntu, both of these come from the built in store. If you know unix then having access to all the usual bash utilities and syntax is very handy and of course command history is persistent.
4
  • 1
    How do you enable persistent command history in wt? Each time I start a new terminal session it starts with empty history (arror up doesn't yield anything). How to search that history (Ctrl+R doesn't work here)?
    – Stef
    Apr 22, 2021 at 12:52
  • Shells and terminals have nothing to do with each other. Windows terminal is a terminal like xterm, konsole, gnome-terminal... in Linux, or conhost.exe in Windows which is the old terminal. A shell OTOH is a thing that attaches to some terminal to work. PowerShell, cmd, bash, ksh, zsh... are example of shells. Since Windows terminal is a terminal, it obviously can't store the shell's history, so if you use cmd you still won't be able to store any thing
    – phuclv
    Jun 5, 2022 at 14:54
  • @phuclv COMMAND was the default terminal (using CTTY) as well as the default shell. And in Linux, there is still a thing called "Secure Shell", (ssh), which doesn't "attach" to a "terminal." SSH doesn't have a persistent history, but that's not because it's a 'terminal' or a 'shell' -- lots of terminals have persistent history, and lots of shells don't.
    – user165568
    Jul 13, 2022 at 7:58
  • @user165568 how can the terminal have shell command history? It only has scroll back history
    – phuclv
    Jul 13, 2022 at 8:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .