История в bashrc при входе в систему против ручного поиска — очистка и загрузка

История в bashrc при входе в систему против ручного поиска — очистка и загрузка

На работе я использую несколько разных устройств AIX и мне нужно делиться пользователями с коллегами.

Чтобы облегчить себе жизнь и не беспокоить других своими настройками, я создал файл .bashrc, который копирую в /tmp/matthewh всякий раз, когда мне приходится использовать новый хост.

Мой .bashrc создает новый файл истории, поэтому моя личная история команд остается изолированной от других, использующих ту же машину и пользователя.

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

После копирования файла я подключаюсь с помощью ssh user@host -t "bash --rcfile /tmp/matthewh/.bashrc".

Это работает отлично. Проблема возникает, когда я переключаюсь на другого пользователя и получаю файл .bashrc.

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

Проблема в том, что изначально su - apacheзагружается история apache из ~/.bash_history, а затем, когда я загружаю .bashrc, уже слишком поздно. Файл истории изменяется правильно, но он уже загружен. Я могу исправить эту проблему, запустив history -c && history -r, так что все, что мне нужно сделать, это поместить его в .bashrc, и все должно быть в порядке, верно?

К сожалению, если я помещу это в свой файл .bashrc, это сломает все, когда я войду в систему с помощью опции sshи -t "bash --rcfile /tmp/matthewh/.bashrc". Поскольку это использует его как оболочку входа, загрузка истории является частью процесса. Это означает, что в history -r.bashrc загружает историю во второй раз, и моя рабочая история становится вдвое больше, чем должна быть.

Есть ли способ, позволяющий .bashrc определить, загружается ли он вручную или из оболочки входа, чтобы он мог очищать и перезагружать историю только в зависимости от условий?

решение1

Вместо того чтобы очищать и перезагружать историю в rc-файле, отложите это до тех пор, пока оболочка не выдаст первое приглашение:

PROMPT_COMMAND='unset PROMPT_COMMAND; test -f $HISTFILE && history -c && history -r $HISTFILE'

решение2

Один из способов — узнать, установлены ли переменные SSH:

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

Когда вы "su -", они не будут установлены в новой среде. Поэтому вы можете добавить что-то вроде:

[ -z "$SSH_TTY" ] && history -c && history -r

решение3

Одним из решений является проверка того, пуст ли файл истории:

# 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

Было необходимо использовать ${curristicsize// }, поскольку в нем было много начальных пробелов, которые нужно было удалить.

Это похоже на обходной путь, а не на настоящее решение. Мне бы очень хотелось узнать правильный способ проверки, был ли файл получен вручную или из инициализации оболочки.

решение4

Хорошо, вот еще одна идея. Каждая сессия bash будет иметь уникальный идентификатор. Просто чтобы быть уверенным, вы можете сделать также уникальную временную метку. Это не решит вашу проблему напрямую, и я не уверен, что это будет работать, пока я это пишу, но любая новая оболочка создаст свой собственный файл истории на основе PID и временной метки

Вы можете поместить в .bashrc что-то вроде

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

По крайней мере, так вы все будете хранить отдельно.

Не тестировалось, так что если вы решитесь на такую ​​идею, вероятно, придется ее дорабатывать, пока она не заработает :)

Связанный контент