리눅스 입출력 리다이렉션

CompTIABeginner
지금 연습하기

소개

이 실습에서는 리눅스 셸에서 입력과 출력을 리다이렉션하는 핵심 기술을 배웁니다. 표준 출력 (stdout), 표준 에러 (stderr), 표준 입력 (stdin) 이라는 세 가지 표준 스트림을 조작하여 명령어의 데이터 흐름을 제어하는 방법을 살펴봅니다. 이 실습을 통해 필수적인 리다이렉션 연산자를 직접 사용해 보면서 명령어 실행 결과를 저장하고, 에러 메시지를 관리하며, 파일로부터 명령어에 입력을 전달하는 방법을 익힐 수 있습니다.

실습 과정에서 > 연산자를 사용하여 명령어 출력을 파일로 보내 기존 내용을 덮어쓰는 방법과, >> 연산자를 사용하여 데이터를 유지하면서 내용을 추가하는 방법을 연습합니다. 또한 2>를 사용하여 에러 메시지만 별도로 리다이렉션하는 방법과 표준 출력 및 표준 에러를 하나의 파일로 통합하는 방법도 배웁니다. 마지막으로 tee 명령어를 사용하여 화면에 출력을 표시함과 동시에 파일로 저장하는 방법을 익히고, < 연산자를 사용하여 키보드 대신 파일에서 입력을 읽어오도록 표준 입력을 리다이렉션하는 연습을 진행합니다.

이 실습은 학습과 연습을 돕기 위해 단계별 지침을 제공하는 가이드 실습입니다. 각 단계를 완료하고 실무 경험을 쌓으려면 지침을 주의 깊게 따르십시오. 통계 데이터에 따르면 이 실습은 중급 난이도이며, 수료율은 78%입니다. 학습자들로부터 99%의 긍정적인 평가를 받았습니다.

> 연산자를 이용한 표준 출력 리다이렉션

이 단계에서는 명령어의 표준 출력을 리다이렉션하는 방법을 배웁니다. 리눅스 셸에서 대부분의 명령어는 어떤 결과를 생성합니다. 기본적으로 "표준 출력"(또는 stdout) 이라고 불리는 이 결과물은 터미널 화면에 표시됩니다. 하지만 > 연산자를 사용하면 이 출력을 파일로 보낼 수 있습니다. 이는 명령어 실행 결과를 저장하거나 로그 파일을 생성하고 보고서를 만들 때 매우 유용합니다.

먼저, 간단한 명령어를 실행하여 터미널에 출력되는 결과를 확인해 보겠습니다.

echo "Hello from LabEx"

터미널에 다음과 같은 결과가 직접 출력되는 것을 볼 수 있습니다.

Hello from LabEx

이제 이 출력을 터미널 대신 파일로 리다이렉션해 보겠습니다. > 연산자 뒤에 파일 이름을 붙여 사용합니다. 이렇게 하면 셸은 echo 명령어의 출력을 현재 디렉토리 (~/project) 에 있는 hello.txt라는 파일로 보냅니다.

다음 명령어를 실행하세요.

echo "Hello from LabEx" > hello.txt

이번에는 터미널에 아무런 결과도 출력되지 않는 것을 알 수 있습니다. 출력이 hello.txt 파일로 전달되었기 때문입니다. cat 명령어를 사용하여 파일 내용을 확인할 수 있습니다.

cat hello.txt

리다이렉션되었던 텍스트가 출력됩니다.

Hello from LabEx

> 연산자는 파일이 존재하지 않으면 새로 생성합니다. 주의할 점은, 파일이 이미 존재하는 경우 > 연산자는 아무런 경고 없이 기존의 모든 내용을 덮어쓴다는 것입니다. 실제로 어떻게 작동하는지 확인해 보겠습니다.

먼저, 현재 디렉토리의 파일 목록을 나열하고 이를 file_list.txt라는 새 파일에 저장합니다.

ls -l > file_list.txt

