Shell scripts & Cron 김건우 하정호 홍영규
1 Shell script What the shell?
컴퓨터 시스템의 구조 Kernel 어제 배웠죠? Shell... User... 사용자의 명령을 커널에 전달하는 역할
Shell script? 쉘이 실행할 수 있는 코드 Python script = Python이 실행할 수 있는 코드 컴파일 없이 line-by-line으로 해석 지금까지 단순한 한 줄 짜리 명령어만 사용했다면, 이제는 좀더 복잡한 명령을 쉘에서 수행해 보자!
Shell script 101 #!/bin/bash 쉘 스크립트의 첫줄에 꼭 넣어줄 것 SHEBANG: 이 파일을 실행할 때는 이 인터프리터를 쓰세요" 실행할 때 인터프리터를 지정해 주지 않아도 올바르게 실행 가능 #!/usr/bin/env python 마찬가지로 Python script를 이렇게 시작하면, python test.py 대신./test.py로 실행 가능
보고 따라해 봅시다 :)
보고 따라해 봅시다 :)
보고 따라해 봅시다 :) 유저(u)에게 실행(x - execute) 권한을 추가(+)
보고 따라해 봅시다 :)
Commands echo [string] [string]을 출력 ex. echo Hello, world! pwd 현재 경로를 출력 ex. pwd => /home/gunwoo
Commands cat [filename] filename의 내용을 출력 file [filename] filename의 filetype을 출력
file 명령어 직접 써 보기
Commands tee [option] [filename] 입력을 받아 file에 쓰기 ex. tee test.txt ex. ls > tee test.txt test.txt에 이미 내용이 있다면?
어제 배웠지만 중요해서 한 번 더 함 Commands grep [option] [string (regex)] [filename] filename에서 string(정규표현식)과 일치하는 라인을 찾음 filename이 오지 않으면 stdin으로부터 입력을 받음 -i: 대소문자 구분하지 않음 -w: 앞뒤에 알파벳이나 숫자가 붙으면 제외
어제 배웠지만 중요해서 한 번 더 함 Pipeline & Redirect (pipeline) 앞 명령의 output을 뒤 명령의 input으로 넣을 수 있음 > (redirect) ex. command > [filename] 앞 명령의 output을 파일로 저장 >> (append) 앞 명령의 output을 뒤의 파일에 이어붙임 해당 파일이 존재하지 않을 경우 redirect와 동일하게 동작
커맨드 결과 예상해보기 ls / grep b ls / tee test.txt ls / grep r grep o > test2.txt ls / grep -w r grep o > test3.txt cat test.txt grep o ls *.txt ls test[3-7].txt
2 Variables Variables in shell scripts
Variables Local Variables [varname] printenv를 하면 모든 환경변수를 볼 수 있다! 하나의 쉘프로그램에서만 사용사능한 변수 present within the current instance of the shell. It is not available to programs that are started by the shell. Environment Variables (~Global Variable) [VARNAME] 모든 쉘프로그램에서 사용 가능한 변수 available to any child process of the shell. 특정한 환경변수의 내용만 알고 싶다면 ehco $[filename] printenv grep [var]
Variable Declaration varname=value 쉘에서는 모든 변수나 인자를 문자열로 취급합니다. = 양쪽 좌우에 공백 용납 안함 variable names are case sensitive! variable type 를 지정안함 -> int, char, 구분 안함 변수내용을 사용하려면 $varname 를 쓰자! string 중간에 변수를 쓰려면 ${varname}
Special Variables $0: 현재 쉘스크립트의 파일명 (~ sys.argv) $1 ~ $n: 쉘에 부여된 argument의 값 (sys.argv[i]) $?: 직전 명령의 성공여부. 성공적이었을 경우 0을 반환. 실패의 경우 에러코드(1 ~ 255)를 반환.
More Special Variables $$: 쉘 자신의 PID (Process ID) $!: 쉘이 마지막에 실행한 background process PID $*: argument 전체의 리스트 $@: argument 전체의 리스트, 구분자가 IFS의 영향을 받지 않는다 $#: 쉘에 부여된 argument의 개수
$* vs. $@ $@는 인자를 하나 하나 받아와 로 구분한다. IFS에 영향을 받지 않고 스페이스바를 구분자로 사용한다. 1 2 3 4 로 저장됨 $*는 구분자가 IFS의 영향을 받아 변수를 저장할 때 원래 인자를 입력 받은 형태와 다르게 저장될 수 있다. IFS : Internal Field Separator
Try it yourself!
read read varname 을 사용하면 사용자의 입력을 변수로 받을 수 있다. read var 에 부가적으로 read -s var 을 하면 패스워드 칠 때처럼 타이핑하는게 화면에 보이지 않는다
3 Operators Operators in shell scripts
Integer Operators `expr $a $b` 작은 따옴표가( ) 가 아닌 tab 위의 역따옴표(`)! 띄어쓰기 O $(($a $b)) 띄어쓰기 X 자리에 +, -, *, /, % 대입 단, expr을 사용할 경우 곱하기 연산에서 * 혹은 \* 을 써야함.
Real Number Operatoration
awk 데이터를 깔끔하게 처리하기 위한 프로그래밍 툴 C 형태의 문법을 갖는 필드 단위 패턴 처리 언어 명령어 형식: awk [option] [-F] [ {script} ] 기본적으로 탭 또는 공백을 통해 구별 된 각 단어들을 하나의 변수로 처리하지만, 이를 무시하고 내가 원하는 특정 문자(:, ;, 등)으로 처리하기 위해서 -F 사용. awk를 잘 다룰 줄 알면 데이터 처리 능력이 쑥쑥 올라간다!
Relational Operators Syntax In Python [ $A -gt $B ] A>B [ $A -lt $B ] A<B [ $A -ge $B ] A >= B [ $A -le $B ] A <= B [ $A -eq $B ] A == B [ $A -ne $B ] A!= B 띄어쓰기를 주의하자!
String Operators Syntax In Python String1 = String2 String1 == String2 String1!= String2 String1!= String2 -n String String is not None -z String String is None 띄어쓰기를 주의하자!
Boolean Operators Operator In Python -a and -o or && and* or*
Boolean Operators: && and 왼쪽 clause 계산 결과로 인해 오른쪽 값을 계산할 필요가 없다면 오른쪽 clause 를 무시한다! &&: 왼쪽 clause가 거짓일 때 오른쪽 clause 무시 : 왼쪽 clause 가 참일 때 오른쭉 clause 무시
Try it yourself!
4 Flow Controls Flow controls in shell scripts: if, for, while, until, case
Flow Control: if if [condition] then commands exit elif [condition] then commands exit else commands fi
Try it yourself! 사용자가 두 숫자를 입력하고, 두 숫자의 크기에 따라 A>B면 A win! A<B면 B win! A=B면 Draw! 그 외에는 error 로 표시되도록 쉘스크립트를 만들어보자
Try it yourself! Execution Example:
Try it yourself! Script Example:
Flow Control: for for i in var1 var2 var3 do commands done for ((i=0;i<100;i++)) do commands done for i in {1..10} do commands done for i in {1..100..10} do commands done for i in *: 현재 디렉토리 안의 파일들을 하나씩 가리킨다. $i를 통해 하나씩 이용가능하다.
Flow Control: while & until while: condition이 참이라면 do 와 done 사이 반복 until: condition이 거짓이라면 do 와 done 사이 반복 while [condition] do commands done until [condition] do commands done : 와 1은 참을 나타낸다! break 와 continue 사용가능
Flow Control: case case $var in pattern1) commands;; pattern2) commands;; pattern3) commands;; esac pattern에 *을 사용하면 나머지 경우를 포함한다! break 사용가능
Flow Control: examples
Try it yourself! 추천예제 by 김두현 선배님 1부터 100까지의 숫자가 input되고 그 실행한 결과가 각각 redirection과 pipe를 이용하여 각각 다른 이름의 파일로 저장하도록 한 뒤 스크립트 맨 마지막에 그 결과파일을 파싱하여 내가 원하는 하나의 결과파일로 만들어보자 input숫자 실행방법: input숫자를 그 제곱으로 output 결과파일 만드는 법: output에 49 패턴이 있는것만 모아보자
Try it yourself! 추천예제 by 김두현 선배님
Try it yourself! 추천예제 by 김두현 선배님
5 Functions Functions in shell scripts
Function Declaration funcname() { commands return //omittable } funcname
Function Declaration
6 Cron
Cron 이란? Unix 기반 OS에서 미리 작업을 백그라운드에서 수행하도록 예약할 수 있는 Daemon! 작업? 쉘에서 할 수 있는 모든 것! (ex. 주기적으로 메일 자동으로 다운 받기) 예약? 특정 시간 or 주기적으로 ~ Cron은 시간을 뜻하는 그리스어인 chronos 에서 기원 Daemon : 사용자에 의해 직접 제어되지 않고 백그라운드에서 작업되는 프로세스
Cron 사용법 Cron 설치하기 apt-get install cron Cron 시작,종료,재시작하기 시작 : service cron start or /etc/init.d/cron start 종료 : service cron stop or /etc/init.d/cron stop 재시작 : service cron restart or /etc/init.d/cron restart Cron 실행 확인하기 ps aux grep cron
Crontab Crontab Cron은 Crontab (Cron Table) 으로 예약된 작업들을 관리한다 /var/spool/cron /etc/cron.d /etc/crontab 세 군데에 저장되어있음! (역할이 조금씩 다르다) Cron은 시작될 때 각 crontab 파일들을 읽고 sleep 상태로 들어감. 매 분마다 변경사항을 확인한다. /var/spool/cron 개별 사용자를 위한 crontab /etc/cron.d 관리자가 직접 지정한 시스템 관련 작업들을 위한 crontab /etc/crontab 주기적인 패키지 설치를 위한 crontab
Crontab 명령어 crontab -e 예약 작업 작성 및 수정 crontab -r 예약 작업 삭제 crontab -l 예약된 작업 리스트 crontab [filename] [filename]으로 crontab 변경 (crontab 파일 형태를 가지고 있어야 함) crontab -u [username] -l 예약 작업 작성 및 수정
Crontab 스케쥴 등록하기 crontab -e 예약 작업 작성 및 수정, /var/spool/cron/crontabs에 저장됨 vi etc/crontab, vi etc/cron.d 시스템 관련 작업들 직접 등록 /etc/cron.daily, /etc/cron.hourly, /etc/cron.monthly,/etc/cron.weekly 직접 sh 파일을 등록시켜 놓으면 정해진 시간에 수행됨 수행 스케쥴은 이미 /etc/crontab에 저장되어 있음
Crontab 예시 /etc/crontab
Crontab 형식 [MM] [HH] [DD] [mm] [d] [username] [command] MM : 분 (0~59) HH : 시 (0~23) DD : 일 (1~31) mm : 시 (1~12) d : 요일 (0~7) (0, 7은 일요일을 뜻함) 필드에 * 가 들어가면 처음부터 끝까지! (즉, 매분, 매시, 매일, 매달 ) 숫자 범위 8-10, 1-15 가능 리스트 1,2,3 가능 Step Value 0-10/2 는 0,2,4,6,8,10 과 같은 의미 ex) 매 2분마다? */2
Crontab 형식 예시 */1 * * * * user1 sh /home/user1/cron.sh 매 1분마다 /home/user1/cron.sh 실행 (cron 은 절대경로 사용!) 15,45 * * * * user1 sh /home/user1/cron.sh 매시 15, 45분 마다 /home/user1/cron.sh 실행
Cron 환경변수 SHELL cron 이 돌아가는 shell (Default : /bin/sh) PATH cron 프로그램 경로 (Default: /usr/bin:/bin) MAILTO cron 실행 결과를 받아볼 메일 주소 (Default: 실행 유저 메일, 으로 두면 메일이 오지 않는다) HOME cron에 쓰일 홈 디렉토리 ($HOME Default : /etc/passwd의 값) LONGNAME crontab의 소유주 crontab 에서 변수명=값 으로 설정 가능!
Cron 키워드 @yearly, @annually 매년 1월 1일 자정에 실행 @monthly 매달 1일 자정에 실행 @weekly 매주 일요일 자정에 실행 @daily 매일 자정에 실행 @hourly 매시 정각에 실행 @reboot 부팅시 실행
실습
실습
Cron 권한 설정 /etc/cron.allow cron 허용 user 목록 /etc/cron.deny cron 금지 user 목록 둘 다 비어있으면 root 만 사용 가능! 이름이 둘 다 들어 있으면 사용 가능! (allow가 우선)
Anacron crond 는 매 1분마다 crontab들의 변경사항을 확인하며 예약된 작업을 수행한다. 만약! 11시에 예약된 작업이 10시55분 ~ 11시 5분 사이에 있던 서버 보수 작업으로 인해서 작업이 이루어지지 않았다면? -> 수행이 당연히 안된다! Anacron 은 이와 같이 수행을 놓친 작업이 있다면 작업이 가능한 시점에서 놓쳐버린 작업을 수행해주는 daemon
Anacron anacron 은 cron이 cron.daily 등의 정기적 실행 폴더에 있는 shell script 를 execute 하는걸 막는다. (duplicate 실행을 막기 위해) 개인이 crontab으로 설정한 사항들은 다 유지된다. anacron config는 /etc/anacrontab 에 저장된다.
Thanks! Any questions? gunwoo@sparcs.org orangejuice@sparcs.org pablo@sparcs.org