리눅스 리디렉션이란? (feat. 톰캣 로그가 저장되는 원리)
- 운영체제(OS)
- 2023. 3. 14.
리눅스를 쓰면 파일명.sh 형태의 bash 스크립트를 볼 일이 많습니다. 스크립트 내용을 살펴보면 자주 등장하는 기호들이 있는데 대표적인 것이 >, >>, 2>&1, 2> 등입니다. 이를 리디렉션이라고 부릅니다.
예를 들어, 아파치 톰캣을 실행하는 startup.sh 쉘 스크립트 파일에는 서버를 시작하고 출력되는 로그를 catalina.out 파일에 저장하는 내용이 있습니다.
...
CATALINA_OUT="$CATALINA_BASE"/logs/catalina.out
exec "$PRGDIR"/"$EXECUTABLE" start \
>> "$CATALINA_OUT" 2>&1 "&"
...
이 글을 읽으면 리디렉션이 사용된 위 스크립트를 이해하실 수 있습니다.
리디렉션이란?
리눅스에서 리디렉션(redirection)은 명령을 실행할 때 표준 입력과 출력 장치를 변경하는 기능입니다. 이 말을 이해하기 위해서는 리눅스의 표준 입력(stdin), 표준 출력(stdout), 표준 에러(stderr) 개념을 알아야 합니다. 간단히 설명드리겠습니다.
리눅스에서 모든 프로세스는 세 가지 스트림(Stream)이 있습니다.
- 표준 입력(stdin) : 입력을 읽는 스트림입니다. 숫자 0으로 표기합니다.
- 표준 출력(stdout) : 출력을 표시하는 스트림입니다. 숫자 1로 표기합니다.
- 표준 에러(stderr) : 에러를 표시하는 스트림입니다. 숫자 2로 표기합니다.
예를 들어, 프롬프트에 ls를 치면 현재 위치에 있는 파일을 모두 정상 출력합니다. 이게 표준 출력(stdout)입니다. ls /asdf 처럼 존재하지 않는 경로를 대상으로 ls를 치면 리눅스는 명령이 잘못됐다고 에러를 뱉습니다. 이게 표준 에러(stderr)입니다.
리디렉션으로 뭘 할 수 있는지에 대한 예시를 보면 좀 더 이해가 되실 겁니다.
예시) stdout 리디렉션
ls 명령어는 화면에 현재 위치의 파일들을 출력합니다. 그런데 이 출력 결과물을 리디렉션을 이용해서 파일에 저장할 수 있습니다.
ls > ls_result.txt
ls의 출력을 stdout으로 ls_result.txt라는 파일에 리디렉션 하는 명령입니다. 그 결과 ls_result.txt라는 파일이 생성되고 해당 파일에 출력 결과가 저장됩니다.
예시) stderr 리디렉션
이번엔 같은 방법으로 stderr를 리디렉션 해보겠습니다.
ls /asdf 2> ls_nonexistent_result.txt
이번엔 >가 아닌 2>가 사용됐습니다. 그 이유는 리디렉션 기호 앞에는 스트림을 숫자로 표기하기 때문입니다. ls /asdf에 대한 출력은 stderr이기 때문에 2>를 사용해야 합니다. 첫 번째 예시처럼 아무 숫자를 표기하지 않고 쓰면 1번인 stdout으로 리디렉션 한다고 간주됩니다.
만약 위 예시에서 2> 대신 >를 쓰면 출력되는 stdout이 없기 때문에 ls_nonexistent_result.txt에 출력이 저장되지 않습니다.
예시) 추가모드 리디렉션
이미 생성된 파일에 리디렉션을 다시 하면 기존에 있는 내용이 덮어쓰기 됩니다. 그러지 않고 맨 아래부터 추가로 이어서 내용을 넣고 싶으면 > 대신 >>를 사용합니다.
ls >> ls_result.txt
예시) stdout과 stderr를 모두 리디렉션
같은 파일에 stdout과 stderr를 모두 리디렉션 하려면 아래와 같이 표기합니다.
ls /asdf > ls_result.txt 2>&1
맨 앞에 ls /asdf > ls_result.txt까지는 ls의 출력을 stdout으로 ls_result.txt에 리디렉션 한다는 의미입니다. 결과가 stderr이기 때문에 stdout으로 저장하면 저장되는 게 없을 겁니다. 그러나 뒤에 2>&1는 stderr를 stdout으로 리디렉션한다는 의미입니다.
위 명령 내용을 정리하면 이렇습니다.
1. ls 출력을 stdout으로 ls_result.txt에 리디렉트 해줘
2. 그런데 만약 결과가 stderr이면 stdout으로 리디렉션 해줘.
그 결과 ls_result.txt엔 stdout과 stderr 출력 모두 저장됩니다. 참고로 &는 구분자의 역할을 합니다. 표시한 1이 표준 스트림이라는 걸 인식시키기 위해 사용됩니다.
무슨 말인지는 알겠지만 다소 직관적이지 못한 쓰임으로 느껴집니다. 이런 수요를 반영해서인지 대신 사용할 수 있는 &>라는 표시도 있습니다.
ls /asdf &> ls_result.txt
이 구문 역시 stdout과 stderr를 모두 ls_result.txt에 저장하라는 의미입니다. 좀 더 간단합니다.
위 내용들이 헷갈리시면 굳이 이해하지 않으셔도 그냥 stdout과 stderr를 모두 저장하려고 할 때 이런 두 가지 방법이 있다고 생각하시면 됩니다.
startup.sh 이해하기
이제 서두에 말씀드린 startup.sh의 일부 구문을 이해할 수 있습니다.
...
CATALINA_OUT="$CATALINA_BASE"/logs/catalina.out
exec "$PRGDIR"/"$EXECUTABLE" start \
>> "$CATALINA_OUT" 2>&1 "&"
...
1. CATALINA_OUT="$CATALINA_BASE"/logs/catalina.out
로그 파일인 catalina.out 파일 경로를 CATALINA_OUT에 저장합니다.
2. exec "$PRGDIR"/"$EXECUTABLE" start \
톰캣 서버를 시작합니다.
3. >> "$CATALINA_OUT" 2>&1 "&"
그에 대한 stdout과 stderr 출력을 모두 catalina.out에 이어 쓰기 방식으로 리디렉션 합니다.
“&”는 백그라운드 실행을 한다는 표시입니다.
혹시 리눅스 표준 스트림에 대해 더 궁금하시면 아래의 글을 읽어주세요.
'운영체제(OS)' 카테고리의 다른 글
메일로 받은 winmail.dat 파일 여는 방법 3가지 (0) | 2023.03.16 |
---|---|
nslookup 사용법 (IP / 도메인 확인하기) (0) | 2023.03.15 |
리눅스 scp 명령어 사용법 (서버 간 파일 전송) (0) | 2023.03.13 |
리눅스 kill 명령어 사용법 (kill -9 의미) (0) | 2023.03.11 |
맥OS DS_Store 파일이란? (삭제해도 될까?) (0) | 2023.03.10 |