programing

Bash를 사용하여 표준 출력과 표준 오류를 모두 파일로 리디렉션하고 추가하는 방법

showcode 2023. 5. 5. 10:02
반응형

Bash를 사용하여 표준 출력과 표준 오류를 모두 파일로 리디렉션하고 추가하는 방법

표준 출력을 Bash에서 잘린 파일로 리디렉션하려면 다음을 사용해야 합니다.

cmd > file.txt

파일에 추가되는 Bash에서 표준 출력을 리디렉션하려면 다음을 사용해야 합니다.

cmd >> file.txt

표준 출력과 표준 오류를 잘린 파일로 리디렉션하려면 다음을 사용해야 합니다.

cmd &> file.txt

파일에 추가되는 표준 출력과 표준 오류를 모두 리디렉션하려면 어떻게 해야 합니까? cmd &>> file.txt저한테는 안 통했어요.

cmd >>file.txt 2>&1

Bash는 다음과 같이 왼쪽에서 오른쪽으로 리디렉션을 실행합니다.

  1. >>file.txt 열기file.txt 및 모드에서stdout 기거.
  2. 2>&1stderr"현재 어디로 가고 있습니까?"로 이동합니다.이 경우 추가 모드에서 열린 파일입니다.다른 말로 하면,&1는 " 다음파설를사다다용니합시자명일▁" 파일 합니다.stdout현재 사용 중입니다.

사용 중인 Bash 버전에 따라 두 가지 방법이 있습니다.

기존의 휴대용(Bash 4 이전) 방식은 다음과 같습니다.

cmd >> outfile 2>&1

Bash 4로 시작하는 휴대할 수 없는 방법은 다음과 같습니다.

cmd &>> outfile

((으)로 &> outfile)

좋은 코딩 스타일을 위해, 당신은 다음과 같이 해야 합니다.

  • 휴대성이 문제인지 여부를 결정합니다(그 후 기존 방식을 사용).
  • Bash 4 이전 버전에서도 휴대성이 문제인지 여부를 결정합니다(그 후 기존 방식 사용)
  • 어떤 구문을 사용하든 동일한 스크립트 내에서 변경하지 마십시오. (계속!)

스립트이시경으로 #!/bin/sh(의도 여부에 관계없이) Bash 4 솔루션과 일반적으로 Bash 관련 코드는 사용할 수 없습니다.

Bash 4는 Bash 4라는 것을 하십시오.&>>는 더 짧은 구문일 뿐, 새로운 기능이나 이와 유사한 기능을 도입하지는 않습니다.

구문은 (다른 리디렉션 구문 외에도) Bash 해커 Wiki에 설명되어 있습니다.

Bash에서 다른 파일로 리디렉션을 명시적으로 지정할 수도 있습니다.

cmd >log.out 2>log_error.out

다음과 같이 추가됩니다.

cmd >>log.out 2>>log_error.out

이것은 잘 작동할 것입니다.

your_command 2>&1 | tee -a file.txt

모든 로그를 파일에 저장합니다.터미널에 버리는 것뿐만 아니라 txt.

Bash 4( Z 쉘)에서zsh) 4.3.11):

cmd &>> outfile

상자에서 막 나온

사용해 보십시오.

You_command 1> output.log  2>&1

의사방법의 &> x.fileBash 4에서 작동합니다.

여기에 몇 가지 추가 팁이 있습니다.

0, 1, 2, ..., 9는 bash의 파일 설명자입니다.

0은 표준 입력, 1은 표준 출력, 2는 표준 오류를 나타냅니다.3~9개는 다른 임시 용도로 사용할 수 있습니다.

는 운영자 " 운자를사여모든파다설를파른설일또명파는다있수리습니할일션디렉로자영명자용일하▁▁any▁using"를 사용하여 다른 수 .>또는>>(계속).

용도 : <file_descriptor> <filename | &file_descriptor>

20장의 참조를 참조하십시오. I/O 리디렉션.

또 다른 접근 방식:

이전 버전의 Bash를 사용하는 경우 where&>>사용할 수 없습니다. 다음 작업도 수행할 수 있습니다.

(cmd 2>&1) >> file.txt

이는 하위 셸을 생성하므로 기존의 접근 방식보다 효율성이 떨어집니다.cmd >> file.txt 2>&1셸을 따서현 셸예하야는명령해정수재을라예▁that명:(령는▁and하)에서는 cd,pushd 이 은 저에게 더할 수 있는 것처럼 :), 하만지이러저에더게이고수있해다습니할럽연스자식은근접방.

  1. 표준 오류를 표준 출력으로 리디렉션합니다.
  2. 파일에 추가하여 새 표준 출력을 리디렉션합니다.

또한, 특히 표준 출력 및 표준 오류를 다른 명령에 대신 연결하려는 경우에는 괄호를 사용하여 순서의 모호성을 제거합니다.

하위 셸이 시작되지 않도록 하려면 괄호 대신 곱슬곱슬한 대괄호를 사용하여 그룹 명령을 만들 수 있습니다.

{ cmd 2>&1; } >> file.txt

(group 명령을 종료하려면 세미콜론(또는 새 줄)이 필요합니다.)

스크립트에서 직접 리디렉션

스크립트 자체에서 리디렉션을 계획할 수 있습니다.

#!/bin/bash

exec 1>>logfile.txt
exec 2>&1

/bin/ls -ld /tmp /tnt

하면 "" "/" "가 생성됩니다.logfile.txt포함:

