목차
표준 출력(stdout) 이란?
리눅스에서 ls 명령어를 입력하면 그에 맞는 결과값이 터미널 화면에 출력된다.


리눅스는 내부적으로 ls 명령어의 실행 결과를 터미널 화면에 출력하기 위한 함수(ex. printf() ) 를 호출했을 것이다. 체감상으로는 위의 그림과 같이 printf() 함수가 터미널 화면에 바로 출력하게끔 작동하는 것처럼 보인다. 하지만 실제로는 그렇게 작동하지 않는다.

printf() 의 정확한 역할은 터미널 화면에 결과값을 출력하는 역할이 아니라, 표준 출력 이라는 곳으로 결과값을 전달하는 역할을 한다.
그럼 여기서 얘기하는 표준 출력이 도대체 뭘까?
표준 출력(stdout) 이란, 명령어의 실행 결과를 '출력할 곳'으로 이동시켜주는 통로이다.
- 표준 출력에 기본값으로 설정되어 있는 출력할 곳은 '터미널 화면' 이다.
- 표준 출력의 출력할 곳을 '터미널 화면'이 아닌 다른 곳(ex. 파일) 으로도 바꿀 수 있다.
표준 출력(stdout) 활용해보기
터미널 창에 결과값 출력하기
표준 출력(stdout)이란, 명령어의 실행 결과를 '출력할 곳'으로 이동시켜주는 통로라고 설명했다.

아래 명령어를 입력했을 때 터미널 화면에 결과값이 출력되는 이유는, 위의 그림과 같이 표준 출력이 결과값을 기본적으로 터미널 화면에 출력하게끔 설정되어 있기 때문이다.
$ ls
$ pwd
파일에 결과값 출력하기
표준 출력의 출력할 곳을 터미널 화면이 아닌 파일로 바꿔보자.

$ ls > list.txt # 터미널 화면에 아무것도 출력이 안됨
$ pwd > directory.txt # 터미널 화면에 아무것도 출력이 안됨
# 파일에 결과값이 출력(저장)됐는지 확인하기
$ ls
$ cat list.txt
$ cat directory.txt
터미널 화면에 출력돼야 할 결과값이 파일에 출력(저장)되었음을 알 수 있다.

이와 같이 표준 출력을 어디로 연결할 지 변경하는 것을 보고 리다이렉션(Redirection) 이라고 한다.
표준 에러 출력(stderr) 이란?
표준 에러 출력(stderr) 이란?
ls abc 와 같이 파라미터를 잘못 입력해 명령어를 입력하면, 명령어의 결과값이 아래와 같이 터미널 화면에 출력된다.

ls abc 명령어의 결과값이 터미널 화면에 출력되는 방식이 아닌, 파일에 출력되는 방식으로 작동시키기 위해 아래와 같이 명령어를 실행시켜봤다.
$ ls abc > list2.txt
# ls abc 명령어의 결과값이 파일에 잘 출력되었는지 확인하기
$ ls
$ cat list2.txt
그런데 여전히 cannot access 'abc': No such file or directory 라는 메시지가 출력었다. 그리고 list2.txt 파일이 생성되었지만 안에는 아무 내용도 저장되지 않았다. 왜 그럴까?


리눅스에서 명령어의 실행 결과가 아닌 에러 메시지를 출력할 때는 별도의 메서드를 호출(ex. perror() ) 해서 출력한다. 즉, 정상적인 실행 결과값을 출력하는 함수와 에러 메시지를 출력하는 함수가 구별되어 있다. 이 때, 에러 메시지를 출력하는 함수인 perror() 의 역할은 표준 에러 출력 이라는 곳으로 에러 메시지를 전달하는 역할을 한다. 그러면 에러 메시지를 전달 받은 표준 에러 출력은, 기본적으로 터미널 화면에 에러 메시지를 출력한다.

