Step 8. 조건문과 반복문 — 컴퓨터에게 판단과 노가다를 시키기

Step 8. 조건문과 반복문 — 컴퓨터에게 판단과 노가다를 시키기

Level 0 — 컴퓨터 조작과 구조의 이해 | 난이도 ★★☆☆☆ | 예상 소요 시간 3시간

전제: Step 7 완료. 윈도우 파워쉘에서 진행합니다. 인터넷 연결은 필요 없습니다.

  • 준비물: 윈도우 PC, 파워쉘.
  • 안전: 오늘도 전부 안전한 연습 코드입니다.
  • 주의: 비교 기호가 특이합니다. 파워쉘은 > 대신 -gt, = 대신 -eq를 씁니다. 어색해도 규칙은 단순하니, 한 번 틀리고 나면 바로 익숙해집니다.

오늘이야말로 "스크립트다운 스크립트"의 첫날입니다. Step 4에서 로그 파일을 다뤘는데, 실제 서버의 로그는 하루에 수만 줄씩 쌓입니다. 보안 담당자에게 필요한 것은 "실패 로그인이 5건 넘으면 알려 줘"(조건 판단)와 "모든 로그 줄을 하나하나 검사해"(반복 작업)입니다. 사람이 하면 며칠이 걸리고 실수하지만, 컴퓨터는 1초면 하고 지치지도 않습니다. 오늘 배우는 두 도구가 그 자동화의 심장입니다.


1. 학습 목표

이 챕터를 끝내면 다음을 할 수 있습니다:

  • if/else로 "만약 ~라면" 판단을 코드로 옮긴다
  • foreach로 목록 전체를 자동으로 훑고, for로 정해진 횟수를 반복한다
  • 조건 + 반복을 합쳐 "조건에 맞는 것만 골라내기(필터링)"를 만든다
  • 누적 패턴(합계·건수 세기)으로 1~100의 짝수 합계 스크립트를 완성한다

2. 배경 지식 — 오늘의 도구와 개념

오늘의 도구 한눈에 보기

구분 내용
언어·환경 파워쉘 5.1 (프로그래밍의 공통 개념을 배우는 날 — 다른 언어에도 그대로 있습니다)
오늘의 문법 if (조건) { } else { }, foreach ($x in $목록) { }, for ($i=1; $i -le N; $i++) { }
비교 연산자 -eq -ne -gt -lt -ge -le (그리고 나머지 %)
필요한 개념 제어 흐름, 조건식(참/거짓), 반복, 누적 패턴

변수가 알파벳이라면, 조건문과 반복문은 문법입니다. 두 개념 모두 일상에서 이미 쓰고 있는 것들입니다 — "비가 오면 우산을 챙긴다"(조건), "엘리베이터가 올 때까지 기다린다"(반복). 오늘은 이걸 코드로 옮기는 연습일 뿐입니다.

2-1. 제어 흐름 — 물줄기에 댐과 수로 놓기

프로그램은 기본적으로 위에서 아래로 흐릅니다. 이 흐름을 제어 흐름(control flow)이라 합니다. 오늘 배우는 두 도구는 이 흐름에 다는 장치입니다:

  • 조건문(if) — "이 조건이 참이면 A로, 아니면 B로" 흐름을 갈라놓는 수문
  • 반복문(foreach, for) — 같은 구간을 여러 바퀴 도는 순환 수로

프로그래밍 언어가 아무리 달라도 이 둘은 반드시 존재합니다. 파이썬, C, 자바스크립트 전부 마찬가지. 하나를 제대로 배우면 다른 언어에서는 표기만 갈아 끼우면 됩니다.

2-2. 조건식 — 참/거짓으로 답하는 질문

조건문에는 "판단 기준"이 필요합니다. 이걸 조건식이라 하고, 답은 반드시 참(True) 또는 거짓(False) 둘 중 하나입니다.

$a -gt 5 — "a가 5보다 큰가?" a가 7이면 참, 3이면 거짓. 파워쉘의 비교 연산자 표입니다:

연산자 예시 결과
-eq 같다 (equal) $a -eq 5 a가 5면 참
-ne 다르다 (not equal) $a -ne 5 a가 5가 아니면 참
-gt 크다 (greater than) $a -gt 5 a가 6 이상이면 참
-lt 작다 (less than) $a -lt 5 a가 4 이하면 참
-ge 크거나 같다 $a -ge 5 a가 5 이상이면 참
-le 작거나 같다 $a -le 5 a가 5 이하면 참

주의: 수학의 =는 파워쉘에서 "대입"(상자에 넣기)입니다. "같은지 비교"는 반드시 -eq입니다. $a = 5는 "5를 넣어라", $a -eq 5는 "5와 같은가?" — 이 혼동이 초보 최대의 버그 제조기입니다.

2-3. 반복의 두 얼굴

반복에는 상황에 따라 두 가지가 쓰입니다:

  • foreach — "목록의 항목마다 하나씩" (멤버 명단을 앞에서부터 쭉 호명)
  • for — "정해진 횟수만큼" (10바퀴 뛰어라)

둘 다 "반복"이지만 출발점이 다릅니다. 목록이 있으면 foreach, 횟수가 정해져 있으면 for. 오늘 둘 다 해 봅니다.


3. 따라 하기

3-1. 첫 조건문 — if

$a = 7
if ($a -gt 5) { "크다" } else { "작다" }
크다

출력 읽는 법: $a가 7이니 "5보다 큰가?"는 참 → { "크다" } 쪽이 실행됐습니다.

구조 분해: if (조건식) { 참일 때 할 일 } else { 거짓일 때 할 일 }. 중괄호 { }가 "할 일 묶음"입니다.

왜 하는가: 이제 $a를 3으로 바꾸고 다시 실행해 보세요:

$a = 3
if ($a -gt 5) { "크다" } else { "작다" }

이번엔 작다가 나옵니다. 같은 코드인데 값에 따라 다른 동작 — 이것이 조건문의 힘입니다. 코드가 스스로 상황에 반응하기 시작한 겁니다.

3-2. else 없는 if, 그리고 실전형 조건

거짓일 때 할 일이 없으면 else는 생략합니다:

$failCount = 7
if ($failCount -ge 5) { "경고: 로그인 실패가 너무 많습니다!" }
경고: 로그인 실패가 너무 많습니다!

왜 하는가: 이 형태가 보안 알림의 기본형입니다. "실패 횟수가 기준(5) 이상이면 경고." $failCount를 2로 바꾸면 아무 출력도 없습니다 — 조용한 게 정상입니다.

예측해 보기: if ($failCount -gt 5) { ... }-ge 대신 -gt를 쓰면, 실패가 정확히 5건일 때 경고가 뜰까요 안 뜰까요? (정답: 안 뜹니다. -gt는 "초과"라서 5는 포함하지 않습니다. 경계값 — 딱 기준 숫자 — 에서 동작이 어떻게 달라지는지가 프로그래밍 실수의 단골 자리입니다. 직접 5를 넣어 확인해 보세요.)

3-3. foreach — 목록 자동 순회

Step 7의 배열을 꺼내 옵시다:

$members = @("Kim", "Lee", "Park")
foreach ($m in $members) { "안녕, $m!" }
안녕, Kim!
안녕, Lee!
안녕, Park!

출력 읽는 법: 목록의 항목마다 한 번씩, 총 세 번 실행됐습니다.

구조 분해: foreach ($m in $members) — "members 목록에서 하나씩 꺼내 m이라 부르면서" { } 안을 실행합니다. $m은 매 바퀴 바뀝니다: 첫 바퀴 Kim, 둘째 바퀴 Lee, 셋째 바퀴 Park.

왜 하는가: 이 패턴이 실전에서는 이렇게 변합니다 — "파일 목록에서 하나씩 꺼내 검사", "사용자 목록에서 하나씩 꺼내 권한 확인". 100개든 100만 개든 코드는 똑같이 한 줄입니다.

3-4. for — 정해진 횟수 반복

for ($i = 1; $i -le 5; $i++) { "숫자 $i" }
숫자 1
숫자 2
숫자 3
숫자 4
숫자 5

구조 분해 — 괄호 안이 세 조각입니다:

  • $i = 1 — 시작값 (i를 1로 놓고 시작)
  • $i -le 5 — 계속할 조건 (i가 5 이하인 동안만 반복)
  • $i++ — 매 바퀴 끝에 할 일 (i에 1을 더해라 — ++는 "1 증가"라는 뜻의 기호)

