9.1. 내부 변수(Internal Variables)

내장(Builtin) 변수

Bash 스크립트의 동작에 영향을 미치는 변수

$BASH

Bash 실행 파일의 경로로, 보통은 /bin/bash

$BASH_ENV

스크립트가 실행될 때 어디에서 bash 시작 파일을 읽을 것인지를 나타내는 환경 변수

$BASH_VERSINFO[n]

원소 갯수가 6개인 배열로, 현재 설치된 Bash 버전에 대한 정보를 담고 있습니다. 다음에 설명할 $BASH_VERSION 과 비슷하지만 좀 더 자세한 정보를 담고 있습니다.

# Bash 버전 정보:

for n in 0 1 2 3 4 5
do
  echo "BASH_VERSINFO[$n] = ${BASH_VERSINFO[$n]}"
done  

# BASH_VERSINFO[0] = 2                      # Major version no.
# BASH_VERSINFO[1] = 04                     # Minor version no.
# BASH_VERSINFO[2] = 21                     # Patch level.
# BASH_VERSINFO[3] = 1                      # Build version.
# BASH_VERSINFO[4] = release                # Release status.
# BASH_VERSINFO[5] = i386-redhat-linux-gnu  # Architecture
                                            # ($MACHTYPE 과 동일).

$BASH_VERSION

시스템에 설치된 Bash 버전

bash$ echo $BASH_VERSION
2.04.12(1)-release
	      

tcsh% echo $BASH_VERSION
BASH_VERSION: Undefined variable.
	      

어떤 쉘로 동작중인지 알아보려고 할 때 $BASH_VERSION 을 확인해 보는 것은 아주 좋은 방법입니다. 왜냐하면, $SHELL 로는 충분한 정보를 얻을 수 없기 때문입니다.

$DIRSTACK

디렉토리 스택의 내용(pushdpopd의 영향을 받음)

이 내장 변수는 dirs 명령어와 짝을 이룹니다.

$EDITOR

스크립트가 부르는 에디터로서, 보통은 viemacs입니다.

$EUID

"유효" 사용자 아이디 값

su에 의해 쓰일 현재 사용자의 유효 아이디 값.

경고

$EUID$UID와 반드시 같지 않습니다.

$FUNCNAME

현재 함수의 이름

xyz23 ()
{
  echo "$FUNCNAME now executing."  # xyz23 now executing.
}

xyz23

echo "FUNCNAME = $FUNCNAME"        # FUNCNAME =
                                   # 함수 밖에서는 널 값을 갖습니다.

$GLOBIGNORE

globbing 시 포함되지 않을 파일명 패턴들의 목록.

$GROUPS

현재 사용자가 속해 있는 그룹

/etc/passwd에 적혀 있는 현재 사용자의 그룹 아이디 값을 보여줍니다.

$HOME

사용자의 홈 디렉토리로, 보통은 /home/username (예 9-10 참고)

$HOSTNAME

hostname 명령어는 부팅시 init 스크립트에서 시스템 이름을 설정해 줍니다. 하지만 gethostname() 함수로 bash 내부 변수인 $HOSTNAME을 설정해 줄 수도 있습니다. 예 9-10을 참고하세요.

$HOSTTYPE

host type

$MACHTYPE과 마찬가지로 시스템 하드웨어를 알려줍니다.

bash$ echo $HOSTTYPE
i686
$IFS

입력 필드 구분자

디폴트는 공백문자(빈칸, 탭, 뉴라인)지만 콤마로 구분된 데이타 파일을 파싱하려는 경우처럼 변경이 가능합니다. $*$IFS의 첫번째 문자를 사용하는 것에 주의하세요. 예 6-1 참고.

bash$ echo $IFS | cat -vte
$


bash$ bash -c 'set w x y z; IFS=":-;"; echo "$*"'
w:x:y:z
	      

경고

$IFS 는 빈 칸을 다른 문자들과는 다르게 처리합니다.

예 9-1. $IFS 와 빈 칸

#!/bin/bash
# $IFS 는 공백문자를 다른 문자들과 다르게 처리합니다.

output_args_one_per_line()
{
  for arg
  do echo "[$arg]"
  done
}

echo; echo "IFS=\" \""
echo "-------"

IFS=" "
var=" a  b c   "
output_args_one_per_line $var  # output_args_one_per_line `echo " a  b c   "`
#
# [a]
# [b]
# [c]


