모든 bash 스크립트 작업을 완전히 기록하려면 어떻게해야합니까?


44

스크립트 출력에서 ​​오류 메시지와 함께 모든 로그 데이터를 캡처하고 모두 로그 파일로 리디렉션하고 싶습니다.

나는 아래와 같은 스크립트를 가지고있다 :

#!/bin/bash
(
echo " `date` : part 1 - start "
ssh -f admin@server.com 'bash /www/htdocs/server.com/scripts/part1.sh logout exit'
echo " `date` : sleep 120"
sleep 120
echo " `date` : part 2 - start"
ssh admin@server.com 'bash /www/htdocs/server.com/scripts/part2.sh logout exit'
echo " `date` : part 3 - start"
ssh admin@server.com 'bash /www/htdocs/server.com/scripts/part3.sh logout exit'
echo " `date` : END"
) | tee -a /home/scripts/cron/logs

파일의 모든 동작을보고 싶습니다 /home/scripts/cron/logs

그러나 나는 echo 명령 후에 무엇을 넣었는지 볼 수 있습니다.

SSH 명령이 성공적으로 로그를 확인하는 방법은 무엇입니까?

모든 로그 데이터를 수집해야합니다. 스크립트에서 모든 명령의 결과를 모니터링하고 스크립트가 실패하는 동안 발생하는 상황을 더 잘 분석하려면 이것이 필요합니다.


"스크립트"를 사용하여이 작업을 수행 할 수도 있습니다. 이 게시물을 참조하십시오 : [여기] [1] [1] : stackoverflow.com/questions/5985060/…
xX0v0Xx

errexit에주의해야합니다. 예를 들어 무시되거나 오류가 스크립트를 종료하지 않는 것으로 나타났습니다. 스크립트에 이와 비슷한 것이 있다면 : command || 명령이 실패하면 dosmthg 스크립트는 errexit가 설정된 상태에서 즉시 종료되지 않고 dosmthg를 실행하고 스크립트를 계속합니다

답변:


66

나는 일반적으로 모든 스크립트의 시작 부분에 (특히 데몬으로 실행될 경우) 다음과 유사한 것을 넣습니다.

#!/bin/bash
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>log.out 2>&1
# Everything below will go to the file 'log.out':

설명:

  1. exec 3>&1 4>&2

    파일 디스크립터를 저장하여 경로 재 지정 이전의 상태로 복원하거나 다음 경로 재 지정 이전의 상태로 출력하는 데 사용됩니다.

  2. trap 'exec 2>&4 1>&3' 0 1 2 3

    특정 신호에 대한 파일 디스크립터를 복원하십시오. 하위 쉘이 종료 될 때 복원해야하므로 일반적으로 필요하지 않습니다.

  3. exec 1>log.out 2>&1

    리디렉션 stdout파일에 log.out다음 리디렉션 stderrstdout. 순서가 같은 파일로 가고 싶을 때 중요합니다. stdout 해야한다 이전 리디렉션 stderr로 리디렉션됩니다 stdout.

그런 다음 콘솔의 출력을 보려면 간단히로 리디렉션하면 &3됩니다. 예를 들어

echo "$(date) : part 1 - start" >&3

stdout위의 3 행을 실행하기 전에 콘솔로 지정된 곳 으로 이동합니다 .


<< niceroot, 감사합니다! 스크립트 시작 부분에 세 줄 (exec, trap, exec)을 추가했으며 stdout과 stderr을 모두 얻을 수 있습니다. 그러나 한 가지 문제 : "some_command에서 파일 설명자 3 (pipe : XXX)이 유출되었습니다"라는 오류가 발생했습니다 ... 이러한 오류가 발생하는 것을 피할 수있는 방법을 알려주십시오. 사용자 정의 보드에서 busybox 기반 sh를 사용합니다.
kumar

