내부에배쉬 참조 매뉴얼그것은 다음과 같이 말합니다:
lithist
활성화되고cmdhist
이 옵션이 활성화되면 여러 줄 명령은 가능한 경우 세미콜론 구분 기호를 사용하는 대신 포함된 줄 바꿈을 사용하여 기록에 저장됩니다.
그래서 내 질문은 다음과 같습니다어디서/언제/어떻게 가능합니까??
내 장치에서 기능을 활성화하고 테스트해 보았습니다.GNU bash, 버전 4.4.12(1) - 릴리스이 방법:
shopts -s cmdhist
shopts -s lithist
echo -n "this is a test for a ";\
echo "multiline command"
그런 다음 나는
history | tail
다음과 유사한 출력이 예상됩니다.
101 shopts -s cmdlist
102 shopts -s lithist
103 echo -n "this is a test for a ";\
echo "multiline command"
104 history
하지만 이것을 얻으십시오 :
101 shopts -s cmdlist
102 shopts -s lithist
103 echo -n "this is a test for a "; echo "multiline command"
104 history
분명히 여러 줄 명령(bash 기록 번호 103)이 아직 저장되지 않았습니다."세미콜론 구분 기호를 사용하는 대신 삽입라인 나누기". 여기서는 왜 lithist
불가능합니까? 내가 뭘 잘못했나요?
답변1
A는 역사에서 a를 얻는 올바른 방법이 \<new line>
아닙니다 .<new line>
메모리
기록 행은 디스크가 아닌 쉘 메모리에 보관되므로 기록 행만 처리합니다.
지금까지 했던 것처럼 몇 가지 명령을 입력해 보겠습니다.
$ echo -n "this is a test for a ";\
> echo "two line command"
행이 방금 작성되었을 때 메모리에 무엇이 저장되었습니까?
$ history 2
514 echo -n "this is a test for a ";echo "two line command"
515 history 2
보시다시피 "줄 연속"(백슬래시 다음에 줄 바꿈)이 제거되었습니다.
(man bash에서) 다음과 같이 해야 합니다.
\ 쌍이 발생하고 백슬래시 자체가 따옴표로 묶이지 않은 경우 \는 줄 연속으로 처리됩니다(즉, 입력 스트림에서 제거되어 사실상 무시됩니다).
인용하면 개행 문자가 나타날 수 있습니다.
$ echo " A test of
> a new line"
A test of
a new line
그리고 이 시점에서 역사는 다음을 반영할 것입니다.
$ history 2
518 echo "A test of
a new line"
519 history 2
실제 여러 줄 명령:
여러 줄 명령의 가능한 예는 다음과 같습니다.
$ for a in one two
> do echo "test $a"
> done
test one
test two
다음과 같은 경우 기록이 한 줄로 축소됩니다 cmdhist is set
.
$ shopt -p cmdhist lithist
shopt -s cmdhist
shopt -u lithist
$ history 3
24 for a in one two; do echo "test $a"; done
25 shopt -p cmdhist lithist
26 history 3
어느 시점에서 .clear 를 사용하여 (메모리에서) 기록을 지웠기 때문에 각 명령에 대해 숫자가 변경되었습니다 history -c
.
cmdhist를 설정 해제하면 다음 메시지가 표시됩니다.
$ shopt -u cmdhist
$ for a in one two
> do echo "test $a"
> done
test one
test two
$ history 5
5 shopt -u cmdhist
6 for a in one two
7 do echo "test $a"
8 done
9 history 5
각 줄(완전한 명령이 아님)은 기록에서 별도의 줄에 표시됩니다.
설정된 경우에도 lithist
:
$ shopt -s lithist
$ for a in one two
> do echo "test $a"
> done
test one
test two
$ history 5
12 shopt -s lithist
13 for a in one two
14 do echo "test $a"
15 done
16 history 5
그러나 둘 다 설정된 경우:
$ shopt -s cmdhist lithist
$ for a in one two
> do echo "test $a"
> done
$ history 5
23 history 15
24 shopt -p cmdhist lithist
25 shopt -s cmdhist lithist
26 for a in one two
do echo "test $a"
done
27 history 5
명령은 for
여러 줄 명령으로 저장되며 세미콜론( ;
) 대신 "개행" 문자를 사용합니다. 위의 lithist가 설정되지 않은 경우와 비교해 보세요.
디스크
위의 모든 내용은 셸 메모리에 저장된 명령 목록을 사용하여 해석됩니다. 디스크에 명령이 기록되지 않았습니다. (기본값) 파일이 ~/.bash_history
변경되지 않습니다.
이 파일은 실행 중인 쉘이 종료되면 변경됩니다. 이때 기록은 파일을 덮어쓰거나( histappend
설정되지 않은 경우) 추가됩니다.
명령을 디스크에 제출하려면 다음이 필요합니다.이 세트를 가지고:
export PROMPT_COMMAND='history -a'
이렇게 하면 각 명령줄이 각각의 새 명령줄에 있는 파일에 추가됩니다.
이제 cmdhist와 lithist에 대해 논의해 보겠습니다. 상황은 보이는 것만큼 간단하지 않습니다. 하지만 걱정하지 마세요. 곧 모든 것이 명확해질 것입니다.
아래의 모든 명령을 입력하는 데 시간이 걸렸다고 가정합니다(바로가기 없음, 별칭 없음, 기능 없음, 실제 명령이 필요합니다. 죄송합니다).
먼저 메모리( history -c
)와 디스크(백업하기) ( history -w
) 그런 다음 3번 시도합니다.
- 기본값인 cmdhist(설정) 및 lithist(설정되지 않음)를 사용합니다.
- 동시 설정
- 둘 다 설정되지 않았습니다.
- unset cmdhist로 lithist를 설정하는 것은 의미가 없습니다(테스트할 수 있습니다).
실행할 명령 목록:
$ history -c ; history -w # Clear all history ( Please backup).
$ shopt -s cmdhist; shopt -u lithist
$ for a in one two
> do echo "test $a"
> done
$ shopt -s cmdhist; shopt -s lithist
$ for a in one two
> do echo "test $a"
> done
$ shopt -u cmdhist; shopt -u lithist
$ for a in one two
> do echo "test $a"
> done
당신은 (메모리에서) 다음과 같이 끝날 것입니다 :
$ history
1 shopt -s cmdhist; shopt -u lithist
2 for a in one two; do echo "test $a"; done
3 shopt -s cmdhist; shopt -s lithist
4 for a in one two
do echo "test $a"
done
5 shopt -u cmdhist; shopt -u lithist
6 for a in one two
7 do echo "test $a"
8 done
9 history
세 개의 여러 줄 명령은 다음과 같이 끝납니다.
- 2번 줄 중 하나(한 줄, 한 명령).
- 4번으로 표시된 여러 줄 중 하나(여러 줄 중 하나의 명령)
- 6부터 8까지 번호가 매겨진 여러 줄 중 하나
좋아요, 그런데 파일에서 무슨 일이 일어나고 있나요? 이미 말했지만...
마지막으로 파일에서:
간단합니다. 파일에 쓰고 고양이를 보내서 확인하세요.
$ history -w ; cat "$HISTFILE"
shopt -s cmdhist; shopt -u lithist
for a in one two; do echo "test $a"; done
shopt -s cmdhist; shopt -s lithist
for a in one two
do echo "test $a"
done
shopt -u cmdhist; shopt -u lithist
for a in one two
do echo "test $a"
done
history
history -w ; cat "$HISTFILE"
줄 번호도 없고 명령만 있으며 여러 줄이 시작하고 끝나는 위치를 알 수 있는 방법이 없습니다. 여러 줄이 있어도 판단할 방법이 없습니다.
실제로, 위와 같이 명령이 파일에 기록되면 파일을 다시 읽을 때 여러 줄에 대한 모든 정보가 손실됩니다.
구분 기호(개행 문자)는 하나만 있으며 각 줄은 명령으로 다시 읽혀집니다.
해결책이 있습니까? 예, 추가 구분 기호를 사용하십시오.
HISTTIMEFORMAT이 바로 그런 일을 합니다.
과거 시간 형식
이 변수를 값으로 설정하면 각 명령이 실행된 시간이 주석( ) 문자 뒤에 에포크(예, 항상 초) 이후의 초 수로 파일에 저장됩니다 #
.
변수를 설정하고 파일을 다시 작성하면 다음과 같은 결과를 ~/.bash_history
얻습니다.
$ HISTTIMEFORMAT='%F'
$ history -w ; cat "$HISTFILE"
#1490321397
shopt -s cmdhist; shopt -u lithist
#1490321397
for a in one two; do echo "test $a"; done
#1490321406
shopt -s cmdhist; shopt -s lithist
#1490321406
for a in one two
do echo "test $a"
done
#1490321418
shopt -u cmdhist; shopt -u lithist
#1490321418
for a in one two
#1490321418
do echo "test $a"
#1490321420
done
#1490321429
history
#1490321439
history -w ; cat "$HISTFILE"
#1490321530
HISTTIMEFORMAT='%FT%T '
#1490321571
history -w ; cat "$HISTFILE"
이제 어디에서 어떤 줄이 여러 줄인지 알 수 있습니다.
이 형식은 '%FT%T '
History 명령을 사용할 때만 시간을 표시합니다.
$ history
1 2017-03-23T22:09:57 shopt -s cmdhist; shopt -u lithist
2 2017-03-23T22:09:57 for a in one two; do echo "test $a"; done
3 2017-03-23T22:10:06 shopt -s cmdhist; shopt -s lithist
4 2017-03-23T22:10:06 for a in one two
do echo "test $a"
done
5 2017-03-23T22:10:18 shopt -u cmdhist; shopt -u lithist
6 2017-03-23T22:10:18 for a in one two
7 2017-03-23T22:10:18 do echo "test $a"
8 2017-03-23T22:10:20 done
9 2017-03-23T22:10:29 history
10 2017-03-23T22:10:39 history -w ; cat "$HISTFILE"
11 2017-03-23T22:12:10 HISTTIMEFORMAT='%F'
12 2017-03-23T22:12:51 history -w ; cat "$HISTFILE"
13 2017-03-23T22:15:30 history
14 2017-03-23T22:16:29 HISTTIMEFORMAT='%FT%T'
15 2017-03-23T22:16:31 history
16 2017-03-23T22:16:35 HISTTIMEFORMAT='%FT%T '
17 2017-03-23T22:16:37 history
답변2
이것은 여러 줄 명령이 아닌 것 같습니다(귀하가 반환을 이스케이프했기 때문에). 실제 보상이 있는 일을 한다면 차이가 있습니다.
$ for i in /tmp/g*
> do echo $i
> done
/tmp/gigabyte
$ shopt -s lithist
$ for i in /tmp/g*
> do echo $i
> done
/tmp/gigabyte
$ history
[...]
517 for i in /tmp/g* ; do echo $i ; done
518 shopt -s lithist
519 for i in /tmp/g*
do echo $i
done
520 history
답변3
iTerm은 여러 줄 명령을 완벽하게 처리하고 여러 줄 명령을 하나의 명령으로 저장한 다음 ++를 사용하여 Cmd기록을 탐색할 수 있습니다. 더 많은 iTerm 팁을 확인하세요:Shift;iTerm으로 효과적으로 작업하세요
답변4
나는 노력했다 shopt -s lithist cmdhist
.
그러나 로그아웃 및 로그인 후에도 기록 복구는 ~/.bash_history
여전히 여러 줄로 나누어져 있습니다.
1953 2019-05-23 16:57:53 shopt -s cmdhist; shopt -s lithist
1954 2019-05-23 16:57:58 for i in 1 2 3
1955 2019-05-23 16:58:34 do echo $i
1956 2019-05-23 16:58:34 done
1957 2019-05-23 16:58:08 history 5
1958 2019-05-23 16:58:27 history -a
1959 2019-05-23 16:54:12 history 10 | less
이 동작이 예상됩니까?
내가 가진 것은 다음과 같습니다 ~/.bash_history
.
#1558601873
shopt -s cmdhist; shopt -s lithist
#1558601878
for i in 1 2 3
do echo $i
done
#1558601888
history 5
#1558601907
history -a
#1558601652
history 10 | less
해결책
이전 ~/.bash_history를 삭제하여 문제를 해결한 다음 로그아웃하고 로그인한 후에도 여러 줄 기록이 제대로 작동했습니다.
1 2019-06-12 13:53:11 \rm .bash_history
2 2019-06-12 13:53:27 fx mcd
3 2019-06-12 13:53:28 mcd ()
{
mkdir $@;
cd $1
}
4 2019-06-12 14:55:14 nmcli-restart-hotspot -s
5 2019-06-12 21:34:35 ssh lab
6 2019-06-12 23:38:45 history | less