echo; echo "IFS=:"
echo "-----"

IFS=:
var=":a::b:c:::"               # 위와 같지만 ":" 를 " "로 바꿔줍니다.
output_args_one_per_line $var
#
# []
# [a]
# []
# [b]
# [c]
# []
# []
# []

# awk 의 "FS" 필드 구분자도 위와 같은 동작을 합니다.

# Thank you, Stephane Chazelas.

echo

exit 0

(S. C. 에게 정확한 설명과 예제에 감사.)

$IGNOREEOF

EOF 무시: 로그 아웃하기 전에 몇 개의 end-of-files (control-D)를 무시할 것인지.

$LC_COLLATE

주로 .bashrc/etc/profile 에서 세트되는 이 변수는 파일명 확장이나 패턴 매칭시의 대조(collation) 순서를 제어합니다. 이 값이 잘못 처리되면 파일명 globbing시 원치 않는 결과를 가져 올 수 있습니다.

참고: Bash 2.05 이후로, 파일명 globbing 은 대괄호에 들어 있는 문자 범위에 나타나는 대소문자를 더 이상 구분하지 않습니다. 예를 들어, ls [A-M]*File2.txtfile1.txt 모두와 일치될 것입니다. 자신만의 대괄호 매칭 동작을 원래대로 바꾸려면 /etc/profile이나 ~/.bashrc등에 export LC_COLLATE=C 라고 해서 LC_COLLATEC로 세트해 주면 됩니다.

$LC_CTYPE

이 내부 변수는 globbing 과 패터 매칭의 문자 해석을 제어합니다.

$LINENO

쉘 스크립트에서 이 변수가 들어 있는 줄의 줄번호를 나타내는데, 스크립트에서 쓰일 때만 의미가 있고, 주로 디버깅에 쓰입니다.

last_cmd_arg=$_  # 저장.

echo "$LINENO 번째 줄, 변수 \"v1\" = $v1"
echo "처리된 마지막 명령어 인자 = $last_cmd_arg"

$MACHTYPE

머신 종류

시스템 하드웨어를 구분해 줍니다.

bash$ echo $MACHTYPE
i686-debian-linux-gnu
$OLDPWD

바로 전 작업 디렉토리 ("OLD-print-working-directory")

$OSTYPE

운영 체제 종류

bash$ echo $OSTYPE
linux-gnu
$PATH

실행 파일의 경로, 보통은 /usr/bin/, /usr/X11R6/bin/, /usr/local/bin, 등등.

명령어가 주어지면 쉘은 실행 파일들을 위한 경로에 들어있는 디렉토리들에 대해서 자동으로 해쉬 테이블 탐색을 수행합니다. 경로에는 환경 변수인 $PATH에 디렉토리들이 콜론으로 구분되어 들어 있습니다. 보통 $PATH 정의는 /etc/profile이나 ~/.bashrc에 들어 있습니다(27장 참고).

bash$ echo $PATH
/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin:/sbin:/usr/sbin

PATH=${PATH}:/opt/bin 라고 하면 /opt/bin을 현재 경로에 추가 시킵니다. 이렇게 하면 경로에 임시로 디렉토리를 적절하게 추가할 수 있습니다. 스크립트가 끝나면 원래 $PATH 로 복구됩니다(스크립트같은 자식 프로세스는 부모 프로세스인 쉘의 환경 변수를 바꿀 수 없습니다).

참고: 보통은 현재 "작업 디렉토리"를 나타내는 ./은 보안상의 이유로 $PATH에서 제외시킵니다.

$PIPESTATUS

마지막으로 실행된 파이프의 종료 상태. 아주 재미있는 것은, 이 결과와 마지막으로 실행된 명령어의 종료 상태가 똑같지는 않다는 것입니다.

bash$ echo $PIPESTATUS
0

bash$ ls -al | bogus_command
bash: bogus_command: command not found
bash$ echo $PIPESTATUS
141

bash$ ls -al | bogus_command
bash: bogus_command: command not found
bash$ echo $?
127
	      

$PPID

어떤 프로세스의 부모 프로세스의 프로세스 아이디(pid)를 $PPID이라고 합니다. [1]

이것들을 pidof 명령어와 비교해 보세요.

$PS1

명령어줄에서 볼 수 있는 메인 프롬프트.

$PS2

2차 프롬프트로, 추가적인 입력이 필요할 때 ">" 로 표시됩니다.