이제 file_list.txt의 내용을 확인합니다.

cat file_list.txt

프로젝트 디렉토리에 있는 파일 목록이 다음과 같이 표시될 것입니다.

total 4
-rw-rw-r-- 1 labex labex  0 Jun 25 14:56 file_list.txt
-rw-rw-r-- 1 labex labex 17 Jun 25 14:56 hello.txt

이제 다른 명령어를 실행하고 그 출력을 동일한 파일인 file_list.txt에 리다이렉션해 보겠습니다.

echo "This is new content." > file_list.txt

file_list.txt의 내용을 다시 확인해 보면, 원래 있던 파일 목록이 사라지고 새로운 내용으로 대체된 것을 볼 수 있습니다.

cat file_list.txt

출력 결과는 다음과 같습니다.

This is new content.

이것이 > 연산자의 덮어쓰기 동작 방식입니다. 다음 단계에서는 기존 내용을 덮어쓰지 않고 파일 끝에 출력을 추가하는 방법을 배우겠습니다.

>> 연산자를 이용한 표준 출력 추가

이 단계에서는 기존 내용을 삭제하지 않고 파일의 끝에 출력을 추가하는 방법을 배웁니다. 이전 단계에서 > 연산자는 대상 파일을 덮어쓴다는 것을 확인했습니다. 이를 방지하려면 추가 (append) 연산자인 >>를 사용할 수 있습니다. 이 연산자는 시간이 지남에 따라 새로운 기록을 계속 추가해야 하는 로그 파일을 관리할 때 매우 유용합니다.

먼저 초기 내용이 담긴 파일을 만들어 보겠습니다. 파일 이름은 greetings.txt로 정하겠습니다.

echo "Hello, this is the first line." > greetings.txt

내용을 확인합니다.

cat greetings.txt

출력 결과는 다음과 같습니다.

Hello, this is the first line.

이제 파일을 덮어쓰는 대신 >> 연산자를 사용하여 새 줄을 추가해 보겠습니다.

echo "This is the second line, appended." >> greetings.txt

greetings.txt의 내용을 다시 확인합니다.

cat greetings.txt

이번에는 기존 내용 뒤에 새로운 줄이 추가된 것을 확인할 수 있습니다.

Hello, this is the first line.
This is the second line, appended.

>> 연산자는 로그 파일을 만드는 데 최적입니다. activity.log라는 간단한 로그 파일을 만들고 date 명령어를 사용하여 타임스탬프를 추가해 보겠습니다.

date > activity.log

이제 동일한 파일에 또 다른 타임스탬프를 추가해 봅니다.

date >> activity.log

최종 activity.log 파일을 열어 두 항목이 모두 있는지 확인합니다.

cat activity.log

출력 결과에 두 개의 타임스탬프가 표시되며, 이는 두 번째 명령어가 파일을 덮어쓰지 않고 출력을 추가했음을 보여줍니다. 정확한 시간은 실행 시점에 따라 다를 수 있습니다.

Wed Jun 25 14:56:53 CST 2025
Wed Jun 25 14:56:56 CST 2025

이처럼 >>는 기존 데이터를 보존하면서 파일 끝에 새로운 데이터를 추가하므로, 새로운 정보로 파일을 안전하게 업데이트할 수 있는 방법입니다.

2> 연산자를 이용한 표준 에러 리다이렉션

이 단계에서는 에러 메시지를 관리하는 방법을 배웁니다. 명령어는 표준 출력 (stdout) 외에도 "표준 에러"(stderr) 라고 불리는 또 다른 유형의 출력을 생성합니다. 이는 에러 메시지와 진단 정보를 위해 특별히 사용되는 별도의 스트림입니다. 기본적으로 stdoutstderr는 모두 터미널에 표시되지만, 지금까지 배운 리다이렉션 연산자 (>>>) 는 stdout에만 영향을 미칩니다.

