로그인 할 때마다 BASH 기록이 500 행으로 잘 렸습니다.


22

어떤 이유로, 재부팅 후 시스템이 BASH 기록을 유지할 수 없습니다. 내 관련 섹션은 다음과 같습니다 ~/.bashrc.

shopt -s histappend
PROMPT_COMMAND='history -a; updateWindowTitle'
export HISTCONTROL=ignoredups
export HISTSIZE=9999
export HISTFILESIZE=999999
export HISTFILE="$HOME/.bash_history"

내가 알 수있는 한 필요한 옵션이 모두 있습니다 ( 과거의 모든 재부팅없이 여러 재부팅에서 기록을 유지할 수 있다는 것을 알고 있습니다). 그러나 몇 번의 재부팅 전에이 옵션을 추가했지만 재부팅 후 여전히 대부분의 기록을 잃어 버렸습니다. 비어 있지 않지만 재부팅 전에 9999 줄이 없습니다.

누군가 불평하기 전에, 나는이 질문들을 읽었습니다. 위에 나열된 제안 중 일부를 구현했지만 나머지는 도움이되지 않았거나 관련이 없었습니다.

다른 관련 명령이있을 수있는 기회가있을 때 ~/.bashrc 여기에서 내 전체를 볼 수 있습니다 .

그래서, 내가 무엇을 놓치고 있습니까? 내 역사가 저장되지 않는 이유는 무엇입니까? 다른 파일이 관련이 있다고 생각되면 알려 주시면 게시하겠습니다. 나는 실행에 의해 확인 grep -i hist \.*내에서 $HOME유일하게 관련된 것으로 나타났다되는 .파일이 문자열을 포함 hist하거나 HIST이었다 .bashrc.

Linux Mint Debian Edition, GNU bash, 버전 4.2.36 (1)-릴리스 (x86_64-pc-linux-gnu)를 실행 중이며 내가 좋아하는 터미널 에뮬레이터 (관련된 경우)는 terminator입니다.


최신 정보:

의견에서 @mpy의 제안에 따라 기본값 과 반대로 ~/.bashrc설정하도록 변경 했으며 대화 형 쉘 의 문제를 해결하는 것으로 보입니다 . 로그인 셸은 기록이 줄 에서 잘린 상태로 여전히 동일한 동작을 표시합니다 . 그러나 관련 파일에 설정된 관련 변수 가 없습니다 .HISTFILE=~/bash_history~/.bash_history500HIST

$ for f in /etc/profile ~/.profile ~/.bash_profile ~/.bash_login; do \
   echo -ne "$f :"; echo `grep HIST $f`; \
done
/etc/profile :
/home/terdon/.profile :grep: /home/terdon/.profile: No such file or directory
/home/terdon/.bash_profile :grep: /home/terdon/.bash_profile: No such file or directory
/home/terdon/.bash_login :grep: /home/terdon/.bash_login: No such file or directory
$ grep -r HIST /etc/profile.d/  <-- returns nothing

그럼, 왜 설정입니다 HISTSIZEHISTFILESIZE~/.bashrc내가 명시 적으로 설정하지 않는 충분하지 $HISTFILE기본값이 아닌 다른 뭔가 ~/.bash_history?


.bash_history 또는 root의 소유자입니까? ls -l .bash_history
Adnan Bhatti

1
@MSStp 예, 나 소유입니다. 제안에 감사하지만 어쨌든 권한 문제가 될 수있는 방법을 알지 못합니다. 읽기 / 쓰기 권한이 있거나 그렇지 않습니다. 일부 역사가 저장되어 있기 때문에 분명합니다. bash에 사용자가이 파일을 소유하지 않았을 때 문제를 일으킨 설정이있는 경우, 불만이 있거나 전체 히스토리 기능이 작동하지 않습니다.
terdon

당신이 history명령 을 실행할 때 , 당신이 보는 출력 cat .bash_history은 줄 번호가 아닌 당신이 보는 것과 동일 합니다. 나는 평균은 수행 history명령 목록 타임 스탬프 또는 기타 정보를? 내가 묻는 이유는, 당신이 이러한 난해한 것을 본다면, 그것은 다른 모듈 / 기능 / 프로그램이 있다는 것을 의미합니다. 이것은 쉘 히스토리와 그것이 무엇이든 잘못되거나 버그가있는 버전으로 엉망이되어 슬픔을 유발할 수 있습니다 .
MelBurslan

@ Mel_Burslan 예, 동일하지만 유일한 차이점은 줄 번호입니다.
terdon

