Run The Bridge

shell script master -9- (마지막) 본문

Cloud/Linux

shell script master -9- (마지막)

anfrhrl5555 2022. 1. 27. 00:40
728x90

0. 파이프

mknod 명령으로 파이프를 만들 수 있다.

 mknod /tmp/mypipe p

---

다음 명령을 입력하면 파이프에 hello world가 저장되어 있을 것

echo hello world > /tmp/mypipe

파이프에는 읽기 끝과 쓰기 끝이 존재하며, 파이프의 쓰기쪽에 기록 된 데이터는 파이프의 읽기 쪽에서 읽을 수 있다.

프로세스(echo)가 파이프에 쓰기를 시도하는 경우, 반대쪽 프로세스에서 파이프에서 충분한 데이터를 읽을 때까지는 쓰기 동작이 완료되지 못하고 echo 명령은 블록(blocking)이 된다.

---

새로운 터미널을 열고 /tmp/mypipe에 어떤 값이 들어갔는지 확인한다.

 

파일종류는 p로 파이프를 나타낸다.

ls -l /tmp/mypipe
prw-r--r--. 1 root root 0 Feb  7 02:06 /tmp/mypipe
cat /tmp/mypipe
hello world

cat 명령을 입력하면 echo로 실행된 명령은 종료된다.

---

사용사례를 보자.

 

흔히들 '|'를 많이쓰며 파이프라고 칭하는데, 여기서 파이프의 이름은 'unnamed pipe'라고 한다.

cat hello.txt |  more

즉, 위의 명령들을 사용해서 workflow를 작성할 수 있다.


1. 프로세스 대체

ls -R images
images:
bakcup.sh  Balloon.jpg  Candy.jpg  glob.gif  settings_down.png  settings_up.png  shadingimage.tiff  smaller.tiff

ls -R images_mirror
images_mirror:
Balloon.jpg  glob.gif  settings_down.png  settings_up.png  shadingimage.tiff  smaller.tiff

images에는 Candy.jpg가 있다.

images_mirror에는 Candy.jpg가 없는것을 확인한다.

---

리눅스에는 comm이라는 명령어가 존재한다. 두 개의 비교 대상 디렉토리의 차이점을 확인할 떄 유용한 명령

comm -23 <(ls -R ./images | sort) <(ls -R ./images_mirror | sort)
bakcup.sh
Candy.jpg
./images:

comm은 1, 2, 3의 명령이 존재한다.

1: 두 개의 내용을 비교하되, 파일 1에 있는것은 출력하지 않는다.

2: 두 개의 내용을 비교하되, 파일 2에 있는것은 출력하지 않는다.

3: 두 개의 파일내용을 비교하되, 공통적으로 존재하는 파일은 출력하지 않는다.

  -1              suppress column 1 (lines unique to FILE1)
  -2              suppress column 2 (lines unique to FILE2)
  -3              suppress column 3 (lines that appear in both files)

그리고 ()를 통해 프로세스 대체 명령을 사용한다.

 

'<(명령어)'으로 사용하며 선행 결과를 선행 프로세스화해서 실행된다. 

---

또다른 사용방법

/root/shell_script/shell_cmd/images

while read file; do
>  (( i++))
> done < <(find . -type f -name "*.jpg")

read로 file을 읽어들이는데, 프로세스 대체를 사용해서 파일 타입이 *.jpg인 것을 읽고, 해당 결과를 file로 넘긴다.
(이 실행은 우선적으로 실행된다.)

 

그리고 echo $i를 찍어보면 jpg의 개수를 알 수 있다.

echo $i
2

2. 서브 쉘

서브쉘의 예시를 작성한다.

echo begin;(for i in {100..110}; do echo $i >> num100; sleep 1;done)&

---

다음의 명령을 실행 후 바로 tail 명령을 사용한다.

tail -f num100
tail -f num100
100
101
102
103
104
105
106
107
108
109
110

바로 이런것을 서브쉘이라고 부른다.


3. 함수

sum이라는 함수를 만들고, i 부터 k까지 더하는 스크립트를 작성한다.

 

그리고 total에 매개변수를 전달한다

sum () { declare -i sum; START=$1; END=$2; for i in `eval echo {$START..$END}`; do ((sum +=i)); done; echo $sum; }
total=$(sum 1 100); echo $total
5050

'sum()'안에는 아무 명령도 적지 않는다.

---

흔히 알고 있는 함수 표현으로 바꾸면 다음과 같이 표현할 수 있다. → 훨 쉽죠? ㅎㅎ

sum() {
	START=$1
	END=$2
	for i in `eval echo {$START..$END}`
	do
		((sum +=i))
	done
	echo $sum
}

total=$(sum 1 100)  # 함수 이름과 매개 변수 2개를 전달해준다. → 즉 매개 변수 $0 $1 $2로 볼 수 있다.
echo $total

4. 명령어(shift)

set 명령어를 통해 1, 2, 3, 4, 5를 매개변수화 한다.

set 1 2 3 4 5

---

