어떤 수업을 찾고 있나요?

예: PowerShell, 네트워크, XSS, Step 138

전체 커리큘럼 둘러보기 →

PowerShell

Step 3. 파이프(|) — 명령을 조립하는 사고방식

Step 3예상 실습 시간 · 2~3시간

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

전제: Step 2 완료. 윈도우 파워쉘에서 진행합니다.

  • 준비물: 윈도우 PC, 파워쉘.
  • 안전: 오늘 수업 명령은 프로세스와 파일 정보를 읽습니다. 프로세스를 종료하거나 파일을 변경하지 않습니다. 접근할 수 없는 정보는 관리자 권한을 추가하지 말고 표시된 오류와 함께 기록하세요.
  • 주의: 오늘 나오는 문법 두 개({}와 $_)가 좀 낯섭니다. 지금 완벽히 이해하려 하지 말고, 통째로 따라 치며 감각부터 익히세요. 왜 그런지는 뒤에서 설명합니다.

오늘은 개념적으로 가장 중요한 날 중 하나입니다. 명령 하나하나는 도구일 뿐이고, 파이프는 그 도구들을 "조립"하는 방법입니다. 보안 조사의 대부분은 "이상하게 오래 도는 프로세스만 골라 줘", "수만 줄 로그에서 실패한 로그인만 뽑아 줘" 같은 문제 — 전부 "목록 → 필터 → 정렬 → 자르기"의 조립입니다. 이 조립 사고가 익숙해지면, 낯선 문제도 같은 뼈대로 풀리기 시작합니다.


1. 학습 목표

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

  • 파이프(|)로 명령의 출력을 다음 명령의 입력으로 넘긴다
  • Sort-Object, Select-Object -First N, Where-Object 세 기계를 조립한다
  • "○○한 것 상위 N개" 형태의 조합 명령을 스스로 설계한다
  • 모르는 명령의 속성(꼬리표)을 Get-Member로 조사한다

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

오늘의 도구 한눈에 보기

구분 내용
언어·환경 Windows PowerShell 5.1 / PowerShell 7 — 파이프(|) 연산자
오늘의 명령어 Sort-Object(정렬), Select-Object -First N(자르기), Where-Object(필터), Get-Member(속성 조사), Measure-Object(개수)
필요한 개념 객체(object)와 속성(property), $_와 {} 문법, 비교 연산자 -eq/-gt 등

공장을 상상해 보세요. 원재료가 컨베이어 벨트 위를 지나가고, 각 공정의 기계가 재료를 받아서 자기 일을 하고 다음 기계로 넘깁니다.

원재료 → [자르기] → [다듬기] → [포장] → 완성품

파워쉘의 파이프(|)가 바로 이 컨베이어 벨트입니다. 왼쪽 명령의 결과물이 벨트를 타고 오른쪽 명령의 재료가 됩니다.

2-1. 파워쉘 파이프의 비밀 — 글자가 아니라 물건이 지나간다

Linux의 파이프는 바이트 스트림을 전달하며 텍스트와 바이너리를 모두 담을 수 있습니다. 텍스트 출력은 뒤의 명령이 정해진 형식에 따라 해석합니다. 반면 이 수업의 PowerShell cmdlet 사이에서는 속성을 가진 객체가 전달됩니다.

파워쉘은 다릅니다. 벨트 위를 지나가는 게 글자가 아니라 객체(object) — "꼬리표가 달린 물건"입니다. 예를 들어 Get-Process가 넘기는 건 프로세스 하나하나인데, 각각에 이런 꼬리표(속성, property)가 붙어 있습니다:

프로세스 객체 하나
├── Name: "chrome"
├── CPU: 245.3
├── WorkingSet64: 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 시간(초). 현재 CPU 사용률(%)이나 시작 후 지난 시간과 다릅니다.
  • WS(K) — 작업 집합(물리 메모리에 올라온 페이지)의 크기를 KiB 단위로 표시한 값. PowerShell 7은 기본 표에서 WS(M)처럼 MiB로 표시할 수 있습니다. WorkingSet64 속성 자체는 바이트 단위입니다.
  • 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 사용률(%) 순위와 같지 않습니다. 위 표는 출력 형식을 설명하는 예시이며 실제 이름·개수·값은 실행 시점에 따라 달라집니다. CPU 값이 비어 있는 프로세스는 0초를 썼다고 단정하지 마세요. 권한이나 프로세스 종료 시점 때문에 값을 읽지 못할 수 있습니다.

예측해 보기: Get-Process | Sort-Object WorkingSet64 -Descending | Select-Object -First 5는 뭘 보여 줄까요? CPU 자리에 WorkingSet64이 들어갔습니다. 예측한 뒤 실행해 보세요.
(정답: 작업 집합 크기가 큰 상위 최대 5개 프로세스. 작업 관리자의 기본 메모리 열은 다른 지표일 수 있습니다. 꼬리표 이름만 바꿨을 뿐인데 완전히 다른 질문에 답했습니다 — 이게 조립의 힘입니다.)