2
좋아, 다소 이상한 제안이지만, 위태로운 문제이기도합니다 ;). 기본값이 아닌 다른 파일을 HISTFILE로 시도하십시오 ~/.bash_history. 매우 구성된 설명 : bash는 기본 쉘이라고 가정하므로 시스템 시작시 비 대화식 쉘은 X 세션의 부모입니다 (또한 X를 사용한다고 가정합니다). histappend 옵션에 대해서는 아무것도 알지 못합니다 (.bashrc는 대화 형 쉘에 의해 읽히는 것),이 상위 쉘이 모든 것을 실행하는 한 모든 것이 정상이지만 종료시 (즉, 시스템 정지) 재정의 ~/.bash_history(기본값)를 무시 하고 히스토리를 엉망으로
만듭니다

답변:


17

이 문제는 실제로 로그인과 비 로그인 쉘 의 다른 동작 으로 귀결됩니다 . 내 역사를 제어하는 ​​변수를 설정했습니다 ~/.bahsrc. 이 파일은 로그인 쉘을 시작할 때 읽지 않으며 대화식의 비 로그인 쉘 (에서 시작 man bash) 만 읽습니다 .

bash가 대화식 로그인 쉘 또는 --login옵션이 있는 비 대화식 쉘로 호출되면 /etc/profile파일이 존재하는 경우 먼저 파일에서 명령을 읽고 실행 합니다. 해당 파일을 읽은 후 ~ / .bash_profile, ~/.bash_login~/.profile을 순서대로 찾아서 존재하고 읽을 수있는 첫 번째 명령을 읽고 실행합니다. --noprofile쉘이 동작을 억제하기 시작할 때 옵션을 사용할 수있다.

[. . . ]

로그인 쉘이 아닌 대화식 쉘이 시작될 때 bash는 ~ / .bashrc에서 해당 파일이있는 경우 명령을 읽고 실행합니다. --norc 옵션을 사용하여이를 방지 할 수 있습니다. --rcfile 파일 옵션은 bash가 ~ / .bashrc 대신 파일에서 명령을 읽고 실행하도록합니다.

따라서 로그인하거나 tty로 가져 오거나 ssh를 사용할 때마다 .history파일을 올바른 크기로 설정하지 않아서 파일이 잘 렸습니다 ~/.profile. 나는 마침내 이것을 깨달았고 대신에 ~/.profile 그들이 속한 곳에 변수를 설정했다.~/.bashrc

그래서 ~/.history내가 잘린 이유 는 대화 형이 아닌 비 로그인 쉘에서 읽은 파일에 히스토리 변수 만 설정했기 때문에 다른 유형의 쉘을 실행할 때마다 변수가 무시되고 파일이 잘려 나갔기 때문입니다 따라서.


좋은 지적, 공유 주셔서 감사합니다! 그러나 나는 동의하지 않습니다 : 이 파일은 로그인 쉘을 시작할 때 읽히지 않으며 대화 형 쉘에서만 읽습니다. 로그인 쉘도 대화식이 될 수 있기 때문입니다. 그렇지 않으면 전체 역사 메커니즘이 의미가 없습니다. IMHO .bashrc는 읽지 않습니다 (비 대화식 또는 로그인 쉘).
mpy

@mpy 사실, 죄송합니다. 대화 형의 비 로그인 쉘을 의미했습니다. 답변이 수정되었습니다.
terdon

1
@terdon, 일반적인 관용구는 대화식 쉘 옵션이 ~ / .profile 또는 ~ / .bash_profile에 들어 가지 않는다는 것입니다. 대화식 쉘 옵션은 ~ / .bashrc에 있습니다. 두 곳에서 설정을 유지하지 않으려면 ~ / .bash_profile의 맨 위에 다음 명령을 입력하십시오. export BASH_ENV=~/.bashrc ; if [ -f ~/.bashrc ]; then . ~/.bashrc; fi... ~ / .bashrc의 맨 위에는 실제로 대화식으로 실행 중인지 확인하십시오. [ -z "$PS1" ] && return... 물론, 관용구 일뿐입니다.
노아 Spurrier

1
@NoahSpurrier BASH_ENV는 관련이 없으며 비 대화식 쉘에만 영향을 미칩니다. "이디엄"에 관해서는, 데비안이 시작 했고 개인적으로 동의하지 않는 것입니다. 나는 종종 xset.bashrc에 그래픽 옵션 등을 가지고 있으며 tty 또는 through에서 로그인 쉘을 실행할 때 활성 옵션을 원하지 않습니다 ssh. 내가 원하는 내의 .profile과 분리의 .bashrc. 로그인 할 때 많은 (전부는 아님) 로그인 관리자가 .profile을 소싱하므로 전역 변수는 터미널을 열 때마다 한 번만 읽히는 위치에 가장 잘 설정됩니다.
terdon

