배쉬 히스토리 : “무시 된”및 “삭제 된”설정은 세션 간 공통 히스토리와 충돌합니다.

우선, 이것은 SE의 기존 스레드와 중복되지 않습니다. 더 나은 bash 기록 에서이 두 스레드 ( 1 , 2 )를 읽었 지만 답변이 없습니다.-Fedora 15에 있습니다.

.bashrc사용자 디렉토리 (/ home / aahan /) 의 파일에 다음을 추가 했는데 작동하지 않습니다. 누구나 실마리가 있습니까?

HISTCONTROL=ignoredups:erasedups  # no duplicate entries
HISTSIZE=1000                     # custom history size
HISTFILESIZE=100000                 # custom history file size
shopt -s histappend                      # append to history, don't overwrite it
PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"  # Save and reload the history after each command finishes

좋아 이것은 bash 기록 (우선 순위)으로 원하는 것입니다.

  • 사본을 저장하지 않고 기존 사본을 지우십시오.
  • 열려있는 모든 터미널과 즉시 내역 공유
  • 덮어 쓰지 말고 항상 기록을 추가하십시오.
  • 여러 줄 명령을 단일 명령으로 저장 (기본적으로 꺼져 있음)
  • 기본 기록 크기와 기록 파일 크기는 얼마입니까?


답변

이것은 실제로 매우 흥미로운 행동이며 처음에 질문을 크게 과소 평가했다고 고백합니다. 그러나 먼저 사실 :

1. 작동하는 것

기능은 몇 가지 방식으로 달성 될 수 있지만 각각 다르게 작동합니다. 각각의 경우에, 이력이 다른 터미널 (업데이트 됨)로 “전달”되게하려면 Enter, 이력을 검색하고자하는 터미널 을 눌러야한다 .

  • 옵션 1:

    shopt -s histappend
    HISTCONTROL=ignoredups
    PROMPT_COMMAND="history -a; history -n; $PROMPT_COMMAND"
    

    여기에는 두 가지 단점이 있습니다.

    1. 로그인시 (터미널을 열 때) 히스토리 파일의 마지막 명령이 현재 터미널의 히스토리 버퍼로 두 번 읽 힙니다.
    2. 다른 터미널의 버퍼는 히스토리 파일과 동기화되지 않습니다.
  • 옵션 2 :

    HISTCONTROL=ignoredups
    PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
    

    (예, 필요에 shopt -s histappend와, 네, 그것은 수 없습니다 history -c 중간에 PROMPT_COMMAND이 버전은 두 가지 중요한 단점이 있습니다)

    1. 히스토리 파일을 초기화해야합니다. 비어 있지 않은 줄을 하나 이상 포함해야합니다 (무엇이든 가능).
    2. history명령은 잘못된 출력을 제공 할 수 있습니다 (아래 참조).

[편집]
“그리고 승자는 …”

  • 옵션 3 :

    HISTCONTROL=ignoredups:erasedups
    shopt -s histappend
    PROMPT_COMMAND="history -n; history -w; history -c; history -r; $PROMPT_COMMAND"
    

    이것은 가능한 한 멀다. 공통 히스토리와 공통 히스토리를 동시에 사용할 수 있는 유일한 옵션 erasedups입니다.
    이것은 아마도 모든 문제에 대한 최종 해결책 일 것입니다.


2. 옵션 2 가 작동하지 않는 이유는 무엇입니까 (또는 실제로 예상대로 작동하지 않는 것은 무엇 입니까)?

앞에서 언급했듯이 위의 각 솔루션은 다르게 작동합니다. 그러나 설정이 작동하는 방식에 대한 가장 오해의 소지가있는 것은 history명령 의 출력 분석에서 비롯됩니다 . 대부분의 경우 명령이 잘못된 출력을 제공 할 수 있습니다 . 왜? 때문에 그것을 실행 하기 전에 다른 순서 history에 포함 된 명령 PROMPT_COMMAND! 그러나 두 번째 또는 세 번째 옵션을 사용하는 경우 .bash_history내용 변경 ( watch -n1 "tail -n20 .bash_history"예 : 사용) 을 모니터링 하고 실제 기록이 무엇인지 확인할 수 있습니다.

3. 옵션 3 이 왜 그렇게 복잡한가?

그것은 모두 erasedups작동 방식에 있습니다. bash 매뉴얼에서 “(…) erasedups은 현재 행과 일치하는 모든 이전 행이 해당 행을 저장하기 전에 히스토리 목록에서 제거되도록합니다 . 그래서 이것은 실제로 OP가 원했던 것입니다 (그리고 이전에 생각했던 것처럼 복제본 이 순서대로 나타나지 않음 ) . 각 history -.명령이 다음에 있거나없는 이유는 다음과 같습니다 PROMPT_COMMAND.

  • history -n 전에 거기에 있어야 history -w에서 읽을 .bash_history다른 단말기에서 저장 명령,

  • history -w 파일과 중복을 삭제하는 기록을 저장하기 위해 거기에있을,

  • history -a history -w중복 지우기를 트리거하지 않기 때문에에 대신 배치 해서는 안됩니다 .

  • history -c또한 필요 가 각 명령 후에 기록 버퍼를 부수고 방지하기 때문에,

  • 마지막으로, history -r되어 필요에 따라서 마지막으로 터미널 세션에서 공유 역사를 만드는 파일에서 기록 버퍼를 복원 할 수 있습니다.


