본문 바로가기

Language&Configuration/[Liunx]

[Linux] I/O 재지향(Redirection) 및 파이프(pipe)에 대한 이해와 사용법

1. I/O 재지향(redirection)

A. 개요

리눅스 쉘은 항상 아래와 같이 표준 입출력파일 형태로 열고 있습니다.

  • 표준입력(stdin: 키보드)
  • 표준출력(stdout: 모니터)
  • 표준에러(stderr: 모니터)

기본적으로 프로그램은 연산 결과를 출력 장치(파일, 모니터, 프린터 등)로 내보내는데, 출력되는 데이터를 임의로 다른 장치로 보내는 것을 재지향(redirection)이라고 합니다. 다시 말하면 파일이나 프로그램, 명령어 등의 출력을 낚아채어 다른 파일이나 프로그램, 명령어의 표준 입력으로 보내는 것을 말합니다.

B. 사용법

리눅스에서 열려 있는 파일은 파일 디스크립터(file descriptor)를 할당 받게 됩니다.

  • 표준 입력(stdin) = 0
  • 표준 출력(stdout) = 1
  • 표준 에러(stderr) = 2
    이렇게 0, 1, 2파일 디스크립터를 할당받기 때문에 이를 이용해서 재지향을 할 수 있습니다.

> file
표준 출력을 파일로 재지향 합니다. 파일이 없으면 새로 만들고, 파일이 있으면 덮어씁니다.

>> file
표준 출력을 파일로 재지향 합니다. 파일이 없으면 새로 만들고, 파일이 있으면 파일의 끝에 덧붙입니다.

2>&1
표준 에러를 표준 출력으로 재지향합니다. 표준 에러도 표준 출력의 자격으로 보내집니다.

< file
파일로부터 표준 입력을 받도록 재지향합니다.

C. 예제

ex) test.txt 파일의 출력을 test.out 파일로 저장

cat test.txt > test.out

ex) today.log 파일의 출력을 week.log 파일의 끝에 덧붙임

cat today.log >> week.log

ex) cat 명령어의 에러를 표준 출력으로 재지향하고 표준 출력을 out 파일로 재지향

[root@test]# cat nofile > out 2>&1[root@test]# cat outcat: nofile: No such file or directory

에러가 표준 출력으로 재지향 되었기 때문에 화면에 에러가 출력되는 대신에 out 파일에 기록됩니다.

ex) ls 명령어의 에러를 /dev/null 로 재지향

[root@test]# ls -xy 2> /dev/null[root@test test]#

/dev/null특수 파일로 이 파일로 출력된 데이터는 버려집니다.
ls 명령에 xy 라는 잘못된 옵션을 입력하여 에러가 발생하였지만, /dev/null 로 재지향하여 출력을 없애버렸습니다.


2. 파이프(PIPE)

A. 개요

여러개의 명령어를 실행할 때 이전 명령어의 결과를 다음 명령어의 입력값으로 사용하고 싶을 때가 있습니다.

명령어입력 - 실행 - 결과 의 과정을 파이프 안에 흐르는 액체로 비유한다면, 첫 번째 명령어 파이프의 결과를 화면으로 출력하는 대신 다른 명령어 파이프로 흘러가도록 연결한다고 생각하시면 됩니다.

4가지 shape 가 흐르는 명령어 파이프가 있다고 가정했을 때, 아래처럼 특정 shape 를 필터링 하는 명령어 파이프에 | 를 통해서 연결하면 화면에 출력되는 최종 결과는 필터링 파이프를 통과한 결과가 되는 거죠.

B. 사용법

cat /etc/passwd | grep mail
/etc/passwd 파일에는 현재 시스템의 계정 정보들이 들어있습니다. cat 명령어에 의해 각 계정 정보가 라인별로 출력이 되는데, 그 중에서 mail 이라는 문자열이 들어간 라인만 필터링해서 출력하고 싶을 때, 파이프( | )를 사용하여 cat 명령어의 결과를 grep 명령어로 전달할 수 있습니다.

쉘 프롬프트(Shell prompt)에서 한번에 사용 가능한 파이프의 개수는 제한이 없습니다. 이전 명령어의 출력값을 필터링하거나 가공할 때 주로 사용하기 때문에 awk, cut, grep, more 등의 명령어들을 조합해서 많이 사용합니다.

