FreeBSD sh에서 현재 디렉터리를 터미널 제목으로 표시하기
터미널을 여러 개 열어 놓고 작업하다 보면 각 터미널이 어느 디렉터리에 있는지 제목 표시줄만 보고 구분하고 싶을 때가 있습니다.
예를 들어 현재 디렉터리가 다음과 같다면,
/home/hodong/projects/nimfsoft.com
터미널 제목에는 다음처럼 표시되도록 만들 수 있습니다.
~/projects/nimfsoft.com
현재 디렉터리가 홈 디렉터리 밖에 있다면 축약하지 않고 전체 경로를 표시합니다.
/usr/local/src
이 글에서는 FreeBSD의 /bin/sh와 ~/.shrc를 기준으로 설정합니다.
터미널 제목 변경 원리
xterm 호환 터미널 에뮬레이터는 OSC(Operating System Command) 이스케이프 시퀀스를 이용하여 터미널 제목을 변경할 수 있습니다.
printf '\033]0;%s\007' '새 터미널 제목'
각 부분의 의미는 다음과 같습니다.
\033 ESC 문자
]0; 아이콘 이름과 창 제목 설정
%s 표시할 문자열
\007 BEL 문자로 OSC 시퀀스 종료
따라서 현재 디렉터리를 그대로 제목으로 지정하려면 다음처럼 작성할 수 있습니다.
printf '\033]0;%s\007' "$PWD"
OSC 제목 변경 기능의 지원 여부는 터미널 에뮬레이터와 설정에 따라 다를 수 있습니다.
홈 디렉터리를 ~로 축약하기
$PWD가 $HOME과 같거나 그 하위 디렉터리라면 홈 디렉터리 부분을 ~로
표시합니다.
set_terminal_title() {
if [ -n "${HOME-}" ]; then
case "$PWD" in
"$HOME")
_terminal_title_path='~'
;;
"$HOME"/*)
_terminal_title_path="~${PWD#"$HOME"}"
;;
*)
_terminal_title_path=$PWD
;;
esac
else
_terminal_title_path=$PWD
fi
printf '\033]0;%s\007' "$_terminal_title_path"
unset _terminal_title_path
}
${HOME-}은 HOME 변수가 설정되지 않은 경우에도 오류 없이 빈 문자열로
처리되도록 합니다.
홈 디렉터리가 정상적으로 설정된 경우에는 case 문으로 현재 경로를
분류합니다.
case "$PWD" in
"$HOME")
_terminal_title_path='~'
;;
"$HOME"/*)
_terminal_title_path="~${PWD#"$HOME"}"
;;
*)
_terminal_title_path=$PWD
;;
esac
현재 디렉터리가 홈 디렉터리와 정확히 같으면 제목은 ~가 됩니다.
/home/hodong -> ~
현재 디렉터리가 홈 디렉터리의 하위 디렉터리이면 $HOME 부분을 제거한 뒤
앞에 ~를 붙입니다.
/home/hodong/projects/nimfsoft.com
-> ~/projects/nimfsoft.com
${PWD#"$HOME"}은 $PWD의 앞부분에서 $HOME과 일치하는 가장 짧은 문자열을
제거합니다.
예를 들어 다음 환경에서,
HOME=/home/hodong
PWD=/home/hodong/projects/nimfsoft.com
${PWD#"$HOME"}의 결과는 다음과 같습니다.
/projects/nimfsoft.com
여기에 ~를 붙이면 최종 제목은 다음과 같습니다.
~/projects/nimfsoft.com
"$HOME"/* 패턴을 별도로 사용하므로 /home/hodong2처럼 이름 앞부분만
우연히 같은 다른 디렉터리를 홈 디렉터리 아래로 잘못 판단하지 않습니다.
/home/hodong2/projects
-> /home/hodong2/projects
_terminal_title_path는 셸 함수 안에서 사용하기 위한 임시 변수입니다.
FreeBSD sh의 함수 변수는 기본적으로 현재 셸에 남을 수 있으므로, 함수
마지막에서 unset하여 다른 설정과 충돌할 가능성을 줄였습니다.
cd를 실행할 때 제목 갱신하기
셸이 시작될 때 제목을 한 번 설정하는 것만으로는 부족합니다. cd를
실행하여 디렉터리를 이동할 때도 제목을 다시 설정해야 합니다.
다음 함수는 기존 셸 내장 cd를 호출한 뒤, 디렉터리 변경이 성공한 경우에만
터미널 제목을 갱신합니다.
cd() {
command cd "$@" || return $?
set_terminal_title
}
함수 안에서 단순히 cd "$@"를 호출하면 같은 이름의 함수가 다시 호출되어
재귀에 빠집니다.
cd "$@"
command cd "$@"를 사용하면 같은 이름의 함수 대신 셸 내장 cd를
실행합니다.
command cd "$@"
"$@"를 사용하므로 사용자가 cd에 전달한 인자를 그대로 유지합니다.
cd
cd -
cd /usr/local/src
디렉터리 변경에 실패하면 실패 상태를 반환하고 제목은 갱신하지 않습니다.
command cd "$@" || return $?
따라서 존재하지 않는 디렉터리로 이동하려고 해도 현재 디렉터리와 터미널 제목은 그대로 유지됩니다.
최종 .shrc 설정
다음 패치를 ~/.shrc에 적용합니다.
--- a/.shrc 2026-07-15 19:28:53.358286000 +0900
+++ b/.shrc 2026-07-15 19:47:56.461994000 +0900
@@ -46,6 +46,37 @@
bind ^[[5~ ed-move-to-beg
bind ^[[6~ ed-move-to-end
+# Update terminal title to the current working directory.
+set_terminal_title() {
+ if [ -n "${HOME-}" ]; then
+ case "$PWD" in
+ "$HOME")
+ _terminal_title_path='~'
+ ;;
+ "$HOME"/*)
+ _terminal_title_path="~${PWD#"$HOME"}"
+ ;;
+ *)
+ _terminal_title_path=$PWD
+ ;;
+ esac
+ else
+ _terminal_title_path=$PWD
+ fi
+
+ printf '\033]0;%s\007' "$_terminal_title_path"
+ unset _terminal_title_path
+}
+
+# Change directory and update the terminal title.
+cd() {
+ command cd "$@" || return $?
+ set_terminal_title
+}
+
+# Set the initial terminal title.
+set_terminal_title
+
# set prompt: ``username@hostname:directory $ ''
PS1="\u@\h:\w \\$ "
set_terminal_title을 처음 한 번 호출하는 이유는 .shrc를 읽는 시점의 현재
디렉터리를 터미널 제목에 반영하기 위해서입니다.
set_terminal_title
그 뒤에는 cd 함수가 디렉터리 이동에 성공할 때마다 제목을 다시
갱신합니다.
설정을 현재 셸에 적용합니다.
. ~/.shrc
이제 다음처럼 디렉터리를 이동하면,
cd ~/projects/nimfsoft.com
터미널 제목에 다음 경로가 표시됩니다.
~/projects/nimfsoft.com
홈 디렉터리 밖으로 이동하면 전체 경로를 표시합니다.
cd /usr/local/src
/usr/local/src
PS1 안에서 함수를 호출하지 않는 이유
처음에는 다음처럼 PS1 안에서 함수를 호출하는 방법을 생각할 수 있습니다.
PS1='$(set_terminal_title)\u@\h:\w \$ '
그러나 이 구성은 필자가 사용한 FreeBSD sh 환경에서 의도대로 동작하지
않았습니다. 프롬프트가 비정상적으로 표시되었고 터미널 제목도 갱신되지
않았습니다.
따라서 특정한 프롬프트 재평가 동작에 의존하지 않고, 기존 PS1은 그대로
유지했습니다.
PS1="\u@\h:\w \\$ "
대신 디렉터리가 실제로 변경되는 cd 호출을 감싸서, 이동이 성공한 직후
제목을 갱신하도록 구성했습니다.
주의 사항
이 설정은 OSC 제목 변경 시퀀스를 지원하고, 애플리케이션의 제목 변경을 허용하는 터미널 에뮬레이터에서 동작합니다.
터미널 에뮬레이터가 OSC 제목 변경을 지원하지 않거나 보안 설정으로 차단한 경우에는 제목이 바뀌지 않을 수 있습니다.
또한 이 예제는 일반적인 사용자 디렉터리 이름을 가정합니다. 디렉터리 이름에 ESC나 BEL 같은 터미널 제어 문자가 포함된 특수한 환경에서는 경로를 그대로 터미널 제어 시퀀스에 넣지 않도록 별도의 정제가 필요합니다.
이 설정은 사용자가 cd 함수를 통해 디렉터리를 변경할 때 제목을
갱신합니다. 셸 시작 시에는 set_terminal_title을 한 번 직접 호출하여 초기
제목을 설정합니다.
전체 동작 요약
터미널 제목은 다음 규칙으로 표시됩니다.
/home/hodong -> ~
/home/hodong/projects -> ~/projects
/home/hodong/projects/nimfsoft.com -> ~/projects/nimfsoft.com
/home/hodong2/projects -> /home/hodong2/projects
/usr/local/src -> /usr/local/src
작은 설정이지만 여러 프로젝트의 터미널을 동시에 열어 놓고 작업할 때 현재 위치를 빠르게 구분할 수 있어 편리합니다.