본문 바로가기

스터디/리눅스 커맨드라인

[리눅스] 28. 키보드 입력 읽기

 

앞 장에서 작성한 스크립트들은 대다수 컴퓨터 프로그램에서 사용하는 일반적인 기능이 빠져있다.
바로 대화식 모드이다.

이 것은 사용자와 프로그램 사이에 상호 작용하는 것을 말한다. 모든 프로그램들이 대화식으로 작동할 필요는 없지만 일부 프로그램에서는 사용자로부터 직접적인 입력을 허용하는 것이 효과적일 수 있다.

 

 

1. read - 표준 입력에서 값 읽어오기

read는 쉘의 내장 명령어로 표준 입력으로 들어온 내용을 한 줄씩 읽어올 때 사용된다. 이 명령어는 키보드 입력을 읽어올 때나 리다이렉션을 적용하여 파일의 데이터를 읽어올 때 사용될 수 있다.
"read [-options] [variable ...]

options는 옵션 중 하나 이상을 지정하고, variable에는 입력 값을 할당할 변수명을 하나 이상 입력한다. 만약 변수명을 입력하지 않으면 쉘 변수 REPLY가 데이터를 갖게 된다.

* read 옵션

  • -a array : 입력값을 array에 할당한다.
  • -d delimiter : delimiter 문자열에서 개행 문자가 아닌 가장 첫 번째 문자를 입력의 끝을 가리키는 데 사용한다.
  • -e : Readline을 이용하여 입력을 관리한다.
  • -n num : 입력된 행 전체 대신 num 수의 문자만을 읽어온다.
  • -p prompt : prompt 문자열을 이용하여 입력을 위한 프롬프트를 띄운다.
  • -r : Paw 모드. 백슬래시 기호를 이스케이프로 해석하지 않는다.
  • -s : Raw모드. 문자를 입력할 때마다 해당 문자를 다시 표시하지 않는다. 비밀번호같은 중요한 정보를 입력할 때 사용
  • -t seconds : 타임아웃. 일정 시간(초) 후에 입력을 종료한다.
  • -u fd : 표준 입력 대신 fd 파일 디스크립터를 입력으로 사용한다.
echo -n "Please enter an integer -> "
read int 


if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
	if [ $INT -eq 0 ]; then
    	echo "INT is zero"
    else 
    	if [ $INT -lt 0 ]; then
        	echo "INT is negative"
        else
        	echo "INT is positive"
        
        if [$((INT % 2)) -eq 0 ]; then
        	echo "INT is even"
        else
        	echo "INT is odd"
        
else
	echo "INT is not an integer." >&2
    exit 1​

echo 명령어와 -n 옵션을 함께 사용하여 프롬프트를 띄우고 read 명령어로 int 변수에 입력될 값을 기다린다.

if read -t 10 -sp "Enter secret passphrase > " secret_pass; then
	echo -d "\n Secret passphrase = '$secret_pass'"

else
	echo -e "\n Input timed out" >&2
    exit 1

이 스크립트는 사용자에게 비밀번호를 입력하라는 프롬프트를 띄우고 10초동안 입력을 기다린다.
그 시간 동안 입력이 없으면 오류 메시지를 띄우고 종료한다. -s 옵션을 사용해서 입력된 비밀번호는 표시되지 않는다.

(1) IFS로 입력 필드 구분하기

일반적으로 쉘은 read에 제공된 입력 내용을 단어로 나누는 작업을 수행한다. 지금까지는 입력 행에서 하나 이상의 스페이스로 분리된 각 단어들이 read에 의해 별도의 변수에 할당된다는 것을 의미한다. 이러한 방식은 IFS(입력 필드 구분자)라고 하는 쉘 변수에 의해 설정된다.
IFS의 기본 값은 스페이스, 탭, 개행 문자를 포함하고 있고 각각 별도의 항목으로 구분된다.

FILE=/etc/passwd

read =p "Enter > " user_name

file_info=$(grep "^$user_name:" $FILE)

if [ -n "$file_info" ]; then
	IFS=":" read user pw uid gid name home shell <<< "$file_info"
    echo "User = '$user'"
    .
    .
    .
else
	echo "No user '%user_name'" >&2
    exit 1​

이 스크립트는 사용자에게 시스템의 사용자 계정명을 입력하라는 메시지를 띄우고 /etc/passwd 파일에서 해당 사용자 정보를 찾아 각 필드들을 표시한다. 

file_info=$(grep "^$user_name:" $FILE) : grep 명령어의 결과 값을 file_info라는 변수에 할당한다.

IFS=":" read user pw uid gid name home shell <<< "$file_info": 세 가지로 구성되어있다. 변수 할당문, read 명령과 그 인자로 입력된 변수명, 다소 낯선 리다이렉션 연산자다.