사용자 인터페이스_06 파일을 읽어서 처리할 때 키보드에서 입력받기

 
  • 출처 : 유닉스 리눅스 쉘스크립트 예제사전_한빛미디어

명령어: tty, read
키워드: 표준 입력, 키보드, 외부 파일
사용처: read 명령어로 파일에 읽어들이는 처리 도중에 read 명령어로 키보드에서 입력받고 싶을 때


실행예제

$ ./read-redirect.sh
Input Target Directory :
/home/user1/test  <---------- 키보드에서 디렉터리 입력

data1.txt	data2.txt

스크립트

#!/bin/sh

tty=`tty`  #-------------------- 3
while read question  #---------- 1
do
  echo $question
  read dir <$tty  #------------ 4
  echo "Command: ls $dir"
  ls $dir
done <question.txt  #---------- 2

   

해설

이 스크립트는 question.txt에 있는 질문을 한 줄씩 순서대로 표시하면서 키보드에서 입력된 디렉터리 속 파일을 ls 명령어로 표시합니다.

read 명령어는 표준 입력(키보드에서 입력)을 읽어서 그 값을 셸 변수에 대입하지만 파일 내용을 한 줄씩 읽어서 셸 변수에 대입할 수도 있습니다. 그럴 때는 우선 1처럼 while 조건식에 read 명령어를 지정함과 동시에 2처럼 done 직후에 리다리렉트를 쓰면 while 루프 전체에 입력 리다이렉트합니다. 이렇게 하면 파일 내용을 read 명령어가 한 줄씩 읽어서 셸 변수 question에 대입합니다.

이 예제의 question.txt에는 [파일1]과 같은 내용이 적혀 있습니다.디렉터리명을 붇는 질의문을 외부 파일에 두고 사용자에게 받은 입력값으로 그 디렉터리를 ls해서 그 안에 있는 파일을 표시합니다.

  • 파일1스크립트에서 사용하는 질문 파일

    Input Target Directory : 
    

하지만 이렇게 read 명령어로 리다이렉트하는 처리 안에서 다시 read 명령어로 키보드 입력을 받으려 하면 표준 입력은 이미 파일이므로 제대로 동작하지 않습니다.

따라서 3처럼 미리 터미널 정보를 명령어 치환으로 저장합니다. 셸 스크립트에서는 명령행을 `(그레이브, 역따옴표)로 감싸면 그 부분을 명령어 실행된 결과로 바뀌므로 이것을 명령어 치환이라고 부릅니다. 이 예제에서 tty 명령어 실행 결과가 셸 변수 tty에 대입됩니다.

그리고 표준 입력이 리다이렉트된 처리 안에서도 4처럼 단말 정보를 직접 리다이렉트하면, while 반복문에서 이미 다른 read 명령어로 리다이렉트하고 있더라도 문제없이 키보드 입력을 받을 수 있습니다.

   

주의사항

  • 예제에 나온 tty 명령어 출력은 구체적으로는 다음처럼 “/dev/pts/0” 같은 현재 이용하는 갓아 터미널의 디바이스 파일명이 됩니다.

    • tty 명령어 출력

      $ tty
      /dev/pts/0
      

      4에서 이 가상 터미널을 리다이렉트하므로 키보드 입력을 명시적으로 지정할 있습니다.