본문 바로가기
IT일반/Linux

Command Line - 키보드 입력 읽기

by 버섯도리 2022. 6. 6.

<read 옵션>

옵션 설명
-a array 입력값을 array에 할당한다. 인덱스 0으로 시작함.
-d delimiter delimiter 문자열에서 개행 문자가 아닌 가장 첫 번째 문자를 입력의 끝으로 가리키는 데 사용한다.
-e Readline을 이용하여 입력을 관리한다. 이것은 커맨드라인과 같은 방식으로 입력 내용을 편집할 수 있게 해준다.
-n num 입력된 행 전체 대신 num 수의 문자만을 읽어온다.
-p prompt prompt 문자열을 이용하여 입력을 위한 프롬프트를 띄운다.
-r Raw 모드. 백슬래시 기호를 이스케이프로 해석하지 않는다.
-s 묶음 모드. 문자를 입력할 떄마다 해당 문자를 다시 표시하지 않는다. 이것은 비밀번호 같은 중요한 정보 등을 입력할 때 등에 유용하다.
-t seconds 타임아웃. 일정 시간(초) 후에 입력을 종료한다. read 명령은 입력 시간이 초과되면 0이 아닌 종료 상태 값을 반환한다.
-u fd 표준 입력 대신 fd 파일 디스크립터를 입력으로 사용한다.

 

[cmd_test@btjeon-naver ~]$ vi read_integer.sh
------------------------------------------------------------------------------------------
#!/bin/bash

# read_integer: Evaluate the value of an integer.

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."
                fi
                if [ $((int % 2)) -eq 0 ]; then
                        echo "$int is even."
                else
                        echo "$int is odd."
                fi
        fi
else
        echo "Input value is not an integer.">$2
        exit 1
fi
------------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./read_integer.sh 
Please enter an integer -> 5
5 is positive.
5 is odd.

read 명령어를 통해 표준 입력 값을 int 변수에 할당받는다.

 

[cmd_test@btjeon-naver ~]$ vi read_multiple.sh
-----------------------------------------------------------------------------------------
#!/bin/bash

# read_multiple: Read multiple values from keyboard

echo -n "Please enter one or more values -> "
read var1 var2 var3 var4 var5

echo "var1 = '$var1'"
echo "var2 = '$var2'"
echo "var3 = '$var3'"
echo "var4 = '$var4'"
echo "var5 = '$var5'"
-----------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./read_multiple.sh 
Please enter one or more values -> a b c d e
var1 = 'a'
var2 = 'b'
var3 = 'c'
var4 = 'd'
var5 = 'e'
[cmd_test@btjeon-naver ~]$ ./read_multiple.sh 
Please enter one or more values -> a
var1 = 'a'
var2 = ''
var3 = ''
var4 = ''
var5 = ''
[cmd_test@btjeon-naver ~]$ ./read_multiple.sh 
Please enter one or more values -> a b c d e f g
var1 = 'a'
var2 = 'b'
var3 = 'c'
var4 = 'd'
var5 = 'e f g'

여러 변수 할당 예제

 

[cmd_test@btjeon-naver ~]$ vi read_single.sh
-----------------------------------------------------------------------------------------
#!/bin/bash

# read_single: Read multiple values into default variable

echo -n "Please enter one or more values -> "
read 

echo "REPLY = '$REPLY'"
-----------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./read_single.sh 
Please enter one or more values -> a b c d
REPLY = 'a b c d'

read 다음에 변수가 없다면 REPLY 변수에 모든 값이 할당된다.

 

[cmd_test@btjeon-naver ~]$ vi read_single_p.sh
------------------------------------------------------------------------------------------
#!/bin/bash

# read_single: Read multiple values into default variable

read -p "Please enter one or more values -> "

echo "REPLY = '$REPLY'"
------------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./read_single_p.sh 
Please enter one or more values -> a b c d
REPLY = 'a b c d'

-p 옵션 예제

 

[cmd_test@btjeon-naver ~]$ vi read_secret.sh
--------------------------------------------------------------------------------------------
#!/bin/bash

# read_secret: Input a secret passphrase

if read -t 10 -so "Please Enter passphrace > " secret_pass; then
        echo -e "\nSecret passphase = '$secret_pass'"
else
        echo -e "\nInput timed out" >&2
        exit 1
fi
--------------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./read_secret.sh
Please Enter passphrace > 
Secret passphase = '1992'
[cmd_test@btjeon-naver ~]$ ./read_secret.sh
Please Enter passphrace > 
Input timed out
[cmd_test@btjeon-naver ~]$ 199

-t -s 옵션을 사용하여 비밀번호 입력을 받는 예제

 

read 명령어에서 입력된 내용을 단어로 나눌 때 IFS(입력 필드 구분자)라고 하는 쉘 변수에 의해 설정된다. IFS의 기본값은 스페이스, 탭, 개행 문자를 포함하고 있고 각각 별도의 항목으로 구분된다.

[cmd_test@btjeon-naver ~]$ vi read_ifs.sh
--------------------------------------------------------------------------------------------
#!/bin/bash

# read_ifs: read fields from a file

FILE=/etc/passwd

read -p "Enter a username > " user_name

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

if [ -n "$file_info" ]; then
        OLD_IFS="$IFS"
        IFS=":"
        read user pw uid gid name home shell <<< "$file_info"
        IFS="$OLD_IFS"

        echo "User =            '$user'"
        echo "UID =             '$uid'"
        echo "GID =             '$gid'"
        echo "Full Name =       '$name'"
        echo "Home Dir =        '$home'"
        echo "Shell =           '$shell'"