왜 하는가: 목록 없이 "n부터 m까지" 식의 숫자 반복이 필요할 때 씁니다. 포트 1번부터 1024번까지 점검하기 같은 일이 실전 예시입니다.

3-5. 조건 + 반복 합체 — 필터링

이제 둘을 합쳐 봅시다. "목록에서 조건에 맞는 것만 골라내기":

$scores = @(85, 42, 91, 55, 78)
foreach ($s in $scores) {
    if ($s -ge 60) { "$s 점: 합격" }
}
85 점: 합격
91 점: 합격
78 점: 합격

출력 읽는 법: 42와 55는 조건(60 이상)에 안 맞아 걸러졌습니다. 반복문이 전부 돌되, 조건문이 출력을 선별한 겁니다.

왜 하는가: "전부 훑되 조건 맞는 것만 처리" — 이것이 로그 분석의 정확한 작동 원리입니다. 수만 줄을 foreach로 돌리고, "ERROR 포함" 같은 조건으로 낚는 것. 오늘 이 5줄이 그 원리의 축소판입니다.

3-6. 대망의 종합 — 짝수의 합 구하기

오늘의 완료 기준 과제를 같이 해 봅시다: 1부터 100까지 중 짝수만 더하기.

짝수 판별법부터: 어떤 수를 2로 나눈 나머지가 0이면 짝수입니다. 나머지 연산자는 %입니다. $n % 2가 0이면 짝수.

$sum = 0
for ($i = 1; $i -le 100; $i++) {
    if ($i % 2 -eq 0) { $sum = $sum + $i }
}
$sum
2550

한 줄씩 해설:

  1. $sum = 0 — 합계를 담을 상자를 0으로 준비 (비어 있는 주머니)
  2. 1부터 100까지 반복하되
  3. $i % 2 -eq 0 — 나누어 떨어지면(짝수면)
  4. $sum = $sum + $i — 주머니에 그 수를 더해라. 오른쪽이 먼저 계산되고 결과가 다시 $sum에 들어갑니다
  5. 최종 출력: 2550 (2+4+6+…+100, 실측 확인)

왜 하는가: "누적"(반복하면서 값을 쌓아 올리기)은 데이터 처리의 기본 패턴입니다. 총 에러 수, 총 전송량, 평균 계산 — 전부 이 모양입니다.

3-7. 실전 연결 — Step 4의 로그와 합치기

오늘의 기술이 실제 로그 파일에서 어떻게 쓰이는지, 맛보기로 연결해 봅시다. 먼저 실험용 로그를 만듭니다 (Step 4의 생성기와 같은 요령):

1..20 | ForEach-Object { if ($_ % 3 -eq 0) { Add-Content scanlog.txt "ERROR 번호 $_" } else { Add-Content scanlog.txt "OK 번호 $_" } }

이제 파일을 읽어 배열로 담고(Step 7), 반복하며 조건으로 걸러 봅시다:

$lines = Get-Content scanlog.txt
$errCount = 0
foreach ($line in $lines) {
    if ($line.Contains("ERROR")) { $errCount = $errCount + 1 }
}
"전체 $($lines.Count)줄 중 에러 $errCount 건"
전체 20줄 중 에러 6 건

한 줄씩 해설:

  1. Get-Content — 파일 전체를 읽어 줄 단위 배열로 만듭니다. 20줄이면 20칸짜리 배열
  2. $errCount = 0 — 누적 주머니 준비 (3-6절의 패턴)
  3. foreach — 20줄을 하나씩 돌면서
  4. $line.Contains("ERROR") — "이 줄에 ERROR라는 글자가 포함되어 있나?"라는 조건식. 포함되어 있으면 참
  5. 최종 보고 — 큰따옴표 안의 $($lines.Count) 표기 기억하시죠?

왜 하는가: 이 일곱 줄이 "로그 분석 스크립트"의 최소 완전체입니다. 파일을 읽고, 전부 훑고, 조건으로 세고, 요약을 말한다 — 실무의 로그 분석도 규모만 클 뿐 이 구조를 벗어나지 않습니다. 여러분은 지금 Step 4(텍스트 검색), Step 7(변수·배열), Step 8(조건·반복)의 세 기술이 하나의 도구로 합쳐지는 순간을 보고 있는 겁니다.


