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

매직 문자 '~': Bash 틸드(Tilde) 확장 완벽 가이드 – 실전 예제 5가지

매직 문자  ~ : Bash 틸드(Tilde) 확장 완벽 가이드 – 실전 예제 5가지Bash 셸에는 '~'(틸드)로 시작하는 특수 변수들이 있으며, 이를 활용하는 기능을 틸드 확장(Tilde Expansion)이라고 합니다.

틸드는 셸 내부에 있는 다른 변수들의 값을 대신 가리키는 일종의 별칭(synonym)입니다. 즉, 틸드 확장이란 이러한 약어를 그것이 의미하는 실제 디렉터리 경로로 변환하는 과정을 말합니다.

이 글에서는 다양한 예제와 함께 Bash의 틸드 확장 기능을 자세히 살펴보겠습니다.

틸드 확장의 기본 규칙

틸드 확장은 '~' 뒤에 오는 문자(+, -, 또는 정수 N)에 적용되며, 공백이나 슬래시(/)를 만나면 확장이 종료됩니다.

틸드 확장은 주로 다음과 같은 특정 경로명으로 확장됩니다.

  • 홈 디렉터리(Home Directory)
  • 현재/이전 작업 디렉터리(Current/Previous Working Directory)
  • 디렉터리 스택(Directory Stack)에 저장된 디렉터리

1. 홈 디렉터리 확장

틸드 확장을 사용하면 현재 사용자의 홈 디렉터리 또는 지정된 사용자 이름의 홈 디렉터리로 손쉽게 확장할 수 있습니다.

문법

~      $HOME 변수 또는 현재 사용자의 홈 디렉터리로 확장
~USER  지정한 사용자 이름(USER)의 홈 디렉터리로 확장

예제 1. 현재 사용자의 홈 디렉터리

단독으로 사용된 틸드(~)는 $HOME 변수가 정의되어 있다면 그 값으로 확장되고, $HOME이 정의되어 있지 않으면 현재 사용자의 홈 디렉터리 값으로 확장됩니다.

아래 예제에서 HOME 변수의 값은 /home/oracle이므로, cd ~ 명령은 현재 디렉터리를 $HOME 값으로 변경합니다.

## 홈 디렉터리가 /home/oracle인 oracle 사용자로 로그인
# su oracle
[tmp]$ pwd
/tmp

[tmp]$ echo $HOME
/home/oracle

[tmp]$ cd ~

[~]$ pwd
/home/oracle

그런데 HOME 변수를 다른 값으로 바꾸면 어떻게 될까요? 아래 예제에서 HOME을 /sbin으로 변경한 후 cd ~를 실행하면, 실제 홈 디렉터리가 아닌 $HOME 값만을 따라갑니다. 반면 unset으로 HOME 변수를 제거하면, /etc/passwd에 설정된 oracle 사용자의 실제 홈 디렉터리로 이동합니다. 즉, 틸드 확장에서는 HOME 변수가 실제 홈 디렉터리보다 우선권을 가집니다.

[~]$ export HOME=/sbin

[oracle]$ cd ~

[~]$ pwd
/sbin

[~]$ unset HOME

[sbin]$ cd ~

[oracle]$ pwd
/home/oracle

예제 2. 지정한 사용자의 홈 디렉터리

다음 스크립트는 파일 이름에 현재 날짜가 포함된 로그 파일을 백업하고, 시작 시간과 종료 시간을 oracle 사용자 홈 디렉터리의 backup.log 파일에 기록합니다.

#! /bin/bash

echo "Initiating the backup at `date`" >> ~oracle/backup.log

da=`date +%F`
cp $da.log{,.bak}

echo "END BACKUP at `date`" >> ~oracle/backup.log

$ ls -l /home/oracle/
total 8
-rw-r--r-- 1 root   root       99 Jun  4 14:23 backup.log

주의할 점은, 지정한 사용자 이름이 존재하지 않으면 확장이 일어나지 않는다는 것입니다. 아래 예제에서 'ora'라는 사용자는 없으므로, ~ora는 /home/ora로 확장되지 않고 그대로 출력됩니다.

$ echo ~ora
~ora

