Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I use a bunch of different aix machines at work and need to share users with co-workers.

To make my life easier but not bother others with my customizations, I have created a .bashrc file that I copy to /tmp/matthewh whenever I have to use a new host.

My .bashrc sets a new history file so my personal command history stays isolated from others using the same machine and user.

# History options
export HISTTIMEFORMAT="%F %T "
export HISTCONTROL=ignorespace 
export HISTSIZE=2000
export HISTFILESIZE=2000
export HISTFILE="/tmp/matthewh/$USER.bash_history"

After copying the file over, I connect with ssh user@host -t "bash --rcfile /tmp/matthewh/.bashrc".

This works perfectly. The problem occurs when I switch to another user and source the .bashrc file.

$ su - apache
$ . /tmp/matthewh/.bashrc

The problem is that the initial su - apache loads apache's history from ~/.bash_history and then when I source .bashrc after, it's too late. The history file gets changed correctly but it has already been loaded. I can fix this issue by running history -c && history -r, so all I need to do is put that in the .bashrc too and everything should be fine, right?

Unfortunately, if I put that in my .bashrc file it breaks things when I log in with ssh and the -t "bash --rcfile /tmp/matthewh/.bashrc" option. Since that sources it as a login shell, loading the history is part of the process. This means that the history -r in the .bashrc loads the history a second time and my working history is twice as big as it should be.

Is there a way for .bashrc to detect if it is being sourced manually or from a login shell so it can only clear and reload the history conditionally?

share|improve this question

5 Answers 5

up vote 1 down vote accepted

Instead of clearing and reloading the history in the rc file, defer it until the shell issues the first prompt:

PROMPT_COMMAND='unset PROMPT_COMMAND; test -f $HISTFILE && history -c && history -r $HISTFILE'
share|improve this answer
    
If I did this wouldn't it reload the history file each time I enter a command? If I have two or more terminals open (gnu screen or tmux) this would cause different panes/windows to cross-contaminate history. E.g. in one window I'm making changes to different htaccess files and restarting httpd, in another window I'm doing db2 queries to check things. If I have PROMPT_COMMAND set this way the history for these sessions will get mixed together and make repeated commands less convenient. –  Matthew Aug 13 at 21:10
1  
I think you missed the detail that it begins with unset PROMPT_COMMAND. –  aecolley Aug 13 at 21:27
    
You are correct, this would work. I was worried that the history would not be loaded until a command was entered after logging in or sourcing the .bashrc, but this gets executed immediately when the first prompt is shown. –  Matthew Aug 13 at 21:43

One way is to find whether the SSH variables are set:

SSH_CLIENT='...'
SSH_CONNECTION='...'
SSH_TTY=/dev/pts/1

When you "su -", these will not be set in the new environment. So, you could add something like:

[ -z "$SSH_TTY" ] && history -c && history -r
share|improve this answer
    
This does work for my specific scenario, but will not work when using su without the - or if connecting with ssh but not using the -t "bash --rcfile /path/to/.bashrc" option. I'd like to find a more reliable solution if one exists, like if it's possible to actually find out if .bashrc is being sourced manually or not. –  Matthew Aug 13 at 21:19

One solution is to check if the history file is empty or not:

# If this was sourced manually history will not be empty
currhistsize="`history | wc -l`"
if [[ "${currhistsize// }" != "0" ]]; then
    # Clear the old history, then reload the correct history
    history -c
    history -r
fi

It was necessary to use ${currhistsize// } because it had a bunch of leading whitespace that needed to be removed.

This feels like a workaround and not a real solution though. I'd be very interested in a proper way for checking if the file is being sourced manually or from a shell initialization.

share|improve this answer

Something I just thought of. Never tried it and who knows if there are other repurcussions.

I know this is not a good practice, but who knows it may be perfect for your situation.

You can always create a second user with the same uid. I would normally not recommend this, but I don't ever 100% recommend against anything because it could be the perfect thing for your situation

e.g. if apache is uid:30, gid: 8

Then create a user, maybe matthewapache with uid:30, gid: 8

You should have access identical to apache (in fact if you do "id" command it will say you're apache) but your home dir, history, etc.. are all in /home/matthewapache (or wherever you set your home dir)

Try it out. Log in as apache, run "history". Then log in as matthewapache, run "history".

Ben

share|improve this answer
    
This doesn't answer the question or even address the problem. Maybe you misread the question? –  Matthew Aug 22 at 23:53
    
"My .bashrc sets a new history file so my personal command history stays isolated from others using the same machine and user." - the way I have outlined above will make sure each user login gets its own separate history file, isn't that what you're looking for? The way you are asking now, from what I know, is not possible. Instead of responding to your direct question, I was responding to your original goal since I do not think your direct question is doable. –  ben Sep 6 at 1:22
    
that quoted text is just an explanation of what my .bashrc is doing for background and is not the probelm. My question was about the difference between how histories are set when logging in via ssh vs switching users with su. I don't have an issue setting the history location, it's being set exactly as I want. Read the last sentence in the original question and it very clearly states what I'm asking. The downvotes are because your answers doesn't address the question at all. Your answer states an alternative for something that there is no problem with. –  Matthew Sep 6 at 22:25

Okay here's another idea. Each bash session will have a unique id. Just to be sure you can make a unique timestamp as well. This won't directly solve your problem, and I'm not sure this will work as I'm writing it, but any new shell will create its own history file based on PID and timestamp

You can put in the .bashrc something like

mypid=echo $$
mydatestamp=`date +"%Y%m%d_%H%M%S"`
export HISTFILE="/root/historyfiles/$mypid.$mydatestamp.bash_history"

At least you keep everything separate that way.

Non tested so if you go with this type of idea probably need to tweak it till it works :)

share|improve this answer
    
Again this doesn't answer the question or even address the problem. I have no problem with the history file location, just that it gets loaded automatically at login via ssh and does not when switching users with su - username. –  Matthew Aug 22 at 23:56
    
"My .bashrc sets a new history file so my personal command history stays isolated from others using the same machine and user." - since from what I know what you are directly asking is not doable, I am offering you alternatives to accomplish what you are trying to do. Which is for each user who logs in to have their own separate history file. Too bad you are trying to vote down people who are attempting to help you with ideas because that definitely will discourage me (and maybe others) from trying to help you with ideas in the future. –  ben Sep 6 at 1:23
    
I don't have a problem with the histories being separate, that's working fine. The problem was about how the histories were getting loaded and the difference between logging in with ssh vs switching to the user with su. Read the original question. I don't know what you think you're answering. –  Matthew Sep 6 at 22:28

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.