위 예제에서는 ls abc > list2.txt 라는 명령어를 통해 표준 출력을 터미널 화면이 아닌 파일로 연결되도록 바꿨다. 하지만 표준 출력과 표준 에러 출력은 서로 독립적인 통로이기 때문에, 에러 메시지가 발생했을 때는 표준 출력이 아닌 표준 에러 출력의 통로를 거쳐 터미널 화면으로 에러 메시지가 출력된 것이다.
그럼 어떻게 해야 에러 메시지를 터미널 화면이 아닌 파일로 출력되게 만들 수 있을까?
아래 명령어와 같이 > 가 아닌 2> 라는 기호를 사용해야 한다. 그러면 표준 에러 출력은 파일에 저장된다. 확인해 보자.
$ ls abc 2> list3.txt
# 표준 에러 출력이 파일에 잘 저장되었는지 확인
$ ls
$ cat list3.txt

에러 메시지가 터미널 화면에 출력되지 않고 파일에 저장되는 것을 확인할 수 있다. 아래의 그림과 같이 작동한 것이다.

한 가지 더 테스트 해보자.
아래와 같이 명령어를 입력했을 때 명령어의 정상적인 결과값은 어떻게 처리가 되는 지 확인해보자.
$ ls 2> list4.txt
# 표준 출력이 파일에 저장되는 지 확인
$ ls
$ cat list4.txt

에러 메시지가 아닌 정상적인 결과값은 표준 출력을 통해 전달되므로 파일이 아닌 터미널 화면으로 출력되는 것을 확인 할 수 있다.
표준 출력과 표준 에러 출력 둘 다 파일로 출력(= 리다이렉션) 하고 싶다면 어떻게 해야 할까?
'표준 출력' 과 '표준 에러 출력' 둘 다 파일로 출력하려면?
1. 서로 다른 파일로 출력하게 만들고 싶은 경우
$ ls > list.txt 2> error.txt # 정상적인 결과값을 출력하는 경우
$ ls xxx > list.txt 2> error.txt # 에러 메시지를 출력하는 경우
2. 같은 파일로 출력하게 만들고 싶은 경우
$ ls > all.txt 2> all.txt # 이렇게 작성하면 충돌로 인해 메시지가 잘못 기록될 수 있다.
$ ls > all.txt 2> &1 # 이렇게 작성하는 것이 올바른 방식이다.
정리
- 표준 출력(stdout) 이란, 명령어의 실행 결과를 '출력할 곳'으로 이동시켜주는 통로이다.
- 표준 출력을 어디로 연결할 지 변경할 때(= 리다이렉션)는 > 를 사용한다.
- 표준 에러 출력(stderr) 이란, 명령어를 실행 시 발생한 에러 메시지를 '출력할 곳'으로 이동시켜주는 통로이다.
- 표준 에러 출력을 어디로 연결할 지 변경할 때 (= 리다이렉션) 는 2> 를 사용한다.
표준 출력(stdout)과 표준 에러 출력(stderr) 의 추가 기능
기존 파일에 덮어 쓰기 vs 기존 파일에 이어서 쓰기
1. 표준 출력인 경우
[기존 파일에 덮어 쓰기]
$ pwd > result.txt # pwd 의 출력 결과값을 result.txt 파일에 저장
# 파일에 출력값이 잘 저장되었는지 확인
$ ls
$ cat result.txt
# 경로 이동 후 pwd 의 출력 결과값을 이전 경로의 result.txt 파일에 저장
# 한 번 더 이 명령어를 실행시키면 기존파일에 덮어씌움 (즉, 기존 파일의 내용이 날아감)
$ cd nex-box
$ pwd > ../result.txt

일반적으로 서버를 운영하다보면 로그를 꾸준히 쌓아나가는 게 중요하다. 그런데 명령어 새로 한번 쳤다고 기존 파일의 내용이 덮어씌워지면 문제가 될 수 있다. 따라서 기존 파일의 내용은 사라지지 않은 채로 기존 파일에 출력값을 이어서 작성하는 방법을 알아보자.
[기존 파일에 이어서 쓰기]
# 기존 파일 내용 확인
$ cat result.txt
# 기존 파일에 이어서 출력값 남기기
$ pwd >> result.txt
# 파일 내용 확인
$ cat result.txt

