지난 글에서는 한줄의 입력을 처리하는 hello.py 를 만들어 보았다.
여러줄이 들어올 땐 어떻게 할까?
쉽다. 여러번 읽으면 된다.
name = input()
print("Hello "+ name)
조금 깔끔한 출력을 위해 질문을 출력하는 print(“name?”)을 제거했다.
여기까지는 다를게 없고,
while True:
name = input()
print("Hello "+ name)
while 문을 추가해보았다.
실행해보면 한도 끝도없이 계속 질문을 한다. ctrl+c 를 눌러서 그만두자.
$ python3 hello_multi.py
KHS
Hello KHS
ABC
Hello ABC
123
Hello 123
^CTraceback (most recent call last):
File "hello_multi.py", line 2, in <module>
name = input()
KeyboardInterrupt
$
이 상태에서 echo와 파이프로 연결해보자.
$ echo "KHS" | python3 hello_multi.py
Hello KHS
Traceback (most recent call last):
File "hello_multi.py", line 2, in <module>
name = input()
EOFError: EOF when reading a line
$
첫 줄에서 KHS에 대한 반응이 Hello KHS
로 잘 나왔다.
그런데 오류가 났다.
잘보니 ctrl+c 를 눌렀을때와 같은 위치에서(입력을 기다리는 부분) 에러가 조금 다르다.
EOFError이고 오류내용은 “줄을 읽으려는데 EOF예요”
EOF
EOF는 End Of File의 약자인데, 파일의 끝이란 이야기다.
“파일이 무슨 상관이지?” 싶겠지만…
파일을 열어서 한줄씩 읽다보면 결국 끝이 오게 되고, 거기까지가 그 파일의 전체내용이다.
한줄씩 읽는 입장에서는 파일을 읽다가 마지막까지 가던,
표준입력을 읽다가 더이상 입력이 없던,
둘다 EOF인 것이다.
언어에 따라다르지만 표준입출력을 제공하는 언어는 isEOF() 라던지, null이 리턴되던지 해서 EOF를 알리는 방법을 제공하고 있다. 파이썬에서 input()함수는 EOFError를 던짐으로써 그 방법을 제공한다.
자 이제 에러가 안나게 해보자. 정확히 말하자면 EOF를 처리하는 것이다.
while True:
try:
name = input()
except EOFError as eof:
break
print("Hello "+ name)
EOFError가 잡히면 그냥 루프를 탈출하게 했다.
다시 해보자.
$ echo "KHS" | python3 hello_multi.py
Hello KHS
$
에러가 나지 않는다.
이제 진짜 여러 입력을 넣어보자.
한줄에 이름이 하나씩 쓰여있는 파일을 만들고 cat names.txt 를 파이프로 연결하면 된다.
KHS
sng2c
홍길동
cat 하면 파일의 내용이 표준출력으로 나오고,
$ cat names.txt
KHS
sng2c
홍길동
$
파이프로 연결하면, 여러줄의 입력이 하나씩 처리가 되면서
$ cat names.txt | python3 hello_multi.py
Hello KHS
Hello sng2c
Hello 홍길동
$
아름다운 결과를 볼 수 있다.
뽀나스
홍길동만 뽑아보겠다.
$ cat names.txt | python3 hello_multi.py | grep 홍길동
Hello sng2c
$
뽀나스2
키보드로 EOF를 넣어보자. 그냥 실행하면 무한정 물어보는건 알고 있을 것이다.
입력을 기다릴때 ctrl+d 를 눌러보자.
$ python3 hello_multi.py
KHS
Hello KHS
sng2c
Hello sng2c
^d
$
ctrl+c 를 눌렀을 때와 비교해보자.