/ born2beroot / docs / monitoring.md
monitoring.md
  1  # monitoring.sh
  2  
  3  At server startup, the script will display some information (lilsted below) on all terminals every 10 minutes (take a look at `wall`). The banner is optional. No error must be visible.
  4  
  5  Your script must always be able to display the following information:
  6  
  7  - The architecture of your operating system and its kernel version.
  8  - The number of physical processors.
  9  - The number of vritual processors.
 10  - The current available RAM on your server and its utilization rate as a percentage.
 11  - The current available memory on your server and its utilization rate as a percentage.
 12  - The current utilization rate of your processors as a percentage.
 13  - The date and time of the last reboot.
 14  - Whether LVM is active or not.
 15  - The number of active connections.
 16  - The number of users using the server.
 17  - The IPv4 address of your server and its MAC (Media Access Control) address.
 18  - The nuber of commands executed with the `sudo` program.
 19  
 20  i) During the defense, you will be asked to explain how this script works. You will also bave to interrupt it without modifying it. Take a look at cron.
 21  
 22  서버가 작동하면, 스크립트는 아래의 정보를 매 10 분마다 터미널에 출력해야 한다(`wall` 옵션을 참고할 것). 배너를 넣는 것은 선택 사항이고, 스크립트에서 오류가 발생해선 안된다.
 23  
 24  여러분의 스크립트는 아래의 정보를 언제나 출력해야 한다:
 25  
 26  - 여러분이 사용하는 운영 체제와 커널 버전
 27  - 물리 프로세서의 개수
 28  - 가상 프로세서의 개수
 29  - 여러분의 서버의 RAM 사용량을 퍼센티지로 표시
 30  - 여러분의 서버의 메모리 사용량을 퍼센티지로 표시
 31  - 현재 프로세서의 사용량을 퍼센티지로 표시
 32  - 마지막 재부팅 시각
 33  - LVM 활성화 여부
 34  - 현재 활성화된 네트워크 연결의 개수
 35  - 서버를 사용하고 있는 유저의 수
 36  - 여러분의 서버의 IPv4 주소의 MAC 주소
 37  - `sudo`와 함께 실행된 명령어의 개수
 38  
 39  i) 여러분이 디펜스를 진행하는 동안, 스크립트가 어떻게 작동하는지 설명할 수 있어야 한다. 또한 스크립트를 수정하지 않고, 진행되는 스크립트를 중단할 수도 있어야 한다. cron을 살펴볼 것.
 40  
 41  ---
 42  
 43  먼저, 스크립트에 표시해야 할 사항들을 하나씩 구현해보자.
 44  
 45  ## 운영체제와 커널 버전 출력
 46  
 47  커널 버전을 출력하는 명령어는 많지만(`hostnamectl`, `cat /proc/version` ...) 서브젝트의 사진과 가장 유사하게 출력하기 위해선 `uname -a`를 사용해야 한다. `-a` 플래그는 `uname`의 모든 옵션(커널 이름, 호스트 이름, 커널 버전, 아키텍처, 프로세서 ...)을 한꺼번에 출력한다.
 48  
 49  ```sh
 50  echo "#Architecture: $(uname -a)"
 51  ```
 52  
 53  참고: [https://www.cyberciti.biz/faq/command-to-show-linux-version/](https://www.cyberciti.biz/faq/command-to-show-linux-version/)
 54  
 55  ## 물리 프로세서의 개수
 56  
 57  물리 프로세서 개수를 세기 위해 `lscpu` 명령어를 사용하였다. `Socket(s)`의 항목을 `grep`과 `awk`로 가져온다.
 58  
 59  ```sh
 60  echo "#CPU physical : $(lscpu | grep 'Socket' | awk '{ print $2 }')"
 61  ```
 62  
 63  - CPU 소켓은 컴퓨터의 마더 보드를 CPU와 연결하는 장치이다. 따라서 소켓의 개수는 곧 물리 CPU의 개수라고 볼 수 있을 것이라고 생각하였다.
 64  - `nproc` 명령어는 CPU 코어의 개수를 세는 것이기에, 물리 프로세서의 개수와 차이가 날 것이다.
 65  
 66  <img src="../img/socketcore.png" alt="socketcore" width="600" />
 67  이미지 출처: https://www.intel.com/content/www/us/en/developer/articles/technical/performance-counter-monitor.html
 68  
 69  참고: [https://www.cyberciti.biz/faq/check-how-many-cpus-are-there-in-linux-system/](https://www.cyberciti.biz/faq/check-how-many-cpus-are-there-in-linux-system/)
 70  
 71  ## 가상 프로세서의 개수
 72  
 73  `/proc/cpuinfo`의 항목을 출력하여 가상 프로세서(vCPU)의 개수를 출력한다. `/proc/cpuinfo`는 현재 컴퓨터의(즉 가상 머신의) CPU 정보를 표시한다. 0 부터 카운팅되기 때문에, `processor : 0`은 하나의 가상 프로세서가 있다는 의미이다.
 74  
 75  ```sh
 76  echo "vCPU : $(cat /proc/cpuinfo | grep 'processor' | wc -l)"
 77  ```
 78  
 79  참고: [https://webhostinggeeks.com/howto/how-to-display-the-number-of-processors-vcpu-on-linux-vps/](https://webhostinggeeks.com/howto/how-to-display-the-number-of-processors-vcpu-on-linux-vps/)
 80  
 81  ## 서버의 RAM 사용량 표시
 82  
 83  ```sh
 84  RAM_RATE=$(free -m | grep Total | awk '{ printf("%d/%dMB (%.2f%%)\n", $3, $2, $3/$2 * 100.0) }')
 85  echo "#Memory Usage: $RAM_RATE"
 86  ```
 87  
 88  - `-m` 플래그는 MB 단위로 사용량을 표시한다.
 89  - 퍼센티지 기호를 `printf`로 출력하기 위해선 두 번 적어야 한다.
 90  
 91  질문:
 92  
 93  1. `free`로 출력하는 메모리 사용량 중에서, `buff/cache`를 포함하지 않는 이유는?
 94     - 일반적으로 Memory utilization은 특정한 순간에 사용 가능한 메모리의 사용량을 나타낸다고 한다. `buff/cache`가 메모리의 일정 부분을 점유하고 있지만, 서브젝트가 요구하는 것은 직접 사용할 수 있는(available) 용량을 의미한다고 생각하였기에, `buff/cache`를 포함시키지 않았다.
 95  2. RAM과 메모리의 차이는?
 96     - 간단하게 RAM은 컴퓨터가 종료되면 데이터가 사라지는 휘발성을 가지고, 그 외의 Memory는 하드디스크와 같이 장기적으로 데이터를 저장할 수 있다.
 97  
 98  참고:  
 99  [https://stackoverflow.com/questions/10585978/how-to-get-the-percentage-of-memory-free-with-a-linux-command](https://stackoverflow.com/questions/10585978/how-to-get-the-percentage-of-memory-free-with-a-linux-command)  
100  [https://devconnected.com/how-to-check-ram-on-linux/](https://devconnected.com/how-to-check-ram-on-linux/)  
101  [https://beforb.tistory.com/5](https://beforb.tistory.com/5)  
102  [https://www.easytechjunkie.com/what-is-the-difference-between-ram-and-memory.htm](https://www.easytechjunkie.com/what-is-the-difference-between-ram-and-memory.htm)
103  
104  ## 서버의 메모리 사용량 표시
105  
106  서브젝트에서 말하는 메모리는 RAM이 아닌 메모리, 즉 하드디스크를 의미한다고 생각하여, `df` 명령어를 사용하였다.
107  
108  ```sh
109  DISK_USED=$(df -m /home /root | awk '{ sum += $3 } END { printf("%d", sum) }')
110  DISK_TOTAL=$(df -m /home /root | awk '{ sum += $2 } END { printf("%d", sum / 1024) }')
111  DISK_RATE=$(awk -v USED="$DISK_USED" -v TOTAL="$DISK_TOTAL" 'BEGIN { printf("(%d%%)\n", USED/TOTAL / 1024 * 100) }')
112  echo "#Disk Usage: $DISK_USED/${DISK_TOTAL}Gb $DISK_RATE"
113  ```
114  
115  - root와 home 디렉터리의 디스크 용량을 합쳐서 계산하였다.
116  - `-m` 플래그는 MB 단위로 사용량을 표시한다.
117  
118  참고:  
119  [https://maktooob.tistory.com/19](https://maktooob.tistory.com/19)  
120  [https://www.unix.com/filesystems-disks-and-memory/40966-sum-df-command.html](https://www.unix.com/filesystems-disks-and-memory/40966-sum-df-command.html)  
121  [https://www.hostinger.com/tutorials/vps/how-to-check-and-manage-disk-space-via-terminal](https://www.hostinger.com/tutorials/vps/how-to-check-and-manage-disk-space-via-terminal)
122  
123  ## 프로세서의 사용량 표시
124  
125  서브젝트 사진에는 'CPU Load'로 적혀있는데, CPU 사용률(CPU Usage)과 CPU 부하(CPU Load)는 완전히 같은 의미는 아니라고 한다.
126  
127  - CPU Load는 CPU에 실행중이거나 대기중인 작업의 개수(즉 프로세스의 개수)를 평균으로 나타낸 값이다.
128    - CPU Load는 CPU가 얼마나 잘 사용되고 있는지 확인하는 지표로 사용할 수 있다.
129    - CPU Load는 일반적으로 0~1의 값을 갖는다(다만 이는 단일 코어의 경우이고, 코어의 개수에 따라 값은 배가 된다). 만약 1의 값을 넘어가는 경우, CPU에서 처리하지 못하고 대기하는 프로세스가 있다는 의미이다.
130    - CPU Load 수치는 낮을 수록 좋다.
131    - Linux에서 `uptime` 명령어로 CPU Load를 확인할 수 있다.
132  - CPU Usage는 시스템 사용률(CPU System)과 사용자 사용률(CPU User) 등을 합친 값이다.
133    - 시스템 사용률은 운영체제가 사용한 CPU 사용률을 의미하며, 사용자 사용률은 응용프로그램이 사용하는 CPU 사용률을 의미한다.
134    - 시스템 사용률이 높다면 시스템 사양을 높여야 한다.
135    - 사용자 사용률이 높다면 시스템 업그레이드 또는 어플리케이션의 분배에 대해 고민해야 한다.
136  
137  따라서 'CPU Load'의 값을 서브젝트에 나온 대로 utilization의 의미로 해석하여, CPU Usage를 출력하였다.
138  
139  `cat /proc/stat`로 별 다른 패키지의 설치 없이 확인할 수도 있지만, `/proc/stat`은 시스템이 부팅된 이후, [CPU의 사용률을 누적하여 나타낸 것](https://www.idnt.net/en-US/kb/941772)이기에, 실제 사용률과 다를 수 있다고 생각하였다. 무엇보다, 리눅스는 현재 CPU의 사용률을 "한 번에" 나타낼 수 있는 시스템 요소를 가지지 않는다고 한다!
140  
141  나는 `top` 명령어를 두 번 실행하여, 첫 번째 `top`의 결과를 제외한 값을 출력하였다(첫 번째 값은 CPU 변화량을 비교할 샘플이 없기 때문에, 대신 마지막 부팅 이후의 평균 CPU Load값을 나타낸다고 한다([https://bugzilla.redhat.com/show_bug.cgi?id=174619](https://bugzilla.redhat.com/show_bug.cgi?id=174619))).
142  
143  ```sh
144  CPU_USAGE=$(top -d 0.5 -b -n2 | grep -Po "[0-9.]*(?=( id,))" | tail -1 | awk '{ printf("%.1f%%\n", 100-$1) }')
145  echo "#CPU load: $CPU_USAGE"
146  ```
147  
148  - `-d` : 실행 반복 딜레이를 설정한다. 여기서는 첫 번째 `top`과 두 번째 `top` 실행을 0.5초 간격으로 설정함.
149  - `-b` : Batch 모드로 실행. 사실 여기서는 큰 차이는 없지만, 인터랙티브 모드로 실행하였을 땐 모든 프로세스가 표시되지 않는 반면, Batch 모드는 모두 표시한다. 일반적으로 Batch 모드는 해당 결과를 데이터로 사용할 때 자주 쓰이는 듯하다. [https://unix.stackexchange.com/questions/138484/what-does-batch-mode-mean-for-the-top-command](https://unix.stackexchange.com/questions/138484/what-does-batch-mode-mean-for-the-top-command)
150  - `-n` : `top`을 실행할 횟수 설정. 첫 번째 `top` 결과는 잘못된 값을 가지기에 두 번 실행하여 마지막 값을 취한다(`tail -1`).
151  - `-Po` : `grep` 명령어에서 사용되는 플래그. `-P`는 `Perl` 언어 방식의 정규 표현식을 사용한다는 의미이고, `-o`는 현재 정규 표현식에 해당하는 부분만 출력한다는 의미이다.
152  - `[0-9.]*(?=( id,))` : `grep` 명령어와 함께 사용하는 정규 표현식.
153    - `[0-9.]*` : 주어진 문자열에서 한 자리 숫자와 점(`.`) 문자를 모두 찾는다(`... 0.0 us, 100.0 id ...`문자열에서 `0.0 100.0`를 매칭한다).
154    - `(?=( id,))` : 정규 표현식의 Lookaround 기능 중 하나인 Positive Lookahead. `?=` 이후의 조건이 만족되는 이전의 매칭을 결과에 포함한다(따라서 매칭된 패턴 중 `100.0 id,` 문자열에서 `100.0`만 출력된다).
155  
156  * 만약 CPU 사용률을 테스트하고 싶다면, `stress`를 사용하자:
157  
158  ```sh
159  # stress 패키지 설치
160  apt install stress
161  
162  # worker를 1로 설정, output이 안나오게 quiet, background 실행
163  stress -c 1 -q &
164  
165  # stress 프로세스 모두 중단
166  pkill stress
167  ```
168  
169  참고:  
170  [https://www.baeldung.com/linux/get-cpu-usage](https://www.baeldung.com/linux/get-cpu-usage)  
171  [https://brunch.co.kr/@leedongins/76](https://brunch.co.kr/@leedongins/76)  
172  [https://sabarada.tistory.com/146](https://sabarada.tistory.com/146)  
173  [https://unix.stackexchange.com/questions/69185/getting-cpu-usage-same-every-time](https://unix.stackexchange.com/questions/69185/getting-cpu-usage-same-every-time)
174  [https://stackoverflow.com/questions/9229333/how-to-get-overall-cpu-usage-e-g-57-on-linux](https://stackoverflow.com/questions/9229333/how-to-get-overall-cpu-usage-e-g-57-on-linux)  
175  [https://scripter.co/grep-po/](https://scripter.co/grep-po/)  
176  [https://elvanov.com/2388](https://elvanov.com/2388)
177  
178  ## 마지막 재부팅 시각 표시
179  
180  Linux의 `who` 명령어는 호스트에 로그인한 사용자의 정보를 출력한다. `-b` 플래그는 마지막 부팅 시간을 출력한다.
181  
182  ```sh
183  echo "#Last boot: $(who -b | awk '{ printf("%s %s\n", $3, $4) }')"
184  ```
185  
186  참고: [https://hbase.tistory.com/256](https://hbase.tistory.com/256)
187  
188  ## LVM 활성화 여부
189  
190  `/etc/fstab` 파일을 확인하여 LVM 사용 여부를 확인한다. `fstab` 파일은 리눅스에서 사용하는 파일시스템 정보를 저장하고 있으며, 리눅스 부팅 시 마운트 정보를 저장하고 있다. 만약 `root`의 파일시스템이 `/dev/mapper/<VM name>`이라면, LVM을 사용하고 있다는 의미가 된다. `dev/mapper`의 의미는, 리눅스 커널의 물리적 공간을 가상 공간으로 한 단계 추상화하여 매핑하였다는 뜻이다([https://en.wikipedia.org/wiki/Device_mapper](https://en.wikipedia.org/wiki/Device_mapper)).
191  
192  ```sh
193  if [[ $(cat /etc/fstab | grep 'root') =~ "/dev/mapper" ]]; then
194  	echo "#LVM use: yes"
195  else
196  	echo "#LVM use: no"
197  fi
198  ```
199  
200  - 정규식을 이용하여 `/dev/mappper`가 대상에 포함되어 있는지 확인한다(포함된다면 1, 아니면 0 반환).
201  - 스크립트의 대괄호의 개수는 작동에는 차이가 없지만, 괄호가 하나인 경우 별도의 프로세스가 실행(`/usr/bin/[`), 반면 괄호가 두 개인 경우 bash 자체적으로 내장된 기능을 사용하여 별도의 프로세스를 실행하지 않는다. ([http://bahndal.egloos.com/531206](http://bahndal.egloos.com/531206))
202  
203  참고:  
204  [https://meongj-devlog.tistory.com/134](https://meongj-devlog.tistory.com/134)  
205  [https://askubuntu.com/questions/202613/how-do-i-check-whether-i-am-using-lvm](https://askubuntu.com/questions/202613/how-do-i-check-whether-i-am-using-lvm)
206  
207  ## 활성화된 네트워크 연결 개수 표시
208  
209  `ss` 명령어는 리눅스 시스템의 소켓 상태를 조회할 수 있는 유틸리티이다. `ss`는 옵션 없이 사용하면 listening socket(Clinet측 소켓의 연결 요청이 있을 때까지 기다리는 Server의 소켓. Client 소켓에서 연결 요청을 하고 Server 소켓이 허락을 해야 통신을 할 수 있도록 연결된다.)을 제외하고 현재 연결되어 있는 모든 소켓(TCP/UDP/Unix)을 표시한다. TCP 소켓을 표시하기 위해선 `-t` 옵션을 주면 된다.
210  
211  - 소켓(Socket)이란? : 프로그램이 네트워크에서 데이터를 통신할 수 있도록 연결해주는 통신 인터페이스. 소켓은 인터넷과 프로세스 사이에 놓여 그 둘을 연결하는 역할을 한다.
212  - TCP(Transmission Control Protocol) : 서버와 클라이언트 간에 데이터를 신뢰성 있게 전달하기 위해 만들어진 프로토콜. 서버와 클라이언트가 1대 1로 연결되며, 연결형 서비스를 지원하는 프로토콜로 인터넷 환경에서 기본으로 사용한다. IP가 데이터의 배달을 처리한다면 TCP는 패킷을 추적하고 관리한다.
213  - UDP(User Datagram Protocol) : 연결 상태를 유지하기보단 주어진 목적지로 데이터를 전달만 하는 비연결지향(connectionless) 프로토콜. 커뮤니케이션이 일어나기 전까지 연결이 이루어지지 않는다(즉 커뮤니케이션의 순간에만 연결이 되어있다). - 'fire-and-forgot' 프로토콜.
214  
215  <img src="../img/socket.png" alt="socket" width="600" />
216  이미지 출처: https://ghfkdgml.tistory.com/14
217  
218  연결된 소켓은 `State` 필드가 `ESTAB`으로 표시된다. 따라서 `ESTAB`이 표시된 행의 개수를 세어 출력하였다.
219  
220  ```sh
221  TCP_CONN=$(ss -t | grep 'ESTAB' | wc -l)
222  echo "#Connections TCP : $TCP_CONN ESTABLISHED"
223  ```
224  
225  참고:  
226  [https://www.lesstif.com/lpt/linux-socket-ss-socket-statistics-91947283.html](https://www.lesstif.com/lpt/linux-socket-ss-socket-statistics-91947283.html)  
227  [https://medium.com/@su_bak/term-socket%EC%9D%B4%EB%9E%80-7ca7963617ff](https://medium.com/@su_bak/term-socket%EC%9D%B4%EB%9E%80-7ca7963617ff)  
228  [https://codinghero.tistory.com/98](https://codinghero.tistory.com/98)  
229  [https://simhyejin.github.io/2016/07/04/connectionoriented-connectionless/](https://simhyejin.github.io/2016/07/04/connectionoriented-connectionless/)  
230  [https://www.spiceworks.com/tech/networking/articles/tcp-vs-udp/](https://www.spiceworks.com/tech/networking/articles/tcp-vs-udp/)
231  
232  ## 현재 서버를 사용하고 있는 유저의 수 표시
233  
234  `who` 명령어로 현재 접속한 사용자의 정보의 개수를 세어 표시하자.
235  
236  ```sh
237  echo "#User log: $(who | wc -l)"
238  ```
239  
240  ## 서버의 IPv4 주소와 MAC 주소 표시
241  
242  Linux 서버의 IP 주소는 `hostname` 명령어를 통해 확인할 수 있다. IP 주소를 나타내는 옵션으로는 `-i`와 `-I`가 있는데, 실제 서버의 IP 주소를 확인하기 위해선 `-I` 옵션을 사용해야 한다.
243  
244  왜냐하면 `i` 옵션이 보여주는 IP 주소는 루프백(loopback) 주소이기 때문이다. 루프백 주소는 호스트 자기 자신과 통신하기 위한 주소이기 때문에, 실제로 외부에서 접근하는 IP 주소와는 다르다. 네트워크가 연결되지 않아도 루프백 주소에 접근할 수 있다. 우리가 익숙하게 들은 localhost가 바로 루프백 주소이다.
245  
246  `-I` 옵션은 루프백 주소와 IPv6 주소를 제외하고, 호스트가 실제로 네트워크에서 여겨지는 주소를 반환한다.
247  
248  MAC 주소는 `/sys/class/net/enp0s3/address`에서 확인할 수 있다.
249  
250  - MAC 주소란? : 네트워크 상에서 서로를 구분하기 위해 장치(Device)마다 할당된 물리적 주소를 의미한다. 하드웨어 주소, 물리적 주소, 이더넷(Ethernet) 주소 등으로 불리기도 한다. IP 주소는 네트워크 주소로, 통신 중 변동 가능성이 존재한다. 따라서 안전한 통신을 위해서는 변하지 않는 기계의 고유한 주소 번호가 있어야 하는데, 맥 주소가 이러한 역할을 담당한다. 따라서 두 장치의 통신에는 데이터의 목적지인 IP 주소 뿐만 아니라 맥 주소가 함께 지정되어야 한다.
251  - `enp0s3` : 이더넷 장치에 할당된 이름(`en`이 이더넷을 의미한다).
252  
253  ```sh
254  echo "#Network: IP $(hostname -I)($(cat /sys/class/net/enp0s3/address))"
255  ```
256  
257  참고:  
258  [https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-net](https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-net)  
259  [https://www.howtouselinux.com/post/linux-command-get-mac-address-in-linux](https://www.howtouselinux.com/post/linux-command-get-mac-address-in-linux)  
260  [https://stackoverflow.com/questions/60615270/hostname-i-vs-hostname-i-in-linux](https://stackoverflow.com/questions/60615270/hostname-i-vs-hostname-i-in-linux)  
261  [https://askubuntu.com/questions/754213/what-is-difference-between-localhost-address-127-0-0-1-and-127-0-1-1](https://askubuntu.com/questions/754213/what-is-difference-between-localhost-address-127-0-0-1-and-127-0-1-1)  
262  [https://jhnyang.tistory.com/404](https://jhnyang.tistory.com/404)
263  
264  ## 실행된 sudo 명령어의 개수 표시
265  
266  `journalctl` 명령어를 사용하여 실행된 sudo 명령어들을 구하였다. `journalctl`은 `systemd`의 서비스 로그를 검색하고 확인할 수 있는 유틸리티이다. 리눅스용 시스템/서비스 매니저인 `systemd` 프로세스는 로그 데이터를 journal이라는 바이너리 형식으로 저장한다.
267  
268  ```sh
269  echo "#Sudo : $(jorunalctl _COMM=sudo | grep 'COMMAND' | wc -l) cmd"
270  ```
271  
272  참고:  
273  [https://www.lesstif.com/system-admin/linux-journalctl-82215080.html](https://www.lesstif.com/system-admin/linux-journalctl-82215080.html)
274  [https://unix.stackexchange.com/questions/167935/details-about-sudo-commands-executed-by-all-user](https://unix.stackexchange.com/questions/167935/details-about-sudo-commands-executed-by-all-user)
275  
276  # CRON 설정
277  
278  이제 마지막으로 주기적으로 10분마다 스크립트가 실행되면 터미널에 결과가 출력되는 과정을 완료하자.
279  
280  `crontab`은 cron 작업을 설정하는 파일이다. cron은 UNIX 운영체제에서 어떤 작업을 특정 시간에 실행시키기 위한 [데몬(daemon)](https://haruhiism.tistory.com/9)이다. cron 프로세스는 `/etc/crontab` 파일에 설정된 내용을 읽고 작업을 수행한다.
281  
282  우선, `monitoring.sh`를 `chmod +x`를 이용하여 실행 가능하도록 설정한다.
283  
284  그리고 `crontab -e`를 입력하여 `crontab`에 아래처럼 쓴다.
285  
286  ```sh
287  # crontab
288  
289  */10 * * * * /root/monitoring.sh | wall
290  ```
291  
292  - 매 10분마다 스크립트 실행.
293  - `wall` : 터미널에 접속된 모든 사용자의 터미널로 메세지를 보내는 명령어.
294  
295  `crontab`을 확인하고 싶다면 `contab- l`을 입력한다.
296  `crontab`을 중지하고 싶다면 `crontab -r`을 입력하면 된다.
297  
298  참고:  
299  [https://jootc.com/p/201811172241](https://jootc.com/p/201811172241)  
300  [https://jdm.kr/blog/2](https://jdm.kr/blog/2)
301  
302  맨데토리는 여기서 끝!