에https://www.tutorialspoint.com/unix/shell_scripting.htm
기본 구조
파일명: test.sh
#!/bin/sh
echo "Hello, World"
- 확장자: .sh
- 첫 번째 행에 해당 쉘 명시
- #!bin/sh
- #!bin/bash
- 쉘 스크립트 파일을 실행시키려면 실행 권한을 줘야 함
$ chmod 755 test.sh
실행
$ ./test.sh
or
$ sh test.sh
or
$ bash test.sh
기본 문법
주석(comment)
#으로 시작
입력/출력
- 입력: read
- 출력: echo
#!/bin/sh
read NAME
echo "Hello, $NAME!"
결과
$ ./test.sh
dozob
Hello, dozob!
※ Tip
Bash에서는 -e 플래그로 특수 문자를 escape 할 수 있음
#!bin/bash
echon -e "Hello\n$NAME!" # 개행('\n')됨
Variables
- 변수 이름으로 영문자, 숫자, 언더바('_') 사용
- 변수에 값을 할당할 때 '='의 앞뒤에 공백이 없어야 함
- 문자열인 경우 쌍따옴표(")로 감싸야 함
- 변수를 사용할 때는 앞에 $를 붙임, 변수는 {}로 감쌀 수 있음
- readonly 키워드를 앞에 붙여 읽기 전용 변수를 정의할 수 있음
- 변수 삭제는 unset으로 가능하나 readonly 변수는 삭제 못함
#!/bin/sh
var1=1234
var2="text"
echo "var2=$var2"
readonly var3="initialized readonly variable"
var3="try to assign readonly variable"
unset var2
결과
$ ./test.sh
var2=text
./test.sh: 9: var3: is read only
Special Variables
변수 | 기능 |
$0 | 스크립트명 |
$1 ~ $9 | N번째 인수 |
$# | 스크립트에 전달된 인수 개수 |
$* | 모든 인수를 모아 하나로 처리 |
$@ | 모든 인수를 각각 처리 |
$? | 직전에 실행한 명령(command)의 종료 값 (성공: 0, 실패: 1) |
$$ | 쉘 스크립트의 프로세스 ID |
$! | 마지막으로 실행한 백그라운드 프로세스 ID |
Metacharacters (특수 문자)
* ? [ ] ' " \ $ ; & ( ) | ^ < > new-line space tab |
문자열 내에 쓰일 때는 '\'를 앞에 붙여야 함
Sequence | Quoting | Description |
1 | Single quote | All special characters between these quotes lose their special meaning. |
2 | Double quote | Most special characters between these quotes lose their special meaning with these exceptions - - $, `, \$, \', \", \\ |
3 | Backslash | Any character immediately following the backslash loses its special meaning. |
4 | Back quote | Anything in between back quotes would be treated as a command and would be executed. |
Example
#!/bin/bash
echo <-$1500.**>; (update?) [y|n]
# -bash: syntax error near unexpected token `;'
echo \<-\$1500.\*\*\>\; \(update\?\) \[y\|n\]
echo '<-$1500.**>; (update?) [y|n]'
echo 'It\'s Shell Programming
# It\s Shell Programming
echo 'It\'s Shell Programming'
# Syntax error: Unterminated quoted string
VAR=ZARA
echo "$VAR owes <-\$1500.**>; [ as of (`date +%m/%d`) ]"
# ZARA owes <-$1500.**>; [ as of (07/02) ]
변수 값의 치환
문법 | 설명 |
${var} | 변수 값으로 치환 |
${var:-word} | if var is null or unset, word is substitued for var. The value of var does not change. |
${var:=word} | if var is null or unset, var is set to the value of word. |
${var:+word} | if var is set, word is substituted for var. The value of var does not change. |
${var:?message} | If var is null or unset, message is printed to standard error. This checks that variables are set correctly. |
#/bin/sh
echo "1. \${var:-default value1}: \"${var:-default value1}\", var=${var}"
echo "2. \${var:=default value2}: \"${var:=default value2}\", var=${var}"
var="assigned value"
echo "var=\"assigned value\""
echo "3. \${var:+default value3}: \"${var:+default value3}\", var=${var}"
echo "4. \${var:?default value4}: \"${var:?default value4}\", var=${var}"
unset var
echo "unset var"
echo "5. \${var:+default value5}: \"${var:+default value5}\", var=${var}"
echo "6. \${var:?default value6}:"
echo " \"${var:?default value6}\", var=${var}"
결과
$ ./test.sh
1. ${var:-default value1}: "default value1", var=
2. ${var:=default value2}: "default value2", var=default value2
var="assigned value"
3. ${var:+default value3}: "default value3", var=assigned value
4. ${var:?default value4}: "assigned value", var=assigned value
unset var
5. ${var:+default value5}: "", var=
6. ${var:?default value6}:
./test.sh: line 15: var: default value6
Arrays
#!/bin/bash
# bash shell
ARRAY=(item item2 item3 item4)
ARRAY[0]="ITEM1"
ARRAY[2]="ITEM3"
echo "ARRAY[0]: ${ARRAY[0]}"
echo "ARRAY[2]: ${ARRAY[2]}"
echo "ARRAY[*]: ${ARRAY[*]}"
echo "ARRAY[@]: ${ARRAY[@]}"
결과
$ ./test.sh
ARRAY[0]: ITEM1
ARRAY[2]: ITEM3
ARRAY[*]: ITEM1 item2 ITEM3 item4
ARRAY[@]: ITEM1 item2 ITEM3 item4
Arithmetic Operators
Operator | Description | Example: a=10, b=20 |
+ | Addition | echo `expr $a + $b` → 30 |
- | Substraction | echo `expr $a - $b` → -10 |
\* (Multiplication) | Multiplies values on either side of the operator | echo `expr $a \* $b` → 200 |
/ (Division) | Divide left hand operand by right hand operand | echo `expr $b / $a` → 2 |
% (Modulus) | evide left hand operand by right hand operand and returns remainder | expr `expr $b % $a` → 0 |
= (Assignment) | Aissigns right operand in left operand | a=$b |
== (Equality) | Compares two numbers, if both are same then returns true. |
[ $a == $b ] → false |
!= (Not Equality) | Compares two numbers, if both are different then return true. |
[ $a != $b ] → true |
※ Tip
for example, [ $a == $b ] is correct
whereas, [$a==$b] is incorrect
Relational / Boolean / String Operators
Operator | Description | Example |
-eq | equal | [ $a -eq $b ] |
-ne | not equal | [ $a -ne $b ] |
-gt | greater than | [ $a -gt $b ] |
-lt | less than | [ $a -lt $b ] |
-ge | greater than or equal to | [ $a -ge $b ] |
-le | less than or equal to | [ $a -le $b ] |
Boolean Operators | ||
! | logical negation | [ ! false ] → true |
-o | logical OR | [ $a -lt 20 -o $b -gt 100 ] → true |
-a | logical AND | [ $a -lt 20 $b -gt 100 ] → false |
String Operators | ||
= | equal | [ $a = $b ] → not true. |
!= | not equal | [ $a != $b ] → true |
-z | Checks if the given string operand size is zero; if it is zero length, then is returns true. |
[ -z $a ] → not ture |
-n | Checks if the given string operand size is non-zero; if it is nonzero length, then it returns true. |
[ -n $a ] → not false |
str | Checks if str is not the empty string; if it is empty, then it returns false. |
[ $a ] → not false. |
File Test Operators
Assume a variable file holds an existing file name "test" the size of which is 100 bytes and has read, write and execute permission on -
Operator | Description: Checks if file ~ | Example |
-e file | file exists; is true even if file is a directory but exists. | [ -e $file ] → true |
-s file | file has size greater then 0 | [ -s $file ] → true |
-b file | block special file | [ -b $file ] → false |
-c file | character special file | [ -c $file ] → false |
-d file | directory | [ -d $file ] → not true |
-p file | named pipe | [ -p $file ] → false |
-f file | an ordinary file as opposed to a directory or special file | [ -f $file ] → true |
-t file | file descriptor is open and associated with a terminal | [ -t $file ] → false |
-g file | has its Set Group ID (SGID) bit set | [ -g $file ] → false |
-k file | has its Sticky bit set | [ -k $file ] → false |
-u file | has its Set User ID (SUID) bit set | [ -u $file ] → false |
-r file | readable | [ -r $file ] → true |
-w file | writable | [ -w $file ] → true |
-x file | executable | [ -x $file ] → true |
Decision Making
if ... else
- if ... fi
- if ... else ... fi
- if ... elif ... else ... fi
case ... esac
- case ... esac
case VARIABLE in CONDITION/VALUE) Command ;; esac
#!/bin/sh
DRINK="coffee"
case "$DRINK" in
"beer") echo "맥주"
;;
"juice") echo "주스"
;;
"coffee") echo "커피"
;;
esac
Loops
- while
- for
- until
- select
while command1 ; # this is loop1, the outer loop
do
Statement(s) to be executed if command1 is true
while command2 ; # this is loop2, the inner loop
do
Statement(s) to be executed if command2 is ture
done
Statements(s) to be executed if command1 is true
done
Example
#!/bin/sh
a=0
while [ "$a" -lt 10 ] # this is loop1
#until [ "$a" -ge 10 ]
do
b="$a"
while [ "$b" -ge 0 ] # this is loop2
#until [ "$b" -lt 0 ]
do
echo -n "$b " # -n option lets echo avoid printing a new line character
b=`expr $b - 1`
done
echo
a=`expr $a + 1`
done
Result
0
1 0
2 1 0
3 2 1 0
4 3 2 1 0
5 4 3 2 1 0
6 5 4 3 2 1 0
7 6 5 4 3 2 1 0
8 7 6 5 4 3 2 1 0
9 8 7 6 5 4 3 2 1 0
Example
#!/bin/sh
for var1 in 1 2 3
do
for var2 in 0 5
do
if [ $var1 -eq 2 -a $var2 -eq 0 ]
then
break 2
else
echo "$var1 $var2"
fi
done
done
Result
1 0
1 5
Example
#!/bin/sh
NUMS="1 2 3 4 5 6 7"
for NUM in $NUMS
do
Q=`expr $NUM % 2`
if [ $Q -eq 0 ]
then
echo "$NUM: Number is an even number!"
continue
fi
echo "$NUM: Found odd number"
done
bash
#!/bin/bash
# using array
NUMS=(1 2 3 4 5 6 7)
for NUM in ${NUMS[*]}
do
Q=`expr $NUM % 2`
if [ $Q -eq 0 ]
then
echo "$NUM: Number is an even number!"
continue
fi
echo "$NUM: Found odd number"
done
Result
1: Found odd number
2: Number is an even number!!
3: Found odd number
4: Number is an even number!!
5: Found odd number
6: Number is an even number!!
7: Found odd number
Substitution
Sequence | Escape | Description |
1 | \\ | backslash |
2 | \a | alert (BEL) |
3 | \b | backspace |
4 | \c | suppress trailing newline |
5 | \f | form feed |
6 | \n | new line |
7 | \r | carriage return |
8 | \t | horizontal tab |
9 | \v | vertical tab |
You can use the -E option to disable the interpretation of the backslash escapes (default).
You can use the -e option to enable the interpretation of the backslash escapes.
You can use the -n option to disable the insertion of a new line.
Command Substitution
Command substitution is the mechanism by which the shell performs a given set of commands
and then substitues their output in the place of the commands.
Syntax
`command`
When performing the command substitution make sure that you use the backquote, not the single quote character.
Example
#!/bin/sh
DATE=`date`
echo "Date is $DATE"
USERS=`who | wc -l`
echo "Logged in user are $USERS"
UP=`date ; uptime`
echo "Uptime is $UP"
Result
Date is Wed Aug 9 16:54:06 KST 2023
Logged in user are 0
Uptime is Wed Aug 9 16:54:06 KST 2023
16:54:06 up 10 days, 14:15, 0 users, load average: 0.03, 0.01, 0.00
'OS > Linux' 카테고리의 다른 글
Linux Shell - IO Redirections (0) | 2023.08.09 |
---|---|
LD_LIBRARY_PATH (0) | 2022.12.21 |
CUDA 11.7.1 on WSL2 (0) | 2022.11.13 |
Fastest way to check if a file exists (0) | 2022.11.10 |
Install libjpeg-turbo (0) | 2022.11.06 |