Computer >> 컴퓨터 >  >> 프로그래밍 >> Bash 프로그래밍

Bash 셸 프롬프트 마스터하기: PS1, PS2, PS3, PS4, PROMPT_COMMAND 완벽 가이드

Bash 셸 프롬프트 마스터하기: PS1, PS2, PS3, PS4, PROMPT_COMMAND 완벽 가이드

PS1, PS2, PS3, PS4, PROMPT_COMMAND 환경 변수를 효과적으로 활용하면 리눅스 Bash 셸과의 상호작용이 한층 편리하고 즐거워집니다. 여기서 'PS'는 프롬프트 문자열(Prompt Statement)을 의미합니다. 이 글에서는 간단한 예제를 통해 리눅스 명령 프롬프트 환경 변수의 기본 개념부터 실전 활용법까지 살펴보겠습니다.

1. PS1 – 기본 대화형 프롬프트

리눅스의 기본 대화형 프롬프트는 아래와 같이 더 유용하고 정보성 있는 형태로 변경할 수 있습니다. 다음 예제에서 기본 PS1 값은 "\s-\v\$"로, 셸 이름과 버전 번호를 표시합니다. 이를 사용자 이름, 호스트명, 그리고 현재 작업 디렉터리를 보여주도록 바꿔보겠습니다.

-bash-3.2$  export PS1="\u@\h \w> "

ramesh@dev-db ~> cd /etc/mail
ramesh@dev-db /etc/mail>
[참고: 프롬프트가 "username@hostname current-dir>" 형식으로 변경되었습니다]

이 예제에서 사용된 PS1 코드는 다음과 같습니다:

  • \u – 사용자 이름
  • \h – 호스트명
  • \w – 현재 디렉터리의 전체 경로. 단, 홈 디렉터리에 있을 경우 위 예시처럼 ~ 만 표시됩니다.
  • PS1 값 끝에는 공백이 하나 포함되어 있습니다. 개인적으로는 가독성을 높이기 위해 프롬프트 끝에 공백을 두는 것을 선호합니다.

이 설정을 영구적으로 유지하려면 아래와 같이 .bash_profile 또는 .bashrc 파일에 export PS1="\u@\h \w> "를 추가하면 됩니다.

ramesh@dev-db ~> vi ~/.bash_profile (또는)
ramesh@dev-db ~> vi ~/.bashrc
[참고: 위 파일 중 하나에 export PS1="\u@\h \w> "를 추가하세요]

2. PS2 – 줄 연속(Continuation) 프롬프트

매우 긴 유닉스 명령어는 행 끝에 \를 붙여 여러 줄로 나눌 수 있습니다. 멀티라인 명령어 입력 시 기본 대화형 프롬프트는 "> "입니다. PS2 환경 변수를 사용해 이 기본 동작을 "continue->"로 표시되도록 변경해 보겠습니다.

