커맨드 라인에서 명렁어를 실행하기 전에 Shell 프로그램이 항상 문법 요소를 확인한다. 그리고 특별한 요소를 찾고 그것을 해석하고 명령어를 바꿔서 실행해준다.
Shell 프로그램은 항상 정해진 순서로 expansion 과 substitution을 수행한다.
{}를 사용하여 prefix와 suffix를 설정하여 가능한 조합들을 만들어줄수있다.
$ echo {1,2}
1 2
$ echo a{AA,BB}b
aAAb, aBBb
$ echo {1}
{1}
$ echo a{1, 2}b
a{1, 2}b
$ echo test{1,2}.{c,h}
test1.c,test1.h,test2.c,test2.h
뿐만 아니라 범위에도 사용가능하다.
$ echo {5..10}
5 6 7 8 9 10
$ echo {c..e}
c f e
$ echo {5..k}
{5..k}
+2,+3... 등등도 가능
$ echo {1..10..2}
1 3 5 7 9
$ echo {a..z..3}
a d g j s v y
$ echo {10..50..5}%
10% 15% ... 50%
$ echo {A..Z}{0..9}
A0 A1 ... A9 B0 ... Z9
$ echo {{A..Z},{a..z}} # echo {1,2} -> 1,2 , {{A..Z},{a..z}} -> {A..Z},{a..z}
A B C D E ... z
$ touch test{1,2,3}.txt # test1.txt , text2.txt, text3.txt 파일 생성
$ mkdir /home/bash/test/{foo,bar,baz,cat,dog} # test 디렉토리 밑에 괄호 안 이름으로 디렉토리 생성
주의할것
$ A=foo $ echo {1,2}$A # 1$A 2$A 1foo 2foo $ echo $A{1,2} # $A1 $A2 # null
Brace expansion이 제일 순위가 높기 때문에 제일 먼저 확장된다.
~
: HOME
변수의 값으로 확장해준다.~+
: PWD
변수의 값으로 확장해준다.~-
: OLDPWD
변수의 값으로 확장해준다.$ pwd
/home/my
$ ls
bin prj
$ cd bin
$ cd ../prj
$ echo ~
/home/my
$ echo ~+
/home/my/prj
$ echo ~-
/home/my/bin
$ cd ~
$ pwd
/home/my
echo ~
= echo $HOME
echo ~+
= echo $PWD
$parameter
or ${parameter}
= parameter 변수의 값으로 확장해준다.
${parameter}
이 더 명확하게 표현할때 사용된다.
$ echo Your home directory is $HOME
echo Your home directory is /home/my
$ echo "Your mail INBOX is located in $MAIL"
Your mail INBOX is located in # MAIL=null
$ your_id=${USER}-on-${HOSTNAME}
$ echo $your_id
dragonappear-in
$ OSS=2113
$ echo "CSE$OSSCourse"
CSE
$ echo "CSE${OSS}Course"
CSE2113Course
${PARAMETER:-WORD}
: PARAMETER가 unset(never was defined)이거나 null일때 default 값으로 확장
${PARAMETER-WORD}
: PARAMETER가 unset일때만 default 값으로 확장
$ OSS=2113
$ echo ${OSS:-1000}
2113
$ echo ${OSS-1000}
2113
$ unset OSS
$ echo ${OSS:-1000}
1000
$ echo ${OSS-1000}
1000
$ OSS=
$ echo ${OSS:-1000}
1000
$ echo ${OSS-1000}
#null
$(command-name)
or 'command-name'
: 커맨드 대체
$ echo User $(whoami) is on `hostname`
User drgaonappear is on ubuntu
$ echo `echo `ls`` # incorrect
$ echo $(echo $(ls)) # correct
Test.txt
$ echo "Today is $(date)"
Today is 2022년 1월 8일 토요일 18시 37분 52초 KST
$ echo "Today is `date +%y%m%d`"
Today is 20220108
$((EXPRESSION))
: Arithmetic Expansion
[EXPRESSION]
: deprecatred
$ a=10
$ b=20
$ c=a+b
$ echo $a $b $c
10 20 a+b
$ c=$((a+b))
$ echo $a $b $c
10 20 30
$ d=$((c=a**2))
$ echo $a $b $c $d
10 20 100 100
$ expr a + $((b+3))
expr: non-integer argument
$ expr: $a + $((b+3))
33
위 세가지 명령어가 동시에 발생하면 왼쪽에서 오른쪽으로 발생한다.
$ x=5
$ y=10
$ ans=$((x+y))
$ echo "$x + $y = $ans"
5 + 10 = 15
$ echo $x $((x++)) $x # left-to-right
5 5 6 # not 5 5 5
Wildcard : 기존에 존재하는 파일들의 이름을 표시하기 위한 glob이라고 불리는 특별한 문자들을 Wildcards라고 부른다.
$ touch test{1..3}.{c,h,o}
test1.c test1.h test1.o test2.c test2.h test2.o test3.c test3.h test3.o
$ ls test?.o
test1.o test2.o test3.o
$ ls test?,py
No such file or directory
$ ls *.[ch]
test1.c test1.h test2.c test2.h test3.c test3.h
$ ls test?.[ch]
test1.c test1.h test2.c test2.h test3.c test3.h
$ ls *.[^ch] # ch를 제외한
test1.o test2.o test3.o
$ ls test?.[c-o]
test1.c test1.h test1.o test2.c test2.h test2.o test3.c test3.h test3.o
$ ls test?.{c..o}
ls: cannot access 'test?.d' : No such file or directory
...
ls: cannot access 'test?.m' : No such file or directory
ls: cannot access 'test?.n' : No such file or directory
test1.c test1.h test1.o test2.c test2.h test2.o test3.c test3.h test3.o
Shell Methacharacters는 쉘에서 특별한 의미를 가진 문자들이다.
Quoting은 특정한 문자의 특정 의미를 제거하고, 우회한다.
Bash에서는 3가지 quoting 메커니즘이 존재한다.
\은 wildcard 앞에 있으면 wildcard의 특정의미를 제거한다.
echo 'Path is $Path'
-> Path is $Path
echo 'Today is $(date)'
-> Today is $(date)
echo "Path is $PATH"
-> Path is /Users/dragonappear ...
echo "Today is $(date)"
-> TToday is 2022년 1월 8일 토요일 20시 35분 59초 KST