Positional Parameters
- 스크립트 파일을 실행할 때
- function 을 호출할 때
- 스크립트 파일을 source 할 때
인수를 주게되면 해당 스크립트 및 함수 내에서 positional paramters 가 자동으로 설정됩니다. 첫번째 인수는 $1
, 두번째는 $2
... 식으로 할당되며 scope 은 local 변수와 같습니다.
sh
과 같이 array 를 사용할 수 없는 환경에서 활용할 수 있습니다.
$0
스크립트 파일 이름를 나타냅니다.
$ cat test.sh
#!/bin/sh
echo \$0 : $0
echo \$1 : $1
echo \$2 : $2
.................
$ ./test.sh 11 22
$0 : ./test.sh
$1 : 11
$2 : 22
-----------------
# shell 함수는 $0 값이 /bin/bash 가 된다.
$ testfunc() { echo \$0 : $0; echo \$1 : $1; echo \$2 : $2; }
$ testfunc 11 22
$0 : /bin/bash
$1 : 11
$2 : 22
sh -c
형식으로 실행했을 경우는 첫번째 인수를 가리킵니다.
$ sh -c 'echo $0, $1, $2' 11 22 33
11, 22, 33
프롬프트 에서 사용할 경우
$ echo $0
/bin/bash
$ $0 --version
GNU bash, version 4.3.46(1)-release (x86_64-pc-linux-gnu)
...
Symbolic link 와 $0
어떤 명령을 다른 이름으로 symbolic link (또는 hard link) 한 후 링크 이름으로 실행을 하면
$0
값이 링크 이름 됩니다.
$ cat ccache.sh
#!/bin/sh
echo "Im running '$0'"
---------------------------
$ chmod +x ccache.sh
$ ./ccache.sh
Im running './ccache.sh'
$ ln -s ccache.sh gcc.sh
$ ./gcc.sh
Im running './gcc.sh'
$ ln -s ccache.sh clang.sh
$ ./clang.sh
Im running './clang.sh'
$1, $2, $3 ...
각 인수들을 나타냅니다.
--------- test.sh --------
#!/bin/sh
echo number of arguments = $#
echo \$0 = "$0"
echo \$1 = "$1"
echo \$2 = "$2"
echo \$3 = "$3"
######### output ########
$ ./test.sh 11 22 33
number of arguments = 3
$0 = ./test.sh
$1 = 11
$2 = 22
$3 = 33
$#
$0
을 제외한 전체 인수의 개수를 나타냅니다.
$ cat test.sh
#!/bin/sh
echo $#
.....................
$ ./test.sh 11 22 33
3
$ set --
$ ./test.sh "$@"
0
$ ./test.sh "$*" # "" 이 인수로 잡힌다.
1
$@ , $*
$@
, $*
는 positional parameters 전부를 포함합니다. array 에서 사용되는 @
, *
기호와 의미가 같다고 볼 수 있습니다. 변수를 quote 하지 않으면 단어분리에 의해 두 변수의 차이가 없지만 quote 을 하게 되면 "$@"
의 의미는 "$1"
"$2"
"$3"
... 와 같게되고 "$*"
의 의미는 "$1c$2c$3 ... "
와 같게됩니다. ( 여기서 c
는 IFS
변수값의 첫번째 문자 입니다. )
--------- test.sh --------
#!/bin/sh
echo \$@ : $@
echo \$* : $*
echo '======== "$@" ======='
for v in "$@"; do # 또는 for v do ...
echo "$v"
done
echo '======== "$*" ======='
for v in "$*"; do
echo "$v"
done
########### output ##########
$ ./test.sh 11 22 33
$@ : 11 22 33
$* : 11 22 33
======== "$@" =======
11
22
33
======== "$*" =======
11 22 33
-----------------------------
$ f1() { "$@" ;}
$ f1 date +%D
01/22/16
$ f1() { "$*" ;}
$ f1 date +%D
date +%D: command not found # 'date +%D' 가 명령 이름이 된다.
"$*"
는 항상 IFS 변수값의 첫번째 문자를 인수 구분자로 갖습니다.
$ set -- 11 22 33 44 55
$ IFS=XYZ
$ echo "$*" , $*
11X22X33X44X55 , 11 22 33 44 55
$ IFS=YZ
$ echo "$*" , $*
11Y22Y33Y44Y55 , 11 22 33 44 55
$ IFS=:
$ echo "$*" , $*
11:22:33:44:55 , 11 22 33 44 55
set
set 명령은 보통 shell 옵션을 설정할때 사용하지만 positional paramters 를 설정하거나 삭제할때도 사용됩니다. 다음 3가지 방법은 11 22 33 을 각각 $1
$2
$3
positional parameters 에 할당합니다.
$ set 11 22 33
$ set - 11 22 33
$ set -- 11 22 33
$ echo $1 $2 $3
11 22 33
# 'set --' 은 현재 설정되어 있는 positional parameters 를 모두 삭제합니다.
$ set --
$ echo $1 $2 $3
$
사용예 )
--------- test.sh --------
#!/bin/sh
# set 명령을 이용하여 script 내에서 positional parameters 를 설정
set -- 11 22 33
echo number of arguments = $#
echo \$0 = "$0"
echo \$1 = "$1"
echo \$2 = "$2"
echo \$3 = "$3"
######### output ########
$ ./test.sh
number of arguments = 3
$0 = ./test.sh
$1 = 11
$2 = 22
$3 = 33
--------- set 활용 --------
$ date
Sat Dec 31 07:45:56 KST 2016
$ set -- $(date)
$ echo 오늘은 $2 월 $3 일 $1 요일 $4 시 입니다.
오늘은 Dec 월 31 일 Sat 요일 07:46:29 시 입니다.
shift
shift [n]
shift 명령은 현재 설정되어 있는 positional parameters 를 좌측으로 n
만큼 이동시킵니다.
결과로 n
개의 positional parameters 가 삭제 됩니다.
$ set -- 11 22 33 44 55
$ echo $@
11 22 33 44 55
$ shift 2
$ echo $@
33 44 55
$IFS
$IFS
변수와 set
명령을 이용하여 스트링에서 필드를 분리해낼 수 있습니다.
#!/bin/sh
line="11:22:33:44:55"
set -f; IFS=: # globbing 을 disable
set -- $line # IFS 값에 따라 필드를 분리하여 positional parameters 에 할당
set +f; IFS=`echo " \n\t"`
echo number of fields = $#
echo field 1 = "$1"
echo field 2 = "$2"
shift 3
echo \$@ = "$@"
############# output #############
number of fields = 5
field 1 = 11
field 2 = 22
$@ = 44 55
Substring expansion
Substring expansion 은 bash 에서만 사용할수 있습니다.
$ set -- 11 22 33 44 55
$ echo ${@:3}
33 44 55
$ echo ${@:2:2}
22 33