에https://www.tutorialspoint.com/unix/shell_scripting.htm

 

Shell Scripting Tutorial

Shell Scripting Tutorial - A shell script is a computer program designed to be run by the Unix/Linux shell which could be one of the following:

www.tutorialspoint.com

 

기본 구조

파일명: 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

+ Recent posts