참고로 중괄호({ })를 활용한 브레이스 확장(Brace Expansion)에 대해서도 이전 글에서 다룬 적이 있으니 함께 참고하시기 바랍니다.

2. 현재/이전 작업 디렉터리 확장

'+' 및 '-'와 함께 사용된 틸드는 작업 디렉터리를 나타내는 데 사용됩니다.

  • ~+ : 현재 작업 디렉터리를 담고 있는 PWD 변수의 값으로 확장됩니다.
  • ~- : 이전 작업 디렉터리를 담고 있는 OLDPWD 변수의 값으로 확장됩니다. OLDPWD가 설정되어 있지 않으면 확장되지 않습니다.

예제 3. 이전/현재 작업 디렉터리 확장

다음 예제는 현재 디렉터리의 파일과 이전 작업 디렉터리의 파일을 비교합니다.

$ cat comp.sh
#! /bin/bash

set -x
cd /var/opt/gg
if [ -f gg.c ]
then
echo "File1 exists"
fi

cd /var/opt1/gg
if [ -f gg.c ]
then
echo "File2 exists"
cmp ~+/gg.c ~-/gg.c
fi

$ ./comp.sh
+ cd /var/opt/gg
+ '[' -f gg.c ']'
+ echo 'File1 exists'
File1 exists
+ cd /var/opt1/gg
+ '[' -f gg.c ']'
+ echo 'File2 exists'
File2 exists
+ cmp /var/opt1/gg/gg.c /var/opt/gg/gg.c
cmp: EOF on /var/opt1/gg/gg.c
$

위 실행 결과에서 알 수 있듯이:

  • ~+/gg.c는 /var/opt1/gg/gg.c로 확장됩니다.
  • ~-/gg.c는 /var/opt/gg/gg.c로 확장됩니다.

이 글은 진행 중인 Bash 튜토리얼 시리즈의 일부입니다.

3. 디렉터리 스택 확장

각 bash 프로세스는 스택(stack) 객체를 내장하고 있으며, 이를 통해 스크립트가 처리 과정에서 방문한 디렉터리들을 추적할 수 있습니다.

이는 방문했던 디렉터리를 참조하거나 되돌아가기 위한 매우 간단한 메커니즘입니다. 틸드 확장 역시 디렉터리 스택에 있는 디렉터리들로 확장하는 기능을 제공합니다.

  • ~+N : 디렉터리 스택에서 N번째 디렉터리로 확장됩니다. 옵션 없이 실행한 dirs 명령 출력 목록 기준 왼쪽부터 0부터 세어 계산합니다.
  • ~-N : 디렉터리 스택에서 N번째 디렉터리로 확장됩니다. 단, 오른쪽부터 0부터 세어 계산합니다.

디렉터리 스택을 조작하는 dirs, pushd, popd 명령의 사용법은 이전 글을 참고하시기 바랍니다.

예제 4. ~+로 왼쪽에서 N번째 디렉터리 표시

다음 예제에서 디렉터리 스택에는 4개의 디렉터리가 있습니다. ~+2는 왼쪽에서 0부터 세었을 때 두 번째 위치에 있는 디렉터리 경로를 반환합니다.

$ dirs -v
 0  /sbin
 1  /var/opt/midas
 2  /var/opt/GG/bin
 3  /root

$ cd ~+2

$ pwd
/var/opt/GG/bin

단, 스택의 맨 위(0번 위치)에는 항상 현재 디렉터리가 위치한다는 점에 유의하세요. 따라서 위 명령 실행 후 디렉터리 스택은 다음과 같이 변경됩니다.

$ dirs -v
 0  /var/opt/GG/bin
 1  /var/opt/midas
 2  /var/opt/GG/bin
 3  /root

예제 5. ~-로 오른쪽에서 N번째 디렉터리 표시

다음 예제는 앞선 예제와 유사하지만, ~-를 사용하기 때문에 스택의 아래쪽(오른쪽 끝)에서부터 디렉터리를 계산합니다.

$ dirs -v
 0  /var/opt/GG/bin
 1  /var/opt/midas
 2  /var/opt/GG/bin
 3  /root

$ cd ~-2

$ pwd
/var/opt/midas

$ dirs -v
 0  /var/opt/midas
 1  /var/opt/midas
 2  /var/opt/GG/bin
 3  /root