Computer >> 컴퓨터 >  >> 프로그래밍 >> Bash 프로그래밍

Linux 터미널 리디렉션 완벽 가이드: 어디서든 데이터 읽고 쓰기

입력과 출력의 리디렉션(redirection)은 모든 프로그래밍 및 스크립팅 언어가 기본적으로 갖춘 기능입니다. 엄밀히 말하면 컴퓨터와 상호작용하는 순간마다 항상 일어나는 동작이기도 합니다. 입력은 stdin(표준 입력, 보통 키보드나 마우스)에서 읽히고, 출력은 stdout(표준 출력, 텍스트 또는 데이터 스트림)으로 전달되며, 오류는 stderr(표준 오류)로 전송됩니다. 이러한 데이터 스트림의 존재를 이해하면 Bash나 Zsh 같은 셸을 사용할 때 정보가 어디로 향할지 직접 통제할 수 있습니다.

표준 입력, 표준 출력, 표준 오류는 리눅스 파일시스템상에 실제 위치로 존재합니다. /dev 디렉터리에서 확인할 수 있습니다:

$ ls /dev/std*
/dev/stderr@  /dev/stdin@  /dev/stdout@

이들을 직접 다룰 일은 많지 않지만, 데이터를 보낼 수 있는 '메타 위치'라고 생각하면 때때로 유용합니다.

리디렉션의 기본 원리는 간단합니다. 출력을 보낼 때는 > 문자를, 입력을 받아올 때는 < 문자를 필요한 만큼 사용하면 됩니다.

출력 리디렉션

ls 명령의 결과를 파일에 저장하려면 다음과 같이 입력합니다:

$ ls > list.txt

평소처럼 ls의 결과가 화면에 나타나지 않습니다. 출력이 화면 대신 list.txt 파일에 기록되기 때문입니다. 이 기능은 매우 유연해서 한 파일의 내용을 다른 파일로 복사하는 데도 활용할 수 있습니다. 꼭 텍스트 파일일 필요는 없으며, 바이너리 데이터에도 리디렉션을 사용할 수 있습니다:

$ cat image.png > picture.png

(굳이 이런 방식을 쓰는 이유가 궁금하다면, 파일 권한에 때때로 유용한 부수 효과가 있기 때문입니다.)

입력 리디렉션

명령 "안으로" 입력을 리디렉션할 수도 있습니다. 다만 대부분의 명령은 이미 인자(argument)로 입력을 받도록 설계되어 있기 때문에, 출력 리디렉션만큼 자주 쓰이지는 않습니다. 그럼에도 명령이 인자 목록을 요구하고, 그 목록이 파일 안에 들어 있어 복사·붙여넣기 없이 빠르게 터미널로 넣고 싶을 때 유용합니다:

$ sudo dnf install $(<package.list)

입력 리디렉션의 대표적인 활용법으로는 here-document(줄여서 here-doc)와 here-string 기법이 있습니다. 이 방식은 특별한 EOF(파일 끝) 마커를 만날 때까지 텍스트 블록 전체를 표준 입력 스트림으로 보냅니다. 마커는 대부분 EOF를 쓰지만, 고유하다고 판단되는 문자열이면 무엇이든 가능합니다. 터미널에 아래 내용을 두 번째 EOF까지 직접 입력해 보세요:

$ echo << EOF
> foo
> bar
> baz
> EOF

예상되는 결과는 다음과 같습니다:

foo
bar
baz

here-doc는 Bash 스크립트 작성자들이 여러 줄의 텍스트를 파일이나 화면에 한꺼번에 출력할 때 즐겨 쓰는 요령입니다. EOF 마커로 절을 마무리하는 것만 잊지 않으면, 길게 늘어진 echoprintf 문장 목록을 피할 수 있는 효율적인 방법입니다.

here-stringhere-doc과 비슷하지만 문자열 하나로만 구성됩니다(따옴표로 묶어 여러 문자열을 하나처럼 보내는 것도 가능합니다):

$ cat <<< "foo bar baz"
foo bar baz

오류 메시지 리디렉션

오류 메시지는 stderr라는 스트림으로 전송되며, 리디렉션 시에는 2>로 지정합니다. 다음 명령은 오류 메시지를 output.log라는 파일로 보냅니다:

$ ls /nope 2> output.log

/dev/null로 데이터 보내기

표준 입력, 표준 출력, 오류를 위한 위치가 있는 것처럼, 리눅스 파일시스템에는 '아무데도 없는 곳(nowhere)'을 위한 위치도 있습니다. 이름은 null이며 /dev 디렉터리에 있어서, 자주 쓰는 사람들은 "슬래시 dev 슬래시 null"이라고 말하기 번거로워 흔히 "devnull"이라고 부릅니다.

리디렉션을 사용하면 데이터를 /dev/null로 보낼 수 있습니다. 예를 들어 find 명령은 검색 과정에서 권한 충돌을 자주 보고하는 등 출력이 다소 장황한 편입니다:

$ find ~ -type f
/home/seth/actual.file
find: `/home/seth/foggy': Permission denied
find: `/home/seth/groggy': Permission denied
find: `/home/seth/soggy': Permission denied
/home/seth/zzz.file

find 명령은 이를 오류로 처리하기 때문에, 오류 메시지만 /dev/null로 보내면 결과를 깔끔하게 정리할 수 있습니다:

$ find ~ -type f 2> /dev/null
/home/seth/actual.file
/home/seth/zzz.file

리디렉션 활용하기

리디렉션은 Bash에서 데이터를 한곳에서 다른 곳으로 옮기는 효율적인 방법입니다. 항상 쓰이지는 않겠지만, 필요할 때 활용할 줄 안다면 파일을 열고 데이터를 복사·붙여넣는 등 마우스 이동과 수많은 키 입력이 따르는 불필요한 작업을 크게 줄일 수 있습니다. 번거로운 방법에 의존하지 말고, 리디렉션으로 더 편리한 터미널 작업 환경을 경험해 보세요.