1. 표준 에러 출력인 경우
[기존 파일에 덮어 쓰기]
$ ls abc 2> error.txt # ls 의 에러 출력 결과값을 error.txt 파일에 저장
# 파일에 출력값이 잘 저장되었는지 확인
$ ls
$ cat error.txt
# 한 번 더 이 명령어를 실행시키면 기존 파일을 덮어 씌움
$ ls abc 2> error.txt

[기존 파일에 이어서 쓰기]
# 기존 파일 내용 확인
$ cat error.txt
# 기존 파일에 이어서 출력값 남기기
$ ls abc 2>> error.txt
# 파일 내용 확인
$ cat error.txt
# 한 번 더 테스트해보기
$ ls fff 2>> error.txt
$ cat error.txt

정리
> 대신 >> 를 사용하면 파일을 덮어쓰지 않고 파일의 끝에 이어서 출력값을 덧붙여 기록하게 된다. 만약 기존의 출력값이 사라지면 안 되는 경우에는 반드시 >> 를 사용하도록 하자.
Spring Boot 서버가 출력하는 로그를 파일로 남기기
사전 환경 세팅
1. JDK 설치하기
Java 17을 기준으로 구성되 Spring Boot 서버를 실행시킬 예정이다. Spring Boot 서버를 실행시키려면 JDK 가 설치되어 있어야 한다. 따라서 JDK 17버전을 설치해보자.
$ sudo apt update # 패키지 목록 최신화
$ sudo apt install openjdk-17-jdk # openjdk-17-jdk라는 패키지 설치
2. 잘 설치됐는지 확인하기
$ sudo apt list --installed | grep openjdk-17-jdk # 설치된 패키지 확인하기
$ java -version # 설치된 자바 버전 확인하기


3. 서버 실행시키기
# 기존 빌드된 파일을 삭제하고 새롭게 JAR 로 빌드
$ ./gradlew clean build
# 새롭게 빌드된 JAR 파일은 build/libs 에 있다
$ cd build/libs
# 지정한 JAR 파일을 하나의 독립 실행 프로그램처럼 JVM 위에서 실행
$ java -jar linux-springboot-0.0.1-SNAPSHOT.jar

Spring Boot 프로젝트를 실행시켰더니 로그가 터미널 화면에 출력된 것을 확인할 수 있다.
즉, 아래와 같이 구성되어 있을 것이다.

그렇다면 이 구조에서 Spring Boot의 로그를 터미널 화면이 아닌 파일에 남기게끔 바꿔보자.
Spring Boot 서버가 출력하는 로그를 파일로 남기기
1. 실행시킨 서버 종료시키기
Ctrl + c 누르기
2. 표준 출력과 표준 에러 출력을 파일로 리다이렉션하기
# 표준 출력과 표준 에러 출력에서 발생하는 값을 app.log 파일로 전송
$ java -jar linux-springboot-0.0.1-SNAPSHOT.jar >> app.log 2>&1
- 표준 출력과 표준 에러 출력을 같은 파일로 출력하게 만들기 위해 2>&1 을 사용
- Spring Boot 를 실행시킬 때마다 기존 로그 파일의 내용이 삭제되지 않게 > 대신에 >> 를 사용

3. 로그가 파일에 잘 저장되었는지 확인하기
# Ctrl + c 로 서버 종료 후 app.log 파일 출력하기
$ ls
$ cat app.log
app.log 파일에 Spring Boot 의 로그가 저장되어있음을 알 수 있다.

'리눅스 > 리눅스 입문' 카테고리의 다른 글
| [리눅스 입문] 명령어들을 자동화시킬 수 있는 쉘 스크립트 (0) | 2025.10.06 |
|---|---|
| [리눅스 입문] 백엔드 서버를 운영할 때 자주 사용하는 명령어 (0) | 2025.10.06 |
| [리눅스 입문] 패키지 매니저 (apt) (0) | 2025.10.01 |
| [리눅스 입문] 리눅스 권한 문제 (Permission Denied) (0) | 2025.09.30 |
| [리눅스 입문] 우분투 리눅스(Ubuntu Linux) 시작 및 기본 명령어 (1) | 2025.09.28 |