답변

프롬프트 명령에서 -c스위치를 사용하고 있습니다. 보낸 사람 man bash:

-c   모든 항목을 삭제하여 기록 목록을 지 웁니다.

모든 열린 터미널과 역사를 공유하려면 다음을 사용하십시오 -n.

-n   히스토리 파일에서 아직 읽지 않은 히스토리 라인을 현재 히스토리 목록으로 읽습니다. 이것은 현재 bash 세션이 시작된 이후 히스토리 파일에 추가 된 행입니다.

기본 크기는 다음 매뉴얼에도 있습니다.

HISTSIZE 명령 기록에서 기억해야하는 명령의 수입니다 (아래 기록 참조). 기본값은 500입니다.

여러 줄 명령을 저장하려면

cmdhist의 쉘 옵션이 활성화 된 경우, 구문 정확성을 유지하기 위해 필요한 세미콜론을 추가, 같은 역사 항목에 여러 줄의 명령의 각 라인을 저장하려고하는 쉘됩니다. lithist의 쉘 옵션이 포함 된 줄 바꿈 대신 세미콜론으로 명령을 저장하려면 쉘을 발생합니다.

또한 HIST * 명령을 export환경 변수 HISTCONTROL=ignoredups:erasedups가 아닌 bash 전용 변수로 시작하면 안됩니다 . 충분합니다.


답변

이것이 내가 생각 해낸 것이며 지금까지는 만족합니다…

alias hfix='history -n && history | sort -k2 -k1nr | uniq -f1 | sort -n | cut -c8- > ~/.tmp$$ && history -c && history -r ~/.tmp$$ && history -w && rm ~/.tmp$$'  
HISTCONTROL=ignorespace  
shopt -s histappend  
shopt -s extglob  
HISTSIZE=1000  
HISTFILESIZE=2000  
export HISTIGNORE="!(+(*\ *))"  
PROMPT_COMMAND="hfix; $PROMPT_COMMAND" 

노트:

  • 예, 복잡합니다 …하지만 모든 중복을 제거하면서 각 터미널 내에서 연대기를 유지합니다!
  • My HISTIGNORE는 인수가없는 모든 명령을 무시합니다. 이것은 일부 사람들에게는 바람직하지 않으며 생략 될 수 있습니다.

답변

대신 이것을 사용하십시오 :

HISTCONTROL=ignoreboth

답변

다음을 잊었 기 때문에 작동하지 않습니다.

 -n   read all history lines not already read from the history file
      and append them to the history list

그러나 실제로 history -n는 버그가있는 것 같습니다 export HISTCONTROL=ignoreboth:erasedups.

실험하자 :

$ PROMPT_COMMAND=
$ export HISTCONTROL=ignoreboth:erasedups
$ export HISTFILE=~/.bash_myhistory
$ HISTIGNORE='history:history -w'
$ history -c
$ history -w

여기서 우리는 딥 지우기를 켜고, 히스토리를 커스텀 파일로 전환하고, 히스토리를 지 웁니다. 모든 명령이 완료되면 빈 기록 파일과 현재 기록에 하나의 명령이 있습니다.

$ history
$ cat ~/.bash_myhistory
$ history
$ 1  [2019-06-17 14:57:19] cat ~/.bash_myhistory

두 번째 터미널을 열고 6 개의 명령도 실행하십시오. 그 후 :

$ echo "X"
$ echo "Y"
$ history -w
$ history
  1  [2019-06-17 15:00:21] echo "X"
  2  [2019-06-17 15:00:23] echo "Y"

이제 현재 기록에는 두 가지 명령이 있으며 기록 파일에는 다음이 있습니다.

#1560772821
echo "X"
#1560772823
echo "Y"

첫 번째 터미널로 돌아 가기 :

$ history -n
$ history
1  [2019-06-17 14:57:19] cat ~/.bash_myhistory 
2  [2019-06-17 15:03:12] history -n

어 … 어떤 echo명령도 읽을 수 없습니다. 두 번째 터미널로 다시 전환하고 다음을 수행하십시오.

$ echo "Z"
$ history -w

이제 히스토리 파일은 다음과 같습니다.

#1560772821
echo "X"
#1560772823
echo "Y"
#1560773057
echo "Z"

첫 번째 터미널로 다시 전환하십시오.

$ history -n
$ history
  1  [2019-06-17 14:57:19] cat ~/.bash_myhistory 
  2  [2019-06-17 15:03:12] history -n
echo "Z"

echo "Z"명령이에 병합 되었음을 알 수 있습니다 history -n.

또 다른 버그 는 명령 시간이 아닌 명령 번호로 기록에서 명령을 읽었 기 때문이라고 생각합니다. 나는 다른 echo명령이 역사에 나타 났을 것으로 기대한다


답변

삭제 된 부분은 선행 및 후행 공백을 자르지 않습니다 (일부 언어에서는 mp 프처럼). 이것은 버그입니다. 또한 삭제 된 항목이 이전 항목을 모두 삭제하지는 않습니다.