$PS3

3차 프롬프트로 select 루프문에서 표시됩니다(예 10-27 참고).

$PS4

4차 프롬프트로, 스크립트에 -x 옵션이 걸려서 실행될 때 스크립트의 매 줄마다 "+"로 표시됩니다.

$PWD

작업 디렉토리(현재 있는 디렉토리)

내장 명령인 pwd와 비슷합니다.

#!/bin/bash

E_WRONG_DIRECTORY=73

clear # 화면 정리.

TargetDirectory=/home/bozo/projects/GreatAmericanNovel

cd $TargetDirectory
echo "$TargetDirectory 디렉토리의 오래된 파일을 지웁니다."

if [ "$PWD" != "$TargetDirectory" ]
then    # 실수로 다른 디렉토리를 지우지 않게 합니다.
  echo "지울 디렉토리가 아닙니다!"
  echo "$TargetDirectory 디렉토리가 아니라 $PWD 디렉토리입니다,"
  echo "취소합니다!"
  exit $E_WRONG_DIRECTORY
fi  

rm -rf *
rm .[A-Za-z0-9]*    # 도트 파일 삭제.
# 이름이 여러개의 점으로 시작하는 파일도 지우려면 이렇게 하세요.   rm -f .[^.]* ..?*   
# (shopt -s dotglob; rm -f *)   라고 해도 됩니다.
# 지적해 줘서 고마워요. S.C.

# 파일이름에는 "/"를 제외하고 0 - 255 사이의 모든 문자가 들어갈 수 있습니다.
# 이상한 문자로 시작하는 파일을 지우는 것은 연습문제로 남겨 놓습니다.

# 필요하다면 다른 작업을 하세요.

echo
echo "끝."
echo "$TargetDirectory 디렉토리의 오래된 파일을 모두 삭제했습니다."
echo


exit 0

$REPLY

read에 변수가 안 주어졌을 때 저장되는 기본값이고, select 메뉴에서는 변수의 값이 아니라 선택한 숫자가 저장됩니다.

#!/bin/bash

echo
echo -n "제일 좋아하는 야채가 뭐에요? "
read

echo "제일 좋아하는 야채가 $REPLY 군요."
# REPLY 는 가장 최근의 "read"가 변수 없이 주어졌을 때 그 값을 담고 있습니다.

echo
echo -n "제일 좋아하는 과일은요? "
read fruit
echo "당신이 제일 좋아하는 과일은 $fruit 지만,"
echo "\$REPLY 의 값은 여전히 $REPLY 네요."
# $fruit 변수가 "read"의 값을 가져가 버렸기 때문에 $REPLY 는 여전히
# 앞에서 설정된 값을 갖고 있습니다.

echo

exit 0

$SECONDS

스크립트가 얼마나 돌았는지를 나타내는 초 단위 시간.

#!/bin/bash

ENDLESS_LOOP=1
INTERVAL=1

echo
echo "스크립트를 끝내려면 Control-C 를 누르세요."
echo

while [ $ENDLESS_LOOP ]
do
  if [ "$SECONDS" -eq 1 ]
  then
    units=second
  else  
    units=seconds
  fi

  echo "이 스크립트는 $SECONDS $units 동안 돌고 있습니다."
  sleep $INTERVAL
done


exit 0

$SHELLOPTS

현재 켜 있는 쉘 옵션들의 목록으로서 읽기 전용 변수

$SHLVL

쉘 레벨로 Bash 가 얼마나 깊이 중첩되어 있는지를 나타냄. 만약에 명령어줄에서 $SHLVL 이 1 이었다면 스크립트에서는 2 가 됩니다.

$TMOUT

$TMOUT 환경 변수를 0 이 아닌 값 time으로 설정해 놓으면 그 시간이 지난 다음에는 로그아웃이 됩니다.

참고: 불행하게도 이 변수는 콘솔상의 쉘 프롬프트나 엑스텀(한텀)에서만 동작합니다. 예를 들어, read 문에서 $TMOUT을 같이 쓰고 싶겠지만 실제로는 제대로 동작하지 않습니다.(ksh 버전에서는 read의 타임아웃이 제대로 동작한다고 보고된 바 있습니다).

