[Linux] 리다이렉션(redirection: <, >) , 파이프(pipe: |)

반응형

 

 

0. 들어가기 전에, 표준 입출력에 대해서

리눅스에서 cat 같은 명령어를 실행하면 자동으로 표준 입출력 채널이 열려 동작한다.

여기서 표준 입출력 채널은 아래의 세 채널을 합쳐서 말한다.

입출력 채널 내용 숫자
표준 입력(stdin) 데이터를 입력하는 채널 키보드 입력, 파일 입력 등 0
표준 출력(stdout) 실행 결과가 출력되는 채널 디스플레이 출력, 파일 출력 등 1
표준 에러 출력(stderr) 실행 중 발생하는 에러 메시지가 출력되는 채널 디스플레이 출력, 파일 출력 등 2

리눅스에서는 명령어의 입출력을 표준입출력으로 추상화하고 있다. 그래서 명령어 내부에서는 실제 입출력이 어디에 연결되는지 신경쓰지 않으며 사용자가 명령어를 실행할 때 자유롭게 지정할 수 있다.

 

 

1. 리다이렉션 (Redirection)

표준 입출력을 어디로 연결할지 변경하는 것을 리다이렉션이라 한다.

 

1.1. 입력 리다이렉션

1.1.1. 키보드 입력

cat 명령어는 표준 입력으로 입력한 내용을 읽어서 그대로 표준 출력에 출력하는 명령어 이다. 그래서 인자를 지정하지 않고 cat 명령어를 실행하여 키보드 입력을 표준입력으로 실행해보면 다음 캡쳐와 같이 동작한다.

표준 입력으로 입력한 내용을 표준 출력에 출력하는 cat 명령어

1.1.2. 파일 입력

파일을 표준입력으로 연결해보자. 이를 입력 리다이렉션이라고 하며, < 기호를 사용한다.

호스트명이 들어있는 /etc/hostname 파일을 표준입력으로 연결하면 다음과 같이 파일내용이 그대로 출력된다.

호스트명 파일을 표준입력으로 연결

즉, cat 명령어로 파일 내용을 출력하는 방식은 다음과 같이 두가지이다.

$ cat < /etc/hostname # 파일 입력 리다이렉션 사용
$ cat /etc/hostname # cat 명령어 인자로 파일 지정

두 방식의 출력 결과는 같다. 하지만 내부적으로 차이가 있다.

리다이렉션을 사용한 경우, 표준 입력을 읽어서 표준 출력에 그대로 출력한다는 cat 명령어의 기본 동작에 의한 방식이다.

파일을 인자로 지정한 경우, 사용자의 편의를 위해 cat 명령어가 제공하는 방식을 사용한 방식이다.

 

 

1.2. 출력 리다이렉션

표준 출력 리다이렉션 할 수 있으며 기호 > 이다. 명령어의 실행 결과를 화면에 출력하는 것이 아니라 파일에 저장하는 방식으로 많이 사용된다.
다음과 같이 파일 리스트를 출력하는 ls 명령어의 실행 결과를 list.txt 로 출력할 수 있다.

ls 실행 결과를 텍스트 파일로 출력

 

 

1.3. 에러  출력

출력 채널에는 표준 출력 뿐만아니라 표준 에러 출력도 있다. 표준 에러 출력은 프로그램의 에러 메시지를 출력하기위해 사용된다.

 

콘솔에 출력되는 메시지가 표준 출력에 의한 것인지, 표준 에러 출력에 의한것인지 판단하기는 쉽지 않다. 위 【1.2. 출력 리다이렉션】 의 캡쳐를 참고하면, 출력 리다이렉션하면 명령어의 실행결과는 출력되지 않는다. cat 명령어로 확인해본것이지 리다이렉션으로 출력되지 않았다.

 

다음과 같이 표준 출력을 list2.txt 파일에 리다이렉션 해보자.

표준 출력을 파일에 리다이렉션해도 에러메시지는 출력되며, 파일도 생성된다.

표준 출력을 파일에 리다이렉션해도 에러메시지는 출력되며, 출력결과 파일도 생성되는 것을 확인할 수 있다. 이는 표준 출력과 에러 출력이 별도의 채널을 사용하기 때문이다.

 

이때 표준 에러 출력도 파일에 리다이렉션 할 수 있는데 기호2> 를 사용한다.

표준 출력과 표준 에러 출력은 별도의 채널을 사용한다.

 

다음과 같이 명령어를 실행하면 ls 명령어의 실행결과는 list2.txt 에 출력 및 저장되며 에러 메시지는 error.txt 에 출력 및 저장된다.

$ ls /abcde > list2.txt 2> error.txt # /abcde 는 임의의 디렉토리로 존재하지 않는 디렉토리이다

표준 출력과 표준 에러 출력은 별도의 채널을 사용한다.

 

 

1.4.  표준 출력과 표준 에러  출력을 함께 리다이렉션

표준 출력과 표준 에러 출력을 파일 하나에 리다이렉션 할 수도 있다. 표준 출력을 리다이렉션한 뒤에 2>&1 을 붙여주면 된다.

 

