[Linux 셸 스크립트] bash - 129 중간 파일 없이 명령어 출력을 파일처럼 다루기
본문 바로가기
IT 이야기/Linux 셸 스크립트

[Linux 셸 스크립트] bash - 129 중간 파일 없이 명령어 출력을 파일처럼 다루기

by 찬찬이 아빠 2021. 7. 6.
반응형
  1. 사용 명령어

(1) comm

 

  2. 키워드 & 사용처

(1) 키워드

프로세스 치환, 이름 파이프, FIFO

 

(2) 사용처

중간 파일을 만들지 않고 명령어 출력 결과를 그대로 파일처럼 다루고 싶을 때 사용합니다.

 

 

  3. 실행 예제
$ ./process-subst.sh
			app.log.20210701
            app.log.20210702
            app.log.20210703
            app.log.20210704
        app.log.20210705
        	myapp
obj.conf

obj.conf는 dir1만 있고 app.log.20210705는 dir2에만 있음

 

 

  4. 스크립트

#!/bin/bash

 

# 비교할 두 디렉터리 정의

dir1="/var/tmp/backup1"           

dir2="/var/tmp/backup2"           

 

# comm 명령어로 출력을 비교

# 중간 파일을 만들지 않아도 프로세스 치환으로 처리 가능

comm <(ls "$dir1") <(ls "$dir2")                   

 

 

  5. 해설

이 스크립트는 두 디렉터리 내부의 파일 목록을 비교해서 그 차이를 표시합니다. comm 명령어를 사용하여 중간 파일을 만들지 않고 bash 프로세스 치환(Process Substitution) 표기법으로 처리합니다.

 

bash 프로세스 치환이란 명령어 입력과 출력을 FIFO(이름 파이프, named pipe)와 파일 디스크립터를 나타내는 /dev/fd 이하의 디바이스 파일에 접속해서 실행하는 기능입니다. 명령어 출력 결과를 파일로 다른 명령어에 넘기려며 다음과 같이 사용합니다.

명령어1 < (명령어2)

일반적으로 파일을 대상으로 하는 명령어를 실행할 때 중간 파일을 작성하지 않고 처리하는 용도가 많을 것입니다. 다음 예에서는 ls 명령어 실행 결과를 파일로 보고 commandA를 실행합니다.

commandA <(ls -alF)

예제에서는 ls 명령어의 결과를 comm 명령어로 비교할 대상 목록 파일로 쓰고자 프로세스 치환을 사용합니다. 우선 에서 비교할 두 디렉터리를 정의합니다. 두 디렉터리 내부 파일 목록을 비교하는 경우를 가정합니다. 에서 프로세스 치환을 써서 두 ls 명령어 결과를 비교합니다. comm 명령어는 원래 다음처럼 두 파일을 인수로 받습니다.

comm a.txt b.txt

하지만 는 두 파일을 프로세스 치환으로 지정하면 명령어 결과를 그대로 이용할 수 있습니다.

 

프로세스 치환을 사용하지 않으면 다음처럼 두 ls 명령어 결과를 일단 임시 파일에 출력하고, 그걸 비교한다는 번거로움이 있습니다. 프로세스 치환을 사용하면 이런 임시 파일을 만들지 않아도 쉽게 작업할 수 있습니다.

ls "$dir" > dir1.tmp
ls "$dir2" > dir2.tmp
comm dir1.tmp dir2.tmp

이렇게 해서 comm 명령어 결과로 '디렉터리 $dir1에만 있는 파일', '디렉터리 $dir2에만 있는 파일', '양쪽에 있는 파일'로 나눠서 출력할 수 있습니다. 프로세스 치환은 그 외에도 파일을 대상으로 하는 명령어로 응용할 수 있는 표기법입니다.

 

 

<주의사항>

프로세스 치환 표기법 <(명령어)는 언뜻 보면 '입력 리다이렉트와 서브셸' 처럼 보이지만 그렇지 않습니다. 어디까지나 <(명령어)처럼 서로 붙여써야 프로세스 치환표기법이 됩니다. 예를 들어 에서 다음처럼 괄호 앞에 스페이스를 넣으면 에러가 발생하므로 주의해야 합니다.

comm < (ls "$dir1") < ls "$dir2")

프로세스 치환은 이 예에서 본 것처럼 입력을 연결하는 처리와 반대로 출력을 연결하는 >(명령어)라는 표기법이 있습니다. 이것은 처리 결과를 표준 출력에는 출력하지 않고 파일에 직접 쓰는 프로그램처럼 파이프 처리하고 싶을 때 이용할 수 있습니다. mu-calc 명령어가 직접 결과를 지정한 파일에 출력하는 명령어라고 가정했을 때, 다음처럼 쓰면 결과를 파일이 아니라 표준 출력으로 줄 번호와 함께 표시할 수 있습니다.

my-calc >(cat -n)

FreeBSD 버전에 따라서는 프로세스 치환이 제대로 동작하지 않는 경우도 있습니다. 그때는 ports에서 bash 최신판을 설치하기 바랍니다.

 

 

 

참고서적 : 유닉스 리눅스 셸 스크립트 예제 사전

반응형

댓글