셸 스크립팅 · 반복과 함수 · 실습
반복문과 함수
목표
반복과 함수를 실제로 쓸 수 있는 형태로 익힙니다. 특히 "매칭되는 파일이 없을 때", "인자에 공백이 있을 때", "인자가 아예 없을 때" 같은 경계 상황에서 깨지지 않게 만듭니다.
왜 중요한가
셸 함수는 값을 반환하지 않습니다. 계산한 값은 표준출력으로 내보내고, 성공/실패는 종료 코드로 알립니다. 이 규약을 지켜야 if is_number "$x" 같은 자연스러운 사용이 가능합니다. 그리고 파일 목록은 ls 를 파싱하지 말고 셸의 글로브에 맡깁니다 - $(ls *.log) 는 공백이 든 파일 이름에서 깨지고, 매칭이 없을 때 오류 메시지를 루프 입력으로 흘려보냅니다. 대신 글로브를 쓰면 매칭이 없을 때 패턴 문자열이 그대로 남는 다른 함정이 생기므로 [ -f "$f" ] || continue 방어선이 필요합니다.
단계
1. /root/bin/loop1.sh 를 만들어 1 부터 5 까지 한 줄에 하나씩 출력하게 하세요.
2. /root/loops/logs 디렉터리를 만들고 그 안에 .log 파일 4개, .txt 파일 2개를 두세요. 그리고 /root/bin/count.sh <디렉터리> 를 만들어 그 디렉터리 바로 아래의 .log 파일 개수만 출력하게 하세요. 빈 디렉터리를 주면 0 이 나와야 합니다.
3. /root/loops/users.csv 에 이름,역할 형식으로 3줄 이상 넣고, /root/bin/readcsv.sh 를 만들어 그 파일을 읽어 이름(역할) 형식으로 한 줄씩 출력하게 하세요(인자 없이 실행합니다).
4. /root/bin/lib.sh 에 slugify 함수를 정의하세요. 단어들을 소문자로 바꾸고 하이픈으로 잇습니다. /root/bin/use.sh 는 그 파일을 source 로 불러와 사용해야 합니다. use.sh Hello World -> hello-world.
5. /root/bin/isnum.sh <문자열> 을 만드세요. 숫자로만 이루어졌으면 종료 코드 0, 아니면 0이 아닌 코드입니다. 아무것도 출력하지 않아야 합니다. 빈 문자열, 부호, 소수점은 모두 숫자가 아닙니다.
6. /root/bin/each.sh 를 만들어 받은 인자마다 [인자] 형식으로 한 줄씩 출력하게 하세요. each.sh "a b" c 는 두 줄이어야 합니다. 인자가 없으면 아무것도 출력하지 않습니다.
7. /root/bin/sum.sh 를 만들어 받은 숫자 인자들의 합을 출력하게 하세요. 인자가 없으면 0.
8. /root/bin/summary.sh <디렉터리> 를 만드세요. 그 디렉터리의 .log 파일 개수와 전체 줄 수를 다음 두 줄로 출력합니다.
files=<개수>total_lines=<합계>
참고
. /root/bin/lib.sh와source /root/bin/lib.sh는 같은 명령입니다. 새 프로세스를 만들지 않아 함수 정의가 남습니다.wc -l < 파일은 파일명을 출력에 붙이지 않아 계산에 쓰기 편합니다.- 흔한 실수 1: 2번과 8번에서 빈 디렉터리를 넣으면 글로브가 확장되지 않고 패턴 문자열이 그대로 남아 개수가 1 로 나옵니다.
- 흔한 실수 2: 6번에서
for x in $*를 쓰면"a b"가 두 개로 쪼개집니다.
단계 8개
- 1부터 5까지 출력하기
- 글로브로 파일 세기
- CSV 한 줄씩 읽기
- 함수를 라이브러리로 분리
- 종료 코드로 판정하기
- 공백이 든 인자 안전하게 순회
- 가변 인자 합산
- 디렉터리 요약 리포트