1
@WilsonF 예. 파일을 순차적으로 읽고 개인 파일 ( ~/.profile또는 ~/.bashrc)을 마지막에 읽습니다. 이것들에서 설정된 것은 전역 설정보다 우선합니다. 당신이 옳습니다 /etc/bash.bashrc. 에서 변수를 설정해서는 안됩니다 . 대신 ~/.profile(또는 ~/.bash_profile)를 사용하십시오 .
terdon

11

내 제안은 다른 파일을 다음과 같이 사용하는 것입니다. HISTFILE 기본값이 아닌~/.bash_history 입니다.

분석적인 설명은 없지만 bash기본 (로그인) 셸로 사용하고 X(매우 가능성이 높은) 셸을 사용 bash하면 (그래픽 ) 로그인:

systemd
 ...
  |-login
  |   `-bash      <<====
  |       `-slim
  |           |-X -nolisten tcp vt07 -auth /var/run/slim.auth
  |           |  `-{X}
  |           `-fluxbox
  |               `-xterm -bg black -fg white
  |                   `-bash
 ...

이 인스턴스는 로그인 쉘이라고 생각하므로 읽지 ~/.bashrc않으므로 histappend옵션 에 대해 아무것도 알지 못합니다 .

man bash (1) : 로그인 쉘 이 아닌 대화식 쉘 이 시작될 때 bash는 이러한 파일이 존재하는 경우 /etc/bash.bashrc 및 ~ / .bashrc에서 명령을 읽고 실행합니다. (...)

이 "부모 쉘"이 실행되는 한 모든 것이 정상이지만 종료 (즉, 시스템 정지)시 ~/.bash_history(기본값이므로 ) 재정의 하고 시스템에서 기록을 엉망으로 만들거나 (기본값으로) 500 윤곽. (또는 아마도 둘 다 ...)

너무 ~/.bashrc드문 설정 이어서는 안되기 때문에 기록 구성을 포함하는 것만으로는 충분 하지 않습니다. 나는 그것에 대한 설명이 없습니다.


"로그인 셸은 여전히 ​​동일한 동작을 표시합니다"라는 문제와 관련하여 다음과 같이 기록 구성을 포함 할 수 있습니다 ~/.bash_profile.

man bash (1) : bash가 대화식 로그인 쉘 또는 --login 옵션을 사용하는 비 대화식 쉘로 호출 될 때 해당 파일이 존재하면 먼저 / etc / profile 파일에서 명령을 읽고 실행합니다. 해당 파일을 읽은 후 ~ / .bash_profile, (...)을 찾습니다.

불행히도 나는 사람 bash이기 때문에 내 구성의 세부 사항으로 더 정당한 설명을 게시 할 수 없습니다 zsh...


2
내 기록 옵션을 명시 적으로 설정하면 ~/.bash_profile문제가 해결되었습니다. 이제 ~/.bash_history내 기록 파일로 사용 하고 있지만 ~/.bashrc질문에 표시된 모든 줄을에 추가 했습니다 ~/.bash_profile. 누가 대화식 쉘을 망쳐 놓았는지 확실하지 않지만 지금은 작동하는 것 같습니다. 감사합니다!
terdon

1
수락하지 못해서 죄송하지만 진행 상황을 설명하는 답변을 게시하지 못했습니다. 나는 @Gilles의 도움으로 그것을 알아 내고 마침내 답변을 게시했습니다. 실제로 (매우 좋은) 해결 방법을 제시하는 대신 문제를 설명하고 향후 방문자를 도울 수 있기 때문에 내 동의를 원했습니다.
terdon

2

모든 설정은 매뉴얼 페이지에 따라 순서가 다르며 기록 파일은 크기 (바이트)에 의해 제한되지 않으므로 가능한 유일한 설명입니다. 쉘이 죽는 방법과 관련이 있습니다.

온라인 참조에 따르면, 정상 종료 (기록 저장)는 쉘이 SIGHUP을 수신 할 때만 발생합니다. 재부팅 할 때 시스템이 어떻게 신호를 전파하는지 설명 할 수는 없지만 쉘이 SIGKILL 또는 SIGPWR로 종료되는 것으로 생각됩니다.

WM이 비동기 적으로 실행되고 (대기) bash가 SIGHUP 이외의 종료 강제 신호를받는 WM에서 터미널 에뮬레이터가 생성 되었기 때문일 수 있습니다. 또한 초기 우아한 SIGHUP이 X-> WM-> xterm을 통해 셸에 도달하기 전에 OS가 모든 프로세스에 "최종 종료"를 신속하게 전송해야 할 수도 있습니다. OS가 다운 될 준비가되어야합니다.

나는이 물건으로 깊은 물 위에 있지만, 그 선을 따라 무언가가 불규칙한 행동을 일으키는 것으로 생각합니다. 이전 에이 문제가 있었으며 가장 확실한 해결책은 exit역사를 유지하려는 bash입니다.