타임 아웃을 쉘 스크립트에서 구현할 수는 있으나 그렇게 효과적이지 않습니다. 한가지 가능한 방법은, 타임 아웃이 났을 때 타이밍 루프가 스크립트에게 시그널을 보내도록 세팅해야 하고 타이밍 루프가 발생시킨 (예 30-4 참고) 인터럽트를 처리할 시그널 처리 루틴도 만들어야 합니다, 휴~~.

예 9-2. 타임 아웃 처리 입력

#!/bin/bash
# timed-input.sh

# TMOUT=3            스크립트에서는 쓸모가 없습니다.

TIMELIMIT=3  # 여기서는 3초, 다른 값으로 세트할 수 있습니다.

PrintAnswer()
{
  if [ "$answer" = TIMEOUT ]
  then
    echo $answer
  else       # 두 번의 인스턴스를 구분하기 위해서.
    echo "제일 좋아하는 야채는 $answer 이군요."
    kill $!  # 백그라운드에서 도는 TimerOn 함수가 더 이상 필요없기 때문에 kill 시킴.
             # $! 는 백그라운드에서 돌고 있는 가장 최근 작업의 PID 입니다.
  fi

}  



TimerOn()
{
  sleep $TIMELIMIT && kill -s 14 $$ &
  # 3초를 기다리고 알람 시그널(sigalarm)을 스크립트에 보냄.
}  

Int14Vector()
{
  answer="TIMEOUT"
  PrintAnswer
  exit 14
}  

trap Int14Vector 14   # 타이머 인터럽트(14)는 우리 의도대로 타임아웃을 처리함.

echo "제일 좋아하는 야채가 뭐죠? "
TimerOn
read answer
PrintAnswer


# 이는 분명히 타임아웃 입력에 대한 미봉책입니다만,
# Bash 로 할 수 있는 최선을 다한 것입니다.
# (독자들에게 도전: 더 나은 해결책을 제시해 보세요.)

# 더 우아한 다른 것이 필요하다면 C 나 C++ 의 'alarm'이나 'setitimer' 같은
# 적당한 라이브러리 함수를 써서 구현하기 바랍니다.

exit 0

stty를 쓴 다른 방법.

예 9-3. 타임 아웃 처리 입력, 한 번 더

#!/bin/bash
# timeout.sh

# Stephane Chazelas 작성.
# 이 문서의 저자가 수정.

INTERVAL=5                # 타임아웃 인터벌

timedout_read() {
  timeout=$1
  varname=$2
  old_tty_settings=`stty -g`
  stty -icanon min 0 time ${timeout}0
  eval read $varname      # 아니면 그냥     read $varname
  stty "$old_tty_settings"
  # "stty" 맨 페이지 참조.
}

echo; echo -n "이름이 뭐죠? 빨리 대답해요! "
timedout_read $INTERVAL your_name

# 모든 터미널 타입에서 동작하지 않을 수도 있습니다.
# 최대 타임아웃은 어떤 터미널이냐에 달려있습니다.
# (보통은 25.5 초).

echo

if [ ! -z "$your_name" ]  # 타임아웃 전에 입력이 있다면...
then
  echo "아하, 이름이 $your_name 군요."
else
  echo "타임아웃."
fi

echo

# 이 스크립트는 "timed-input.sh" 스크립트와 약간 다르게 동작하는데,
# 키가 눌릴 때마다 타임아웃 카운터가 리셋됩니다.

exit 0
$UID

사용자 아이디 값

/etc/passwd에 저장되어 있는 현재 사용자의 사용자 식별 숫자

비록 su에 의해서 임시로 다른 사용자로 인식되더라도 현재 사용자의 실제 아이디를 나타냅니다. $UID는 읽기만 되는 변수로 명령어 줄이나 스크립트에서 변경할 수 없습니다. 그리고, id 내장 명령과 짝을 이룹니다.

예 9-4. 내가 루트인가?

#!/bin/bash
# am-i-root.sh:   내가 루트야 아니야?

ROOT_UID=0   # 루트 $UID는 0.

if [ "$UID" -eq "$ROOT_UID" ]  # Will the real "root" please stand up?
then
  echo "루트네요."
else
  echo "그냥 보통 사용자에요.(그래도 당신 어머니는 있는 그대로의 당신을 사랑하신답니다)."
fi

exit 0


# ============================================================= #
# 스크립트가 이미 종료됐기 때문에 밑의 코드는 실행되지 않습니다.

# 루트인지 알아내는 다른 방법:

ROOTUSER_NAME=root

