Step 3. 파이프(|) — 명령을 조립하는 사고방식
Level 0 — 컴퓨터 조작과 구조의 이해 | 난이도 ★★☆☆☆ | 예상 소요 시간 2~3시간
전제: Step 2 완료. 윈도우 파워쉘에서 진행합니다.
- 준비물: 윈도우 PC, 파워쉘.
- 안전: 오늘 실험은 전부 "읽기"입니다. 시스템을 바꾸는 명령이 없으니 마음껏 쳐 보세요.
- 주의: 오늘 나오는 문법 두 개(
{}와$_)가 좀 낯섭니다. 지금 완벽히 이해하려 하지 말고, 통째로 따라 치며 감각부터 익히세요. 왜 그런지는 뒤에서 설명합니다.
오늘은 개념적으로 가장 중요한 날 중 하나입니다. 명령 하나하나는 도구일 뿐이고, 파이프는 그 도구들을 "조립"하는 방법입니다. 보안 조사의 대부분은 "이상하게 오래 도는 프로세스만 골라 줘", "수만 줄 로그에서 실패한 로그인만 뽑아 줘" 같은 문제 — 전부 "목록 → 필터 → 정렬 → 자르기"의 조립입니다. 이 조립 사고가 익숙해지면, 낯선 문제도 같은 뼈대로 풀리기 시작합니다.
1. 학습 목표
이 챕터를 끝내면 다음을 할 수 있습니다:
- 파이프(
|)로 명령의 출력을 다음 명령의 입력으로 넘긴다 Sort-Object,Select-Object -First N,Where-Object세 기계를 조립한다- "○○한 것 상위 N개" 형태의 조합 명령을 스스로 설계한다
- 모르는 명령의 속성(꼬리표)을
Get-Member로 조사한다
2. 배경 지식 — 오늘의 도구와 개념
오늘의 도구 한눈에 보기
| 구분 | 내용 |
|---|---|
| 언어·환경 | 파워쉘 5.1 — 오늘의 주인공은 파이프(` |
| 오늘의 명령어 | Sort-Object(정렬), Select-Object -First N(자르기), Where-Object(필터), Get-Member(속성 조사), Measure-Object(개수) |
| 필요한 개념 | 객체(object)와 속성(property), $_와 {} 문법, 비교 연산자 -eq/-gt 등 |
공장을 상상해 보세요. 원재료가 컨베이어 벨트 위를 지나가고, 각 공정의 기계가 재료를 받아서 자기 일을 하고 다음 기계로 넘깁니다.
원재료 → [자르기] → [다듬기] → [포장] → 완성품
파워쉘의 파이프(|)가 바로 이 컨베이어 벨트입니다. 왼쪽 명령의 결과물이 벨트를 타고 오른쪽 명령의 재료가 됩니다.
2-1. 파워쉘 파이프의 비밀 — 글자가 아니라 물건이 지나간다
리눅스의 파이프(Step 19에서 배웁니다)는 글자(텍스트)를 넘깁니다. 그래서 "몇 번째 단어만 잘라내기" 같은 눈속임이 필요하죠.
파워쉘은 다릅니다. 벨트 위를 지나가는 게 글자가 아니라 객체(object) — "꼬리표가 달린 물건"입니다. 예를 들어 Get-Process가 넘기는 건 프로세스 하나하나인데, 각각에 이런 꼬리표(속성, property)가 붙어 있습니다:
프로세스 객체 하나
├── Name: "chrome"
├── CPU: 245.3
├── WorkingSet: 892345600
├── Id: 4520
└── ...
그래서 오른쪽 명령은 "글자를 뜯어 맞추기"가 아니라 꼬리표 이름으로 정확히 집어냅니다. Sort-Object CPU는 "CPU라는 꼬리표를 기준으로 정렬해"라는 뜻이고, 화면에 어떻게 보이든 상관없이 정확합니다. 이게 "파워쉘 파이프는 정확하다"는 말의 의미입니다.
2-2. 오늘의 기계(명령) 소개
| 명령 | 역할 | 공장 비유 |
|---|---|---|
Sort-Object 속성 |
기준 속성으로 정렬 | 줄 세우기 기계 |
Select-Object -First N |
앞에서 N개만 | 자르기 기계 |
Where-Object {조건} |
조건에 맞는 것만 통과 | 검수 기계 |
Get-Member |
꼬리표(속성) 목록 보기 | 설계도 열어보기 |
2-3. $_ 와 {} — 검수 기계의 사용법
Where-Object만 문법이 특이합니다:
Where-Object {$_.CPU -gt 100}
읽는 법:
{}(중괄호): "이 안에 검사 조건이 있습니다"$_: "벨트 위를 지금 지나가는 이 물건 하나"를 가리키는 대명사$_.CPU: "지나가는 물건의 CPU 꼬리표"-gt: "greater than, ~보다 큰"
통째로 읽으면: "지나가는 각 물건에 대해, CPU가 100보다 큰 것만 통과시켜라."
비교 연산자는 수학 기호 대신 글자를 씁니다:
| 기호 | 뜻 |
|---|---|
-eq |
같다 (equal) |
-ne |
다르다 (not equal) |
-gt |
크다 (greater than) |
-lt |
작다 (less than) |
처음엔 이 문법이 외계어처럼 보입니다. 정상입니다. 오늘은 통째로 외워서 쓰고, 이해는 반복하며 따라오게 두세요 — 실은 이게 문법 습득의 지름길입니다.
3. 따라 하기
3-1. 재료 확인 — Get-Process
Get-Process
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
238 15 5120 18420 0.23 4520 1 ApplicationFrameHost
2156 89 185412 245800 45.12 8812 1 chrome
...
지금 이 컴퓨터에서 실행 중인 프로그램(프로세스) 목록입니다. 컬럼을 봅시다:
ProcessName— 프로그램 이름CPU(s)— 지금까지 쓴 CPU 시간(초)WS(K)— 메모리 사용량Id— 프로세스 번호(PID)
양이 많아서 화면을 가득 채웁니다. 이 재료를 이제 가공해 봅시다.
3-2. 첫 파이프 — 정렬하기
Get-Process | Sort-Object CPU -Descending
같은 목록인데, 이번엔 CPU를 많이 쓴 순서로 나옵니다. 읽는 법:
|— "왼쪽 결과를 오른쪽으로 넘겨라"Sort-Object CPU— "CPU 꼬리표 기준으로 정렬해"-Descending— "내림차순(큰 것부터)". 빼면 오름차순(작은 것부터)
잠깐 멈추고 체감하세요: 방금 일어난 일은 "왼쪽 기계가 만든 물건이, 벨트를 타고 오른쪽 기계의 재료가 된 것"입니다. Sort-Object는 Get-Process가 뭔지 몰라도 됩니다 — 벨트 위의 물건을 정렬하는 게 자기 일이니까요.
3-3. 벨트 연장 — 앞의 10개만
정렬은 됐는데 전부 다 나오니 여전히 깁니다. 벨트에 기계를 하나 더 달아 봅니다:
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
614 26 31684 28228 11,861.81 24832 1 cloud-drive-daemon
1997 97 753512 309468 4,024.48 41684 1 ChatGPT
2453 64 521032 168260 3,970.92 35616 1 chrome
... (딱 10줄만 나옴)
Select-Object -First 10— "앞에서 10개만 골라라"
이제 읽기 좋습니다. "CPU 상위 10개 프로세스" — 작업 관리자에서 CPU 열 눌러 정렬한 것과 같은 정보를, 명령 한 줄로 얻었습니다. (위 출력은 실제 실행 결과입니다 — 당신 화면의 1위는 다른 프로그램일 수 있습니다.)
예측해 보기:
Get-Process | Sort-Object WorkingSet -Descending | Select-Object -First 5는 뭘 보여 줄까요? CPU 자리에 WorkingSet이 들어갔습니다. 예측한 뒤 실행해 보세요.
(정답: 메모리를 많이 쓰는 상위 5개 프로세스. 꼬리표 이름만 바꿨을 뿐인데 완전히 다른 질문에 답했습니다 — 이게 조립의 힘입니다.)
3-4. 검수 기계 — Where-Object
이번엔 정렬이 아니라 필터입니다.
Get-Process | Where-Object {$_.CPU -gt 100}
CPU를 100초 넘게 쓴 프로세스만 남습니다. (없으면 아무것도 안 나올 수 있습니다 — 그건 "해당 없음"이라는 정상 결과입니다. 숫자를 50이나 10으로 낮춰 다시 쳐 보세요.)
이 명령은 벨트 위를 지나가는 프로세스 하나하나를 붙잡고 묻습니다: "너 CPU 100 넘어?" — 넘으면 통과, 아니면 폐기.
이번엔 이름으로 골라 봅시다:
Get-Process | Where-Object {$_.ProcessName -eq "powershell"}
이름이 정확히 powershell인 프로세스만 남습니다. (지금 파워쉘이 켜져 있으니 최소 1개는 나와야 정상입니다.)
3-5. 꼬리표가 궁금하면 — Get-Member
"CPU 말고 또 어떤 꼬리표가 있지?" 궁금할 때의 명령:
Get-Process | Get-Member
TypeName: System.Diagnostics.Process
Name MemberType Definition
---- ---------- ----------
...
CPU Property double CPU {get;}
Id Property int Id {get;}
ProcessName Property string ProcessName {get;}
WorkingSet Property long WorkingSet {get;}
...
Property라고 적힌 것들이 전부 꼬리표 후보입니다. 이 목록을 보고 "아, 이런 속성도 있구나" 하고 다음 조합의 아이디어를 얻으면 됩니다. 모르는 명령의 속성이 궁금할 때 Get-Member — 앞으로 수백 번 쓰게 될 조사 습관입니다.
3-6. 파일에도 같은 생각을 — 응용 조합
파이프는 프로세스 전용이 아닙니다. Get-ChildItem(파일 목록)도 똑같이 벨트에 올릴 수 있습니다:
Get-ChildItem $HOME | Sort-Object Length -Descending | Select-Object -First 5
읽는 법: "내 홈의 파일 목록을 얻어서 → 크기(Length) 큰 순으로 정렬 → 5개만." "내 홈에서 가장 큰 파일 5개는?"이라는 질문에 명령 한 줄로 답했습니다. 디스크 정리할 때 쓰는 실전 조합입니다.
지금까지의 패턴을 정리하면:
(목록 얻기) | (가공: 정렬/필터) | (자르기)
이 뼈대에 재료와 조건만 갈아 끼우면 되는 겁니다.
4. 미션과 연습문제
미션 — 조립 설계사
다음 질문들에 답하는 명령을 스스로 조립해 보세요. 정답은 5번 섹션에 있지만, 먼저 만들어 보고 실행해 본 뒤 비교하세요.
- "메모리(WorkingSet)를 500MB(=524288000) 넘게 쓰는 프로세스만 보여 줘"
- "이름이 powershell인 프로세스가 지금 몇 개인지 보여 줘" (힌트: 필터 뒤에
| Measure-Object를 붙이면 개수를 세어 줍니다) - "C:\Windows\System32에서 가장 최근에 수정된 파일 3개를 보여 줘" (힌트: 수정 시각 꼬리표는
LastWriteTime) - "프로세스를 이름순(가나다)으로 정렬해서 앞 10개만 보여 줘" (힌트: 이번엔 -Descending이 필요할까요?)
연습문제
문제 1. 파워쉘의 파이프가 리눅스 파이프와 다른 점 하나를 설명하세요.
문제 2. Where-Object {$_.Length -gt 1000000}에서 $_는 무엇을 가리키나요?
문제 3. "내 홈 폴더에서 크기가 0인 파일만 찾아 줘"를 명령으로 조립해 보세요.
문제 4. 어떤 명령의 출력에서 쓸 수 있는 속성(꼬리표) 목록을 알고 싶습니다. 어떤 명령을 뒤에 붙이면 되나요?
5. 모범 답안과 완료 기준
미션 해설
# 1
Get-Process | Where-Object {$_.WorkingSet -gt 524288000}
# 2
Get-Process | Where-Object {$_.ProcessName -eq "powershell"} | Measure-Object
# 3
Get-ChildItem C:\Windows\System32 | Sort-Object LastWriteTime -Descending | Select-Object -First 3
# 4
Get-Process | Sort-Object ProcessName | Select-Object -First 10
몇 개나 맞혔는지보다 중요한 건, 틀린 문제에서 어느 기계를 잘못 골랐는지 복습하는 겁니다.
연습문제 해답
문제 1 해답. 리눅스 파이프는 글자(텍스트)를 넘기지만, 파워쉘 파이프는 객체(속성/꼬리표가 붙은 물건)를 넘깁니다. 그래서 파워쉘은 화면 표시와 무관하게 속성 이름으로 정확하게 정렬·필터할 수 있습니다.
문제 2 해답. 파이프(벨트) 위를 지금 지나가는 항목 하나를 가리키는 대명사입니다. $_.Length는 "지금 지나가는 그 항목의 Length 속성"입니다.
문제 3 해답.
Get-ChildItem $HOME -File | Where-Object {$_.Length -eq 0}
(-File을 빼도 동작하지만, 폴더까지 섞여 나옵니다. 비교는 -eq — =가 아닙니다!)
문제 4 해답. | Get-Member를 붙입니다. 예: Get-ChildItem | Get-Member. Property로 표시된 줄들이 정렬·필터에 쓸 수 있는 속성 후보입니다.
완료 기준 체크리스트
- [ ] 파이프
|가 "왼쪽 결과를 오른쪽 재료로 넘긴다"는 걸 설명할 수 있다 - [ ] 파워쉘이 글자 대신 "객체(꼬리표 달린 물건)"를 넘긴다는 걸 안다
- [ ]
Get-Process | Sort-Object ... | Select-Object -First N조합을 만들 수 있다 - [ ]
Where-Object {$_ ... }껍데기를 외워서 쓸 수 있다 - [ ] 속성이 궁금할 때
Get-Member를 찾는 습관이 생겼다 - [ ] 미션 4문제를 스스로 조립해 봤다
6. 흔한 실수와 해결
벽 1. Where-Object가 하나도 통과시키지 않는다 (빈 결과)
원인 후보 셋: ① 조건의 숫자가 너무 크다 — 기준을 낮춰 보세요. ② 속성 이름 오타 — Get-Process | Get-Member로 정확한 철자를 확인. ③ 비교 대상이 글자인데 숫자처럼 비교 (또는 반대). 빈 결과는 고장이 아니라 "해당 없음"일 수 있다는 것도 기억하세요.
벽 2. {} 나 $_ 를 빼먹었다
Where-Object $_.CPU -gt 100처럼 중괄호 없이 치면 오류가 납니다. 이 명령만은 형태가 특이하니, 일단 Where-Object { $_.속성 비교 }라는 껍데기째로 외우세요. 안의 내용만 바꾸는 겁니다.
벽 3. = 를 썼다가 오류 (또는 이상한 결과)
파워쉘에서 =는 "대입"(변수에 넣기)이지 "같다 비교"가 아닙니다. 비교는 -eq, 크기는 -gt/-lt. 수학 기호를 쓰고 싶은 유혹이 오지만, 파워쉘의 전통입니다.
벽 4. 정렬이 숫자가 아니라 글자 순서로 된 것 같다
드물게, 속성이 글자(string)로 저장된 경우 "10"이 "9"보다 앞에 오는 식으로 정렬됩니다. Get-Process의 CPU/WorkingSet은 숫자라 이 문제가 없지만, 나중에 CSV 파일 등을 다룰 때 만나는 함정이니 기억해 두세요.
벽 5. 파이프 다음에 뭘 붙여야 할지 모르겠다
공식처럼 외우세요: "목록 얻고 → 가공하고 → 자른다." 그리고 헷갈리면 한 칸씩 치세요. Get-Process만 쳐 보고, 거기에 | Sort-Object ...를 붙여 보고, 또 | Select-Object ...를 붙여 보는 식으로. 한 칸씩 결과를 눈으로 확인하며 벨트를 늘리는 게 초보의 정석입니다.
7. 정리
오늘의 조립 부품
| 기계(명령) | 역할 | 예 |
|---|---|---|
Sort-Object 속성 -Descending |
정렬 (큰 것부터) | Sort-Object CPU -Descending |
Select-Object -First N |
앞 N개 자르기 | Select-Object -First 10 |
Where-Object {$_.속성 조건} |
조건 필터 | Where-Object {$_.CPU -gt 100} |
Get-Member |
속성 목록 조사 | Get-Process | Get-Member |
Measure-Object |
개수 세기 | ... | Measure-Object |
비교 연산자
-eq(같다) / -ne(다르다) / -gt(크다) / -lt(작다)
만능 뼈대
(목록 얻기) | (정렬 또는 필터) | (자르기)
명령어보다 중요한 감각
"문제를 컨베이어 벨트로 번역하라." "이상한 프로세스 찾아 줘"는 곧 "목록 얻고 → 조건으로 거르고 → 보기 좋게 자른다"입니다. 그리고 한 칸씩 붙여 가며 확인하는 것이 초보의 조립법입니다.
알아두면 좋은 것 하나: Select-Object는 -First N 말고도 Select-Object ProcessName, CPU처럼 보고 싶은 꼬리표(컬럼)만 골라서 출력하는 재주가 있습니다. Get-Process | Select-Object ProcessName, CPU -First 5를 쳐 보세요 — 보고서 만들 때 쓰는 기술입니다.
전부 체크되면 Step 3 완료입니다. 사이드바의 체크박스를 눌러 진도를 저장하세요.