리디렉션(Redirection)
리디렉션(redirection)의 사전적 의미는 '방향 전환'이다. '스트림을 리디렉션 한다'라고 하면 스트림을 어느 방향으로 보내는 것일까? 정답은 파일이다. 리눅스의 리디렉션은 스트림을 파일로 저장하거나 파일의 내용을 스트림으로 가져오는 것을 의미한다.
출력 리디렉션(Output Redirection)
출력 리디렉션은 프로세스의 출력 스트림을 파일로 출력하는 것을 의미한다. 프로세스의 표준 스트림 중 표준 출력과 표준 에러가 출력 스트림이므로 두 스트림을 파일로 리디렉션 할 수 있다. 표준 출력과 표준 에러 외에도 프로세스가 열어놓은 다른 스트림을 파일로 출력할 수 있다.
표준 출력과 표준 에러 리디렉션 하기
출력 리디렉션의 기본 형식은 다음과 같다.
$ command [stream_number]> file
$ command [stream_number]>> file
>를 부등호보다는 화살표로 생각하면 이해하기 쉽다. 실행한 명령의 출력 스트림을 파일로 보낸다는 의미이다. >는 저장할 내용을 파일에 덮어쓴다. 그래서 기존 파일에 리디렉션 하면 파일 내용이 삭제되고 새롭게 저장한 내용만 남는다. 파일이 존재하지 않는 경우에는 파일을 생성하면서 내용을 저장한다. >>는 파일의 끝부분에 내용을 추가한다. 이 역시 존재하지 않는 파일에 리디렉션 하면 파일을 새롭게 생성해 저장한다.
>나 >> 앞에 스트림 번호는 입력할 수도 있고, 생략할 수도 있다. 스트림 번호를 생략하면 표준 출력(스트림 번호 1)이 기본 값으로 설정된다. 표준 에러는 스트림 번호 2로 표기한다.
$ mkdir redirect-test
$ cd redirect-test/
echo 명령어가 표준 출력으로 보내는 내용을 파일로 리디렉션 해보자. 명령 뒤에 >를 붙이고, 그 뒤에 저장할 파일 이름을 지정한다. greetings라는 파일이 없던 상태이므로 파일이 새로 생성된다.
$ echo "hello, world!" > greetings
$ ls
$ cat greetings
$ echo "hey~" > greetings
$ cat greetings
이미 존재하는 greetings 파일에 다시 표준 출력을 리디렉션 하면 이전에 저장한 내용은 없어지고, 새로운 내용이 저장된다.
기존 내용을 덮어쓰지 않고 파일에 새로운 내용을 추가하려면 > 대신 >>를 사용하면 된다. 새로운 내용은 파일 끝에 저장된다.
표준 에러를 리디렉션 하는 것도 표준 출력을 리디렉션 하는 것과 비슷하다. 일반적으로 정상 출력 내용은 표준 출력을 통해, 에러 메시지 등은 표준 에러를 통해 출력된다.
실행할 수 없는 명령을 입력해 에러를 발생시킨다.
$ this is error command > errmsg
표준 출력을 리디렉션 해보자. 리디렉션 했지만 에러 메시지가 화면에 그대로 출력되고, errmsg 파일에는 아무런 내용이 없는 것을 확인할 수 있다.
$ this is error command 2> errmsg
이번에는 표준 에러를 리디렉션 하고, errmsg 파일의 내용을 확인해 보자. 화면에는 아무 내용도 나오지 않고, errmsg 파일을 확인해 보면 에러 메시지가 저장되어 있다. 표준 에러를 파일로 리디렉션 했기 때문이다.
표준 출력과 표준 에러 한꺼번에 리디렉션 하기
출력되는 내용을 리디렉션 하려면 해당 내용이 표준 출력을 통해 출력됐는지, 표준 에러를 통해 출력됐는지 알아야 합니다. 명령의 실행 결과가 성공할지 실패할지 모르는 상황이라면 어떤 스트림을 리디렉션해야 할지 더욱 알 수 없었다. 이런 경우 표준 출력과 표준 에러를 한꺼번에 리디렉션 해보자.
$ ping -c 5 www.google.com > stdout 2> stderr
$ cat stdout
$ cat stderr
명령 > 파일1 2> 파일2 형태로 명령을 내리면 표준 출력은 '파일1'에, 표준 에러는 '파일2'에 각각 리디렉션 된다.
표준 출력과 표준 에러를 한 파일에 리디렉션 할 수는 없을까? 조금 복잡하지만 가능하다. 표준 에러를 표준 출력으로 리디렉션 하고, 표준 출력은 파일로 리디렉션 하는 방법이다.
$ command [stream_number]> file [n]>&[m]
n은 리디렉션 할 소스 스트림 번호이고, m은 리디렉션을 받을 대상 스트림 번호이다. 예를 들어, 표준 에러를 표준 출력으로 리디렉션 하려면 2>&1이라고 작성한다.
그런데 명령이 조금 복잡해 보인다. 특히 명령 순서가 바뀌면 동작하지 않으니 더욱 유의해야 한다. 그래서 Bash에서는 더 쉬운 방법을 제공한다. 바로 &>이다. &>는 표준 출력과 표준 에러를 동시에 리디렉션 하는 명령이다.
$ command &> file
입력 디렉션(Input Direction)
입력 디렉션은 출력 리디렉션과 반대 개념으로, 파일 내용을 프로세스의 표준 입력으로 전달한다. 프로세스는 표준 입력으로부터 파일 내용을 읽는다.
$ command [stream_number]< file
> 대신 <를 사용하는 것만 다르고 출력 리디렉션과 형식이 같다. <는 지정된 파일의 내용을 스트림 번호에 해당하는 스트림으로 리디렉션 하라는 뜻이다. 스트림 번호가 생략되면 스트림 번호가 0인 표준 입력으로 리디렉션 한다.
실습을 위해서 좋아하는 노래의 가사를 입력해 보자. vi lyrics로 lyrics 파일을 생성하자.
$ vi lyrics
좋아하는 노래의 가사를 작성해 봤다.
$ wc < lyrics
wc는 텍스트의 줄 수, 단어 수, 문자 수를 출력하는 명령이다. wc를 실행하면 표준 입력으로부터 텍스트 입력을 기다린다. 다음과 같이 lyrics 파일의 내용을 wc의 표준입력으로 디렉션하면 lyrics 파일의 줄 수, 단어 수, 문자 수를 출력할 수 있다.
$ grep "you" < lyrics
$ grep "you" < lyrics > youonly
입력 리디렉션으로 얻은 결과를 출력 리디렉션으로 파일에 저장할 수도 있다. 입력 리디렉션과 출력 리디렉션은 명령 순서가 바뀌어도 동작하는 데 문제없다. 하지만 순서를 지키는 것이 명령을 이해하기에 좋다.
here documents(<<)
입력 리디렉션을 사용하면 파일 내용을 프로세스의 표준 입력으로 쉽게 리디렉션 할 수 있다. 그런데 프로세스의 표준 입력으로 넣을 데이터를 셸에서 직접 입력하고 싶을 수도 있다. 이런 경우 다음과 같은 순서로 입력 리디렉션을 실행한다.
입력할 데이터를 임시 파일에 저장 -> 입력 리디렉션 실행 -> 임시 파일 삭제
이 과정은 임시 파일을 생성하고 삭제해야 해서 번거로워 보인다. 이럴 때 here documents 기능을 사용하면 임시 파일을 만들지 않고도 입력 리디렉션을 실행할 수 있다. here documents 기능은 프로세스의 입력 스트림에 연결할 내용을 파일에서 읽어오는 대신 셸에서 직접 입력하는 방법을 제공한다. 지금까지 셸에서 데이터 한 줄만 입력했다. 데이터가 여러 줄 일 때는 어떻게 입력해야 할까? here documents 기능은 구분자를 이용해 데이터를 여러 줄 입력할 수 있다.
$ command [stream_number]<< seperator
[text]
seperator
heredoc은 입력 리디렉션의 < 대신 <<를 사용한다. 프로세스에 연결할 스트림 번호를 지정하는데, 생략하면 표준 입력인 0을 의미한다. 입력 리디렉션은 뒤에 파일이 오는데, heredoc은 구분자가 와야 한다. 여기서 구분자는 입력할 텍스트의 시작과 끝을 지정하는 역할을 한다. 구분자는 영문 한 단어를 사용하며, 어떤 값이든 사용할 수 있다. 의미상 EOF(End of File) 또는 END 등을 주로 사용한다.
$ wc << EOF
You know I want you
It's not a secret I try to hide
I know you want me
So don't keep sayin' our hands are tied
You claim it's not in the cards
EOF
heredoc은 여러 용도로 사용할 수 있지만, 새로운 텍스트 파일을 만들 때 특히 유용하다.
$ cat << EOF
cat
test
1
2
3
4
EOF
here strings(<<<)
here strings는 heredoc과 유사한 기능이다. here doc이 텍스트 여러 줄을 입력하기 위한 기능이라면, here strings는 텍스트 한 줄을 입력하기 위한 기능이다. 사용법은 다음과 같다.
$ command [stream_number]<<< string
heredoc은 <<를 사용하지만, here strings는 <를 더 붙여서 <<<를 사용한다. 입력 스트림 번호를 지정하고, 생략하면 표준 입력으이 입력 스트림으로 지정된다. 문자열 부분에는 프로세스의 입력 스트림에 넣을 문자열을 입력한다. 문자열이 한 단어라면 쿼팅할 필요가 없지만, 두 단어 이상일 때는 쿼팅해야 한다.
cat 명령어의 표준 입력에 "hello, world"를 입력한다. cat은 입력받은 데이터를 표준 출력으로 내보내고, 이 데이터가 화면에 출력된다.
$ cat <<< "hello, world"
here strings는 셸 변수와 함께 사용할 때 유용하다. VAR변수에 lyrics 파일 내용을 다음과 같이 저장한다. 그러면 here strings의 문자열 부분에 $VAR를 입력해 lyrics 파일 내용을 사용할 수 있다.
$ VAR=$(cat lyrics)
$ grep "you" <<< $VAR
정리하자면
출력 리디렉션
- > file : 파일에 덮어쓰기
- >> file : 파일에 내용 추가하기
입력 리디렉션
- < file : 파일 내용 리디렉션 하기
here documents : << 여러 줄 입력
here strings : <<< 한 줄 입력
함께 읽으면 좋은 글
>, >>, < 이건 뭐야? Bash 셸에서 리다이렉션(Redirection) 사용하기
리다이렉션(Redirection)리눅스를 사용하는 와중에 >, >>, 리다이렉션 연산자이다.리다이렉션은 셸에서 표준 입출력 스트림을 다른 방향으로 전환하는 기능을 말한다. Bash 셸에서는 기본적으로 세
jettstream.tistory.com
|이 대체 뭐야? 리눅스(Linux) 파이프라인(Pipeline)을 알아보자
파이프라인(Pipeline)파이프라인은 리디렉션에서 한걸을 더 나아간 기능이다. 리디렉션이 프로세스 스트림과 파일 간의 상호작용이라면 파이프라인은 프로세스 스트림 간의 상호작용이다.파이프
jettstream.tistory.com
'프로그래밍 > 리눅스' 카테고리의 다른 글
리눅스 필수 커맨드라인 툴 grep (0) | 2025.02.10 |
---|---|
|이 대체 뭐야? 리눅스(Linux) 파이프라인(Pipeline)을 알아보자 (0) | 2025.02.09 |
리눅스(Linux) IPC의 종류에 대해서 알아보자 (0) | 2025.02.04 |
리눅스(Linux) 포어그라운드 프로세스와 백그라운드 프로세스 (0) | 2025.02.04 |
리눅스(Linux) 프로세스의 작동 (0) | 2025.01.31 |
댓글