나는 history -a당신의 질문에 주목 했고, 왜 그것이 역사를 보존하기에 충분하지 않을지 생각할 수 없습니다.

bash를 실제로 죽이는 요소를 파악하고 신호가 발생하는 위치를 파악하고 문제를 해결하는 방법으로 이동하거나 마지막 신호가 무엇인지 알 때 간단히 기록을 플러시하면 문제를 해결할 수 있습니다 (디스크가 여전히 온라인 상태라고 가정) ) :

trap "echo got 1  >/tmp/sig1;  exit" SIGHUP
trap "echo got 2  >/tmp/sig2;  exit" SIGINT
trap "echo got 15 >/tmp/sig15; exit" SIGTERM
 .. and so on...

포함 된 스크린 샷은 두 번째 및 세 번째 단락에서 내가 말하고있는 것을 보여줍니다. 왼쪽부터 쉘이있는 순서 오른쪽에서 왼쪽 껍질을 죽이고 역사를 고양이로 삼는다.

남자 배쉬

시작시, (...) HISTFILESIZE 값 (+ 기본값 500)으로 지정된 행 수를 초과하지 않도록 필요한 경우 HISTFILE 값으로 이름이 지정된 파일이 잘립니다.

histappend 쉘 옵션이 활성화 된 경우 (여기서는 + 기본값) 행이 내역 파일에 추가되고, 그렇지 않으면 내역 파일을 덮어 씁니다.

온라인 참조

3.7.6 신호

Bash가 대화식 일 때 트랩이 없으면 SIGTERM을 무시하고 ( 'kill 0'이 대화식 쉘을 종료하지 않음) SIGINT가 잡히고 처리됩니다 (대기 내장 대기 가능). Bash가 SIGINT를 수신하면 실행 루프가 중단됩니다. 모든 경우에 Bash는 SIGQUIT를 무시합니다. 작업 제어가 유효하면 (작업 제어 참조) Bash는 SIGTTIN, SIGTTOU 및 SIGTSTP를 무시합니다.

Bash에 의해 시작된 내장되지 않은 명령에는 신호 핸들러가 상위에서 쉘에 의해 상속 된 값으로 설정되어 있습니다. 작업 제어가 유효하지 않으면 비동기 명령은 상속 된 핸들러 외에도 SIGINT 및 SIGQUIT를 무시합니다. 명령 대체의 결과로 실행되는 명령은 키보드 생성 작업 제어 신호 SIGTTIN, SIGTTOU 및 SIGTSTP를 무시합니다.

SIGHUP을 받으면 기본적으로 쉘이 종료됩니다. 종료하기 전에 대화식 쉘은 SIGHUP을 실행 또는 중지 된 모든 작업으로 다시 보냅니다. 중지 된 작업은 SIGHUP을 수신 할 수 있도록 SIGCONT로 전송됩니다. 쉘이 SIGHUP 신호를 특정 작업으로 전송하지 못하게하려면 disown 내장 (작업 제어 내장 참조)이있는 작업 테이블에서 제거하거나 disown -h를 사용하여 SIGHUP을 수신하지 않도록 표시해야합니다.

huponexit 쉘 옵션이 shopt로 설정되면 (Shopt Builtin 참조) Bash는 대화식 로그인 쉘이 종료 될 때 모든 작업에 SIGHUP을 보냅니다.

Bash가 명령이 완료되기를 기다리고 트랩이 설정된 신호를 수신하면 명령이 완료 될 때까지 트랩이 실행되지 않습니다. Bash가 대기 내장을 통해 비동기 명령을 기다리는 경우 트랩이 설정된 신호를 수신하면 대기 내장이 종료 상태가 128보다 큰 상태로 즉시 리턴되어 트랩이 실행됩니다.

실증 스크린 샷

신호


나는 당신이 그 스크린 샷에서하고있는 일을 실제로 얻지 못합니다. /tmp/pso당신이 죽이고 있는 것은 무엇입니까 ? 나는 다른 킬 신호에 대한 당신의 요점을 봅니다 (당신이 말한 것처럼, 그것이 history -a다루어야 할 것이 있다고 생각했습니다 ). 나는 그것을 잠시 테스트하고 다시보고 할 것입니다.
terdon

$ cat tmp / ps * \ n ps -o pid = | head -n1> ~ / tmp / pso \ n 17201 \ n
Ярослав Рахматуллин

0

/ etc / profile 및 /etc/profile.d/*를 확인하십시오.

기록 설정에 문제가있을 수 있습니다.


고맙지 만 grep -r HIST /etc/profile.d/아무것도 반환하지 않고 이미 확인했습니다 /etc/profile.
terdon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.