명령줄 입력을 로그 파일로 캡처하고 동시에 실행하는 방법은 무엇입니까?

명령줄 입력을 로그 파일로 캡처하고 동시에 실행하는 방법은 무엇입니까?

명령줄에서 몇 가지 명령을 실행한다고 가정해 보겠습니다.

#capture what follows
$ echo "foo"
foo

# don't capture
$ echo "bing"
bing

# capture again
$ echo "bar"
bar

명령을 기록하는 방법선택적으로로그 파일에오직포착주문하다CLI에 직접 게시하시겠습니까? 즉, 다음과 같은 것을 효과적으로 구현 .bash_history하지만 특정 명령에만 해당됩니다.

$ cat command.log
echo "foo"
echo "bar"

알아채다산출STDOUT각 명령의 to는 다음과 같아야 합니다.아니요기록됩니다.
나는 본 적이IO 리디렉션, 그러나 실행 가능한 솔루션을 찾을 수 없습니다.

답변1

가장 쉬운 방법은 bash가 이미 제공하는 기능을 사용하는 것입니다. 특히 HISTIGNORE변수는 다음과 같습니다.

   HISTCONTROL
          A  colon-separated  list  of values controlling how commands are
          saved on the history list.   If  the  list  of  values  includes
          ignorespace,  lines  which  begin with a space character are not
          saved in the history list. 

그러니 간단한 일을 할 수 있습니다

$ HISTCONTROL=ignorespace

그러면 앞에 공백이 포함된 명령을 입력하면 무시됩니다.

HISTCONTROL=ignorespace
$ history -c            ## clear previous history for this session
$ echo foo
foo
$   echo bar
bar
$ history 
1  echo foo
2  history 

위에서 볼 수 있듯이 공백으로 시작하는 명령은 무시됩니다.


다음을 사용할 수도 있습니다 HISTIGNORE.

    HISTIGNORE
          A colon-separated list of patterns used to decide which  command
          lines  should  be  saved  on  the history list.  Each pattern is
          anchored at the beginning of the line and must  match  the  com‐
          plete  line  (no  implicit  `*'  is  appended).  Each pattern is
          tested against the line after the checks specified  by  HISTCON‐
          TROL  are  applied.   In  addition  to  the normal shell pattern
          matching characters, `&' matches the previous history line.  `&'
          may  be  escaped  using  a  backslash;  the backslash is removed
          before attempting a match.  The second and subsequent lines of a
          multi-line compound command are not tested, and are added to the
          history regardless of the value of HISTIGNORE.

HISTIGNORE비슷한 값을 설정한 다음 무시하려는 명령에 추가하면 #foo동일한 효과를 얻을 수 있습니다 .

$ HISTIGNORE="*#foo"
$ history -c  
$ echo foo
foo
$ echo "bar" #foo
bar
$ history 
1  echo foo
2  history 

두 경우 모두 파일에 저장하려면 를 실행하세요 history > file. 또는 file세션 기록 파일을 다음과 같이 설정하세요.

$ HISTFILE="/tmp/file"
$ HISTCONTROL=ignorespace
$ history -c
$ echo foo
foo
$   echo bar
bar
$ history -a   ## write the session's history to $HISTFILE
$ cat /tmp/file 
echo foo
history -a

답변2

이와 같은 함수를 정의하면

loglast() {
    fc -ln -1 | sed 's/^[[:space:]]*//' >> "${1:-${logfile:-~/command.log}}"
}

그런 다음 기록하려는 각 명령 후에 실행하여 loglast이전 명령을 기록할 수 있습니다.

사용되는 로그 파일은 (순서대로) 선택적 첫 번째 인수 loglast이거나, $logfile인수가 제공되지 않은 경우 또는 $HOME/command.log마지막 기본값입니다.

추가된 sed -s '/^[[:space:]]*//선행 공백을 제거합니다 fc.

답변3

사용 script명령:

script -f filename.log

새 세션을 시작하고 모든 명령을 기록합니다. 종료하면 파일이 닫힙니다.

답변4

script명령을 기록하는 명령을 생각할 수 있습니다 . 그러나 이는 표준 출력에서 ​​얻은 모든 내용을 기록해야 한다는 단점도 있습니다.

script -a #Start your scripting session. 

Script started, file is typescript
echo "Hello"
Hello
echo "Another Hello"
Another Hello
#Press Ctrl - D to exit the scripting session. 

Script done, file is typescript

이제 세션에서 수행하는 모든 작업이 로그인됩니다.타이프스크립트문서.

cat typescript
Script started on Fri 21 Nov 2014 10:12:56 AM CST
echo "Hello"
Hello
echo "Another Hello"
Another Hello

Script done on Fri 21 Nov 2014 10:13:08 AM CST

편집하다

그러나 명령의 출력이 아닌 명령만 기록하면 되므로 제안과 같은 작업을 수행할 수 있습니다.여기.

  1. 그렇지 않은 경우 screen를 사용하여 설치하십시오 apt-get install screen.
  2. 이제 파일에 다음 내용을 추가합니다 ~/.screenrc(파일이 없어도 생성 가능).

    screen -t "window 0" 0 bash -ic 'HISTFILE=~/.bash_history.${WINDOW} bash'
    screen -t "window 1" 1 bash -ic 'HISTFILE=~/.bash_history.${WINDOW} bash'
    screen -t "window 2" bash -ic 'HISTFILE=~/.bash_history.${WINDOW} bash'
    bind c screen bash -ic 'HISTFILE=~/.bash_history.${WINDOW} bash'
    bind ^C screen bash -ic 'HISTFILE=~/.bash_history.${WINDOW} bash'
    
  3. 이제 명령을 입력하여 세션을 시작 screen하고 평소대로 명령을 실행하십시오.

  4. 이제 명령이 실행된 화면 번호에 해당하는 파일을 검사하여 screen해당 명령에서 사용한 명령 목록을 볼 수 있습니다.~/.bash_history.${WINDOW}${WINDOW}

관련 정보