4. 미션과 연습문제

미션 — 로그인 감시 스크립트 (축소판)

실제 보안 로그 감시의 모형을 만들어 봅시다. 아래는 한 사용자의 시간대별 로그인 실패 횟수입니다:

$failLog = @(0, 1, 0, 3, 9, 12, 2, 0)

과제:

  1. foreach로 이 목록을 돌면서, 실패가 5건 이상인 시간대만 "위험: N건 실패"라고 출력하세요
  2. 반복이 끝난 뒤, 전체 실패 합계를 "총 실패: M건"으로 출력하세요 (누적 패턴 활용)

연습문제

문제 1. $a = 5$a -eq 5의 차이를 설명하세요.

문제 2. foreachfor 중 어떤 것을 써야 할지 구분하는 기준은?

문제 3. @(3, 7, 2, 8)에서 5 이상만 출력하는 코드를 써 보세요.

문제 4. 누적 패턴 스크립트를 두 번 연속 실행했더니 합계가 두 배가 됐습니다. 원인과 해결은?


5. 모범 답안과 완료 기준

미션 모범 답안

$failLog = @(0, 1, 0, 3, 9, 12, 2, 0)
$sum = 0
foreach ($f in $failLog) {
    if ($f -ge 5) { "위험: $f건 실패" }
    $sum = $sum + $f
}
"총 실패: $sum건"

기대 출력 (실측 확인):

위험: 9건 실패
위험: 12건 실패
총 실패: 27건

검증하는 법: "위험"이 정확히 두 줄이고 총합이 27이면 완벽합니다. 위험이 세 줄 이상이면 조건을 다시 보세요. 총합이 다르면 $sum 초기화(= 0)를 빼먹었을 가능성이 큽니다.

심화: 조건을 -gt 5로 바꾸면 어떤 줄이 사라질까요? 이유와 함께 예측한 뒤 확인해 보세요. (정답: 없습니다. 9와 12 모두 5 초과라 결과가 같습니다. 대신 기준을 9로 올린 -ge 9 vs -gt 9를 비교해 보면 경계값 차이가 확실히 보입니다.)

연습문제 해답

문제 1 해답. $a = 5대입 — 상자에 5를 넣는 동작입니다. $a -eq 5비교 — "a가 5와 같은가?"라는 질문으로 답은 참/거짓입니다. 조건 자리에 =를 쓰는 것이 초보 최대의 버그입니다.

문제 2 해답. 다룰 목록이 이미 있으면 foreach ("목록의 항목마다 하나씩"), 횟수나 숫자 범위가 정해져 있으면 for ("1부터 100까지")를 씁니다.

문제 3 해답.

$nums = @(3, 7, 2, 8)
foreach ($n in $nums) {
    if ($n -ge 5) { $n }
}

출력은 78입니다. "전부 훑되 조건 맞는 것만 처리" — 필터링 패턴입니다.

문제 4 해답. $sum = 0 초기화를 빼먹었거나, 같은 파워쉘 창에서 이전 실행의 $sum이 남은 채로 다시 실행했기 때문입니다 (변수는 창이 열려 있는 동안 살아 있습니다 — Step 7 복습). 스크립트 맨 위에 $sum = 0을 두고 매번 처음부터 통째로 실행하세요.

완료 기준 체크리스트

  • [ ] -eq, -gt, -lt 등 비교 연산자를 구분해 쓸 수 있다
  • [ ] =-eq의 차이를 설명할 수 있다
  • [ ] if/else로 조건에 따른 분기를 작성할 수 있다
  • [ ] foreach로 배열의 모든 항목을 순회할 수 있다
  • [ ] for로 횟수 반복을 작성할 수 있다
  • [ ] 누적 패턴으로 합계를 구할 수 있다
  • [ ] 미션: 로그인 감시 스크립트(축소판)를 완성했다

6. 흔한 실수와 해결

벽 1. =-eq를 헷갈린다