ramesh@dev-db ~> myisamchk --silent --force --fast --update-state \
> --key_buffer_size=512M --sort_buffer_size=512M \
> --read_buffer_size=4M --write_buffer_size=4M \
> /var/lib/mysql/bugs/*.MYI
[참고: 줄 연속 프롬프트로 기본값 ">"가 사용되었습니다]
ramesh@dev-db ~> export PS2="continue-> "

ramesh@dev-db ~> myisamchk --silent --force --fast --update-state \
continue-> --key_buffer_size=512M --sort_buffer_size=512M \
continue-> --read_buffer_size=4M --write_buffer_size=4M \
continue-> /var/lib/mysql/bugs/*.MYI
[참고: 수정된 "continue-> "가 줄 연속 프롬프트로 사용되었습니다]

긴 명령어를 \를 사용해 여러 줄로 나누면 읽기 쉽고 매우 유용하다고 느꼈습니다. 반면 긴 명령어를 나누는 것을 선호하지 않는 분들도 본 적이 있습니다. 여러분은 어떠신가요? 긴 명령어를 여러 줄로 나누는 것을 좋아하시나요?

3. PS3 – 셸 스크립트 내 select 문 프롬프트

셸 스크립트 안의 select 루프에 사용자 지정 프롬프트를 정의할 때 PS3 환경 변수를 활용할 수 있습니다.

PS3 미설정 시 스크립트와 실행 결과:

ramesh@dev-db ~> cat ps3.sh

select i in mon tue wed exit
do
  case $i in
    mon) echo "Monday";;
    tue) echo "Tuesday";;
    wed) echo "Wednesday";;
    exit) exit;;
  esac
done

ramesh@dev-db ~> ./ps3.sh

1) mon
2) tue
3) wed
4) exit
#? 1
Monday
#? 4
[참고: select 명령 프롬프트로 기본값 "#?"가 표시됩니다]

PS3 설정 시 스크립트와 실행 결과:

ramesh@dev-db ~> cat ps3.sh

PS3="Select a day (1-4): "
select i in mon tue wed exit
do
  case $i in
    mon) echo "Monday";;
    tue) echo "Tuesday";;
    wed) echo "Wednesday";;
    exit) exit;;
  esac
done

ramesh@dev-db ~> ./ps3.sh
1) mon
2) tue
3) wed
4) exit
Select a day (1-4): 1
Monday
Select a day (1-4): 4
[참고: select 명령 프롬프트로 수정된 "Select a day (1-4): "가 표시됩니다]

PS3를 활용하면 사용자에게 더 명확한 안내 메시지를 제공할 수 있어 스크립트의 사용성이 크게 향상됩니다.

4. PS4 – set -x 디버깅 추적 출력 접두사

PS4 셸 변수는 셸 스크립트를 디버그 모드로 실행할 때 표시되는 프롬프트를 정의합니다.

PS4 미설정 시 스크립트와 실행 결과:

ramesh@dev-db ~> cat ps4.sh

set -x
echo "PS4 demo script"
ls -l /etc/ | wc -l
du -sh ~

ramesh@dev-db ~> ./ps4.sh

++ echo 'PS4 demo script'
PS4 demo script
++ ls -l /etc/
++ wc -l
243
++ du -sh /home/ramesh
48K     /home/ramesh
[참고: set -x로 출력을 추적할 때 기본값 "++"가 표시됩니다]

PS4 설정 시 스크립트와 실행 결과:

아래 ps4.sh에서 정의된 PS4는 다음 두 코드를 포함합니다:

  • $0 – 스크립트 이름을 나타냅니다
  • $LINENO – 스크립트 내 현재 줄 번호를 표시합니다
ramesh@dev-db ~> cat ps4.sh

export PS4='$0.$LINENO+ '
set -x
echo "PS4 demo script"
ls -l /etc/ | wc -l
du -sh ~

ramesh@dev-db ~> ./ps4.sh
../ps4.sh.3+ echo 'PS4 demo script'
PS4 demo script
../ps4.sh.4+ ls -l /etc/
../ps4.sh.4+ wc -l
243
../ps4.sh.5+ du -sh /home/ramesh
48K     /home/ramesh
[참고: set -x로 출력을 추적할 때 수정된 "{스크립트명}.{줄번호}+"가 표시됩니다]

이처럼 PS4에 스크립트 이름과 줄 번호를 포함하면 디버깅 시 어떤 위치의 코드가 실행되었는지 즉시 파악할 수 있어 문제 해결이 훨씬 수월해집니다.

5. PROMPT_COMMAND

Bash 셸은 PS1 변수를 표시하기 직전에 PROMPT_COMMAND의 내용을 실행합니다.

ramesh@dev-db ~> export PROMPT_COMMAND="date +%k:%m:%S"
22:08:42
ramesh@dev-db ~>
[참고: PROMPT_COMMAND와 PS1 출력이 서로 다른 줄에 표시됩니다]

PROMPT_COMMAND 값을 PS1과 같은 줄에 표시하려면 아래와 같이 echo -n을 사용하면 됩니다.

ramesh@dev-db ~> export PROMPT_COMMAND="echo -n [$(date +%k:%m:%S)]"
[22:08:51]ramesh@dev-db ~>
[참고: PROMPT_COMMAND와 PS1 출력이 같은 줄에 표시됩니다]

PROMPT_COMMAND는 시간 표시 외에도 명령어 실행 기록 자동 저장, 작업 디렉터리 히스토리 관리 등 다양한 용도로 응용할 수 있으니 적극 활용해 보시기 바랍니다.