stderr를 리다이렉션하려면 파일 디스크립터 번호인 2를 지정해야 합니다. 사실 > 연산자는 stdout의 파일 디스크립터인 1을 사용하는 1>의 줄임표현입니다. 따라서 stderr를 리다이렉션하려면 2>를 사용합니다.

실제로 어떻게 작동하는지 확인하기 위해 에러를 발생시켜 보겠습니다. 존재하지 않는 파일을 나열해 보라고 명령하겠습니다.

ls non_existent_file

이 명령어는 실패하며 터미널에 에러 메시지를 출력합니다.

ls: cannot access 'non_existent_file': No such file or directory

이제 일반적인 > 연산자를 사용하여 이를 리다이렉션해 보겠습니다.

ls non_existent_file > output.txt

에러 메시지가 여전히 터미널에 출력되는 것을 볼 수 있습니다. > 연산자가 이를 캡처하지 못했기 때문입니다. output.txt 파일을 확인해 보면 비어 있는 것을 알 수 있습니다.

cat output.txt

표준 출력은 생성되지 않고 표준 에러만 발생했기 때문에 파일에 아무것도 기록되지 않은 것입니다.

이제 2>를 사용하여 표준 에러를 error.log라는 파일로 올바르게 리다이렉션해 보겠습니다.

ls non_existent_file 2> error.log

이번에는 터미널에 아무런 메시지도 나타나지 않습니다. 에러가 성공적으로 리다이렉션되었습니다. error.log의 내용을 확인하여 캡처된 메시지를 볼 수 있습니다.

cat error.log

ls 명령어에서 발생한 에러 메시지가 출력됩니다.

ls: cannot access 'non_existent_file': No such file or directory

>>가 표준 출력을 추가하는 것과 마찬가지로, 2>>를 사용하여 표준 에러를 파일에 추가할 수 있습니다. 또 다른 존재하지 않는 파일을 나열해 보고 그 에러를 error.log에 추가해 보겠습니다.

ls another_fake_file 2>> error.log

이제 error.log의 내용을 다시 확인합니다.

cat error.log

새로운 에러 메시지가 파일 끝에 추가된 것을 볼 수 있습니다.

ls: cannot access 'non_existent_file': No such file or directory
ls: cannot access 'another_fake_file': No such file or directory

이 기술은 정상적인 출력과 에러 메시지를 분리하는 데 매우 유용하며, 메인 출력 파일을 어지럽히지 않고 나중에 검토할 수 있도록 에러를 기록할 수 있게 해줍니다.

표준 출력과 표준 에러를 단일 파일로 리다이렉션하기

이 단계에서는 표준 출력과 표준 에러를 포함한 명령어의 모든 출력을 하나의 파일로 캡처하는 방법을 배웁니다. 이는 발생한 에러를 포함하여 스크립트나 명령어의 실행 전체 기록을 남기고 싶을 때 특히 유용합니다.

stdoutstderr를 모두 생성하는 명령어를 사용해 보겠습니다. 존재하는 파일 (/etc/passwd) 과 존재하지 않는 파일 (non_existent_file) 을 동시에 나열해 봅니다.

ls -l /etc/passwd non_existent_file

터미널에 두 종류의 출력이 표시됩니다. 첫 번째 줄은 표준 에러이고, 두 번째 줄은 표준 출력입니다.

ls: cannot access 'non_existent_file': No such file or directory
-rw-r--r-- 1 root root 1916 Jul 18  2024 /etc/passwd

stdout을 위해 >만 사용하여 리다이렉션을 시도하면 에러 메시지는 여전히 화면에 나타납니다.

ls -l /etc/passwd non_existent_file > output_only.txt

터미널 출력:

ls: cannot access 'non_existent_file': No such file or directory

그리고 output_only.txt에는 표준 출력 내용만 담기게 됩니다.

cat output_only.txt
-rw-r--r-- 1 root root 1916 Jul 18  2024 /etc/passwd