3-4. 검수 기계 — Where-Object

이번엔 정렬이 아니라 필터입니다.

Get-Process | Where-Object {$_.CPU -gt 100}

CPU를 100초 넘게 쓴 프로세스만 남습니다. (없으면 아무것도 안 나올 수 있습니다 — 그건 "해당 없음"이라는 정상 결과입니다. 숫자를 50이나 10으로 낮춰 다시 쳐 보세요.)

이 명령은 벨트 위를 지나가는 프로세스 하나하나를 붙잡고 묻습니다: "너 CPU 100 넘어?" — 넘으면 통과, 아니면 폐기.

이번엔 이름으로 골라 봅시다:

Get-Process | Where-Object {$_.ProcessName -in "powershell", "pwsh"}

-in은 뒤에 나열한 값 중 하나와 일치하는지 검사합니다. Windows PowerShell의 프로세스 이름은 보통 powershell, PowerShell 7은 pwsh이므로 둘을 함께 고릅니다. 다른 호스트에서는 이름이 다를 수 있습니다. 현재 세션 자체를 확실히 확인하려면 다음을 실행하세요.

Get-Process -Id $PID | Select-Object ProcessName, Id, CPU, WorkingSet64

3-5. 꼬리표가 궁금하면 — Get-Member

"CPU 말고 또 어떤 꼬리표가 있지?" 궁금할 때의 명령:

Get-Process | Get-Member -MemberType Properties
   TypeName: System.Diagnostics.Process

Name        MemberType    Definition
----        ----------    ----------
...
CPU         ScriptProperty System.Object CPU {get=$this.TotalProcessorTime.TotalSeconds;}
Id          Property      int Id {get;}
ProcessName Property      string ProcessName {get;}
WorkingSet64 Property      long WorkingSet64 {get;}
...

-MemberType Properties는 일반 Property뿐 아니라 ScriptProperty, AliasProperty 등 여러 속성 종류를 포함합니다. 예를 들어 CPU는 ScriptProperty입니다. 표의 Definition 세부 표시는 버전에 따라 달라질 수 있습니다. 이 목록을 보고 "아, 이런 속성도 있구나" 하고 다음 조합의 아이디어를 얻으면 됩니다. 모르는 명령의 속성이 궁금할 때 Get-Member — 앞으로 수백 번 쓰게 될 조사 습관입니다.

3-6. 파일에도 같은 생각을 — 응용 조합

파이프는 프로세스 전용이 아닙니다. Get-ChildItem(파일 목록)도 똑같이 벨트에 올릴 수 있습니다:

Get-ChildItem $HOME -File | Sort-Object Length -Descending | Select-Object -First 5

읽는 법: 홈 바로 아래의 일반 파일을 고르고 → Length(바이트) 내림차순 → 최대 5개를 출력합니다. -File은 폴더를 제외합니다. 하위 폴더를 재귀적으로 검색하거나 폴더 전체의 용량을 계산하는 명령은 아닙니다. 기본적으로 숨김 파일도 제외됩니다.

지금까지의 패턴을 정리하면:

(목록 얻기) | (가공: 정렬/필터) | (자르기)

이 뼈대에 재료와 조건만 갈아 끼우면 되는 겁니다.


4. 미션과 연습문제

미션 — 조립 설계사

다음 질문들에 답하는 명령을 스스로 조립해 보세요. 정답은 5번 섹션에 있지만, 먼저 만들어 보고 실행해 본 뒤 비교하세요.

  1. "메모리(WorkingSet64)를 500MiB(=524288000바이트, PowerShell의 500MB 값) 넘게 쓰는 프로세스만 보여 줘"
  2. "이름이 powershell 또는 pwsh인 프로세스가 지금 몇 개인지 보여 줘" (힌트: 필터 뒤에 | Measure-Object를 붙이면 개수를 세어 줍니다)
  3. "Windows의 System32 폴더 바로 아래에서 가장 최근에 수정된 일반 파일 최대 3개를 보여 줘" (힌트: 수정 시각 꼬리표는 LastWriteTime)
  4. "프로세스를 이름순(가나다)으로 정렬해서 앞 10개만 보여 줘" (힌트: 이번엔 -Descending이 필요할까요?)

연습문제

문제 1. 파워쉘의 파이프가 리눅스 파이프와 다른 점 하나를 설명하세요.

문제 2. Where-Object {$_.Length -gt 1000000}에서 $_는 무엇을 가리키나요?

문제 3. "내 홈 폴더에서 크기가 0인 파일만 찾아 줘"를 명령으로 조립해 보세요.

문제 4. 어떤 명령의 출력에서 쓸 수 있는 속성(꼬리표) 목록을 알고 싶습니다. 어떤 명령을 뒤에 붙이면 되나요?


해설과 완료 기준 · 펼치기/접기

5. 모범 답안과 완료 기준

미션 해설

