bash 스크립트 내의 히스토리 명령


20

History는 BASH 스크립트 내에서 사용할 수없는 셸 내장 명령입니다. BASH 스크립트를 사용하여 이것을 얻을 수있는 방법이 있습니까?
여기 우리는 당신을 위해 내 스크립트를 간다 :

#!/bin/bash
history |  tail -100 > /tmp/history.log
cd /tmp
uuencode history.log history.txt  | mail -s "History log of server" hello@hel.com

답변:


31

Bash는 기본적으로 비 대화식 쉘에서 히스토리를 사용하지 않지만 설정할 수 있습니다.

#!/bin/bash
HISTFILE=~/.bash_history
set -o history
history | tail 

그러나 해당 서버에서 활동을 모니터하려는 경우 쉘 히스토리는 쓸모가 없습니다 (히스토리에 표시되지 않은 명령을 실행하는 것은 쉽지 않습니다). Linux에서 모든 프로세스 실행을 기록하는 방법을 참조하십시오 .

스크립트를 디버깅하는 경우 쉘 기록이 유용한 정보를 얻는 가장 좋은 방법은 아닙니다. 훨씬 더 좋은 도구는 디버그 추적 기능 set -x입니다. 스크립트 상단 근처에 두십시오 . 추적이 표준 오류에 기록됩니다.


이것은 대본에서 작업을 거부합니다.histtest.sh: 5: set: Illegal option -o history
Ken Sharp

