리눅스에 대한 더 많은 정보와 예제를 담은 리눅스 교재를 배포했습니다. 아래의 페이지에서 리눅스 교재를 받아가세요.

https://reakwon.tistory.com/233

 

리눅스 프로그래밍 note 배포

티스토리에 리눅스에 관한 내용을 두서없이 여지껏 포스팅했었데요. 저도 제 포스팅을 찾기가 어렵기도 하고 티스토리에서 코드삽입을 하게 되면 이게 일자로 쭉 쓰여져있는 x같은 현상이 생겨

reakwon.tistory.com

 

재지정(Redirection)

리눅스에서 프로그램은 보통 세 개의 파일 서술사를 열게 됩니다. 바로 표준 입력(standard input, STDIN), 표준 출력(standard output, STDOUT), 그리고 표준 에러(standard error, STDERR)가 되지요. 

순서대로 파일 디스크립터(fild descriptor)는 0, 1, 2입니다.

 

리다이렉션(Redirection)이라고 하는 것은 이러한 서술자 중 하나 이상을 파일로 다시 지정하는 수단이라고 볼 수 있는데요. 어떻게 리다이렉션을 사용할까요?

 

1) program > file_name

>는 이해하기 쉽습니다. program에서 출력하는 것을 file_name이라는 파일에 기록하겠다는 것입니다. 더 잘 이해하기 위해서 저의 리눅스를 활용해보도록 하지요.

제 리눅스의 /tmp 디렉터리에는 다음과 같은 파일들이 있습니다.

무슨 파일들인지는 잘 모르겠네요.


[root@localhost tmp]# ls
systemd-private-b2dd06a5829f42f5b5f2e122f17b9afb-ModemManager.service-OOhWCc
systemd-private-b2dd06a5829f42f5b5f2e122f17b9afb-bolt.service-KuASd9
systemd-private-b2dd06a5829f42f5b5f2e122f17b9afb-chronyd.service-mPGGCi
systemd-private-b2dd06a5829f42f5b5f2e122f17b9afb-colord.service-uTlHDZ
systemd-private-b2dd06a5829f42f5b5f2e122f17b9afb-fwupd.service-mV4Wkl
systemd-private-b2dd06a5829f42f5b5f2e122f17b9afb-rtkit-daemon.service-eaiBmp

ls 명령을 치는 순간 화면에 보이는 파일들의 목록이 있죠? 이것은 표준 출력으로 표시한 것입니다. 쉽게 이해하기 위해서 모니터가 표준 출력이라고 보세요.

 

이제는 이것을 파일로 저장해보도록 합시다. 위의 꺽쇠를 이용하면 됩니다.


[root@localhost tmp]# ls > list_stdout
[root@localhost tmp]# cat list_stdout
list_stdout
systemd-private-b2dd06a5829f42f5b5f2e122f17b9afb-ModemManager.service-OOhWCc
systemd-private-b2dd06a5829f42f5b5f2e122f17b9afb-bolt.service-KuASd9
systemd-private-b2dd06a5829f42f5b5f2e122f17b9afb-chronyd.service-mPGGCi
systemd-private-b2dd06a5829f42f5b5f2e122f17b9afb-colord.service-uTlHDZ
systemd-private-b2dd06a5829f42f5b5f2e122f17b9afb-fwupd.service-mV4Wkl
systemd-private-b2dd06a5829f42f5b5f2e122f17b9afb-rtkit-daemon.service-eaiBmp
tracker-extract-files.0

그러면 list_stdout이 생겨날텐데 이것을 cat명령어로 실행해보면 파일의 내용을 볼 수 있습니다. 위의 ls 명령어의 결과와 같죠?

 

그렇다면 다음의 명령은 어떻게 출력이 될까요? 분명 위의 ls에는 aaa.txt라는 파일은 없었습니다. 과연 파일로 저장될까요? 


[root@localhost tmp]# ls -l aaa.txt > list_aaa
ls: cannot access 'aaa.txt': 그런 파일이나 디렉터리가 없습니다
[root@localhost tmp]# cat list_aaa

list_aaa가 생겨나지 않았고 메시지가 출력이 되네요. 여기서 위의 메시지는 stderr로 출력된 에러 메시지입니다. stderr로 출력된 에러 메시지는 list_aaa의 파일로 저장이 되지 않네요. 

 

그 이유는 기본적으로 ls -l aaa.txt > list_aaa는 ls -l aaa.txt 1> list_aaa와 같이 동작합니다. 여기서 숫자 1은 표줄 출력(stdout)을 의미하게 됩니다. 1이 파일 디스크립터라면 우리는 표준 에러는 다음과 같이 저장할 수 있겠군요. 

 

