## 30.12. Picking Up Where You Left Off

If you want your command history to be remembered even when you log out, set the C shell's savehist shell variable (Section 35.9) to the number of lines of history you want saved. Other shells save history automatically; you don't need to set a variable. (If you want to change the number of lines saved by bash, set its HISTFILESIZE environment variable. In zsh, the variable is SAVEHIST. In ksh, the HISTSIZE variable sets the number of commands available to be recalled in your current shell as well the number saved for other shells.)

When you log out, the specified number of lines from the csh history list will be saved in a file called .history in your home directory. zsh, bash and ksh use the filename given in the HISTFILE environment variable. By default, bash calls the file .bash_history, and the original ksh uses .sh_history -- but note that the new pdksh and zsh don't save history unless you set HISTFILE to a filename. For zsh, I chose $HOME/.zsh_history, but you can use anything you want.

On modern windowing systems, this isn't as trivial as it sounds. On an old-style terminal, people usually started only one main shell, so they could set the history-saving variable in their .login or .profile file and have it apply to their login shell.

However, under window systems like X or networked filesystems that share your home directory between several hosts, or on networked servers to which you might login via ssh, you may have multiple shells saving into the same history file. Linux systems with multiple virtual consoles (Section 23.12) logged on as the same user will have the same problem. The shells might be overwriting instead of appending, or appending instead of overwriting, or jumbling commands together when you want them separated. The sections below give some possible fixes.

### 30.12.1. bash, ksh, zsh

Here's the basic way to give a separate history file to each bash, zsh, or ksh shell: customize your setup file (Section 3.3) to set a different HISTFILE on each host or each window. Use names like $HOME/.sh_history.window `n` or ~/.bash_history.`hostname` to match each file to its window or host. If your setup is always the same each time you log in, that should give each window and/or host the same history it had on the last invocation. (There are related tips in Section 3.18 and a series starting at Section 3.10.)

If you open random windows, though, you'll have a harder time automatically matching a history file to a shell the next time you log in. Cook up your own scheme.

The simplest fix is to use $$ (Section 27.17) -- which will probably expand differently in almost every shell you ever start -- as a unique part of the filename. Here are two possibilities:

>     HISTFILE=/tmp/sh_hist.$$
>     HISTFILE=$HOME/.sh_hist.$$

The first example uses the system's temporary-file directory. If your system's /tmp is cleaned out often, you may be able to leave your history files there and let the system remove them; ask the administrator. Note that the history file may be world-readable (Section 50.2) if your umask isn't set to protect your files. If that matters to you, you could make the temporary files in your home directory (or some protected directory), as in the second example shown earlier. Alternately, at the end of each session, you might want to run a command that appends your shell's history file to a global history file that you then read in at startup of a new session (see below).

Two more bits of trivia:

- The original Korn shell maintains the history file constantly, adding a new line to it as soon as you run a command. This means you share history between all your current shells with the same HISTFILE name, which can be a benefit or a problem.

- In most other shells, each shell process keeps its own history list in memory. History isn't written to the history file (named by the HISTFILE variable in each shell) until the shell exits.

  In bash, you can force a write with the command history -w. In the same way, if you have an existing history file (or, actually, any file full of command lines), you can read it into your current bash with history -r. Section 30.13 has another example. Each shell has its own way to do this, so check your manual page carefully and experiment to get it right.

### 30.12.2. C Shells

In tcsh, you can set a history file name in the histfile variable; the default filename is .history in your home directory. To avoid conflicts between multiple saved tcsh histories, use a system like the one described earlier for Bourne shells.

The original C shell has only one possible filename for its automatic history file: .history. If you set the C shell variable savehist in each of your windows (e.g., by setting it in your .cshrc or .tcshrc), they will all try to write .history at once, leading to trouble. And even if that weren't true, you get the history from every window or host, which might not be what you want.

Of course, you could set savehist manually in a single window when you thought you were doing work you might want to pick up later. But there is another way: use the C shell's command history -h (which prints the history list without leading numbers, so it can be read back in later) and redirect the output to a file. Then use source -h to read it back into your history list when you log in.

Do you want to automate this? First, you'll need to choose a system of filenames, like ~/.history.window `n` or ~/.history.`hostname`, to match each file to its window or host. If each of your C shells is a login shell (Section 3.4),[95] you can run history -h from your .logout file and source -h from your .login file. For nonlogin shells, automation is tougher -- try this:

> [95]xterm -ls (Section 5.10 runs a login shell in your xterm window.

- Set the ignoreeof variable to force you to leave the shell with an exit (Section 24.4) command.

- Set an alias for exit (Section 29.8) that runs history -h before exiting.

- Run source -h from your .cshrc or .tcshrc file. Use a `$?prompt` test to be sure this runs only in interactive shells.

If you choose to run history -h and source -h by hand occasionally, they will allow you the kind of control you need to write a script (Section 30.13) that saves and restores only what you want.

--JP, TOR, and SJC

Copyright © 2003 O'Reilly & Associates. All rights reserved.