username=`id -nu`
if [ "$username" = "$ROOTUSER_NAME" ]
then
  echo "루티 투트 투트(Rooty, toot, toot), 당신은 루트 사용자군요."
else
  echo "그냥 보통 사람이군요."
fi

exit 0

예 2-2 참고.

참고: $ENV, $LOGNAME, $MAIL, $TERM, $USER, $USERNAME은 bash 내장 명령아닙니다. 하지만 종종 bash 시스템 구동 파일에서 환경 변수로 설정이 됩니다. 사용자의 로긴 쉘을 나타내는 $SHELL/etc/passwd를 참고해 설정되거나 "init" 스크립트에서 설정되고, 역시 bash 내장명령어가 아닙니다.

tcsh% echo $LOGNAME
bozo
tcsh% echo $SHELL
/bin/tcsh
tcsh% echo $TERM
rxvt

bash$ echo $LOGNAME
bozo
bash$ echo $SHELL
/bin/tcsh
bash$ echo $TERM
rxvt
	      

위치 매개변수(Positional Parameters)

$0, $1, $2, etc.

위치 매개변수로서, 명령어줄에서 스크립트로 넘겨지거나 함수로 넘겨지거나 set 명령어로 강제로 설정됨(예 5-5예 11-10 참고).

$#

명령어줄 인자 [2] 의 갯수나 위치 매개변수들(예 34-2 참고)

$*

한 낱말로 표시되는 위치 매개변수들 모두

$@

$*과 똑같지만 각 매개변수는 쿼우트된 문자열로 취급됩니다. 즉, 해석되거나 확장없이 있는 그대로 넘겨집니다. 그 결과로 각 인자는 각각이 서로 다른 낱말로 구분돼서 표시됩니다.

예 9-5. arglist: $* 과 $@ 로 인자를 나열하기

#!/bin/bash
# 이 스크립트를 부를 때 "one two three" 같은 인자를 줘서 부르세요.

E_BADARGS=65

if [ ! -n "$1" ]
then
  echo "사용법: `basename $0` argument1 argument2 etc."
  exit $E_BADARGS
fi  

echo

index=1

echo "\"\$*\" 로 인자를 나열하기:"
for arg in "$*"  # "$*" 를 쿼우트하지 않으면 제대로 동작하지 않습니다.
do
  echo "Arg #$index = $arg"
  let "index+=1"
done             # $* 는 모든 인자를 하나의 낱말로 봅니다.
echo "전체 인자 목록은 하나의 낱말로 나타납니다."

echo

index=1

echo "\"\$@\" 로 인자를 나열하기:"
for arg in "$@"
do
  echo "Arg #$index = $arg"
  let "index+=1"
done             # $@ 는 인자들을 분리된 낱말로 봅니다.
echo "전체 인자 목록은 분리된 낱말로 나타납니다."

echo

exit 0

특수 매개변수인 $@에는 쉘 스크립트로 들어오는 입력을 필터링하는 툴로서 쓰입니다. cat "$@"은 자신의 매개변수를 표준입력이나 파일에서 받아 들일 수 있습니다. 예 12-17을 참고하세요.

경고

$*$@은 가끔 $IFS의 설정값에 따라 일관성이 없고 이상한 동작을 합니다.

예 9-6. 일관성 없는 $*$@의 동작

#!/bin/bash

# 쿼우트 여부에 따라 이상하게 동작하는 
# Bash 내부 변수 "$*"와 "$@".
# 낱말 조각남과 라인피드가 일관성 없이 처리됩니다.

# 이 예제 스크립트는 Stephane Chazelas 가 제공하고,
# 본 문서의 저자가 약간 수정했습니다.


set -- "첫번째 인자" "두번째" "세번째:인자" "" "네번째: :인자"
# 스크립트의 인자를 $1, $2 등으로 세팅.

echo

echo 'IFS 는 그대로, "$*"'
c=0
for i in "$*"               # 쿼우트
do echo "$((c+=1)): [$i]"   # 매 인스턴스마다 똑같음.
                            # 인자 에코.
done
echo ---

echo 'IFS 는 그대로, $*'
c=0
for i in $*                 # 쿼우트 안 함
do echo "$((c+=1)): [$i]"
done
echo ---

echo 'IFS 는 그대로, "$@"'
c=0
for i in "$@"
do echo "$((c+=1)): [$i]"
done
echo ---

