일관되게 둘 이상의 터미널이 열려 있습니다. 다양한 비트와 밥을하는 2에서 10 사이. 이제 다시 시작하고 다른 터미널 세트를 연다 고 가정 해 봅시다. 어떤 사람들은 특정한 것을 기억하고 어떤 사람들은 잊어 버립니다.
나는 다음과 같은 역사를 원한다.
ls
, 이미 실행중인 다른 터미널로 전환 한 다음 위로 누르면 ls
이 표시됨)배쉬가 그렇게 작동하도록 할 수있는 일이 있습니까?
~/.bashrc에 다음을 추가하십시오
# Avoid duplicates
HISTCONTROL=ignoredups:erasedups
# When the Shell exits, append to the history file instead of overwriting it
shopt -s histappend
# After each command, append to the history file and reread it
Prompt_COMMAND="${Prompt_COMMAND:+$Prompt_COMMAND$'\n'}history -a; history -c; history -r"
그래서 이것은 내 모든 역사 관련 .bashrc
것입니다.
export HISTCONTROL=ignoredups:erasedups # no duplicate entries
export HISTSIZE=100000 # big big history
export HISTFILESIZE=100000 # big big history
shopt -s histappend # append to history, don't overwrite it
# Save and reload the history after each command finishes
export Prompt_COMMAND="history -a; history -c; history -r; $Prompt_COMMAND"
Mac OS X 10.5의 bash 3.2.17, 10.6의 bash 4.1.7로 테스트되었습니다.
Bash 세션 히스토리 공유에 대한 나의 시도는 다음과 같습니다. 이를 통해 히스토리 카운터가 섞이지 않고 !number
와 같은 히스토리 확장이 작동하는 방식으로 bash 세션간에 히스토리 공유가 가능합니다 (일부 제한 사항이 있음).
Ubuntu 10.04 LTS (Lucid Lynx)에서 Bash 버전 4.1.5 사용.
HISTSIZE=9000
HISTFILESIZE=$HISTSIZE
HISTCONTROL=ignorespace:ignoredups
_bash_history_sync() {
builtin history -a #1
HISTFILESIZE=$HISTSIZE #2
builtin history -c #3
builtin history -r #4
}
history() { #5
_bash_history_sync
builtin history "[email protected]"
}
Prompt_COMMAND=_bash_history_sync
방금 입력 한 줄을 $HISTFILE
에 추가하십시오 (기본값은 .bash_history
). 이로 인해 $HISTFILE
가 한 줄씩 증가합니다.
특수 변수 $HISTFILESIZE
를 특정 값으로 설정하면 가장 오래된 항목을 제거하여 Bash가 $HISTFILE
줄을 $HISTFILESIZE
줄보다 길지 않게됩니다.
실행중인 세션 기록을 지우십시오. 이것은 $HISTSIZE
만큼 이력 카운터를 줄입니다.
$HISTFILE
의 내용을 읽고 현재 실행중인 세션 기록에 삽입하십시오. $HISTFILE
의 행 수만큼 히스토리 카운터가 증가합니다. $HISTFILE
의 줄 수는 반드시 $HISTFILESIZE
일 필요는 없습니다.
history()
함수는 내장 히스토리를 대체하여 히스토리가 표시되기 전에 동기화되었는지 확인합니다. 이것은 숫자로 히스토리 확장에 필요합니다 (자세한 내용은 나중에 참조).
1 단계는 현재 실행중인 세션의 명령이 글로벌 히스토리 파일에 기록되도록합니다.
4 단계는 다른 세션의 명령이 현재 세션 히스토리로 읽히도록합니다.
4 단계는 기록 카운터를 높이기 때문에 어떤 방식 으로든 카운터를 줄여야합니다. 이것은 3 단계에서 수행됩니다.
3 단계에서 히스토리 카운터는 $HISTSIZE
만큼 줄어 듭니다. 4 단계에서 히스토리 카운터는 $HISTFILE
의 행 수만큼 증가합니다. 2 단계에서 $HISTFILE
의 행 수가 정확히 $HISTSIZE
인지 확인합니다 (이는 $HISTFILESIZE
가 $HISTSIZE
와 같아야 함을 의미합니다).
숫자로 히스토리 확장을 사용하는 경우 always 사용하기 전에 즉시 숫자를 찾아야합니다. 즉, 번호 조회와 사용 사이에 bash 프롬프트가 표시되지 않습니다. 그것은 일반적으로 enter와 ctrl + c가 없음을 의미합니다.
일반적으로 Bash 세션이 둘 이상 있으면 번호 별 히스토리 확장이 두 개의 Bash Prompt 디스플레이간에 값을 유지한다는 보장은 없습니다. Prompt_COMMAND
가 실행될 때 다른 모든 Bash 세션의 기록이 현재 세션의 기록에 통합되기 때문입니다. 다른 bash 세션에 새 명령이 있으면 현재 세션의 기록 번호가 달라집니다.
나는이 제약이 합리적이라고 생각한다. 임의의 이력 번호를 기억할 수 없으므로 어쨌든 매번 번호를 찾아야합니다.
일반적으로 이처럼 숫자로 기록 확장을 사용합니다
$ history | grep something #note number
$ !number
다음 Bash 옵션을 사용하는 것이 좋습니다.
## reedit a history substitution line if it failed
shopt -s histreedit
## edit a recalled history line before executing
shopt -s histverify
히스토리 명령을 파이프로 실행하면 해당 명령이 히스토리에 두 번 나열됩니다. 예를 들면 다음과 같습니다.
$ history | head
$ history | tail
$ history | grep foo
$ history | true
$ history | false
모든 기록에 두 번 나열됩니다. 왜 그런지 모르겠습니다.
_bash_history_sync()
함수가 매번 실행되지 않도록 수정하십시오. 예를 들어 프롬프트에서 CTRL+C
다음에 실행하면 안됩니다. 나는 종종 그 줄을 실행하고 싶지 않다고 결정할 때 긴 명령 줄을 폐기하기 위해 CTRL+C
를 사용합니다. 때로는 Bash 완료 스크립트를 중지하기 위해 CTRL+C
를 사용해야합니다.
현재 세션의 명령은 항상 현재 세션 기록에서 가장 최신이어야합니다. 이것은 또한 주어진 이력 번호가이 세션의 이력 항목 값을 유지한다는 부작용이 있습니다.
bash
를 사용하는 방법을 모르겠습니다. 그러나 zsh
의 가장 인기있는 기능 중 하나입니다.
개인적으로 zsh
보다 bash
를 선호하므로 시도해 보는 것이 좋습니다.
역사를 다루는 .zshrc
부분은 다음과 같습니다.
SAVEHIST=10000 # Number of entries
HISTSIZE=10000
HISTFILE=~/.zsh/history # File
setopt APPEND_HISTORY # Don't erase history
setopt EXTENDED_HISTORY # Add additional data to history like timestamp
setopt INC_APPEND_HISTORY # Add immediately
setopt HIST_FIND_NO_DUPS # Don't show duplicates in search
setopt HIST_IGNORE_SPACE # Don't preserve spaces. You may want to turn it off
setopt NO_HIST_BEEP # Don't beep
setopt SHARE_HISTORY # Share history between session/terminals
이렇게하려면 ~/.bashrc
에 두 줄을 추가해야합니다.
shopt -s histappend
Prompt_COMMAND="history -a;history -c;history -r;$Prompt_COMMAND"
man bash
에서 :
Histappend Shell 옵션이 활성화 된 경우 (아래의 Shell BUILTIN COMMANDS 아래에서 shopt 설명 참조) 행이 내역 파일에 추가되고, 그렇지 않으면 내역 파일을 덮어 씁니다.
Muerr가 제안한 "history -a"및 "history -r"을 실행하도록 BASH 프롬프트를 편집 할 수 있습니다.
savePS1=$PS1
(당신이 무언가를 엉망으로 만드는 경우가 거의 보장됩니다)
PS1=$savePS1`history -a;history -r`
(이것은 백틱입니다. 모든 프롬프트에서 history -a 및 history -r을 실행합니다. 텍스트가 출력되지 않으므로 프롬프트가 변경되지 않습니다.
PS1 변수를 원하는 방식으로 설정했으면 ~/.bashrc 파일에 영구적으로 설정하십시오.
테스트하는 동안 원래 프롬프트로 돌아가려면 다음을 수행하십시오.
PS1=$savePS1
나는 이것에 대해 기본적인 테스트를 수행하여 일종의 작동하는지 확인했지만 모든 프롬프트에서 history -a;history -r
를 실행하는 부작용에 대해서는 말할 수 없습니다.
아래 문제를 해결하는 bash 또는 zsh 기록 동기화 솔루션이 필요한 경우 http://ptspts.blogspot.com/2011/03/how-to-automatically-synchronize-Shell.html에서 참조하십시오.
문제는 다음과 같습니다. 두 개의 셸 창 A와 B가 있습니다. 셸 창 A에서 sleep 9999
를 실행하고 셸 창 B에서 절전 모드가 완료 될 때까지 기다리지 않고 bash 기록에서 sleep 9999
를 참조하십시오.
여기에서 대부분의 다른 솔루션이이 문제를 해결하지 못하는 이유는 Prompt_COMMAND
또는 PS1
를 사용하여 기록 변경 내용을 기록 파일에 기록하고 있기 때문에 둘 다 너무 늦게 실행되고 있기 때문입니다. sleep 9999
명령이 완료된 후.
맞아, 결국 이것은 괜찮은 해결책을 찾기 위해 짜증을 냈습니다.
# Write history after each command
_bash_history_append() {
builtin history -a
}
Prompt_COMMAND="_bash_history_append; $Prompt_COMMAND"
이것이하는 일은이 스레드에서 말한 것에 대한 일종의 융합입니다. 단, 모든 명령 후에 왜 세계 역사를 다시로드 할 것인지 이해할 수 없습니다. 다른 터미널에서 일어나는 일에 대해서는 거의 신경 쓰지 않지만 항상 한 터미널에서 일련의 명령을 실행합니다.
make
ls -lh target/*.foo
scp target/artifact.foo vm:~/
(간단한 예)
그리고 또 다른 :
pv ~/test.data | nc vm:5000 >> output
less output
mv output output.backup1
어떤 방법으로도 명령을 공유하고 싶지 않습니다.
당신이 사용할 수있는 history -a
현재 세션 기록을 histfile에 추가 한 다음 history -r
다른 터미널에서 histfile을 읽으십시오.
내가 사용하는 대안이 있습니다. 번거롭지 만 때로는 @axel_c가 각 터미널에 별도의 기록 인스턴스를 만들고 싶을 수도있는 문제를 해결합니다 (하나는 모니터링, 하나는 vim 등).
지속적으로 업데이트하는 별도의 추가 기록 파일을 보관합니다. 다음은 핫키에 매핑되었습니다.
history | grep -v history >> ~/master_history.txt
이것은 현재 터미널의 모든 히스토리를 홈 디렉토리의 master_history.txt 파일에 추가합니다.
마스터 히스토리 파일을 검색하는 별도의 단축키가 있습니다.
cat /home/toby/master_history.txt | grep -i
나는 고양이를 사용한다 | grep은 정규식에 들어가기 위해 커서를 끝에 둡니다. 덜 추한 방법은이 작업을 수행하기 위해 경로에 몇 가지 스크립트를 추가하는 것이지만 단축키는 내 목적으로 작동합니다. 또한 정기적으로 작업 한 다른 호스트에서 내역을 가져 와서 해당 내역을 master_history.txt 파일에 추가합니다.
사용했던 까다로운 정규 표현식이나 7 개월 전에 생각해 낸 이상한 Perl one-liner를 빠르게 검색하고 찾을 수 있다는 것은 항상 좋은 일입니다.
마지막 수정 사항을 제공 할 수 있습니다. env 변수 HISTCONTROL이 "ignorespace"(또는 "ignoreboth")를 지정하지 않았는지 확인하십시오.
그러나 여러 동시 세션으로 고통을 느낍니다. bash에서는 단순히 잘 처리되지 않습니다.
@lesmana의 answer 에 대한 개선 사항은 다음과 같습니다. 가장 큰 차이점은 동시 창은 기록을 공유하지 않는다는 것입니다. 즉, 다른 윈도우의 컨텍스트를 현재 윈도우에로드하지 않고도 윈도우에서 계속 작업 할 수 있습니다.
'history'를 명시 적으로 입력하면 OR 새 창을 열면 이전의 모든 창에서 이력을 얻습니다.
또한 이 전략 을 사용하여 컴퓨터에 입력 한 모든 명령을 보관합니다.
# Consistent and forever bash history
HISTSIZE=100000
HISTFILESIZE=$HISTSIZE
HISTCONTROL=ignorespace:ignoredups
_bash_history_sync() {
builtin history -a #1
HISTFILESIZE=$HISTSIZE #2
}
_bash_history_sync_and_reload() {
builtin history -a #1
HISTFILESIZE=$HISTSIZE #2
builtin history -c #3
builtin history -r #4
}
history() { #5
_bash_history_sync_and_reload
builtin history "[email protected]"
}
export HISTTIMEFORMAT="%y/%m/%d %H:%M:%S "
Prompt_COMMAND='history 1 >> ${HOME}/.bash_eternal_history'
Prompt_COMMAND=_bash_history_sync;$Prompt_COMMAND
여러 사람이 동일한 서버에서 작업 할 수 있으므로 기록을 tty 당 파일에 넣기로 결정했습니다. 각 세션의 명령을 분리하면 감사하기가 더 쉽습니다.
# Convert /dev/nnn/X or /dev/nnnX to "nnnX"
HISTSUFFIX=`tty | sed 's/\///g;s/^dev//g'`
# History file is now .bash_history_pts0
HISTFILE=".bash_history_$HISTSUFFIX"
HISTTIMEFORMAT="%y-%m-%d %H:%M:%S "
HISTCONTROL=ignoredups:ignorespace
shopt -s histappend
HISTSIZE=1000
HISTFILESIZE=5000
역사는 이제 다음과 같습니다 :
[email protected]:~# test 123
[email protected]:~# test 5451
[email protected]:~# history
1 15-08-11 10:09:58 test 123
2 15-08-11 10:10:00 test 5451
3 15-08-11 10:10:02 history
파일은 다음과 같습니다.
[email protected]:~# ls -la .bash*
-rw------- 1 root root 4275 Aug 11 09:42 .bash_history_pts0
-rw------- 1 root root 75 Aug 11 09:49 .bash_history_pts1
-rw-r--r-- 1 root root 3120 Aug 11 10:09 .bashrc
여기서 나는 하나의 문제를 지적 할 것이다.
export Prompt_COMMAND="${Prompt_COMMAND:+$Prompt_COMMAND$'\n'}history -a; history -c; history -r"
과
Prompt_COMMAND="$Prompt_COMMAND;history -a; history -n"
Source ~/.bashrc를 실행하면 $ Prompt_COMMAND는 다음과 같습니다.
"history -a; history -c; history -r history -a; history -c; history -r"
과
"history -a; history -n history -a; history -n"
이 반복은 'source ~/.bashrc'를 실행할 때마다 발생합니다. 'echo $ Prompt_COMMAND'를 실행하여 'source ~/.bashrc'를 실행할 때마다 Prompt_COMMAND를 확인할 수 있습니다.
"history -n history -a"와 같은 일부 명령이 깨져있는 것을 볼 수 있습니다. 그러나 좋은 소식은 다른 부분은 여전히 유효한 명령 시퀀스를 형성하기 때문에 여전히 작동한다는 것입니다.
개인적으로 나는 다음과 같은 간단한 버전을 사용합니다.
shopt -s histappend
Prompt_COMMAND="history -a; history -c; history -r"
위에 언급 된 것과 같은 문제는 없지만 대부분의 기능을 가지고 있습니다.
또 다른 요점은 다음과 같습니다. 정말 마법이 없습니다 . Prompt_COMMAND는 단순한 bash 환경 변수입니다. 이 명령은 bash Prompt ($ 기호)를 받기 전에 실행됩니다. 예를 들어, Prompt_COMMAND는 "echo 123"이고 터미널에서 "ls"를 실행합니다. 효과는 "ls; echo 123"을 실행하는 것과 같습니다.
$ Prompt_COMMAND="echo 123"
출력 ( 'Prompt_COMMAND = "echo 123"; $ Prompt_COMMAND'실행과 동일) :
123
다음을 실행하십시오.
$ echo 3
산출:
3
123
"history -a"는 메모리의 히스토리 명령을 ~/.bash_history에 쓰는 데 사용됩니다.
"history -c"는 메모리에서 히스토리 명령을 지우는 데 사용됩니다.
"history -r"은 ~/.bash_history에서 메모리로 기록 명령을 읽는 데 사용됩니다.
역사 명령 설명을 참조하십시오 : http://ss64.com/bash/history.html
추신 : 다른 사용자가 지적했듯이 export 는 불필요합니다. 참조 : . bashrc에서 내보내기 사용
세션 또는 작업별로 내역 파일을 설정하는 스크립트를 작성하여 다음을 기반으로합니다.
# write existing history to the old file
history -a
# set new historyfile
export HISTFILE="$1"
export HISET=$1
# touch the new file to make sure it exists
touch $HISTFILE
# load new history file
history -r $HISTFILE
모든 기록 명령을 저장할 필요는 없지만 내가 관심있는 명령을 저장하고 검색하기가 더 쉬워 모든 명령을 통과합니다. 내 버전에는 모든 기록 파일이 나열되어 있으며 모든 기록 파일을 검색하는 기능이 있습니다.
전체 소스 : https://github.com/simotek/scripts-config/blob/master/hiset.sh
다음은 does n't 개별 세션에서 기록을 혼합하는 솔루션입니다!
기본적으로 각 세션의 기록을 개별적으로 저장하고 모든 프롬프트에서 다시 만들어야합니다. 예, 더 많은 리소스를 사용하지만 들리는 것처럼 느리지는 않습니다. 기록이 10 만 개가 넘는 경우에만 지연이 눈에 띄기 시작합니다.
핵심 논리는 다음과 같습니다.
# on every Prompt, save new history to dedicated file and recreate full history
# by reading all files, always keeping history from current session on top.
update_history () {
history -a ${HISTFILE}.$$
history -c
history -r
for f in `ls ${HISTFILE}.[0-9]* | grep -v "${HISTFILE}.$$\$"`; do
history -r $f
done
history -r "${HISTFILE}.$$"
}
export Prompt_COMMAND='update_history'
# merge session history into main history file on bash exit
merge_session_history () {
cat ${HISTFILE}.$$ >> $HISTFILE
rm ${HISTFILE}.$$
}
trap merge_session_history EXIT
일부 보호 및 성능 최적화를 포함한 전체 솔루션은 this Gist 를 참조하십시오.
사용자 정의 파일에 저장된 무한 히스토리를 선호하기 때문입니다. https://stackoverflow.com/a/19533853/4632019 을 기반으로이 구성을 만듭니다.
export HISTFILESIZE=
export HISTSIZE=
export HISTTIMEFORMAT="[%F %T] "
export HISTFILE=~/.bash_myhistory
Prompt_COMMAND="history -a; history -r; $Prompt_COMMAND"
이것은 ZSH에서 작동합니다.
##############################################################################
# History Configuration for ZSH
##############################################################################
HISTSIZE=10000 #How many lines of history to keep in memory
HISTFILE=~/.zsh_history #Where to save history to disk
SAVEHIST=10000 #Number of history entries to save to disk
#HISTDUP=erase #Erase duplicates in the history file
setopt appendhistory #Append history to the history file (no overwriting)
setopt sharehistory #Share history across terminals
setopt incappendhistory #Immediately append to the history file, not just when a term is killed
나는 이것을 오랫동안 원했다. 특히 새 프로젝트에서 다시 실행하기 위해 명령이 실행되는 곳에서 명령을 검색하거나 명령으로 디렉토리를 찾는 기능을 원했다. 따라서 this tool 을 함께 사용하면 전역 CLI 기록을 저장하기위한 이전 솔루션과 percol (C ^ R로 매핑 됨)이라는 대화식 grepping 도구를 결합합니다. 사용하기 시작한 첫 번째 머신에서 여전히 매끄러운 상태입니다. 이제 2 년 이상 된 CLI 내역이 있습니다.
화살표 키에 관한 한 로컬 CLI 기록을 엉망으로 만들지 않지만 전역 기록에 매우 쉽게 액세스 할 수 있습니다 (C ^ R 이외의 다른 것에 매핑 할 수도 있음)
다음은 내 .bashrc의 스 니펫과 필요한 경우 간단한 설명입니다.
# The following line ensures that history logs screen commands as well
shopt -s histappend
# This line makes the history file to be rewritten and reread at each bash Prompt
PROMPT_COMMAND="$Prompt_COMMAND;history -a; history -n"
# Have lots of history
HISTSIZE=100000 # remember the last 100000 commands
HISTFILESIZE=100000 # start truncating commands after 100000 lines
HISTCONTROL=ignoreboth # ignoreboth is shorthand for ignorespace and ignoredups
HISTFILESIZE 및 HISTSIZE는 개인 취향이며 취향에 따라 변경할 수 있습니다.