아래의 결과를 보면 2(표준에러)가 리다이렉션되어 파일의 내용으로 전달되는 것을 알 수 있습니다.

 


[root@localhost tmp]# ls -l aaa.txt 2> list_aaa
[root@localhost tmp]# cat list_aaa
ls: cannot access 'aaa.txt': 그런 파일이나 디렉터리가 없습니다

 

2) program >> file_name

꺽쇠가 두개 연달아 있는 것은 파일의 끝에 내용을 덧붙이라는 것으로 여러분이 직접 실험해보시기 바랍니다.

 

 

 

 

3) program < file_name

여기서부터는 조금 헷갈릴 수 있으니 잘 들으세요. 아니, 보세요. file_name의 파일 내용을 program의 표준 입력으로 사용하겠다 라는 의미가 됩니다. 

 

ls는 표준입력을 받지 않는다.

자, 프로그램에는 표준 입력으로 사용자의 입력을 받는 것이 있고 그렇지 않는 프로그램이 있습니다. 여기서 ls는 사용자의 입력을 표준입력으로 받을까요? 결론은 아닌데요. 

아래의 내용으로 확인해보겠습니다.

우선 아까 없던 aaa.txt를 만들어볼텐데 aaa.txt에는 aaa라는 문자를 기록하도록 하지요. 그리고 다시 echo를 사용해 bbb라는 내용을 갖는 aaa파일을 만들어봅시다.


[root@localhost tmp]# echo aaa > aaa.txt
[root@localhost tmp]# ls aaa.txt
aaa.txt
[root@localhost tmp]# echo bbb > aaa
[root@localhost tmp]# ls aaa
aaa

(echo는 그 다음의 입력을 표준 출력으로 출력하는데 아까 배운 >을 통해서 파일로 저장했습니다. )

 

이제 ls에 aaa.txt의 내용을 표준입력으로 받아보도록 하겠습니다. 


[root@localhost tmp]# ls < aaa.txt
aaa
aaa.txt
systemd-private-b2dd06a5829f42f5b5f2e122f17b9afb-ModemManager.service-OOhWCc
systemd-private-b2dd06a5829f42f5b5f2e122f17b9afb-bolt.service-KuASd9
systemd-private-b2dd06a5829f42f5b5f2e122f17b9afb-chronyd.service-mPGGCi
systemd-private-b2dd06a5829f42f5b5f2e122f17b9afb-colord.service-uTlHDZ
systemd-private-b2dd06a5829f42f5b5f2e122f17b9afb-fwupd.service-mV4Wkl
systemd-private-b2dd06a5829f42f5b5f2e122f17b9afb-rtkit-daemon.service-eaiBmp
tracker-extract-files.0

뭐 얼핏보면 뭔가 출력이 됐는데 우리가 원하는 결과는 aaa.txt의 내용은 bbb가 ls의 입력으로 들어가서 ls aaa라는 명령어가 수행되어야하는 것입니다. 근데 제가 전달하는 입력을 씹고 현재 디렉터리의 파일 내용을 출력하고 있죠. 이것은 ls의 기본 동작입니다. 

ls는 이 처럼 표준 입력을 받지 않습니다. 대신 argv라고하는 argument vector를 통해서 사용자 입력을 받고 있는 셈입니다.

 

표준입력을 받는 명령어는 무엇이 있을까요? 

대표적으로 cat, grep 등이 있습니다. 

 

cat의 기본 동작

cat의 기본동작(아무런 옵션을 주지 않을때의 동작)은 입력받은 거 그대로 출력하는 기능입니다. 그 입력은 표준입력으로 받습니다. 

표준 입력으로 받으니 이것을 파일의 내용을 입력으로 줘보겠습니다.


[root@localhost tmp]# echo Hello > hello.txt
[root@localhost tmp]# cat < hello.txt
Hello

 

cat명령어는 argv로 파일 이름을 인자로 받을 수 있도록 프로그램이 되어있는데, 결과는 위와 같습니다.

 

 

 

 

grep의 기본 동작

grep은 기본적으로 바로 뒤에 인자가 포함된 문자열이 입력이 되면 그 문자열을 다시 출력해줍니다. 아래의 결과를 보면 알 수 있는데 이 grep은 표준 입력으로 입력을 받습니다.


[root@localhost tmp]# grep reak
AAA
BBB
rea
rreak
rreak
rreakk
rreakk
mmsmsms