C. 예제

ex) test1.txt 파일에서 abc 라는 글자가 포함된 라인만 출력

[root@test]# cat test1.txt
abc
def
qwe
poi
abc
abcdef
abcd

[root@test]# cat test1.txt | grep abc
abc
abc
abcdef
abcd
[root@test]#

ex) 현재 디렉토리에서 c 라는 글자가 들어간 파일만 출력

[root@test]# ls
language.bash  language.delphi   language.javascript
language.c     language.english  language.korean
language.cpp   language.java     language.python
[root@test peter]# ls | grep c
language.c
language.cpp
language.javascript

ex) 현재 디렉토리에서 c 라는 글자가 들어간 파일 중 java 가 들어간 파일을 제외하고 출력

[root@test]# ls | grep c | grep -v java
language.c
language.cpp
[root@test peter]#

ex) /etc 디렉토리의 파일 목록을 한 화면씩 나누어서 출력

[root@test]# ls -l /etc | more
total 1352
-rw-r--r--  1 root root       16 Jan  5 21:14 adjtime
-rw-r--r--  1 root root     1518 Jun  7  2013 aliases
-rw-r--r--  1 root root    12288 Jan  5 21:16 aliases.db
drwxr-xr-x  2 root root     4096 Apr 17 02:00 alternatives
-rw-------  1 root root      541 Aug  3  2017 anacrontab
-rw-r--r--  1 root root       55 Mar  1  2017 asound.conf
drwxr-xr-x  2 root root     4096 Jan  5 21:12 bash_completion.d
-rw-r--r--  1 root root     2853 Nov  5  2016 bashrc
drwxr-xr-x  2 root root     4096 Mar  7 13:27 binfmt.d
-rw-r--r--  1 root root       38 Aug 30  2017 centos-release
-rw-r--r--  1 root root       51 Aug 30  2017 centos-release-upstream
drwxr-xr-x  2 root root     4096 Aug  4  2017 chkconfig.d
-rw-r--r--  1 root root     1108 Jan 31  2017 chrony.conf
-rw-r-----  1 root chrony    481 Jan 31  2017 chrony.keys
drwxr-xr-x  2 root root     4096 Jan  5 21:11 cron.d
drwxr-xr-x  2 root root     4096 Jan  5 21:12 cron.daily
-rw-------  1 root root        0 Aug  3  2017 cron.deny
drwxr-xr-x  2 root root     4096 Jan  5 21:11 cron.hourly
drwxr-xr-x  2 root root     4096 Jun  9  2014 cron.monthly
-rw-r--r--  1 root root      451 Jun  9  2014 crontab
drwxr-xr-x  2 root root     4096 Jun  9  2014 cron.weekly
-rw-------  1 root root        0 Jan  5 21:10 crypttab
-rw-r--r--  1 root root     1620 Nov  5  2016 csh.cshrc
-rw-r--r--  1 root root      841 Jun  7  2013 csh.login
drwxr-xr-x  4 root root     4096 Jan  5 21:11 dbus-1
drwxr-xr-x  2 root root     4096 May 10 07:32 default
drwxr-xr-x  2 root root     4096 Apr 17 02:00 depmod.d
drwxr-x---  4 root root     4096 Mar 13 10:23 dhcp
-rw-r--r--  1 root root     5090 Nov  4  2016 DIR_COLORS
-rw-r--r--  1 root root     5725 Nov  4  2016 DIR_COLORS.256color
-rw-r--r--  1 root root     4669 Nov  4  2016 DIR_COLORS.lightbgcolor
-rw-r--r--  1 root root     1285 Jan  5 12:47 dracut.conf
drwxr-xr-x  2 root root     4096 Jan  5 12:47 dracut.conf.d
-rw-r--r--  1 root root      112 Mar 16  2017 e2fsck.conf
-rw-r--r--  1 root root        0 Nov  5  2016 environment
-rw-r--r--  1 root root     1317 Nov  5  2016 ethertypes
--More--

ex) 실행 중인 프로세스 목록에서 bash 프로세스 목록을 출력

[root@test\]# ps -ef | grep bash  
root 929 472 0 Apr18 tty1 00:00:00 -bash  
root 17937 17935 0 00:23 pts/0 00:00:00 -bash  
root 18009 17937 0 00:57 pts/0 00:00:00 grep --color=auto bash