while [ $# -gt 0 ];do echo $1; shift 1; done
1
2
3
4
5

shitft 1를 선언하면, 전달인자가 하나씩 이동하므로 1에서 2로 이동하게 된다.


5. source 와 bashrc

source 명령은 실제로 스크립트를 실행한 효과를 본다.

 

근데 '~/.bashrc' 와는 어떤 차이가 있을까?

source ~/.bashrc

---

source라는 명령어를 사용하면, bashrc에 등록된 환경변수가 쉘에 등록되어 다시 시작하더라도 소멸되지 않는다.

 

아래와 같은 표현도 source와 동일하다.

. ~/.bashrc

6.작업제어

sleep 명령을 사용한다.

sleep 1000

이 상태에서 우리가 CTRL+C를 누르게 되면, 리눅스 커널에서는 SIGNAL이라는것이 생성되어서

 

현재 sleep 프로세스에 의해 kill된다.

---

이번엔 sleep 프로세스를 백그라운드로 동작한다.

 

그러면 어떤 PID로 백그라운드에서 실행중인지 알 수 있다.

sleep 1000 &
[1] 89206
 ps
   PID TTY          TIME CMD
 88884 pts/0    00:00:00 bash
 89206 pts/0    00:00:00 sleep
 89548 pts/0    00:00:00 ps

---

그러면 백그라운드에서 동작중인 sleep을 포그라운드로 올려본다. → fg

fg 1
sleep 1000

다시 백그라운드로 보내기 위해선 CTRL+Z를 누른다.

 

CTRL+C처럼 마찬가지로 리눅스 커널에서 SIGNAL이 발생해 해당 프로세스로 전달되는 방식이다.


7. 디버깅

다음의 스크립트를 작성 후 실행한다.

#!/bin/bash

export PS4='+$LINENO:$FUNCNAME: '  # 해당 라인번호 출력

### Used for TRACE
trap '(read -p "[$LINENO] $BASH_COMMAND?")' DEBUG  # 라인단위로 실행

set -x  # 디버깅의 시작

function sub() {
  echo 'my subroutine()'
}

echo hello world1
echo hello world2
echo hello world3
sub 1 2
echo hello world4
echo hello world5
echo hello world6
echo hello world7
echo hello world9

set -x 라는 옵션을 주면 디버깅 할 수 있다.

 

나는 디버깅을 쓸 때 bash -x '파일명'을 더 많이쓴다.

bash -x debug.sh

---

trap을 사용해서 라인단위로 출력하는 것은 매우 유용해 보인다.


8. 명령어(cron)

crontab -e 옵션으로 실행한다.

crontab -e

crontab은 '분 시 일 월 요일'로 구성되어 있으며, *를 적으면 '매'라는 뜻을 가진다.

 

*/10은 10분마다 라는 뜻을 담고있다. → 1시간에 총 6회

* * * * * /home/user/Desktop/myscript

*/10 * * * * /home/user/Desktop/myscript

 

---

다음 스크립트는 10분마다가 아니고 현재 시간이 10분일 때 실행한다.

10 * * * * /home/user/Desktop/myscript

---

다음 스크립트는 12월 1일 1시 10분에 실행한다는 뜻을 가진다.

10 1 1 12 * /home/user/Desktop/myscript

---

매주 월요일 1시 10분에 실행한다.

10 1 * * Mon /home/user/Desktop/myscript

---

1, 4는 월요일하고 목요일에 실행한다는 뜻이다.

10 1 * * 1,4 /home/user/Desktop/myscript

0 = 일요일

1 = 월요일

2 = 화요일

3 = 수요일

4 = 목요일

5 = 금요일

6 = 토요일

---

요일의 반복은 '-' 하이픈을 사용하면 된다.

10 1 * * 1-5 /home/user/Desktop/myscript

---

설정한 crontab을 보고싶을 때 '-l' 옵션을 이용한다.

crontab -l
no crontab for root

---

여기까지가 내가 인프런에서 구입한 '리눅스 쉘 스크립트 마스터' 강의의 끝이다.

 

따라온 사람이 있다면 정말 감사하다.

 

여기서 멈추지말고, 쉘 스크립트를 빠르고 편하게 짜기 위해 다음의 두 블로그를 추천한다.


bash, 즉 커맨드라인에서 빠르게 글을 지우고 수정할 수 있는 단축키가 정리된 블로그이다.

https://shared.tistory.com/131

 

리눅스 터미널 단축키

터미널 단축키 모음 ※ 정확히 말하자면 bash 단축키지요 ctrl+u : 커서 왼쪽 문자들 지우기(지운다기 보다는 버퍼에 저장해 둡니다) ctrl+k : 커서 오른쪽 문자들 지우기 ctrl+b : 커서를 왼쪽으로 이동

shared.tistory.com


추가로 vi에서도 자유자재로 움직이기 위해, 나도 vi편집기를 사용할 떄 마다 챙겨보는 블로그이다.

https://wayhome25.github.io/etc/2017/03/27/vi/

 

vi 단축키 정리 · 초보몽키의 개발공부로그

vi 단축키 정리 27 Mar 2017 | vim 학습자료 vi 단축키 삽입 키 기능 i 커서 위치에 Insert I 줄 맨 앞에서 Insert a 커서 다음에 Insert A 줄 맨 뒤에서 Insert o 커서 아래로 한 줄 띄우고 Insert O 커서 위로 한 줄

wayhome25.github.io


https://gmlwjd9405.github.io/2019/05/14/vim-shortkey.html

 

[VIM] vim 유용한 단축키 정리 - Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io


감사합니다.

728x90

'Cloud > Linux' 카테고리의 다른 글

Ansible-playbook, 숫자 입력만으로 원하는 곳 실행하기  (0) 2022.02.16
shell-script로 계산기 만들기  (2) 2022.02.11
shell script master -8-  (0) 2022.01.27
shell script master -7-  (0) 2022.01.27
shell script master -6-  (0) 2022.01.27
Comments