일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- 중식
- 힐링
- 건대입구역
- GitHub
- 대구
- docker
- 정보처리기사
- 10km
- Grafana
- 러닝
- 맛집
- Podman
- Linux
- DSEC
- 소모임
- 유산소
- 한강
- 대전
- 오답노트
- Kubernetes
- Shell
- 뚝섬유원지
- 하체
- 2021
- 자전거
- 달리기
- 성수대교
- Python
- zabbix
- Run The Bridge
- Today
- Total
Run The Bridge
shell script master -9- (마지막) 본문
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
감사합니다.
'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 |