명령의 기본적인 구조를 살펴보면 다음과 같다.
제일 앞에 명령 이름이 오고 다음에 '공백' 그 다음 첫 번째 인수 '공백', ...
⇒ 명령은 공백으로 분리하여 작성한다.
command arg1 arg2 arg3
[ 를 명령으로 인식하고 ]를 마지막 인자로 인식하기 때문에 [ ]는 각각 공백으로 분리하여 작성되어야 한다.
⇒ argument를 상기하면 이해하기 쉽다.
test@test:~$ [ a = b ]; echo $?
1
test@test:~$ [ a=b ]; echo $?
0
test@test:~$ { echo 1;echo 2; }
1
2
test@test:~$ { echo 1; echo 2; }
1
2
test@test:~$ {echo 1; echo 2; }
-bash: syntax error near unexpected token `}'
test@test:~$ { echo 1; echo 2;}
1
2
test@test:~$ { echo 1; echo 2; }
1
2
test@test:~$ { echo 1;echo 2;}
1
2
Command 'aa'
라고 출력됨을 확인할 수 있다. ⇒ 명령어로 인식해버림test@test:~$ clear
test@test:~$ aa = 10
Command 'aa' not found, but can be installed with:
sudo apt install astronomical-almanac
test@test:~$ aa=10
test@test:~$ echo $aa
10
If 문에서 참, 거짓을 판단할 때 프로그래밍 언어에서는 0이 거짓이고 그 외 값은 참이지만 Bash shell 에서는 반대이다.
⇒ 0 : 프로그램의 정상종료 , 그 외의 숫자 : 오류
종료 상태 값 ( $? ) 으로 확인할 수 있음
$ date -@ # 인수를 잘못 사용하여 오류발생
date: invalid option -- '@'
Try 'date --help' for more information.
$ echo $? # 0 이 아닌 종료 상태 값은 if 문에서 모두 거짓에 해당합니다.
1
$ date +%Y
2015
$ echo $? # 정상종료 됐으므로 0 을 리턴. if 문에서는 참이 됩니다.
0
test@test:~$ func() { expr $1+$2; return 5;}
test@test:~$ func 1 2
1+2
test@test:~$ func() { expr $1 + $2; return 5;}
test@test:~$ func 1 2
3
test@test:~$ echo $?
5
test@test:~$ AA=$( func 1 2 )
test@test:~$ echo $AA
3
# 명령문에 shell 에서 사용하는 glob 문자 '*' 가 포함되어 에러 발생
test@test:~$ expr 3 * 4
expr: syntax error
test@test:~$ expr 3 \* 4
12
test@test:~$ expr 3 "*" 4
12
test@test:~$ [ 3 \< 4 ]
test@test:~$ echo [ 3 \< 4 ]
[ 3 < 4 ]
test@test:~$ [ 3 < 4 ]
-bash: 4: No such file or directory
# '<' , '>' 문자는 shell 에서 사용되는 redirection 메타문자
# 마찬가지로 escape 하지 않으면 정상적으로 실행되지 않고 오류가 발생합니다
test@test:~$ [ 5 \< 4 ]
test@test:~$ [ 3 \< 4 ]
test@test:~$ echo $?
0
test@test:~$ [ 3 \< 2 ]
test@test:~$ echo $?
1
test@test:~$ test 3 \> 2
test@test:~$ test 1 \> 2
test@test:~$ echo $?
1
# '( )' ';' 문자도 shell 에서 사용하는 메타문자
$ find * ( -name "*.log" -or -name "*.bak" ) -exec rm -f {} ;
bash: syntax error near unexpected token '('
# 다음과 같이 모두 escape 해줘야 오류없이 정상적으로 실행이 됩니다.
$ find * \( -name "*.log" -or -name "*.bak" \) -exec rm -f {} \;
test@test:~$ AA="hello world"
test@test:~$ echo $AA
hello world
test@test:~$ func () {
> echo arg1 : "$1"
> echo arg2 : "$2"
> }
test@test:~$ func $AA
arg1 : hello
arg2 : world
test@test:~$ func "$AA"
arg1 : hello world
arg2 :
-n이나 - -bar이 grep 명령의 옵션으로 인식이 되어 정상적으로 명령이 실행되지 않는 경우
⇒ 이와 같은 경우 - -를 사용하여 "이 뒤로부터는 옵션이 아니다"라고 선언할 수 있다.
test@test:~$ grep -r "-n"
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
test@test:~$ grep -r -- "-n"
.profile:if [ -n "$BASH_VERSION" ]; then
.bashrc:if [ -n "$force_color_prompt" ]; then
.bashrc:alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo
error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
test@test:~$ grep -r -- "--bar"
test@test:~$ echo hello world | cat -
hello world
test@test:~$ cat hello.txt
1111
2222
3333
test@test:~$ echo hello world | cat - hello.txt
hello world
1111
2222
3333
test@test:~$ echo hello world | cat hello.txt -
1111
2222
3333
hello world
cd ~/tempdir
rm -rf *
cd ~/tempdir && rm -rf *
cd ~/tempdir || { echo >&2 "cd ~/tempdir failed"; exit 1 ;}
. . .
$AA, ${AA}, ${AA: -5}, ..
$(( 1 + 2 ))
$( echo "1.3 + 2.5" | bc )
: 명령 대체 기능을 수행하는데, 명령의 결과를 대체해서 사용한다.${name}
: name이라는 변수에 들어있는 값으로 치환한다. 변수명 다음에 다른 문자가 연이어 나올 경우 유용함
${name:=value}
: name이 null이면 value로 할당하여 저장하고, name에 값이 있으면 그 값을 사용한다. 변수에 기본값을 지정할 때 유용하다.
${#name}
: name의 문자열 길이를 반환한다.
${name:?value}
: 기존에 name 값이 있다면 기본값으로 하고, 값이 없으면 error을 내면서 value의 값을 보여준다.
set : 셸 변수를 출력하는 명령어
env : 환경 변수를 출력하는 명령어
export : 특정 변수의 범위를 환경 변수의 데이터 공간으로 전송하여 자식 프로세스에서도 특정 변수를 사용 가능하게 한다. 전역 변수의 개념
unset : 선언된 변수를 제거한다.
\f : 앞 문자열만큼 열을 밀어서 이동
\n : 새로운 줄로 바꾼다
\r : 앞 문자열의 앞부분부터 뒷문자열 만큼 대체하고 반환한다.
\t : 탭 만큼 띄운다.
*) 는 해당하지 않은 모든 경우를 처리한다.
$ cat case1.sh
#!/bin/bash
echo "################################################"
echo "1. whoami 2. date 3. pwd 4. ls -l "
read number
case $number in
1) whoami;;
2) date;;
3) pwd;;
4) ls -l;;
*) echo "번호를 입력하시오 (1 ~ 4)";;
esac
$ ./case1.sh
################################################
1. whoami 2. date 3. pwd 4. ls -l
1
user
$ ./case1.sh
################################################
1. whoami 2. date 3. pwd 4. ls -l
2
Sat Feb 20 13:59:43 KST 2021
#!/bin/bash
echo "OS ? "
select var in "CentOS7" "Ubuntu" "Windows"
do
echo "Your OS is $var"
break
done
$ ./select.sh
OS ?
1) CentOS7
2) Ubuntu
3) Windows
#? 1
Your OS is CentOS7
#!/bin/bash
var=1
while [ "$var" -le 5 ]
do
echo $var
# var=$[ $var + 1 ]
# var=$(expr $var + 1)
var=`expr $var + 1`
done
$ cat until.sh
#!/bin/bash
COUNTER=20
until [ $COUNTER -lt 10 ]
do
echo COUNTER is $COUNTER
COUNTER=`expr $COUNTER - 1`
done
$ ./until.sh
COUNTER is 20
COUNTER is 19
COUNTER is 18
COUNTER is 17
COUNTER is 16
COUNTER is 15
COUNTER is 14
COUNTER is 13
COUNTER is 12
COUNTER is 11
COUNTER is 10
$ cat pat.sh
#!/bin/bash
# var not exists
unset var1
echo ${var1:-string2}
# var exists
var1=string1
echo ${var1:-string2}
var1=/var/log/apt
# var/log/apt
echo ${var1#*/}
# apt
echo ${var1##*/}
var2=/var/log/apt/log/ifconfig.cfg
# /var/log/apt/
echo ${var2%log*}
# /var/
echo ${var2%%log*}
$ ./pat.sh
string2
string1
var/log/apt
apt
/var/log/apt/
/var/