1. 목표
2.
3. 기초
3.1. Default Shell 찾기
3.2. Shell 종류
3.3.
3.4. Shell 변경하기
3.5. Command Line 단축키
3.6. Variables Type
3.6.1. Shell variables
3.6.2. Local Variables
3.6.3. Environment Variable
3.6.4. 기타
3.7. Variable setup 방법
4.
5. Shell Scripting
5.1. Hello world
5.2. Arguments
5.3. Defined Variables
5.3.1. List Variables
5.4. Environment variables
5.4.1.
5.4.2. export (변수 scope)
5.5. bash command 실행
5.6. Debugmode script 실행
5.7. 사용자 입력 read
5.7.1. command line 을 통한 입력
5.8. while-case
5.9. for 순환
5.9.1. Condition Test
5.10. if condition
6. Script example
6.1. Ping
6.2. 파일 내용 읽기
6.2.1.
1. 목표
Bash Shell Script를 사용할 일이 있어서 급하게 Review하고자 한다.
여기나오는 내용은 educative Shell for programer와 Mastering Linux Shell Scripting에 있는 내용을 정리하였다.
https://github.com/PacktPublishing/Mastering-Linux-Shell-Scripting-Second-Edition
2.
3. 기초
3.1. Default Shell 찾기
~$ ps $$
PID TTY STAT TIME COMMAND
10374 pts/0 Ss 0:00 -bash
$ echo $SHELL
/bin/bash
bash
3.2. Shell 종류
- Bash Shell : Bourne shell, 가장 기초 쉘
- Ksh shell : Korn shell, bash shell과 호환 됨
- Csh : C언어로 만들어진 쉘
3.3.
3.4. Shell 변경하기
$ chsh -s /bin/bash
bash
3.5. Command Line 단축키
단축키 | 행동 |
Ctrl + C | 현 실행 중인 Task를 종료한다 |
Ctrl + L | 화면을 clear 한다 |
Ctrl + w | 커서의 마지막 한문장을 삭제한다 $ aaa bbb ddd
에서 bbb 앞에서 단축키를 입력하면 aaa가 사라진다 $ bbb ddd
|
tab | 자동완성 |
Ctrl + R | 내가 앞서 사용했던 history에서 찾는 단어와 유사성이 있는 실행문을 찾아 준다 (reverse-i-search)`kaf': docker-compose -f docker-compose-kafka-triplet.yml down
|
Ctrl + U | 한라인을 모두 삭제 한다 |
3.6. Variables Type
3.6.1. Shell variables
쉘이 정상적인 작동을 하게끔 사전 정의된 Local Variable이다.
쉘이 시작하면서 로드하게 된다.
$shell_var
3.6.2. Local Variables
하나의 쉡 내부에서만 작동하는 Variable. 다른 쉘에 영향을 주지 않는다.
사용자가 해당 쉘에서만 순간적으로 사용하게 하기 위해 사용된다.
$ MY_VALUE=hello
$ echo $MY_VALUE
hello
bash
3.6.3. Environment Variable
모든 쉘에서 접근 가능한 varialbe이다.
Bash 에서는 export 를 사용해서 정의하게 된다. 대표적으로 PATH 가 있다.
$ cat .profile
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/.local/bin" ] ; then
PATH="$HOME/.local/bin:$PATH"
fi
bash
3.6.4. 기타
$USER |
echoUSER
theyoung
|
$HOSTNAME |
echoHOSTNAME
theyoung-MS-7D77
|
$$ |
echo$
10374
현 스크립트 ID |
$0 |
echo0
-bash
현 실행중인 스크립트의 이름 |
$1~9 |
스크립트 실행시 입력된 아규먼트
|
3.7. Variable setup 방법
$ VAR_NAME=HELLO
$ echo "my name is $VAR_NAME !"
my name is HELLO !
$ echo "my name is ${VAR_NAME} !"
my name is HELLO !
bash
주의 해야할 것은 Uppercase는 일반적으로 Environment Variable로 많이 사용한다
또는{} 를 이용해서 value를 확인할 수 있다.
Space가 필요하다면 " " 를 해줘야 한다
4.
5. Shell Scripting
5.1. Hello world
#!/bin/bash
echo "Hello World"
exit 0
bash
/script$ vi hello.sh
/script$ chmod +x hello.sh
/script$ ./hello.sh
Hello World
bash
- #!/bin/bash : 쉬뱅, '#' 심볼 이후에 스크립트가 시작됨을 system에게 알려줌
- echo : standard 아웃풋
- exit 0 : 종료, 0이외의 값은 오류를 뜻함
/script$ echo $?
0
bash
마지막 스크립트 실행의 결과가 0임을 나타냄
- command1 || command2 : command1이 실패할 경우 command 2가 실행됨. 그외 실행 안됨
#!/bin/bash
echo "Hello New World"
exit 0
bash
위와 같은 shell이 있을 경우
./hello.sh || ./hello2.sh
Hello World
bash
앞에 있는 쉘만 실행 한다.
만약에 앞쉘을 1로 바꾸면
~/script$ ./hello.sh || ./hello2.sh
Hello World
Hello New World
bash
command2가 실행 된것을 확인 할 수 있다.
5.2. Arguments
#!/bin/bash
echo "Hello New World $1, count $#, all the arguments $*"
exit 0
bash
/script$ ./hello2.sh ar1 ar2 ar3 ar4
Hello New World ar1, count 4, all the arguments ar1 ar2 ar3 ar4
bash
- $숫자 : 아규먼트 값
- $# : 아규먼트 카운트
- $* : 모든 아규먼트
5.3. Defined Variables
#!/bin/bash
name="superman"
job="hero"
echo "Hello New World $1, count $#, all the arguments $*"
echo "name ${name}, job ${job}"
exit 0
bash
~/script$ ./hello2.sh
Hello New World , count 0, all the arguments
name superman, job hero
bash
space를 중간에 넣지 말것!!
ex) name = "superman"
5.3.1. List Variables
#!/bin/bash
name="superman"
job="hero"
list=(1 2 3 4 5)
echo "Hello New World $1, count $#, all the arguments $*"
echo "name ${name}, job ${job}"
echo "${list[*]}"
unset list[0]
echo "${list[*]}"
exit 0
bash
~/script$ ./hello2.sh
Hello New World , count 0, all the arguments
name superman, job hero
1 2 3 4 5
2 3 4 5
bash
- unset은 리스트의 특정 index를 삭제함
5.4. Environment variables
printenv로 환경변수 값을 확인할 수 있음
~/script$ printenv
SHELL=/bin/bash
LANGUAGE=ko:en
[omitted]
SSH_TTY=/dev/pts/2
LC_NUMERIC=ko_KR.UTF-8
_=/usr/bin/printenv
OLDPWD=/home/theyoung
bash
5.4.1.
5.4.2. export (변수 scope)
각 스크립트간 로컬 variable은 공유되지 않음.
export활용해서 공유 가능함
단, 실행 스크립트내에서 다른 스크립트를 호출한 경우에 한함
참고로 hello2.sh에서 name정의 부분은 삭제 하였다.
#!/bin/bash
echo "Hello World"
name="spider man"
export name
./hello2.sh
bash
~/script$ ./hello.sh
Hello World
Hello New World , count 0, all the arguments
name spider man, job hero
1 2 3 4 5
2 3 4 5
bash
아주 혹시라도 hello2.sh에 name 정의 부분을 안 삭제 한다고 해도 원래 hello.sh의 name은 해당 프로세스 내에서 수정되지는 않는다.
5.5. bash command 실행
#!/bin/bash
cur_dir=`pwd`
echo $cur_dir
iam=$(whoami)
echo $iam
bash
스크립트 내에서 command를 실행하는 방법은 2가지가 있다
- ` 백틱
- $() : 중괄호
/script$ ./command.sh
/script
theyoung
bash
5.6. Debugmode script 실행
/script$ bash -x ./command.sh
++ pwd
+ cur_dir=/home/theyoung/script
+ echo /home/theyoung/script
/home/theyoung/script
++ whoami
+ iam=theyoung
+ echo theyoung
theyoung
bash
5.7. 사용자 입력 read
#!/bin/bash
echo -n "Your name : "
read
echo "My name is $REPLY"
bash
~/script$ ./read.sh
Your name : steven
My name is steven
bash
$REPLY 를 통해서 입력 결과를 표시함
5.7.1. command line 을 통한 입력
/script$ read -p "Your name is " name
Your name is steven
/script$ echo $name
steven
bash
read 명령어를 통해서 name 변수에 이름이 입력 된것을 확인 가능함
#!/bin/bash
echo -n "Your name : "
read
echo "My name is $REPLY"
read -p "Your ages : " age
echo "My ages is $age"
bash
/script$ ./read.sh
Your name : steven
My name is steven
Your ages : 43
My ages is 43
bash
read -n1 을 아규먼트로 넣을 경우 1회의 키만 받는 다는 의미임
read -sn1 에 s를 넣을 경우 입력값이 보이지 않게 됨
5.8. while-case
#!/bin/bash
while [ -n "$1" ]
do
case "$1" in
-f) echo "--first option selected";;
-s) echo "--second option selected";;
-t) echo "--third option selected";;
*) echo "no option selected";;
esac
shift
done
bash
while [ 비교문 ]
do
done
비교문에서 "-n"은 not empty string이라는 의미이다
case 비교대상 in
*)
esac
in 아래에 비교 대상을 직접적으로 )로 표시 하면 된다.
shift는 arguments를 하나씩 좌측으로 shipt해서 pop하게 된다.
5.9. for 순환
#!/bin/bash
num=1
for param in $@
do
echo "#$num: $param"
num=$(( $num + 1 ))
done
bash
for variable in range
do
done
으로 이루어짐 여기서 $@는 모든 array라는 의미로 foreach 형태로 하나씩 space단위로 값을 빼어냄
num=은 variable을 재정의 하는 형태이고
$()를 통해서 command를 실행 시킴
그 내부에 ()가 하나더 있는데 'Numeric calculations'이라고 함
./for.sh a b c d e f g
#1: a
#2: b
#3: c
#4: d
#5: e
#6: f
#7: g
bash
5.9.1. Condition Test
~/script$ test $PWD == $HOME
/script$ echo $?
1
bash
test를 통해서 현재 있는 위치와 HOME의 path가 같은지를 확인했다.
0이외의 결과는 error임으로 위는 error를 뜻한다
#!/bin/bash
echo "Your basename is $(basename $0)"
test -z $1 || echo "Hello $1"
exit 0
bash
test -z 1은1이 empty string일때 true가 된다.
만약 아무런 파라메터도 없으면 hello는 나오지 않는다.
~/script$ ./test.sh
Your basename is test.sh
~/script$ ./test.sh a
Your basename is test.sh
Hello a
bash
test는 다음과 같이 활용 될 수 있다.
- test expression : expression이 참이냐 false냐
- test ! expression : 결과 반대
- test expression -a expression : and
- test expression -o expression : or
- test -n string : string에 값이 있는가?
- test -z string : string에 값이 없는가?
- test string = string : 두 string은 같은가?
- test 3 -gt 0 : 3은 0보다 큰가?
- test 3 -lt 0 : 3은 0보다 작은가?
- test 3 -eq 0 : 3은 0과 같은가?
- test 3 -nq 0 : 3은 0과 같지 않은가
String을 shell script내에서 test condition으로 사용할 경우 반듯이 ""를 해야한다
if [ "mother" = "Mother" ]
~/script$ test $USER = root
~/script$ echo $?
1
~/script$ test ! $USER = root
~/script$ echo $?
0
~/script$ test -n iam
~/script$ echo $?
0
~/script$ test -z iam
~/script$ echo $?
1
~/script$ test 3 -gt 0
~/script$ echo $?
0
~/script$ test 3 -lt 0
~/script$ echo $?
1
~/script$ test 3 -eq 0
~/script$ echo $?
1
bash
- test -d 디렉토리 : 디렉토리 인가?
- test -x 실행파일 : 실행가능한가?
- test -f 파일 : 파일이 맞는가?
- test -r 파일 : 읽을 수 있는가?
$ test -d script/
~$ echo $?
0
~$ test -x script/
~$ echo $?
0
~$ test -f script/
~$ echo $?
1
bash
복합 컨디션
- test a = b || test b = b : a와b의 string이 같거나 b와 b의 스트링이 같으면 true이다
~/script$ test a = b || test b = c
~/script$ echo $?
1
~/script$ test a = b || test b = b
~/script$ echo $?
0
bash
5.10. if condition
#!/bin/bash
if [ $# -lt 1 ];then
echo "no param"
fi
echo "all params : $*"
exit 0
bash
입력된 파라메터가 1보다 작은지 확인하는 코드
if 컨디션 ; then
if
으로 구성된다
~/script$ ./if.sh a b c
all params : a b c
~/script$ ./if.sh
no param
all params :
bash
else를 추가할 수 있다
if 컨디션 ; then
else
if
#!/bin/bash
if [ $# -lt 1 ];then
echo "no param"
else
echo "all params : $*"
fi
exit 0
bash
~/script$ ./if.sh
no param
~/script$ ./if.sh abc
all params : abc
bash
복합 컨디션은 아래와 같다
#!/bin/bash
if [ $# -lt 1 ] || [ -n "abc" ];then
echo "no param"
else
echo "all params : $*"
fi
exit 0
bash
위의 경우는 무조건 no param이 나오게 된다
-n "abc"는 항상 참이기 때문이다.
~/script$ vi if.sh
~/script$ ./if.sh a b c d
no param
bash
6. Script example
6.1. Ping
#!/bin/bash
read -p "server address : " serveraddr
ping -c 3 $serveraddr 2>1 > /dev/null || echo "Server Dead"
bash
ping에서 -c는 retry의 횟수이다. 2>1은 standard 아웃풋을 모두 /dev/null로 보냄으로써 화면에 표시하지 않겠다는 의미이다.
마지막으로 ping의 결과가 0이 아닌 결과로 error로 판단되면 Server Dead가 표시된다.
~/script$ ./ping.sh
server address : 1.2.3.4
Server Dead
bash
6.2. 파일 내용 읽기
#!/bin/bash
while read line
do
echo $line
done
bash
/script$ ./readfile.sh < ping.sh
#!/bin/bash
read -p "server address : " serveraddr
ping -c 3 $serveraddr 2>1 > /dev/null || echo "Server Dead"
bash
6.2.1.
'Software활용' 카테고리의 다른 글
openssl 명령어 모음 (0) | 2023.09.01 |
---|---|
Window 10 pro 다중 원격 접속하기 (Hex edit) (0) | 2023.08.09 |
mac에서 java version 변경하기 (0) | 2022.08.22 |
linux에서 json Pretty Print 하기 (jq 명령어) (0) | 2022.08.11 |
Slack backup 파일 Discord로 이동하기 (Slackord 사용법) (0) | 2022.08.01 |