파일 포맷
- 파일 첫머리의 #!은 shebang 으로 부르는 것으로 스크립트를 실행하기 위한 인터프리터(여기서는 bash) 이름을 시스템에게 알려준다.
#!/bin/bash
echo "Hello World"
실행 시
- 스크립트 실행 시에 아래와 같이 경로를 포함해야 한다.
- 경로를 포함하지 않으면 (예를 들어 $ hello_world) 시스템은 환경변수 PATH에 규정된 디렉토리 목록에 있는 실행프로그램을 검색하게 된다.
$ ./hello_world
※ 스크립트 저장 장소
~/bin 디렉토리에는 개인적인 용도로 사용하려는 스크립트를 주로 저장하도록 한다.
(이를 위해서는 먼저 .bashrc에 ~/bin 디렉토리를 PATH 변수에 자동으로 추가하게끔 해야 한다)
($ export PATH=~/bin:"$PATH" 명령어로 추가하도록 하자)
시스템 관리자용 스크립트는 /usr/local/sbin 디렉토리에 저장한다.
※ 상수와 변수
쉘 스크립트는 상수와 변수를 구분하지 않는다. 다만, 일반적으로 상수는 대문자로, 변수는 소문자로 기입한다.
변수
- 타입은 무관하다.
- 하지만, 다른 프로그래밍 언어와 달리 쉘은 변수에 할당되는 값을 모두 문자열로 인식한다.
VAR=value
ex)
MY_MESSAGE="Hello World"
MY_SHORT_MESSAGE=hi
MY_NUMBER=1
MY_PI=3.142
MY_OTHER_PI="3.142"
MY_MIXED=123abc
함수
- 함수는 return 명령어 등 최소한 하나의 명령어를 포함해야 한다.
- 아래의 두가지 형식이 가능하다.
- 방식은 $(name) 이다
function name {
commands
return
}
name() {
commands
return
}
※ 지역 변수, 전역 변수
- 쉘 함수 안의 지역 변수는 전역 변수에 영향을 받지 않는다.
중간 결과
- (예시) html 파일을 생성하는 쉘 스크립트
코드)
#!/bin/bash
# Program to output a system information page
TITLE="System Information Report For $HOSTNAME"
CURRENT_TIME=$(date +"%x %r %Z")
TIME_STAMP="Generated $CURRENT_TIME, by $USER"
report_uptime() {
cat <<- _EOF_
<H2> System Uptime </H2>
<PRE> $(uptime) </PRE>
_EOF_
return
}
report_disk_space() {
cat <<- _EOF_
<H2> Dist Space Utilization </H2>
<PRE> $(df -h) </PRE>
_EOF_
return
}
report_home_space() {
if [[ $(id -u) -eq 0 ]]; then # 아래에 나올 조건문을 활용한 것으로, 슈퍼유저(uid 0) 인 경우와 아닌 경우를 구분한다.
cat <<- _EOF_
<H2> Home Space Utilization </H2>
<PRE> $(du -sh /home/*) </PRE>
_EOF_
else
cat <<- _EOF_
<H2> Home Space Utilization </H2>
<PRE> $(du -sh $HOME) </PRE>
_EOF_
fi
return
}
}
cat << _EOF_
<HTML>
<HEAD>
<TITLE> $TITLE </TITLE>
</HEAD>
<BODY>
<H1> $TITLE </H1>
<P> $TIME_STAMP <\P>
$(report_uptime)
$(report_disk_space)
$(report_home_space)
</BODY>
</HTML>
_EOF_
결과)
<HTML>
<HEAD>
<TITLE> System Information Report For donghoon-System-Product-Name </TITLE>
</HEAD>
<BODY>
<H1> System Information Report For donghoon-System-Product-Name </H1>
<P> Generated 2022년 01월 14일 오후 03시 34분 19초 KST, by donghoon <\P>
<H2> System Uptime </H2>
<PRE> 15:34:19 up 4:35, 1 user, load average: 0.26, 0.23, 0.10 </PRE>
<H2> Dist Space Utilization </H2>
<PRE> Filesystem Size Used Avail Use% Mounted on
udev 7.8G 0 7.8G 0% /dev
tmpfs 1.6G 2.1M 1.6G 1% /run
/dev/sdc2 234G 9.8G 212G 5% /
tmpfs 7.8G 48M 7.8G 1% /dev/shm
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
tmpfs 7.8G 0 7.8G 0% /sys/fs/cgroup
/dev/loop1 44M 44M 0 100% /snap/snapd/14295
/dev/loop2 2.3M 2.3M 0 100% /snap/gnome-system-monitor/148
/dev/loop3 56M 56M 0 100% /snap/core18/2253
/dev/loop5 640K 640K 0 100% /snap/gnome-logs/106
/dev/loop6 219M 219M 0 100% /snap/gnome-3-34-1804/77
/dev/loop7 62M 62M 0 100% /snap/core20/1270
/dev/loop8 66M 66M 0 100% /snap/gtk-common-themes/1519
/dev/loop0 384K 384K 0 100% /snap/gnome-characters/550
/dev/loop9 2.5M 2.5M 0 100% /snap/gnome-calculator/748
/dev/loop11 2.7M 2.7M 0 100% /snap/gnome-system-monitor/174
/dev/sdc1 511M 6.6M 505M 2% /boot/efi
/dev/loop10 256M 256M 0 100% /snap/gnome-3-34-1804/36
/dev/loop12 30M 30M 0 100% /snap/snapd/8542
/dev/loop13 768K 768K 0 100% /snap/gnome-characters/741
/dev/loop14 248M 248M 0 100% /snap/gnome-3-38-2004/87
/dev/loop15 1.0M 1.0M 0 100% /snap/gnome-logs/100
/dev/loop16 2.5M 2.5M 0 100% /snap/gnome-calculator/884
/dev/loop17 63M 63M 0 100% /snap/gtk-common-themes/1506
/dev/loop18 128K 128K 0 100% /snap/bare/5
tmpfs 1.6G 28K 1.6G 1% /run/user/121
tmpfs 1.6G 52K 1.6G 1% /run/user/1000
/dev/sdd1 932G 887G 45G 96% /media/donghoon/Samsung_T3
/dev/loop19 56M 56M 0 100% /snap/core18/2284 </PRE>
<H2> Home Space Utilization </H2>
<PRE> 681M /home/donghoon </PRE>
</BODY>
</HTML>
※ 참고
df -h 명령으로 디스크 사용 공간을 확인한다.
du -sh 명령으로 사용자 공간을 확인한다.
조건문
- '[' 와 'expression' 사이는 한칸 띄워야 한다. ']' 도 마찬가지.
if [ expression; ] then
commands
elif [ expression; ] then
commands
else
commands
fi
파일 표현식
문자열 표현식
정수 표현식
정수 표현식 + 정규 표현식 사용 예시)
- [[ ]]는 현대식 테스트 방법으로 자세한건 참조 링크의 p389 ~ 390을 참고하도록 한다.
- 정규 표현식과 매칭은 [[ expression =~ regex ]] 이다. ( == 가 아님에 주의)
#!/bin/bash
# test-integer: evaluate the value of an integer.
INT=st
if [ -z "$INT" ]; then
echo "INT is empty." >&2
exit 1
fi
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
if [ $INT -eq 0 ]; then
echo "INT is zero."
else
if [ $INT -lt 0 ]; then
echo "INT is negative."
else
echo "INT is positive."
fi
if [ $((INT % 2)) -eq 0 ]; then
echo "INT is even."
else
echo "INT is odd."
fi
fi
else
echo "INT is not an interger." >&2
exit1
fi
※ 명령어는 종료 될때 종료 상태(exit status) 값을 생성한다.
※ 생소한 명령어 모음
명령어 | 사용 예시 | 설명 |
$! | echo $! | 백그라운드에서 가장 마지막에 실행된 프로세스 명령어의 PID 값 출력 |
$? | echo $? | 가장 마지막에 종료된 프로세스(명령어)의 종료 상태 (정상 0, 이외에는 조건에 따라 다른 return) 출력 |
$$ | echo $$ | 사용하고 있는 Shell의 PID값을 출력한다. 현재 bash 쉘의 프로세스 ID |
제어 연산자
- command1 && command2 : 두개 명령어가 모두 실행되면, command1이 성공했다는 것을 의미한다.
- command1 || command2 : 두개 명령어가 모두 실행되면, command1이 실패했다는 것을 의미한다.
mkdir temp && cd temp # temp 디렉토리가 생성되면(성공), temp 디렉토리로 작업 디렉토리를 이동한다.
[ -d temp ] || mkdir temp # temp 디렉토리가 존재하지 않으면(실패), temp 디렉토리를 만든다.
사용자 입 출력
- read 명령어로 사용자 입력을 받는다.
- 예시) 사용자의 비번을 입력 받아 출력하는 프로그램. 시간 제한 10초를 두었다.
#!/bin/bash
if read -t 10 -sp "Enter secret passphase > " secret_pass; then
echo -e "\nsecret passphase = $secret_pass"
else
echo -e "\nInput timed out" >&2
exit 1
fi
입력 필드 구분
- IFS(입력 필드 구분자)를 두어 ' '(스테이스), '\t'(탭), '\n'(개행문자) 외에도 설정할 수 있다.
- 파이썬으로 치면 .split()의 역할을 한다.
- 예시) 사용자 이름을 입력 받아 정보를 출력
#!/bin/bash
FILE=/etc/passwd
read -p "Enter a username > " user_name
file_info=$(grep "^$user_name:" $FILE)
if [ -n "$file_info" ]; then
IFS=":" read user pw uid gid name home shell <<< "$file_info"
echo "User = $user"
echo "UID = $uid"
echo "GID = $gid"
echo "Full Name = $name"
echo "Home Dir. = $home"
echo "Shell = $shell"
else
echo "No such user '$user_name'" >&2
exit 1
fi
출처 : https://wiki.lib.sun.ac.za/images/c/ca/TLCL-13.07.pdf
'운영체제 > 리눅스(Linux)' 카테고리의 다른 글
tee 명령어 (0) | 2022.09.06 |
---|---|
리눅스 소소한 질문 모음 (0) | 2022.01.11 |
Makefile 정리 (0) | 2021.10.25 |