/bin/ls: cannot access '/tnt': No such file or directory
drwxrwxrwt 2 root root 4096 Apr  5 11:20 /tmp

또는

#!/bin/bash

exec 1>>logfile.txt
exec 2>>errfile.txt

/bin/ls -ld /tmp /tnt

표준 출력을 만들거나 추가하는 동안logfile.txt오류 출력 생성 또는 추가errfile.txt.

다양한 파일에 로그 기록

의 서로 다른 로그 파일을 생성하여 하나의 전체 로그에 추가하고 다른 마지막 로그를 다시 생성할 수 있습니다.

#!/bin/bash

if [ -e lastlog.txt ] ;then
    mv -f lastlog.txt lastlog.old
fi
exec 1> >(tee -a overall.log /dev/tty >lastlog.txt)
exec 2>&1

ls -ld /tnt /tmp

이 스크립트를 실행하면

  • 한다면lastlog.txt합니다. 을 " 이존니다합재"로 변경하십시오. 이름을 다음으로 변경합니다.lastlog.old (덮lastlog.old존재하는 경우).
  • 새로운 것을 창조합니다.lastlog.txt.
  • 것을 것덧모을다니입붙에 추가합니다.overall.log
  • 모든 것을 단말기로 출력합니다.

단순 및 결합 로그

#!/bin/bash

[ -e lastlog.txt ] && mv -f lastlog.txt lastlog.old
[ -e lasterr.txt ] && mv -f lasterr.txt lasterr.old

exec 1> >(tee -a overall.log combined.log /dev/tty >lastlog.txt)
exec 2> >(tee -a overall.err combined.log /dev/tty >lasterr.txt)

ls -ld /tnt /tmp

그래서 당신은.

  • lastlog.txt log 파일을 실행합니다.
  • lasterr.txt error file
  • lastlog.old 로그 은 다음과 같습니다.
  • lasterr.old 실행 오류 은 과 같습니다.
  • overall.log 로그 이 첨부
  • overall.err 오류 되었습니다.
  • combined.log전체 오류 및 로그 결합 파일이 추가되었습니다.
  • 단말기로의 정지 출력

대화형 세션의 에는 형경우세의를 합니다.stdbuf:

포니치의 코멘트와 관련하여, 그리고 몇 가지 테스트 후에, 저는 동의해야 합니다: 에 동의하는 것은 소용이 없습니다.그렇지만.....

. *interactive* 셸에출사용게능입려면력하을버합퍼다말니에말지하링/력을야해라고서이기에출▁if`합니▁*,▁`다▁shell말▁you말inter▁*해야▁intee▁tell퍼▁to▁this라inter/.
# Source this to multi-log your session
[ -e lasterr.txt ] && mv -f lasterr.txt lasterr.old
[ -e lastlog.txt ] && mv -f lastlog.txt lastlog.old
exec 2> >(exec stdbuf -i0 -o0 tee -a overall.err combined.log /dev/tty >lasterr.txt)
exec 1> >(exec stdbuf -i0 -o0 tee -a overall.log combined.log /dev/tty >lastlog.txt)

이 정보가 제공되면 다음을 시도할 수 있습니다.

ls -ld /tnt /tmp

더 복잡한 샘플

Unix 타임스탬프를 날짜 문자열로 변환하는 방법대한 나의 3가지 설명

더 복잡한 명령을 사용하여 분석하고 재구성했습니다.squid실시간 로그인:각 줄이 밀리초 단위로 UNIX EPOK로 시작할 때, 나는 첫 번째 점에서 줄을 분할하고, 추가합니다.@EPOH SECUNS 에 기호를 지정하여 에 전달합니다.date -f - +%F\ %T그런 다음 다시 조립합니다.date의 출력과 나머지 라인은 다음을 사용하여 점으로 표시됩니다.paste -d ..

exec {datesfd}<> <(:)
tail -f /var/log/squid/access.log |
    tee >(
        exec sed -u 's/^\([0-9]\+\)\..*/@\1/'|
            stdbuf -o0 date -f - +%F\ %T >&$datesfd
    ) |
        sed -u 's/^[0-9]\+\.//' |
        paste -d . /dev/fd/$datesfd -

와 함께date,stdbuf필요한 것은...

에 대한 몇 가지 설명exec그리고.stdbuf명령:

  • 입니다.forks을 이용하여$(...)또는<(...)다른 서브셸(서브셸)에서 바이너리를 실행하는 서브셸을 실행합니다.exec명령은 셸에 실행할 스크립트에 더 이상의 명령이 없으므로 이진(stdbuf ... tee)는 동일한 수준에서 교체 프로세스로 실행됩니다(다른 하위 프로세스를 실행하기 위해 더 많은 메모리를 예약할 필요는 없음).

    bash의 맨 페이지(man -P'less +/^\ *exec\ ' bash):

        exec [-cl] [-a name] [command [arguments]]
               If  command  is  specified,  it  replaces the
               shell.  No new process is created....
    

    이는 실제로 필요하지는 않지만 시스템 설치 공간을 줄입니다.

  • stdbuf 페이지https:https:

    NAME
           stdbuf  -  Run COMMAND, with modified buffering
           operations for its standard streams.
    

    그러면 시스템에서 다음에 대해 버퍼링되지 않은 I/O를 사용하도록 지시합니다.tee지휘권따라서 일부 입력이 오면 모든 출력즉시 업데이트됩니다.

언급URL : https://stackoverflow.com/questions/876239/how-to-redirect-and-append-both-standard-output-and-standard-error-to-a-file-wit

반응형