echo 'IFS 는 그대로, $@'
c=0
for i in $@
do echo "$((c+=1)): [$i]"
done
echo ---

IFS=:
echo 'IFS=":", "$*"'
c=0
for i in "$*"
do echo "$((c+=1)): [$i]"
done
echo ---

echo 'IFS=":", $*'
c=0
for i in $*
do echo "$((c+=1)): [$i]"
done
echo ---

var=$*
echo 'IFS=":", "$var" (var=$*)'
c=0
for i in "$var"
do echo "$((c+=1)): [$i]"
done
echo ---

echo 'IFS=":", $var (var=$*)'
c=0
for i in $var
do echo "$((c+=1)): [$i]"
done
echo ---

var="$*"
echo 'IFS=":", $var (var="$*")'
c=0
for i in $var
do echo "$((c+=1)): [$i]"
done
echo ---

echo 'IFS=":", "$var" (var="$*")'
c=0
for i in "$var"
do echo "$((c+=1)): [$i]"
done
echo ---

echo 'IFS=":", "$@"'
c=0
for i in "$@"
do echo "$((c+=1)): [$i]"
done
echo ---

echo 'IFS=":", $@'
c=0
for i in $@
do echo "$((c+=1)): [$i]"
done
echo ---

var=$@
echo 'IFS=":", $var (var=$@)'
c=0
for i in $var
do echo "$((c+=1)): [$i]"
done
echo ---

echo 'IFS=":", "$var" (var=$@)'
c=0
for i in "$var"
do echo "$((c+=1)): [$i]"
done
echo ---

var="$@"
echo 'IFS=":", "$var" (var="$@")'
c=0
for i in "$var"
do echo "$((c+=1)): [$i]"
done
echo ---

echo 'IFS=":", $var (var="$@")'
c=0
for i in $var
do echo "$((c+=1)): [$i]"
done

echo

# 이 스크립트를 ksh 이나 zsh -y 로 실행해 보세요.

exit 0

참고: $@$*는 큰따옴표로 쿼우트 됐을 때만 달라집니다.

예 9-7. $IFS 가 비어 있을 때 $*$@

#!/bin/bash

# $IFS 가 빈 상태로 세트됐다면,
# "$*" 와 "$@" 는 위치 매개변수를 우리가 생각하는대로 에코하지 않습니다.

mecho ()       # 위치 매개변수 에코.
{
echo "$1,$2,$3";
}


IFS=""         # 빈 상태로 세트.
set a b c      # 위치 매개변수.

mecho "$*"     # abc,,
mecho $*       # a,b,c

mecho $@       # a,b,c
mecho "$@"     # a,b,c

# $IFS 가 비어 있을 경우에 $* 와 $@ 의 동작은
# Bash 나 sh 의 버전에 따라 달라지기 때문에
# 스크립트에서 이 "기능"에 쓰는 것은 권장하지 않습니다.


# Thanks, S.C.

exit 0

다른 특수 매개변수

$-

스크립트로 넘겨진 플래그들

경고

원래 ksh에서 쓰던 것을 bash에서 채택한 것인데 불행히도 잘 동작하지 않는 것 같습니다. 스크립트 자신이 대화형인지 아닌지 스스로 확인하려고 하는 경우에나 쓸만합니다.

$!

백그라운드로 돌고 있는 가장 최근 작업의 PID (process id)

$_

바로 이전에 실행된 명령어의 제일 마지막 인자로 설정되는 특수 변수.

예 9-8. 밑줄 변수(underscore variable)

#!/bin/bash

echo $_         # /bin/bash
# 스크립트를 돌리기 위해 실행된 /bin/bash. 

du >/dev/null   # 명령어 출력이 없음.
echo $_         # du

ls -al          # 명령어 출력이 없음.
echo $_         # -al  (마지막 인자)

:
echo $_         # :
$?

명령어나 함수, 스크립트 자신의 종료 상태(예 23-3 참고).

$$

스크립트 자신의 프로세스 아이디로 보통 임시 파일 이름을 만들 때 사용합니다(예 A-8예 30-5, 예 12-23 참고).

주석

[1]

현재 돌고 있는 스크립트의 pid 는 $$ 입니다.

[2]

"인자"(argument)나 "매개변수" (parameter)는 흔히 서로 바꿔서 쓰기 때문에 이 문서에서는 스크립트나 함수로 넘겨지는 변수를 나타내는 같은 의미로 쓰입니다.