Help with SSH terminal behavior.
May 30, 2007 12:49 PM   RSS feed for this thread Subscribe

Seeking a better understanding of Linux terminals, mostly being used remotely via SSH. History files, paths, ncurses, etc.

I frequently run into oddities when logged in remotely, but I believe if I understood what was going on, I could fix them. Can you help me understand how these things work, and suggest possible solutions or best-practices?

I use SSH and log in as both root and regular users on various systems. Sometimes I directly log in as root, other times I use su. Why is my PATH not properly set to include various *sbin* directories when I su to root, but it is when I log in directly as root?

Why do ncurses programs look fine when logged in locally, but are full of strange characters when done through SSH? Specifically, I'm talking about ntsysv.

Finally, and most frustratingly, please help me understand history files. When I log in multiple times to the same machine, at the same time, which history file goes with which window? Where are they stored? For example: I log in and execute screen, then run some commands. If I exit screen, the history command doesn't show the commands from the screen session, but rather those I executed immediately before entering screen. Is it possible to consolidate the command history so that it's universal across sessions and screens?
posted by odinsdream to computers & internet (11 comments total) 3 users marked this as a favorite
regarding su, you need to execute su - (hyphen) to assume root's (or the user you su to) path.
posted by xmutex at 12:53 PM on May 30, 2007 [1 favorite]


Guessing you're using Bash, which is the norm for most Linux distros, the Bash manual explains:
When the shell starts up, the history is initialized from the file named by the HISTFILE variable (default `~/.bash_history'). The file named by the value of HISTFILE is truncated, if necessary, to contain no more than the number of lines specified by the value of the HISTFILESIZE variable. When an interactive shell exits, the last $HISTSIZE lines are copied from the history list to the file named by $HISTFILE. If the histappend shell option is set (see section 4.2 Bash Builtin Commands), the lines are appended to the history file, otherwise the history file is overwritten. If HISTFILE is unset, or if the history file is unwritable, the history is not saved. After saving the history, the history file is truncated to contain no more than $HISTFILESIZE lines. If HISTFILESIZE is not set, no truncation is performed.
So, depending on settings, each shell's history is written to .bash_history, but only on exit.
posted by Zed_Lopez at 1:07 PM on May 30, 2007


re: ncurses. Probably has to do with the terminal settings. Try this: while logged in locally, do echo $TERM. Do the same while SSHing in. I'd bet they're different.

What terminal program (if any) are you using to connect to the remote machine? Terminal or iTerm on OSX, xterm or rxvt (if XWindows) on a *nix box, PuTTY or cygwin on a Windows machine? See if you can tell from their settings what TERM they're expecting/using remotely.
posted by unixrat at 1:42 PM on May 30, 2007


Also re: the su - thing. Adding a - after any su command su someuser - emulates a full login rather than just a switch of user IDs. This may or may not be wanted when switching user->user, but is often wanted when switching user->root.

Also, the more secure (read: paranoid) administrators disable remote root logins and force users to operate strictly via su - and sudo as a safety measure. YMMV.
posted by unixrat at 1:46 PM on May 30, 2007


I have these tidbits in my .bashrc1:

HOSTNAME="$(hostname)"
HOSTNAME_SHORT="${HOSTNAME%%.*}"

HISTFILE="${HOME}/.history/$(date -u +%Y-%m-%d.%H.%M.%S)_${HOSTNAME_SHORT}_$$"
HISTSIZE=65535
HISTFILESIZE=65535
HISTCONTROL=ignoredups

ARCH=$(uname)
case $ARCH in
  Linux* | CYGWIN*)
    histgrep ()
    {
     grep -r "$@" ~/.history
     history | grep "$@"
    }
    ;;
  *)
    histgrep ()
    {
     find ~/.history -print0 | xargs -0 --max-args=200 grep "$@"
     history | grep "$@"
    }
    ;;
esac


This makes a new history file in the ~/.history directory (I think must be created first: mkdir ~/.history) for each bash session I start, which starts with the date and time, the short name of the host I'm running on (e.g. metatalk instead of metatalk.metafilter.com), and the process identifier. This means that each of these filenames will be unique, even if you are using a filesystem shared by multiple hosts.

histgrep greps through the old history files and the current shell. The only thing it can't do is grep other currently running shells' histories.

It is vastly useful to be able to reproduce that long pipeline I wrote on the shell months ago or to figure out how a datafile is produced, when I forgot to specially note it somewhere.

1 Actually some of them are not in my bashrc but in a master script file that I "compile" with a Python script to save time starting up on various hosts.
posted by grouse at 2:20 PM on May 30, 2007 [1 favorite]


Oh yeah, the case $ARCH stuff is because I run the same .bashrc and script file on multiple platforms, some of which don't support grep -r, so I have to simulate it.
posted by grouse at 2:22 PM on May 30, 2007


History: Executed commands don't go to the history file immediatly. The bash history is kept in the computers memory as long as the bash process remains. When you close one the bashs, it's written to disk.
I don't think you can share the history over multiple bash processes easily.
posted by donut at 2:34 PM on May 30, 2007


If you put HISTFILESIZE=10000 in your .bashrc, you'll keep a lot more lines of history (the default is 500).

When you close a bash session, that session's history is appended to the history file. So if your history file is nice and big, everything will turn up in there eventually.
posted by flabdablet at 5:57 PM on May 30, 2007


If you put HISTFILESIZE=10000 in your .bashrc, you'll keep a lot more lines of history (the default is 500).

Unless you set HISTSIZE as well, you'll only get 500 from a single session.

When you close a bash session, that session's history is appended to the history file.

Only if histappend is set.
posted by grouse at 6:07 PM on May 30, 2007


An excellent basic bash tweaking guide includes a simple explanation of why history operates in its current manner and instructions on how to make it better.

I would not suggest using a truly universal history. Redoing the last command in a given shell is made much more complicated when its loading history from every shell.

I use zsh now, with the same history configuration, along with an alias that explicitly pulls all history into the current shell, for when I really need it.

And just for the record, the arrow keys doing an incremental history search is pure gold!
posted by easyasy3k at 10:39 PM on May 30, 2007 [2 favorites]


easyasy3k, how do you enable this configuration in zsh?
posted by donut at 3:30 AM on June 2, 2007


« Older I am going to be buying/buildi...   |   I have some AirTrans passes wh... Newer »
This thread is closed to new comments.


Related Questions
OSX: Future as a programmer dashed by failure to... August 20, 2008
How to split a file by blank lines? April 17, 2008
Can terminal windows be modernized? February 7, 2008
Bash, I command thee to always... October 22, 2007
How do I reset the settings on Terminal for OS X? March 15, 2006