# 1
Get-Process | Where-Object {$_.WorkingSet64 -gt 524288000}
# 2
Get-Process | Where-Object {$_.ProcessName -in "powershell", "pwsh"} | Measure-Object
# 3
Get-ChildItem "$env:WINDIR\System32" -File | Sort-Object LastWriteTime -Descending | Select-Object -First 3
# 4
Get-Process | Sort-Object ProcessName | Select-Object -First 10

몇 개나 맞혔는지보다 중요한 건, 틀린 문제에서 어느 기계를 잘못 골랐는지 복습하는 겁니다.

연습문제 해답

문제 1 해답. Linux 파이프는 바이트 스트림을 전달하며 텍스트나 바이너리를 담을 수 있습니다. 이 예제의 PowerShell cmdlet 파이프는 속성을 가진 객체를 전달하므로 열의 표시 위치 대신 속성 이름으로 정렬·필터합니다. PowerShell에서 외부 실행 프로그램을 연결할 때의 동작은 별도로 구분해야 합니다.

문제 2 해답. 파이프(벨트) 위를 지금 지나가는 항목 하나를 가리키는 대명사입니다. $_.Length는 "지금 지나가는 그 항목의 Length 속성"입니다.

문제 3 해답.

Get-ChildItem $HOME -File | Where-Object {$_.Length -eq 0}

-File로 파일만 입력해야 Length가 파일 크기라는 뜻이 분명해집니다. 이 명령은 홈 바로 아래의 보이는 파일만 검사합니다. 해당 파일이 없으면 결과는 비어 있습니다. 비교는 -eq입니다.

문제 4 해답. | Get-Member를 붙입니다. 예: Get-ChildItem | Get-Member. 속성만 모아서 보려면 Get-Member -MemberType Properties를 사용합니다. 일반 Property 외에 ScriptProperty나 AliasProperty도 포함됩니다.

완료 기준 체크리스트

  • [ ] 파이프 |가 "왼쪽 결과를 오른쪽 재료로 넘긴다"는 걸 설명할 수 있다
  • [ ] 이 수업의 cmdlet 파이프가 속성을 가진 객체를 넘긴다는 걸 안다
  • [ ] Get-Process | Sort-Object ... | Select-Object -First N 조합을 만들 수 있다
  • [ ] Where-Object {$_ ... } 껍데기를 외워서 쓸 수 있다
  • [ ] 속성이 궁금할 때 Get-Member를 찾는 습관이 생겼다
  • [ ] 미션 4문제를 스스로 조립해 봤다

6. 흔한 실수와 해결

벽 1. Where-Object가 하나도 통과시키지 않는다 (빈 결과)

원인 후보 셋: ① 조건의 숫자가 너무 크다 — 기준을 낮춰 보세요. ② 속성 이름 오타 — Get-Process | Get-Member -MemberType Properties로 정확한 철자를 확인. ③ 비교 대상이 글자인데 숫자처럼 비교 (또는 반대). 빈 결과는 고장이 아니라 "해당 없음"일 수 있다는 것도 기억하세요.

벽 2. {} 나 $_ 를 빼먹었다

이 수업의 스크립트 블록 형식에서는 중괄호와 $_를 함께 씁니다. Where-Object CPU -gt 100 같은 간단한 비교 형식도 있지만, 두 형식을 섞지 마세요. 이 명령만은 형태가 특이하니, 일단 Where-Object { $_.속성 비교 }라는 껍데기째로 외우세요. 안의 내용만 바꾸는 겁니다.

벽 3. = 를 썼다가 오류 (또는 이상한 결과)

파워쉘에서 =는 "대입"(변수에 넣기)이지 "같다 비교"가 아닙니다. 비교는 -eq, 크기는 -gt/-lt. 수학 기호를 쓰고 싶은 유혹이 오지만, 파워쉘의 전통입니다.

벽 4. 정렬이 숫자가 아니라 글자 순서로 된 것 같다

드물게, 속성이 글자(string)로 저장된 경우 "10"이 "9"보다 앞에 오는 식으로 정렬됩니다. Get-Process의 CPU/WorkingSet64은 숫자라 이 문제가 없지만, 나중에 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 -MemberType Properties
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 완료입니다.


실습 검증 기록

2026-09-10 · Windows 11, Windows PowerShell 5.1.26100.9444와 PowerShell 7.6.5에서 프로세스 조회·누적 CPU 정렬·필터·Get-Member·파일 정렬 및 미션을 실행했습니다. 실행 중인 프로세스의 값은 계속 변하므로 순위 숫자를 정답으로 고정하지 않고, 별도 샘플 객체와 새 테스트 파일로 조건·순서·파일 제외 여부를 대조했습니다. 프로세스 종료나 시스템 파일 변경은 수행하지 않았습니다.

참고: Microsoft Get-Process · Get-Member and property types · Linux pipe

한 단계 더 가까이

수업을 마쳤나요?

본문의 완료 기준을 확인한 뒤 직접 표시하세요.

화면이나 링크에 문제가 있나요? 알려주세요.
다음 수업