자, 여기서 눈 여겨 봐야할 것은 grep은 굵은 글씨인 rreak, rreakk만 출력하였습니다. 왜냐면 인자로 받은 reak라는 문자열이 포함되있기 때문이죠.

 

표준 입력으로 받으니 우리는 파일을 입력으로 리다이렉션을 쓸 수 있겠군요. 위의 입력했던 내용을 그대로 vi 편집기로 저장합니다. 


[root@localhost tmp]# vi grep_test
[root@localhost tmp]# grep reak < grep_test
rreak
rreakk


vi 편집기 내용


AAA 
BBB 
rea 
rreak
rreakk
mmsmsms 

 

표준 입력으로 받은 결과와 동일함을 알 수 있네요.

 

리다이렉션을 통한 Copy

리다이렉션을 통해서 파일을 복사할 수도 있는데요. 아래를 보도록 합시다.  echo로 file을 생성한 후에 cat의 입력으로 file의 내용을 받습니다. 그 후에 cat은 표준 출력으로 file의 내용을 출력하는데 다시 >로 표준 출력의 내용을 file_copied라는 파일에 저장합니다. 결국은 복사를 수행한 것과 같게 됩니다.


[root@localhost tmp]# echo hello > file
[root@localhost tmp]# cat < file > file_copied
[root@localhost tmp]# cat file_copied
hello

 

 

 

 

 

파이프( | )

파이프라는 것은 program1의 표준 출력을 program2의 표준입력으로 입력받습니다. 명령어의 결과를 다시 어떤 명령어의 입력으로 받아야할때 사용되며 리눅스에서 매우 흔히 쓰입니다. 형식은 아래와 같습니다.

program1 | program2

파이프라는 것은 program1의 표준 출력을 program2의 표준입력으로 입력받습니다. 리눅스에서 매우 흔히 쓰이는데요. 가장 빈번하게 사용하는 grep과 연관시켜서 사용해봅시다. 

우선 제 리눅스에서 /bin으로 이동했습니다. 그리고 ls -l 명령을 보면 무수히 많은 파일들이 보이는데 그 중에서 zip이라는 문자열을 포함한 것을 확인해보고 싶습니다. 

그렇다면 ls -l로 우선 표준 출력을 하고 이 표준 출력된 내용을 zip이라는 인자를 전달받는 grep에게 표준 입력으로  전달시키면 되겠죠?

답은 간단합니다. 아래의 명령을 실행시켜보세요.


[root@localhost bin]# ls -l | grep zip
lrwxrwxrwx. 1 root root           5  5월 10  2019 bunzip2 -> bzip2
lrwxrwxrwx. 1 root root           5  5월 10  2019 bzcat -> bzip2
-rwxr-xr-x. 1 root root       38472  5월 10  2019 bzip2
-rwxr-xr-x. 1 root root       17560  5월 10  2019 bzip2recover
-rwxr-xr-x. 1 root root       40256  5월 10  2019 funzip
-rwxr-xr-x. 1 root root        3447  5월 10  2019 gpg-zip
-rwxr-xr-x. 1 root root        2345 11월  8  2019 gunzip
-rwxr-xr-x. 1 root root      170544 11월  8  2019 gzip
lrwxrwxrwx. 1 root root           6  5월 11  2019 mzip -> mtools
-rwxr-xr-x. 1 root root        5656  5월 13  2019 preunzip
-rwxr-xr-x. 1 root root        5656  5월 13  2019 prezip
-rwxr-xr-x. 1 root root       13352  5월 13  2019 prezip-bin
-rwxr-xr-x. 2 root root      210408  5월 10  2019 unzip
-rwxr-xr-x. 1 root root      105064  5월 10  2019 unzipsfx
-rwxr-xr-x. 1 root root      234496  5월 11  2019 zip
-rwxr-xr-x. 1 root root      105376  5월 11  2019 zipcloak
-rwxr-xr-x. 1 root root        2953 10월 10  2008 zipgrep
-rwxr-xr-x. 2 root root      210408  5월 10  2019 zipinfo
-rwxr-xr-x. 1 root root      100104  5월 11  2019 zipnote
-rwxr-xr-x. 1 root root      100112  5월 11  2019 zipsplit

굳이 그림으로 표현하면 아래와 같이 실행됩니다.

 

이렇게 리다이렉션과 파이프에 대해서 알아보았습니다.

궁금하신 점은 댓글로 달아주세요.

 

 

 

반응형
블로그 이미지

REAKWON

와나진짜

,