4
@ KenSharp 그것은 sh 스크립트에서 그것을 사용하려고했기 때문입니다 (그리고 sh오류 메시지의 정확한 표현에 의해 대시 juding입니다). bash 기록에 액세스하려면 bash ( #!/bin/bash또는로 시작하는 스크립트)를 사용해야 #!/usr/bin/env bash합니다.
Gilles 'SO- 악마 그만'

1
@KenSharp 그렇습니다. 오류 메시지가 표시되면 분명히 대시 아래에서 실행했습니다. Bash에는 오류 메시지가 없습니다 Illegal option(라고 말합니다 set: history: invalid option name).
Gilles 'SO- 악마 그만'

이것의 문제점은 모든 명령 set -o history 을 히스토리에 추가하고 다음과 같은 항목으로 채워질 것이라는 점입니다 if [... vars=$(....
nath

1
@nath 그게 바로 질문이었습니다. 내가 지적한 것처럼 그것은 거의 무의미합니다. 모니터링 활동은 쉘 히스토리로 해결되지 않는 어려운 문제입니다. 스크립트를 디버깅하는 경우 set -x훨씬 유용합니다.
Gilles 'SO- 악마 그만해

6

비 대화식으로 실행할 때 실제로 히스토리 기능을 사용하는지 확실하지 않으면 실행하는 모든 쉘 스크립트가 명령 히스토리를 어지럽히 게됩니다.

소스로 직접 이동하지 왜 ${HOME}/.bash_history교체 history | tail -100와 함께 tail -100 ${HOME}/.bash_history. (타임 스탬프를 사용하는 경우 아마도의 행을 따라 무언가를 수행해야 할 것입니다 grep -v ^# ${HOME}/.bash_history | tail -100).


실제로, 타임 스탬프와 함께, 당신은 실제로 greq -v '^#[0-9]\+$'(나는 때때로 내 껍질에 주석을 "실행"...)
PlasmaBinturong

그리고 실제로, 내 경우에는 올바른 히스토리 라인 번호 를 사용해야 하지만 메소드 history의 출력과 출력 사이에는 차이가 있습니다 grep...
PlasmaBinturong

좋아, 수정 사항은 다음과 같이 기록 목록을 기록 파일과 동기화하는 것이 었습니다 history -a; history -c; history -r. (add, clear, read)
PlasmaBinturong

2

history스크립트의 활성 쉘 세션에서 명령 출력을 사용하려면 별명을 사용하여 명령을 먼저 실행할 수 있습니다. 그런 다음 동일한 별명에서 나머지 스크립트를 호출 할 수 있습니다. 이러한 구성 history을 사용하면 실제 스크립트에서 명령 을 갖는 것과 본질적으로 동일한 결과를 얻을 수 있습니다 .

예를 들어, 스크립트 이름이 script.sh 인 경우 다음과 같이 별명을 작성할 수 있습니다.

alias hy_tmp='history | tail -100 > /tmp/history.log ; bash /patch/to/script.sh'

스크립트를 다음과 같이 변경하십시오.

#!/bin/bash
cd /tmp
uuencode history.log history.txt  | mail -s "History log of server" hello@hel.com

~/bash_history두 컴퓨터에서 파일 을 결합, 정렬 및 동기화하는 프로세스를 작성하는 동안이 질문을 발견 했으므로 과거에 사용한 명령을 쉽게 검색 할 수 있습니다.

업데이트하기 위해 새 셸에 로그인하지 않고도 누적 기록 파일을 업데이트하는 것이 번거롭지 ~/bash_history않습니다. 다른 답변에서 언급했듯이 서버 모니터링의 경우 분명히 작동하지 않습니다.

특히 내 사용법은 다음과 같습니다.

alias hbye='history | cut -c 8- > /home/chris/.bash_history_c; bash /hby.sh

hby.sh그런 다음 스크립트 는 모든 ~/.bash_history*파일 에서 모든 고유 항목을 가져옵니다 .



1

script.sh아래와 같은 스크립트를 작성하십시오 . X라는 스크립트를 작성하고 Y 행의 히스토리 라인을 넣습니다.

#!/bin/bash
SCRIPT_NAME=$1
NUMBER_OF_LINES_BACK=$2

# Enable History in a non interactive shell
HISTFILE=~/.bash_history
set -o history

# echo shabang line and x number of lines of history to new script
echo \#\!\/bin\/bash > $SCRIPT_NAME.sh; history | tail -n $NUMBER_OF_LINES_BACK >> $SCRIPT_NAME.sh;
chmod u+x $SCRIPT_NAME.sh;

# Open the newly created script with vim
vim $SCRIPT_NAME.sh;
~

그런 다음 마지막 14 행 동안 작업 한 "task"라는 태스크를 수행하기위한 스크립트를 작성하려면

script.sh task 14

그런 다음 역사를 정리하여 멋진 대본을 만드십시오!


histtest.sh: 5: set: Illegal option -o history
Ken Sharp

1

history 명령은 bash 스크립트에서 기본적으로 비활성화되어 있기 때문에 history 명령조차도 .sh 파일에서 작동하지 않습니다. 리디렉션을 위해 .sh 파일 내에서 bash_history 파일을 친절하게 리디렉션하십시오.

또는 히스토리 메커니즘은 히스토리 파일을 언급하고 아래에 언급 된대로 런타임 매개 변수를 변경하여 활성화 할 수 있습니다.

#!/bin/bash
HISTFILE=~/.bash_history
set -o history 

참고 : 스크립트 파일 맨 위에 두 줄이 있습니다. 이제 history 명령이 역사에서 작동합니다.


0

모든 사용자에게는 history 명령의 결과 인 자체 기록 파일이 있습니다. 쉘 스크립트에서 history 명령을 사용하는 대신 사용자에 대한 기록 파일을 사용할 수 있습니다. 있을 것이다 .bash_history사용자에 대한 기록 파일됩니다 사용자의 홈 디렉토리에있는 파일.


-1

짧은 답변 :

history -p히스토리 확장을 명시 적으로 수행 하는 데 사용 합니다.

예는 다음과 같습니다.

하나의 유스 케이스는 나를 위해 많이 발생합니다.

  • 이전 명령은 파일 이름 목록을 가져 와서 stdout으로 인쇄합니다.
  • vim으로 해당 파일을 편집해야합니다.

내 bash는이므로 set -o histexpand일반적으로 내가 한 일은 타이핑하는 것입니다.

vim $(!!)

이전 명령으로 나열된 파일을 편집합니다.

슬프게도 때로는 실수가 발생하여로 확인을 활성화합니다 shopt -s histverify.

이제 하나의 추가 Return키를 사용하여 확장을 확인할 수 있습니다 .

오늘 저는 그 세부 사항을 많이 사용하기 때문에 bash 함수로 래핑하고 싶습니다.

function vk() {
    set -o history && set -o histexpand;
    vim -i ~/.viminfok $($(history -p !!));
}

여기서는 command substitution내부 !!명령 하나를 사용 하여 이전 명령 으로 확장 하고 외부 명령을 실행하여 출력을 얻습니다.

이제 세 개의 키만으로도 동일한 효과를 얻을 수 있으며 그 중 하나는 Return!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.