34.1. 대화(interactive)형 모드와 비대화(non-interactive)형 모드 쉘과 스크립트

대화형 모드의 쉘은 명령어를 tty 의 사용자 입력으로부터 읽어 들입니다. 이 대화형 모드 쉘은 그 중에서도 특히나 기본적으로, 활성화시 시작 파일(startup)을 읽어 들이고, 프롬프트를 표시해 주고, 작업 제어를 해줍니다. 사용자는 쉘과 대화를 할 수 있게 됩니다.

스크립트를 실행시키는 쉘은 항상 비대화형 모드 쉘로 동작하지만 계속 자신의 tty에 접근할 수 있습니다. 심지어는 스크립트에서 대화형 모드 쉘을 흉내내는 것도 가능합니다.
#!/bin/bash
MY_PROMPT='$ '
while :
do
  echo -n "$MY_PROMPT"
  read line
  eval "$line"
done

exit 0

# 이 예제 스크립트와 위에서 설명한 많은 부분들은 Stephane Chazelas 가
# 제공해 주었습니다.

보통 read 문(예 11-2 참고)으로 사용자가 입력을 받아 들이는 스크립트를 대화형 모드 스크립트라고 합시다. "실제 세계"에서는 이것보다 조금 더 복잡하지만, 지금 당장은 tty 에 연결되어 있고, 사용자가 콘솔이나 한텀에서 실행시킨 스크립트를 대화형 모드 스크립트라고 가정합니다.

초기화(init)와 시스템 구동(startup) 스크립트는 사람의 개입없이 돌아야 하기 때문에 반드시 비대화형 모드여야 합니다. 많은 수의 관리용이나 시스템 유지용 스크립트 역시 비대화형 모드 스크립트입니다. 항상 같고 반복적인 작업의 자동화에는 비대화형 모드 스크립트가 필요합니다.

비대화형 모드 스크립트는 백그라운드로 돌 수 있지만, 대화형 모드 스크립트는 결코 받을 수 없는 사용자 입력을 기다리면서 멈춰 있게 됩니다. 이렇게 백그라운드로 도는 대화형 모드 스크립트에 대해서는 expect 스크립트나 스크립트 안에 here document를 사용해서 입력을 집어 넣을 수 있습니다. 가장 간단한 방법은 read 문에 입력 재지향을 걸어서(read variable <file) 파일에서 입력을 받도록 하는 것입니다. 이렇게 까다로운 몇 가지 해결책 덕분에 평범한 용도의 스크립트들이 대화형 모드나 비대화형 모드 양 쪽에서 돌 수 있습니다.

만약에 스크립트가 현재 대화형 모드로 돌고 있는지 아닌지는 단순히 프롬프트 변수인 $PS1이 세트됐는지 아닌지로 알아낼 수 있습니다(사용자가 입력을 할 차례라면(being prompted), 스크립트는 프롬프트를 표시해야 하기 때문입니다).
if [ -z $PS1 ] # 프롬프트가 없다?
then
  # 비대화형 모드
  ...
else
  # 대화형 모드
  ...
fi
다른 방법으로는, $- 플래그에서 "i" 옵션이 있는지 없는지로 확인할 수도 있습니다.
case $- in
*i*)    # 대화형 모드 쉘
;;
*)      # 비대화형 모드 쉘
;;
# (1993년 "UNIX F.A.Q."에서 인용)

참고: 스크립트에 -i 옵션을 주거나 #!/bin/bash -i 헤더를 주면 강제로 대화형 모드로 동작하도록 할 수 있습니다. 이렇게 했을 경우에는 스크립트가 엉뚱하게 동작한다거나 에러가 없는데도 에러 메세지를 보여줄 수도 있기 때문에 조심해야 합니다.