증상: if ($a = 5)라고 썼더니 조건이 항상 참처럼 동작하거나 결과가 이상함.
원인: =는 비교가 아니라 대입입니다. "a에 5를 넣고" 그 값(5)으로 판단해 버립니다.
해결: 조건 자리에는 무조건 -eq. "같니?"는 -eq, "넣어라"는 = — 머릿속에 각인하세요.

벽 2. 반복문이 한 번도 안 돌거나 끝나지 않는다

증상: for문을 쳤는데 출력이 없거나, 멈추지 않음.
원인: 조건을 거꾸로 쓴 경우가 많습니다. for ($i=1; $i -ge 100; $i++)처럼 시작하자마자 조건이 거짓이면 한 번도 안 돕니다. 반대로 조건이 영원히 참이면 무한 반복.
해결: 멈추지 않으면 Ctrl + C로 중단하세요. 그리고 "시작값이 조건을 만족하는가", "매 바퀴 조건이 거짓 쪽으로 가는가" 두 가지만 점검하면 됩니다.

벽 3. 중괄호 { } 짝이 안 맞는다

증상: 코드를 여러 줄로 쳤더니 >> 표시가 나오며 입력이 계속됨.
원인: {를 열고 }로 안 닫아서 파워쉘이 "아직 안 끝났구나" 하고 기다리는 중입니다.
해결: }를 추가로 입력하거나, Ctrl + C로 취소하고 다시 치세요. 습관: {를 치는 즉시 }도 같이 치고 그 사이를 채우세요.

벽 4. 합계가 이상하게 크거나 0이다

증상: 누적 결과가 예상과 다름.
원인: 두 가지가 대표적입니다. ① $sum = 0 초기화를 빼먹음(빈 상자에 더하기). ② 반복문 밖에서 변수를 리셋하지 않고 같은 창에서 코드를 여러 번 실행 — 이전 실행의 $sum이 남아 있어서 계속 쌓입니다.
해결: 스크립트 맨 위에 $sum = 0을 두고, 실행할 때마다 처음부터 통째로 다시 실행하세요.

벽 5. -gt-ge의 경계에서 헷갈린다

증상: "5 이상"인데 5에서 동작을 안 함.
원인: -gt(초과)를 써서 5가 제외됐습니다. "이상"은 -ge, "초과"는 -gt.
해결: 기준 숫자 자체를 넣어 테스트해 보세요(경계값 테스트). "정확히 5일 때 어떻게 되어야 하는가"를 먼저 정하고 코드를 고르면 실수가 줄어듭니다.


7. 정리

오늘의 두 기둥

도구 용도 형태
if / else 조건에 따라 갈림길 if (조건) { A } else { B }
foreach 목록 전체 순회 foreach ($x in $list) { ... }
for 횟수 반복 for ($i=1; $i -le N; $i++) { ... }

비교 연산자 암기표

-eq(같다) -ne(다르다) -gt(크다) -lt(작다) -ge(이상) -le(이하) — 그리고 =는 대입, %는 나머지.

오늘의 패턴 카드

패턴 코드 골격 실전 용도
임계값 경고 if ($n -ge 기준) { 경고 } 실패 로그인 알림
필터링 foreach 안에 if 로그에서 이상 징후만 추출
누적 $sum = 0 후 반복하며 더하기 총 건수·총량 집계

명령어보다 중요한 감각

침해 탐지 규칙, 로그 분석, 알림 시스템 — 전부 오늘의 "조건 + 반복" 위에 서 있습니다. "5회 이상 실패 시 경고"를 코드로 쓸 수 있다는 것은, 여러분이 더 이상 로그를 눈으로 읽는 사람이 아니라 로그를 검사하는 프로그램을 만드는 사람이 됐다는 뜻입니다.

같은 도구가 공격과 수비 양쪽에서 쓰인다는 것도 기억하세요. 공격자는 for로 비밀번호 후보를 하나씩 대입하고(무차별 대입 — Level 2에서 랩 환경에서 직접 실습합니다), 수비자는 foreach로 접속 로그를 훑어 이상 징후를 찾습니다. 방화벽 규칙과 접근 통제도 결국 거대한 if문의 집합입니다.


전부 체크되면 Step 8 완료입니다. 사이드바의 체크박스를 눌러 진도를 저장하세요.