LabHub
배우기 러닝패스 코스

Shell Scripting

Loops and Functions

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

반복과 함수를 실제로 쓸 수 있는 형태로 익힙니다. 특히 "매칭되는 파일이 없을 때", "인자에 공백이 있을 때", "인자가 아예 없을 때" 같은 경계 상황에서 깨지지 않게 만듭니다.

왜 중요한가

셸 함수는 값을 반환하지 않습니다. 계산한 값은 표준출력으로 내보내고, 성공/실패는 종료 코드로 알립니다. 이 규약을 지켜야 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.shslugify 함수를 정의하세요. 단어들을 소문자로 바꾸고 하이픈으로 잇습니다. /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=<합계>

참고

1부터 5까지 출력하기

/root/bin/loop1.sh 를 만들어 1 부터 5 까지 한 줄에 하나씩 출력하게 하세요.

for x in 1 2 3 4 5 또는 중괄호 확장 {1..5} 를 쓸 수 있습니다.

글로브로 파일 세기

/root/loops/logs 디렉터리를 만들고 그 안에 .log 파일 4개, .txt 파일 2개를 두세요. 그리고 /root/bin/count.sh <디렉터리> 를 만들어 그 디렉터리 바로 아래의 .log 파일 개수만 출력하게 하세요. 빈 디렉터리를 주면 0 이 나와야 합니다.

매칭되는 파일이 없으면 패턴 문자열이 그대로 남습니다. [ -f "$f" ] || continue 로 걸러 내세요.

CSV 한 줄씩 읽기

/root/loops/users.csv이름,역할 형식으로 3줄 이상 넣고, /root/bin/readcsv.sh 를 만들어 그 파일을 읽어 이름(역할) 형식으로 한 줄씩 출력하게 하세요(인자 없이 실행합니다).

while IFS=, read -r a b 형태를 쓰고 입력은 done 뒤에서 리다이렉션합니다.

함수를 라이브러리로 분리

/root/bin/lib.shslugify 함수를 정의하세요. 단어들을 소문자로 바꾸고 하이픈으로 잇습니다. /root/bin/use.sh 는 그 파일을 source 로 불러와 사용해야 합니다. use.sh Hello World -> hello-world.

함수를 lib.sh 에 정의하고 use.sh 에서 . 또는 source 로 불러오세요. 복붙하면 안 됩니다.

종료 코드로 판정하기

/root/bin/isnum.sh <문자열> 을 만드세요. 숫자로만 이루어졌으면 종료 코드 0, 아니면 0이 아닌 코드입니다. 아무것도 출력하지 않아야 합니다. 빈 문자열, 부호, 소수점은 모두 숫자가 아닙니다.

판정 결과를 출력하면 if 문에서 쓸 수 없습니다. return 0 / return 1 로만 알리세요.

공백이 든 인자 안전하게 순회

/root/bin/each.sh 를 만들어 받은 인자마다 [인자] 형식으로 한 줄씩 출력하게 하세요. each.sh "a b" c 는 두 줄이어야 합니다. 인자가 없으면 아무것도 출력하지 않습니다.

for x in "$@" 와 for x in $* 의 차이를 확인하세요. 인자가 없을 때는 아무것도 하지 않아야 합니다.

가변 인자 합산

/root/bin/sum.sh 를 만들어 받은 숫자 인자들의 합을 출력하게 하세요. 인자가 없으면 0.

누적 변수를 0 으로 초기화하는 것을 잊지 마세요. 인자가 없으면 0 이 나와야 합니다.

디렉터리 요약 리포트

/root/bin/summary.sh <디렉터리> 를 만드세요. 그 디렉터리의 .log 파일 개수와 전체 줄 수를 다음 두 줄로 출력합니다.

파일 개수와 전체 줄 수를 함께 셉니다. 빈 디렉터리에서도 0/0 이 나와야 합니다.