두 스트림을 모두 하나의 파일로 리다이렉션하려면 &> 연산자를 사용할 수 있습니다. 이는 stdout(파일 디스크립터 1) 과 stderr(파일 디스크립터 2) 를 모두 지정된 파일로 보내는 편리한 약식 표현입니다.

한번 해보겠습니다. 모든 출력을 combined.log라는 파일로 리다이렉션합니다.

ls -l /etc/passwd non_existent_file &> combined.log

이번에는 터미널에 아무것도 출력되지 않습니다. 모든 출력이 combined.log에 캡처되었습니다. 내용을 확인해 보겠습니다.

cat combined.log

파일에 표준 출력과 표준 에러가 모두 포함되어 있는 것을 볼 수 있습니다.

ls: cannot access 'non_existent_file': No such file or directory
-rw-r--r-- 1 root root 1916 Jul 18  2024 /etc/passwd

동일한 결과를 얻기 위한 좀 더 전통적이고 약간 복잡한 구문도 있습니다: > file 2>&1. 이를 분석해 보면 다음과 같습니다.

  • > file: 표준 출력 (파일 디스크립터 1) 을 file로 리다이렉션합니다.
  • 2>&1: 표준 에러 (파일 디스크립터 2) 를 표준 출력 (파일 디스크립터 1) 이 가는 곳과 동일한 위치로 리다이렉션합니다. stdout이 이미 file로 가고 있으므로, stderr도 그곳으로 보내집니다.

이 방법을 사용하여 출력을 combined_traditional.log에 저장해 보겠습니다.

ls -l /etc/passwd non_existent_file > combined_traditional.log 2>&1

마찬가지로 터미널에는 아무것도 나타나지 않습니다. 파일을 확인하면 동일한 결과가 나옵니다.

cat combined_traditional.log
ls: cannot access 'non_existent_file': No such file or directory
-rw-r--r-- 1 root root 1916 Jul 18  2024 /etc/passwd

&>가 더 짧고 선호되지만, 오래된 스크립트에서는 2>&1 형식을 자주 보게 되므로 이것이 무엇을 의미하는지 이해하는 것이 중요합니다. 두 스트림을 모두 추가 (append) 하려면 &>> 또는 >> file 2>&1을 사용하면 됩니다.

tee 를 이용한 출력 분할 및 < 를 이용한 표준 입력 리다이렉션

마지막 단계에서는 두 가지 상호 보완적인 리다이렉션 개념을 살펴봅니다. tee 명령어를 사용하여 출력을 분할하는 방법과 < 연산자를 사용하여 파일로부터 명령어에 입력을 제공하는 방법입니다.

tee를 이용한 출력 분할

때로는 명령어의 출력을 파일에 저장하면서 동시에 터미널에서도 보고 싶을 때가 있습니다. >>> 연산자는 출력을 파일로만 리다이렉션하여 화면에서 숨겨버립니다. tee 명령어는 출력을 분할하여 파일과 표준 출력 (화면) 양쪽으로 보냄으로써 이 문제를 해결합니다. 이 이름은 흐름을 두 경로로 나누는 배관의 T 자형 분기관 (T-splitter) 에서 유래되었습니다.

실제로 확인해 보겠습니다. /etc/ 디렉토리의 내용을 나열하고, tee를 사용하여 화면에 목록을 표시하는 동시에 etc_listing.txt라는 파일에 저장해 보겠습니다.

ls /etc/ | tee etc_listing.txt

터미널에 전체 디렉토리 목록이 출력되는 것을 볼 수 있습니다. 동시에 tee 명령어는 정확히 동일한 내용을 etc_listing.txt에 기록했습니다. 이를 확인해 보세요.

cat etc_listing.txt

파일의 내용이 화면에서 본 것과 일치할 것입니다.

기본적으로 tee는 대상 파일을 덮어씁니다. 대신 파일에 내용을 추가하려면 -a 옵션을 사용합니다. 이는 로깅 작업에 매우 유용합니다. 로그 파일을 만들고 두 개의 항목을 추가해 보겠습니다.