else
        echo "No such user '$user_name'" >&2
        exit 1
fi
--------------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./read_ifs.sh 
Enter a username > cmd_test
User =		'cmd_test'
UID =		'1001'
GID =		'1001'
Full Name =	''
Home Dir =	'/home/cmd_test'
Shell =		'/bin/bash'
[cmd_test@btjeon-naver ~]$ ./read_ifs.sh 
Enter a username > test
No such user 'test'

IFS 값을 세미콜론(:)으로 변경 후, /etc/passwd 파일에서 해당 내용을 추출하는 예제이다.

<<< 연산자는 here 문자열이다. here 문자열이란 here 문서와 같은 것으로 다만 길이가 짧은 하나의 문자열로 구성된다. 이 예제에서는 /etc/passwd 파일의 데이터를 read 명령의 표준 입력으로 전달하고 있다.

 

[cmd_test@btjeon-naver ~]$ vi read_validate.sh
-------------------------------------------------------------------------------------------
#!/bin/bash

# read_validate: Validate input

invalid_input () {
        echo "Invalid input '$REPLY'" >$2
        exit 1
}

read p "Enter a single item > " 

# Input is empty (invalid)
[[ -z $REPLY ]] && invalid_input

# Input is multiple item (invalid)
(( $(echo $REPLY | wc -w) > 1 )) && invalid_input

# is input a valid filename?
if [[ $REPLY =~ ^[-[:alnum:]\._]+$ ]]; then
        echo "'$REPLY' is a valid filename."
        if [[ -e $REPLY ]]; then
                echo "And file '$REPLY' exists."
        else
                echo "However, file '$REPLY' does not exist."
        fi

        # is input a floating point number?
        if [[ $REPLY =~ ^-?[[:digit:]]*\.[[:digit:]]+$ ]]; then
                echo "'$REPLY' is a floating point number."
        else
                echo "'$REPLY' is not a floating point number."
        fi

        # is input an integer?
        if [[ $REPLY =~ ^-?[[:digit:]]+$ ]]; then
                echo "'$REPLY' is an integer."
        else
                echo "'$REPLY' is not an integer."
        fi
else
        echo "The string '$REPLY' is not a valid filename."
fi
-------------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./read_validate.sh 
Enter a single item > 34
'34' is a valid filename.
However, file '34' does not exist.
'34' is not a floating point number.
'34' is an integer.
[cmd_test@btjeon-naver ~]$ ./read_validate.sh 
Enter a single item > 24.34
'24.34' is a valid filename.
However, file '24.34' does not exist.
'24.34' is a floating point number.
'24.34' is not an integer.
[cmd_test@btjeon-naver ~]$ ./read_validate.sh 
Enter a single item > foo.txt
'foo.txt' is a valid filename.
And file 'foo.txt' exists.
'foo.txt' is not a floating point number.
'foo.txt' is not an integer.

입력 값 검증 예제

 

[cmd_test@btjeon-naver ~]$ vi read_menu.sh
--------------------------------------------------------------------------------------
#!/bin/bash

# read_menu: a menu driven system information program

clear
echo "
Please Select:

1. Display System Information
2. Display Disk Space
3. Display Home Space Utilization
0. Quit
"

read -p "Enter selection [0-3] > "

if [[ $REPLY =~ ^[[0-3]$ ]]; then
        if [[ $REPLY == 0 ]]; then
                echo "Program terminated."
                exit
        fi
        if [[ $REPLY == 1 ]]; then
                echo "Hostname: $HOSTNAME"
                uptime
                exit
        fi 
        if [[ $REPLY == 2 ]]; then
                df -h
                exit
        fi
        if [[ $REPLY == 3 ]]; then
                if [[ $(id -u) -eq 0 ]]; then
                        echo "Home Space Utilization (All Users)"
                        du -sh /home/*
                else
                        echo "Home Space Utilization ($USER)"
                        du -sh $HOME
                fi
                exit
        fi
else
        echo "Invalid entry.." >&2
        exit 1
fi
--------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./read_menu.sh

Please Select:

1. Display System Information
2. Display Disk Space
3. Display Home Space Utilization
0. Quit

Enter selection [0-3] > 1
Hostname: btjeon-naver
 15:45:16 up 22 days, 22:58,  2 users,  load average: 0.00, 0.01, 0.05

[cmd_test@btjeon-naver ~]$ ./read_menu.sh

Please Select:

1. Display System Information
2. Display Disk Space
3. Display Home Space Utilization
0. Quit

Enter selection [0-3] > 2
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        481M     0  481M   0% /dev
tmpfs           491M     0  491M   0% /dev/shm
tmpfs           491M   56M  435M  12% /run
tmpfs           491M     0  491M   0% /sys/fs/cgroup
/dev/xvda1       50G  2.3G   48G   5% /
tmpfs            99M     0   99M   0% /run/user/0

[cmd_test@btjeon-naver ~]$ ./read_menu.sh

Please Select:

1. Display System Information
2. Display Disk Space
3. Display Home Space Utilization
0. Quit

Enter selection [0-3] > 3
Home Space Utilization (cmd_test)
5.8M	/home/cmd_test

[cmd_test@btjeon-naver ~]$ ./read_menu.sh

Please Select:

1. Display System Information
2. Display Disk Space
3. Display Home Space Utilization
0. Quit

Enter selection [0-3] > 0
Program terminated.

메뉴 방식 예제

 

 

 

 

 

 

출처 : 리눅스 커맨드라인 완벽 입문서