3
위대한 쿵푸 여기! -더 나은 것이 사용하는 것 trap 'exec 2>&4 1>&3' 0 1 2 3 RETURN입니다. RETURN 의사 sigspec은 쉘 함수 또는 스크립트가로 실행될 때마다 파일 디스크립터를 복원합니다. 또는 소스 내장이 실행을 완료합니다. 내 스크립트 에서이 (및 다른 이유로) 마지막 2 줄로 추가합니다 : return& exit 0-단지 2 센트, 당신에게 @nicerobot!
DavAlPi

셸의 전역 변수를 통한 셸 스크립트 로깅에 대한 자세한 내용이 있습니다. 쉘 스크립트에서 비슷한 종류의 로깅을 에뮬레이션 할 수 있습니다. cubicrace.com/2016/03/efficient-logging-mechnism-in-shell.html 이 게시물에는 INFO, DEBUG, ERROR와 같은 로그 수준 소개에 대한 세부 정보가 있습니다. 스크립트 입력, 스크립트 종료, 기능 입력, 기능 종료와 같은 세부 사항 추적
Piyush Chordia

trap신호 열거 는 약간 이상하게 보입니다. 일반적으로 포함 15하는 것이 좋습니다.
tripleee


14

ssh 출력을 로그 파일로 가져 오려면로 리디렉션 stderr해야 stdout합니다. 2>&1bash 스크립트 다음에 추가하면됩니다 .

다음과 같아야합니다.

#!/bin/bash
(
...
) 2>&1 | tee ...

메시지가 올바른 순서로 표시되지 않으면 다른 서브 쉘을 추가하십시오.

#!/bin/bash
((
...
) 2>&1) | tee ...

1
이것은 잘 작동합니다. 실제로 다음과 같이 stdout과 stderr을 모두 지시 할 수 있습니다.( ... ) |& tee output.log
Noam Manos

12

귀하의 질문을 읽을 때 출력을 기록하고 싶지는 않지만 전체 명령 시퀀스를 사용하면 다른 답변이 도움이되지 않습니다.

-x를 사용하여 쉘 스크립트를 호출하여 모든 것을 출력하십시오.

sh -x foo.sh

원하는 파일에 로그인하십시오.

sh -x foo.sh >> /home/scripts/cron/logs


2
-x 옵션의 경우 +1
Coc

10

bash에서는 넣을 수 있으며 set -x그 후에 실행되는 모든 명령 (및 bash 변수)을 인쇄합니다. 으로 끌 수 있습니다 set +x.

편집증이 set -o errexit되고 싶다면 대본을 넣을 수 있습니다 . 이것은 하나의 명령이 0이 아닌 종료 코드를 반환하면 스크립트가 실패하고 중지된다는 것을 의미하며, 이는 무언가 잘못되었음을 알리는 유닉스 표준 방법입니다.

당신은 더 좋은 로그를 얻고 싶은 경우에, 당신은 보라 ts에서 moreutils데비안 / 우분투 패키지로 제공된다. 각 줄 앞에 타임 스탬프가 붙고 인쇄됩니다. 상황이 언제 발생했는지 확인할 수 있습니다.


1
"set -o errexit"는 "set -e"와 동일해야합니다
Ajith Antony

0

다른 사람들의 말에 따라 세트 매뉴얼 은 좋은 자료입니다. 나는 넣었다 :

#!/usr/bin/env bash
exec 1> command.log 2>&1
set -x

스크립트 상단에서 계속 진행하거나 set -ex오류가 발생하면 종료해야합니다.


이것이 ssh 로그 및 성공적인 명령 실행에 어떻게 도움이됩니까?
asktyagi

OP의 더미 스크립트를 사용하여 테스트하면 각 명령과 결과에 관계없이 ssh 시간 초과, 잘못된 도메인 등이 기록됩니다. 또는 유효한 ssh 주소의 경우 원격 셸에 명령이 기록됩니다. ssh 로그인에 대한 추가 정보가 필요한 경우 아마도 ssh -vv?
dragon951
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.