date | tee system_log.txt
echo "User labex performed a system check." | tee -a system_log.txt

첫 번째 명령어는 현재 날짜가 담긴 system_log.txt를 생성합니다. 두 번째 명령어는 tee -a를 사용하여 날짜를 삭제하지 않고 새로운 줄을 추가합니다. 최종 파일을 확인해 보겠습니다.

cat system_log.txt

출력 결과에 두 줄이 모두 표시됩니다.

Wed Jun 25 14:56:53 CST 2025
User labex performed a system check.

<를 이용한 표준 입력 리다이렉션

이제 출력 리다이렉션의 반대인 표준 입력 (stdin) 리다이렉션을 살펴보겠습니다. sort, wc, cat과 같은 많은 명령어는 stdin(보통 키보드) 으로부터 데이터를 읽을 수 있습니다. < 연산자를 사용하면 명령어에 키보드 대신 파일에서 입력을 가져오도록 지시할 수 있습니다.

먼저 항목 목록이 포함된 간단한 파일을 만들어 보겠습니다. 이름은 items.txt로 하겠습니다.

echo "banana" > items.txt
echo "apple" >> items.txt
echo "cherry" >> items.txt

이제 정렬되지 않은 세 개의 항목이 들어 있는 items.txt 파일이 준비되었습니다. sort 명령어는 텍스트 줄을 정렬할 수 있습니다. <를 사용하여 items.txtsort 명령어에 입력으로 넣어보겠습니다.

sort < items.txt

명령어는 items.txt의 내용을 입력으로 읽어 정렬한 후, 그 결과를 표준 출력 (터미널) 에 출력합니다.

apple
banana
cherry

이는 sort items.txt를 실행하는 것과 기능적으로 유사하지만, 파일을 명령어의 표준 입력으로 리다이렉션한다는 강력한 개념을 보여줍니다. 이는 파일 이름을 인자로 받지 않고 오직 stdin으로부터만 읽을 수 있는 명령어와 작업할 때 필수적입니다.

마지막 예로 cat < items.txt를 생각해 보세요. 이는 cat에게 items.txt로부터 입력을 읽으라고 지시하며, cat은 입력을 그대로 출력하는 역할을 하므로 파일의 내용을 화면에 표시하게 됩니다.

cat < items.txt

이것으로 리눅스의 기본적인 입출력 리다이렉션 학습을 마칩니다. 이제 명령어의 입력을 어디서 가져오고 출력을 어디로 보낼지 제어할 수 있는 도구를 갖추게 되었습니다.

요약

이 실습에서는 리눅스에서 명령어 출력을 리다이렉션하는 기본 원리를 배웠습니다. 먼저 > 연산자를 사용하여 명령어의 표준 출력 (stdout) 을 파일로 보내는 방법을 익혔으며, 이 연산자가 기존 파일을 덮어쓴다는 점을 확인했습니다. 덮어쓰기를 방지하기 위해 >> 연산자를 사용하여 파일 끝에 출력을 추가하는 방법도 연습했습니다. 또한 2> 연산자를 사용하여 표준 에러 (stderr) 를 파일로 리다이렉션하는 방법을 배웠는데, 이는 표준 출력과 별개로 에러 메시지만 캡처하는 데 유용합니다.

더 나아가, 종합적인 로깅을 위해 stdoutstderr를 모두 하나의 파일로 리다이렉션하여 이러한 개념들을 통합하는 방법을 살펴보았습니다. 출력을 분할하여 파일에 저장하는 동시에 터미널에 표시할 수 있게 해주는 tee 명령어도 탐구했습니다. 마지막으로 < 연산자를 사용하여 표준 입력 (stdin) 을 리다이렉션함으로써, 명령어가 키보드 대신 파일에서 입력을 읽어오도록 하는 방법을 익혔습니다.