
1. 개요 — 목적을 분명히 하자
- 목적: 점검 스크립트(운영/모니터링)는 가능한 한 환경에 영향을 받지 않고 안정적으로 동작해야 한다.
→ 즉, 포팅성(portability), 예측 가능한 출력(locale/charset), 오류 감지·종료 정책, 경량/빠른 처리를 우선 고려한다.

script 개발 순서:
comments - information display - conditional testing - loops - Arithmetic - String manipulation - variable manipulation and testing - Argument and option handling
(Logic - Flow Design)
ex) user 추가
1. Do you want to add a user?
a.If Yes:
1) Enter the user's name
2) Choice a shell for the User
3) Determine the user's home directory
4) Determinine the group to which the user belongs.
b.If No, go the step 3.
2. Do you want to add another user?
a. If, Yes, go to the step 1.a.
b. If No, go to the Step 3.
3. Exit.
2. Shebang(#!)과 어떤 쉘을 쓸지 결정하는 이유
- 왜 #!/bin/sh로 시작하라고 배웠나?
#!/bin/sh는 가장 기본(표준)인 sh 규격에서 동작하는 것을 약속하겠다는 의미. 시스템마다 sh가 무엇을 가리키는지는 다를 수 있고(dash 또는 bash의 POSIX 모드 등), 따라서 sh를 쓰면 최소한의(포팅 가능한) 문법만 사용해야 한다. - 언제 #!/usr/bin/env bash나 #!/bin/bash를 쓸까?
bash 고유 기능(배열, [[ ]], 확장된 문자열 연산 등)을 명시적으로 쓸 때는 bash를 표기한다. 포팅성을 낮추더라도 bash 기능을 많이 쓴다면 #!/usr/bin/env bash를 권장(환경 PATH에서 bash를 찾음). - 권장 규칙 (실무):
- 점검 스크립트 → 가능한 한 sh 호환 문법으로 작성. (#!/bin/sh)
- bash 전용 기능을 쓰면 #!/usr/bin/env bash로 명시.
- 스크립트 초반에 set -euo pipefail 스타일의 안전 모드를 고려(아래 참조).
3. 파일 확장자 vs 파일 시그니처(=magic number)
- 확장자(.sh, .txt 등)는 주로 사용자/OS 도구(특히 Windows) 편의를 위한 표식일 뿐이며, **리눅스/유닉스는 파일 내용(헤더/매직바이트) 또는 실행 권한(executable bit)**으로 파일을 판단한다. 즉 확장자에 의존하지 말고, 내용/퍼미션으로 판단하라.
- 실무 팁: 업로드 검증(예: 웹 서비스에서 확장자 위조 방지) 시 *파일 시그니처(매직넘버)*를 체크하라(예: PNG 89 50 4E 47 ..., ELF 7f 45 4c 46 등).

4. Shell 프로그래밍 기초
표준 파일 디스크립터 (Standard File Descriptors)
| 이름 | 용도 | 번호 | 설명 |
| stdin | 표준 입력 | 0 | 키보드나 입력 파일 |
| stdout | 표준 출력 | 1 | 명령의 일반 출력 |
| stderr | 표준 에러 출력 | 2 | 에러 메시지 출력 |
| user-defined | 사용자 정의 입출력 | 3~19 | 특별한 파일/소켓 핸들 등 |
💡 예:
ls -l >file.txt
→ 표준출력(1)을 file.txt로 리다이렉션
ls notfound 2>error.txt
→ 에러출력(2)을 error.txt로 리다이렉션
명령 종결 상태(Exit Status)
| 종결 상태 (Exit Status) | UNIX/Linux 시스템에서는 프로그램이 종료될 때 숫자값을 반환(return) 함 | |
| 성공(Success) | 0을 반환 | 예: 명령이 정상적으로 실행됨 |
| 실패(Failure) | 0 이외의 숫자를 반환 | 예: 파일 없음, 권한 없음 등 |
Shell 자동 변수 정리(Special Parameters)

| 변수 | 의미 | 설명 | 예시 |
| $? | 이전 명령의 종료 상태 (Exit Status) | 마지막으로 실행된 명령이 성공했는지(0) 실패했는지(0 이외)를 나타냄 | ls /notfound; echo $? → 2 |
| $$ | 현재 Shell의 프로세스 ID (PID) | 실행 중인 Shell 자체의 PID | echo $$ → 12345 |
| $! | 마지막 백그라운드 프로세스의 PID | &로 실행한 마지막 백그라운드 작업의 PID | sleep 10 & echo $! → 6789 |
| $- | 현재 Shell 옵션 플래그 | Shell이 실행될 때 지정된 옵션(set 명령 포함)을 표시 | echo $- → himBH 등 |
| $# | 위치 매개변수의 개수 | 스크립트에 전달된 인자의 수 | ./test.sh one two → $# = 2 |
| $* | 모든 인자(하나의 문자열로) | 모든 매개변수를 하나의 문자열로 처리함 | " $* " → "one two" |
| $@ | 모든 인자(각각 분리된 문자열로) | 각 인자를 개별적으로 처리함 | " $@" → "one" "two" |
| $0 | 실행된 스크립트 이름 | 현재 실행 중인 쉘 스크립트의 이름 | echo $0 → ./test.sh |
| $1, $2, ... | 위치 매개변수 | 스크립트에 전달된 개별 인자 | ./test.sh a b → $1=a, $2=b |
💡 $* vs $@의 핵심 차이
| 표현 | 의미 | 차이점 |
| "$*" | "인자1 인자2 ..." (하나의 문자열) | 모든 인자를 하나로 합쳐 처리 |
| "$@" | "인자1" "인자2" ... (여러 문자열) | 각 인자를 개별로 유지 |
단순 조건문 연산자 (Simple Conditional Operators)
| 연산자 | 의미 | 동작 | 예시 |
| && | AND (앞 명령 성공 시 다음 실행) | 앞 명령이 성공(0) 일 때만 뒤 명령 실행 | ls -l >/dev/null && echo "Success!" |
| || | OR (앞 명령 실패 시 다음 실행) | 첫 번째 명령이 실행 실패(0이외의 종결 상태)일 때에만 실행 | cmd && echo OK || echo FAIL → 성공이면 OK, 실패면 FAIL |
5. 텍스트 처리 툴들 — 언제 무엇을 쓸까 (빠름/간결/유연성)
- cut
- 장점: 매우 가볍고 빠름(특정 구분자에서 필드만 뽑을 때 탁월).
- 단점: 고정 구분자 필요, 정교한 조건/패턴 처리 불가.
- 실무: “맨 앞 필드만”이나 고정 구분자에서 단순 추출이 필요한 경우 최우선 고려(성능상 유리). (예: /etc/passwd에서 cut -d: -f1,3)
- 성능 비교 사례는 환경에 따라 차이가 있으나, cut이 일반적으로 작고 단순한 작업에서 빠르다.
- awk
- 장점: 필드/패턴/계산/루프/변수까지 가능한 강력한 텍스트 처리 언어. 복잡한 변환이나 요약(Aggregation)에 유리.
- 실무: 열 분리 후 패턴 매칭, 통계, split(), BEGIN/END 블록 등 복합 작업 시 사용.
- sed
- 장점: 스트림 기반 편집(치환, 삭제 등), 원본 파일을 바꾸지 않고 파이프에서 처리 가능.
- 실무: 간단한 치환(s///g), 범위 삭제(예: '1,3d') 등에 자주 사용.
- grep, uniq, sort, paste 등
- grep은 패턴 검색(빠른 라인 필터), uniq -c는 카운트, sort -n/-r은 수치 정렬(옵션 -t로 구분자 지정), paste는 파일 병합(컬럼 결합) 등에 각각 특화.
- tee
- 표준 입력을 읽어 표준 출력(화면)과 하나 이상의 파일에 동시에 기록. 주로 파이프(|)와 함께 사용되어, 특정 명령어의 결과를 화면에 표시하면서 동시에 파일로 저장할 때 유용함
- 조합 팁(성능):
최소한의 도구 호출(파이프라인 길이 단축) → 큰 파일일수록 각 외부 명령 호출 비용이 누적됨. 단순 필드 추출은 cut으로, 조건부/복합 출력은 awk로. (환경별 성능 차이가 있어 time으로 측정 권장).

참고할만한 정리 사이트
https://prakhartripathi.hashnode.dev/log-parsing-tools-compared-choosing-between-grep-awk-and-sed
10 Simple Linux Commands Every Researcher Should Know
Being able to work with and manipulate files directly via the command line is one of the most useful skills to develop when working in the cloud. This blog post will introduce you to 10 common Linux commands that are crucial for your analysis artillery.
blog.ronin.cloud
6. 예제 해설 — 핵심 포인트만 정리
- cut -d " " -f 1,3 data
→ 공백(스페이스)을 구분자로 첫 필드와 세 번째 필드 추출. 주의: 연속 공백이 있거나 탭/다중 공백이면 의도치 않게 빈 필드가 생김. - cut -d : -f1,3,7 /etc/passwd | sort -t : -n -k3 -r | head -5
→ /etc/passwd에서 :로 필드 추출 후 3번째(uid) 기준으로 숫자 정렬(내림차순), 상위 5개 추출. 숫자 정렬 시 sort -n 사용 필수(아니면 문자 정렬됨). - paste exam1 exam2
→ 라인 단위 병합, -d로 구분자 지정 가능, -s로 행 단위 붙이기. - sed '1,3d' data / sed 's/japan/aa/g' data
→ 범위 삭제, 전역 치환(원본 파일은 변경되지 않음 — 스트림 출력). - awk '{split($3, phone, "-"); print $1, phone[1]}' data
→ $3을 -로 분리해 국가번호(또는 앞부분) 추출 — awk의 강점(내장 함수, 필드 기반). - /var/log/lastb 분석 예:
→ awk '{print $3}' lastb.txt | sort -n | uniq -c | sort -nr 같은 조합으로 실패 IP별 카운트 산출 — uniq -c와 sort의 조합은 자주 쓰이는 패턴.
7. 스크립트 작성 시 체크리스트 (안정성·포팅성·성능)
- 함수화: 점검 항목별로 함수로 분리 → 개별 테스트/유닛화 용이.
- 사용자 입력 금지:
- 배포되는 자동화 스크립트에 read 사용 금지(멈춤 위험).
- 자원 사용 주의:
- 대용량 파일 처리 시 외부 명령 호출 수 최소화(파이프라인 축소).
- 권한/보안:
- 절대 set으로 시스템 전역 환경을 덮어쓰지 말 것. (예: set으로 PATH 덮어쓰기 금지)
- 민감정보(토큰, 비밀번호)를 로그에 찍지 않도록 주의.
8. 디버깅/테스트 팁
- sh -xv script.sh 또는 bash -x script.sh로 상세 추적.
- 성능 비교: time으로 여러 명령(예: cut vs awk) 실제 파일에서 측정.
./for_sample.sh
sh -x for_sample.sh
bash -x for_sample.sh
# -xv 옵션 활용하여 디버깅
9. 흔히 발생하는 함정 & 권장 수칙
- 공백(스페이스) 처리 문제: cut -d " "는 연속 공백을 의도대로 처리하지 못함. 공백/탭 혼용이면 awk 또는 tr -s ' '로 정리 후 처리.
- 숫자 정렬 오류: sort의 기본은 문자 정렬 → 수치 정렬하려면 -n 사용.
- 불완전한 안전모드: set -e는 모든 상황에서 완전한 해법이 아님(명시적 예외 처리 필요).
10. 간단한 템플릿 (포팅성/안정성 고려한 점검 스크립트 예시)
/usr/bin/env bash 대신 sh 호환으로 작성 시 bash 확장 기능을 피해야 함. 아래는 bash를 명시적으로 사용한다고 가정한 안전한 템플릿:
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
# 환경 고정 (필요시 변경)
export LANG=C.UTF-8
export LC_ALL=C.UTF-8
log() { printf '%s %s\n' "$(date -Iseconds)" "$*"; }
# 절대 경로로 필요한 바이너리 지정 (필요시)
AWK=$(command -v awk)
CUT=$(command -v cut)
SORT=$(command -v sort)
GREP=$(command -v grep)
# 예: /etc/passwd에서 uid 기준 내림차순 상위 5명
top_uids() {
cut -d: -f1,3 /etc/passwd | ${SORT} -t: -n -k2 -r | head -n 5
}
main() {
log "Starting checks..."
top_uids
log "Done."
}
main "$@"
11. 참고 링크 (권장 문서 · 읽을거리)
- Shebang / portability: Unix StackExchange / ServerFault 토론. Unix & Linux Stack Exchange+1
- Bash shebang 권장 (/usr/bin/env bash): StackOverflow 토론. Stack Overflow
- Magic numbers / file signatures 설명(개요 + 리스트): Wikipedia / GeeksforGeeks. 위키백과+1
- set -euo pipefail 및 안전모드 설명(활용/주의점): 여러 블로그·Gist(예: set 설명 모음). Gist+1
- cut vs awk 성능 토론(간단 벤치/권장): StackOverflow / Linux 포럼 토론. Stack Overflow+1
마무리 요약 (실무 체크리스트)
- 점검 스크립트: 포팅성 우선 → sh 문법으로 작성하거나 bash 사용 시 명시.
- 로케일 고정, 안전 옵션(set -euo pipefail), 절대 경로/재정의된 PATH 주의, 함수화/모듈화, 로그/디버깅 정책을 지켜라.
- 텍스트 처리는 문제 단순도에 따라 cut(단순·빠름) / awk(복합·유연) / sed(스트림 편집) 을 선택, 성능은 time으로 측정.


'OS' 카테고리의 다른 글
| 시스템 보안(1) (0) | 2025.11.18 |
|---|---|
| 리눅스 운영 vol.2 (0) | 2025.10.21 |
| 리눅스 운영 vol.1 (0) | 2025.10.13 |
| 운영체제 개요 ch.06~ch.08 (0) | 2025.09.22 |
| 운영체제 개요 ch.01~ch.05 (0) | 2025.09.18 |