표준출력과 표준 에러 출력을 result.txt 파일에 함께 출력하기 위해서 다음과 같이 하면된다.

$ ls /zxc > result.txt 2>&1

표준 출력과 표준 에러 출력을 모두 result.txt 파일에 리다이렉션

2>&1 은 표준 에러출력(2) 을 표준 출력(1) 과 같은 파일로 리다이렉션 한다는 의미이다.

입출력 채널 숫자
표준 입력(stdin) 0
표준 출력(stdout) 1
표준 에러 출력(stderr) 2

 

1.5. 리다이렉션 주의점, 정리

1.5.1. 리다이렉션 주의점 : 덮어쓰기

이미 존재하는 파일에 리다이렉션하면 기존 파일을 덮어쓰게 된다. 그래서 파일을 잃게되는 경우가 발생할 수 있다. 이를 방지하기 위해 > 대신 >> 을 사용하는 방법이 있다. >> 을 사용하면 파일을 덮어쓰지 않고 파일의 끝에 이어서 출력된다.

>> 기호를 이용하면 덮어쓰기 되지않고 기존 파일 내용에 이어서 출력된다

 

또 다른 방법이 있는데, 셸 옵션으로 noclobber 라는 값을 set 명령어로 지정하는 것이다. 그러면 리다이렉션으로 덮어쓸 때 에러가 발생한다.

$ set -o noclobber # 리다이렉션으로 덮어쓰기 방지설정

set -o noclobber 설정은 덮어쓰기 할 수 없다는 에러메시지가 출력된다.

참고로 위의 설정을 해제하는 방법은 다음과 같다.

$ set +o noclobber # 리다이렉션 덮어쓰기 금지 해제설정

 

1.5.2. 리다이렉션 기호 정리

기호 내용
< FILE 표준 입력을 FILE 로 리다이렉션
> FILE 표준 출력을 FILE 로 리다이렉션
>> FILE 표준 출력의 출력을 FILE 의 끝에 추가
2> FILE 표준 에러 출력을 FILE 로 변경
2>> FILE 표준 에러 출력을 FILE 의 끝에 추가
> FILE 2>&1 표준 출력과 표준 에러 출력을 모두 FILE 로 리다이렉션

 

 

1.6. /dev/null

다음 명령어로 /dev/null 이라는 파일이 존재하는지 확인해보자.

$ ls -l /dev/null

ls -l /dev/null

 

/dev/null특수 파일으로 다음의 특징을 갖는다.

  • 입력 파일로 지정해도 아무 내용도 입력되지 않는다.
  • 출력 파일로 지정해도 어떤 내용도 기록되지 않는다.

 

표준 출력을 /dev/null 로 리다이렉션하면 콘솔에도, 파일에도 아무것도 출력되지않는다.  이 특징을 이용하여 유용하게 사용할 수 있다. 예를 들어, 표준 출력으로 출력되는 내용이 너무 많거나 표준 에러 출력만 확인하고 싶을때 이용하는 방법이다.

 

 

1.6.1. 표준 출력을 /dev/null 로 리다이렉션 : 에러메시지만 확인

다음과 같은 방식으로 이용하면 에러메시지만 콘솔으로 확인할 수 있다.

/dev/null 에는 출력되지 않으므로 에러메시지만 확인 가능하다.

 

1.6.2. 표준 에러 출력을 /dev/null 로 리다이렉션 : 에러메시지 출력 무시

다음과 같은 방식을 사용하면 에러메시지 출력을 무시하는 결과가 된다. 확인하지않아도 되는 에러메시지가 출력될때 이용한다.

표준 에러 출력을 리다이렉션하면 에러메시지를 무시하는 결과가 된다.

 

 

정리하면 굳이 확인할 필요가 없는 메시지가 출력 되는 경우, 명령어의 실행 시간을 확인하는 경우 등에 사용한다.

 

 

2. 파이프 (Pipe) : |

명령어의 표준 출력을 다른 명령어의 표준 입력으로 연결할 수 있다. 이때 사용하는 것이 파이프라하며 기호 | 를 사용한다.

 

■ 여러개의 명령어를 연결하는 파이프 : |

 

$ <명령어1> | <명령어2> [| <명령어3> |] ...

 

 

다음과 같이 파이프로 연결하여 ls 명령어의 결과에 cat -n 으로 행 번호를 부여하여 그 결과를 tmp_list.txt 파일로 출력할 수 있다.

$ ls -l / | cat -n > tmp_list.txt

 

■ 파이프 주의점

파이프는 기본적으로 표준 출력만 다음 명령어에 연결한다. 그래서 표준 에러 출력도 함께 보내려면 2>&1을 사용하여 표준 출력과 표준 에러 출력을 동일하게 리다이렉션 해주어야 한다.

 

예를들어 ls 명령어의 표준 출력과 표준 에러 출력을 less 명령어로 전달하려면 다음과 같다.

$ ls -l / 2>&1 | less

 

 

 

 

 

 

반응형