CMD vs PowerShell vs Bash — 대응 명령어 비교

같은 작업을 명령 프롬프트, PowerShell, bash에서 나란히 비교: 파일, grep, 환경 변수, 프로세스, 네트워크, 서비스, 스크립팅.

CMD vs PowerShell vs Bash · freetoolsforweb.com/tools/cmd-vs-powershell-vs-bash · 2026-10-18 확인

마지막 확인: 2026-10-18, Microsoft Learn의 PowerShell 7.6 및 Windows PowerShell 5.1 참조, Windows 명령 참조, GNU Bash 5.2 매뉴얼 기준.

9개 그룹의 작업 107개, 그리고 별칭·따옴표·정책 안내

파일과 폴더

작업CMD(명령 프롬프트)PowerShellBash(Linux/macOS)
파일 목록 보기 #
PowerShell 별칭: gci, dir, Windows에서는 ls.
dir
Get-ChildItem
ls -l
숨김 파일 포함 목록 #
dir /a
Get-ChildItem -Force
ls -la
모든 파일을 재귀적으로 나열 #
dir /s /b
Get-ChildItem -Recurse -File
find . -type f
현재 디렉터리 표시 #
CMD에서 인수 없이 cd를 실행하면 현재 디렉터리가 출력됩니다. PowerShell 별칭: pwd, gl. $PWD 변수도 있습니다.
cd
Get-Location
pwd
디렉터리 이동 #
CMD에서 폴더와 함께 드라이브도 바꾸려면 /d가 필요합니다. PowerShell 별칭: cd, sl, chdir.
cd /d D:\work
Set-Location D:\work
cd /home/me/work
홈 디렉터리로 이동 #
cd %USERPROFILE%
Set-Location ~
cd ~
폴더 만들기(상위 폴더 포함) #
CMD의 mkdir는 명령 확장이 켜져 있으면(기본값) 중간 폴더도 만듭니다. PowerShell에서 mkdir는 New-Item -ItemType Directory를 감싼 함수입니다.
mkdir a\b\c
New-Item -ItemType Directory -Path a\b\c
mkdir -p a/b/c
빈 파일 만들기 #
type nul > file.txt
New-Item file.txt
touch file.txt
파일 복사 #
copy src.txt dst.txt
Copy-Item src.txt dst.txt
cp src.txt dst.txt
폴더를 재귀적으로 복사 #
xcopy src dst /E /I도 됩니다. robocopy는 공식 지원 도구로, 이어받기와 재시도가 가능합니다.
robocopy src dst /E
Copy-Item src dst -Recurse
cp -r src dst
폴더를 똑같이 미러링 위험 #
위험: 둘 다 원본에 없는 파일을 대상에서 삭제합니다. 두 경로를 바꿔 쓰면 남기려던 폴더가 지워집니다. robocopy /L과 rsync -n으로 미리 시험해 볼 수 있습니다.
robocopy src dst /MIR
(no cmdlet; call robocopy)
rsync -a --delete src/ dst/
파일 이동 #
move a.txt archive\
Move-Item a.txt archive\
mv a.txt archive/
파일 이름 바꾸기 #
ren old.txt new.txt
Rename-Item old.txt new.txt
mv old.txt new.txt
파일 삭제 #
del file.txt
Remove-Item file.txt
rm file.txt
폴더와 내용 삭제 위험 #
위험: /q, -Force, -f를 쓰면 휴지통도 확인 메시지도 없습니다. 먼저 경로를 확인하세요. PowerShell에서는 -WhatIf를 붙이면 무엇이 삭제될지 볼 수 있습니다.
rmdir /s /q folder
Remove-Item folder -Recurse -Force
rm -rf folder
파일 권한 변경 #
Windows는 rwx 비트가 아니라 ACL을 씁니다. 보통 Set-Acl보다 icacls가 쉽습니다.
icacls file.txt /grant alice:F
Get-Acl / Set-Acl
chmod 644 file.txt
파일 체크섬(SHA-256) #
Get-FileHash는 기본으로 SHA256을 씁니다. 다른 알고리즘은 -Algorithm MD5 또는 SHA1. macOS: shasum -a 256.
certutil -hashfile file.iso SHA256
Get-FileHash file.iso
sha256sum file.iso
zip 파일 만들기 #
tar.exe(bsdtar)는 Windows 10 1803 이상에 포함되어 있습니다. -a는 .zip 확장자로 형식을 고릅니다.
tar -a -c -f out.zip folder
Compress-Archive -Path folder -DestinationPath out.zip
zip -r out.zip folder
zip 파일 압축 풀기 #
tar -xf out.zip
Expand-Archive out.zip -DestinationPath dest
unzip out.zip -d dest

파일 내용 읽기와 쓰기

작업CMD(명령 프롬프트)PowerShellBash(Linux/macOS)
파일 내용 출력 #
PowerShell 별칭: gc, type, Windows에서는 cat.
type file.txt
Get-Content file.txt
cat file.txt
파일을 페이지 단위로 보기 #
more file.txt
Get-Content file.txt | Out-Host -Paging
less file.txt
마지막 10줄 #내장 명령어 없음
Get-Content file.txt -Tail 10
tail -n 10 file.txt
로그 파일 실시간으로 보기 #내장 명령어 없음
Get-Content app.log -Tail 10 -Wait
tail -f app.log
파일에 텍스트 쓰기(덮어쓰기) #
CMD에서는 > 앞의 공백도 파일에 들어갑니다. Windows PowerShell 5.1에서 >는 UTF-16 LE로, PowerShell 7은 BOM 없는 UTF-8로 씁니다. Set-Content -Encoding utf8은 양쪽 모두에서 인코딩을 명시합니다.
echo hello> file.txt
'hello' | Set-Content file.txt
echo hello > file.txt
파일에 텍스트 덧붙이기 #
echo hello>> file.txt
Add-Content file.txt 'hello'
echo hello >> file.txt
줄 수 세기 #
find /c /v "" file.txt
(Get-Content file.txt).Count
wc -l file.txt
두 파일 비교 #
Windows의 PowerShell에서 diff는 텍스트 비교가 아니라 Compare-Object의 별칭입니다.
fc a.txt b.txt
Compare-Object (Get-Content a.txt) (Get-Content b.txt)
diff a.txt b.txt
줄 정렬 #
sort file.txt
Get-Content file.txt | Sort-Object
sort file.txt
중복 줄 제거 #내장 명령어 없음
Get-Content file.txt | Sort-Object -Unique
sort -u file.txt
파일의 텍스트 바꾸기 #
-replace는 정규식을 씁니다. 괄호는 Set-Content가 파일을 다시 열기 전에 파일 전체를 읽어 둡니다. macOS sed는 -i ''가 필요합니다.
내장 명령어 없음
(Get-Content f.txt) -replace 'old','new' | Set-Content f.txt
sed -i 's/old/new/g' f.txt

환경 변수

작업CMD(명령 프롬프트)PowerShellBash(Linux/macOS)
모든 변수 나열 #
set
Get-ChildItem Env:
env
변수 읽기 #
echo %PATH%
$env:PATH
echo "$PATH"
현재 세션에서 설정 #
CMD: = 앞뒤에 공백을 넣지 마세요. 공백이 이름과 값에 포함됩니다.
set MY_VAR=hello
$env:MY_VAR = 'hello'
export MY_VAR=hello
영구 설정(내 사용자 계정) #
setx와 SetEnvironmentVariable은 현재 창이 아니라 새로 여는 창에만 적용됩니다. setx는 1024자보다 긴 값을 잘라 내므로 PATH 편집에 쓰지 마세요.
setx MY_VAR hello
[Environment]::SetEnvironmentVariable('MY_VAR','hello','User')
echo 'export MY_VAR=hello' >> ~/.bashrc
변수 삭제 #
set MY_VAR=
Remove-Item Env:MY_VAR
unset MY_VAR
PATH에 폴더 추가(세션) #
Linux/macOS의 PowerShell 7은 PATH를 ; 대신 :로 구분합니다. [IO.Path]::PathSeparator가 올바른 구분자를 알려 줍니다.
set PATH=%PATH%;C:\tools
$env:PATH += ';C:\tools'
export PATH="$PATH:/opt/tools"
명령어 하나에만 설정 #내장 명령어 없음
$env:DEBUG = '1'; ./app; Remove-Item Env:DEBUG
DEBUG=1 ./app

프로세스

작업CMD(명령 프롬프트)PowerShellBash(Linux/macOS)
프로세스 목록 #
tasklist
Get-Process
ps aux
이름으로 프로세스 찾기 #
tasklist /FI "IMAGENAME eq chrome.exe"
Get-Process chrome
pgrep -a chrome
프로세스 ID로 종료 #
/F나 -Force가 없으면 Windows는 프로세스에 종료를 요청합니다. kill은 SIGTERM을 보내고, kill -9는 강제 종료합니다.
taskkill /PID 1234 /F
Stop-Process -Id 1234 -Force
kill 1234
이름으로 종료 #
taskkill /IM notepad.exe /F
Stop-Process -Name notepad
pkill notepad
프로그램 실행 #
start의 빈 ""는 창 제목입니다. 이것이 없으면 따옴표로 묶은 프로그램 경로가 제목으로 인식됩니다.
start "" notepad.exe
Start-Process notepad
gedit &
관리자/root 권한으로 실행 #
Windows PowerShell 5.1은 pwsh 대신 powershell을 쓰세요. Windows 11 24H2 이상에서는 설정에서 내장 sudo 명령어를 켤 수도 있습니다.
runas /user:Administrator cmd
Start-Process pwsh -Verb RunAs
sudo command
CPU 사용량 상위 10개 프로세스 #
Get-Process의 CPU는 현재 %가 아니라 시작 이후 누적 프로세서 시간(초)입니다.
내장 명령어 없음
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10
ps aux --sort=-%cpu | head
포트를 사용 중인 프로세스 #
Get-NetTCPConnection은 Windows 전용입니다. netstat -ano의 마지막 열이 PID이며, tasklist /FI "PID eq 1234"로 조회합니다.
netstat -ano | findstr :8080
Get-NetTCPConnection -LocalPort 8080
sudo ss -ltnp | grep :8080

네트워크

작업CMD(명령 프롬프트)PowerShellBash(Linux/macOS)
IP 주소 표시 #
Get-NetIPAddress 등 Net* cmdlet은 Windows 전용입니다(NetTCPIP 모듈).
ipconfig /all
Get-NetIPAddress
ip addr
호스트에 ping #
Windows ping은 기본으로 4번 후 멈추고, Linux ping은 Ctrl+C를 누를 때까지 계속됩니다.
ping -n 4 example.com
Test-Connection example.com -Count 4
ping -c 4 example.com
TCP 포트 테스트 #
Test-NetConnection은 Windows 전용입니다. PowerShell 7에서는 Test-Connection example.com -TcpPort 443.
내장 명령어 없음
Test-NetConnection example.com -Port 443
nc -zv example.com 443
DNS 조회 #
Resolve-DnsName은 Windows 전용이며, nslookup은 세 셸 모두에 있습니다.
nslookup example.com
Resolve-DnsName example.com
dig example.com
경로 추적 #
tracert example.com
Test-NetConnection example.com -TraceRoute
traceroute example.com
DNS 캐시 비우기 #
bash 줄은 systemd-resolved를 쓰는 시스템에 해당합니다.
ipconfig /flushdns
Clear-DnsClientCache
sudo resolvectl flush-caches
HTTP GET(API 호출) #
Invoke-RestMethod는 JSON을 객체로 파싱하고, Invoke-WebRequest는 상태, 헤더, 원본 내용을 반환합니다.
curl.exe https://api.example.com/items
Invoke-RestMethod https://api.example.com/items
curl https://api.example.com/items
파일 다운로드 #
curl.exe는 Windows 10 1803 이상에 포함되어 있습니다. Windows PowerShell 5.1에서 Internet Explorer가 설정되지 않은 컴퓨터라면 Invoke-WebRequest에 -UseBasicParsing을 붙이세요.
curl.exe -L -o file.zip https://example.com/file.zip
Invoke-WebRequest https://example.com/file.zip -OutFile file.zip
curl -LO https://example.com/file.zip
JSON POST #
CMD에는 작은따옴표가 없으므로 curl.exe에 넘기는 안쪽 큰따옴표는 백슬래시로 이스케이프합니다.
curl.exe -X POST -H "Content-Type: application/json" -d "{\"a\":1}" https://api.example.com
Invoke-RestMethod https://api.example.com -Method Post -ContentType 'application/json' -Body (@{a=1} | ConvertTo-Json)
curl -X POST -H 'Content-Type: application/json' -d '{"a":1}' https://api.example.com
서버에 SSH 접속 #
OpenSSH 클라이언트는 Windows 10 1809 이상과 Windows 11에 기본 설치되어 있습니다.
ssh user@host
ssh user@host
ssh user@host

서비스와 시스템

작업CMD(명령 프롬프트)PowerShellBash(Linux/macOS)
서비스 목록 #
Windows PowerShell 5.1에서 sc는 Set-Content의 별칭이므로 sc.exe를 입력하세요. PowerShell 6 이상에서는 이 별칭이 제거되었습니다.
sc query
Get-Service
systemctl list-units --type=service
서비스 상태 #
sc query Spooler
Get-Service Spooler
systemctl status nginx
서비스 시작 / 중지 #
net start Spooler net stop Spooler
Start-Service Spooler Stop-Service Spooler
sudo systemctl start nginx sudo systemctl stop nginx
서비스 다시 시작 #
net stop Spooler && net start Spooler
Restart-Service Spooler
sudo systemctl restart nginx
부팅 시 자동 시작 #
sc.exe는 start= 뒤에 공백이 있어야 하고, 앞에는 공백이 없어야 합니다.
sc config Spooler start= auto
Set-Service Spooler -StartupType Automatic
sudo systemctl enable nginx
OS와 하드웨어 정보 #
systeminfo
Get-ComputerInfo
uname -a; cat /etc/os-release
컴퓨터 이름 #
hostname
$env:COMPUTERNAME
hostname
현재 사용자 #
Windows의 PowerShell에서는 $env:USERNAME도 됩니다.
whoami
whoami
whoami
디스크 여유 공간 #
이전 Windows 버전에서는 fsutil에 관리자 권한 프롬프트가 필요합니다. Get-Volume(Windows 전용)도 크기와 여유 공간을 보여 줍니다.
fsutil volume diskfree C:
Get-PSDrive -PSProvider FileSystem
df -h
가동 시간 #
Get-Uptime은 PowerShell 6 이상입니다. 5.1에서는 (Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime.
systeminfo | find "Boot Time"
Get-Uptime
uptime
지금 재부팅 #
shutdown /r /t 0
Restart-Computer
sudo reboot
화면 지우기 #
Windows의 PowerShell에서는 cls와 clear 둘 다 작동합니다.
cls
Clear-Host
clear
명령어 기록 #
Get-History는 현재 세션만 다룹니다. PSReadLine은 이전 기록을 (Get-PSReadLineOption).HistorySavePath 파일에 보관하며, 세 셸 모두 Ctrl+R로 기록을 검색합니다.
doskey /history
Get-History
history
명령어 도움말 #
전체 PowerShell 도움말을 받으려면 Update-Help를 한 번 실행하세요(5.1에서는 관리자 권한 필요).
dir /?
Get-Help Get-ChildItem -Examples
man ls
현재 날짜 #
%date%는 컴퓨터의 지역 형식을 따르므로, 이를 파싱하는 스크립트는 로캘이 바뀌면 깨집니다.
echo %date%
Get-Date -Format 'yyyy-MM-dd'
date +%F
5초 대기 #
timeout /t 5
Start-Sleep -Seconds 5
sleep 5
출력을 클립보드에 복사 #
macOS: pbcopy. Wayland: wl-copy. PowerShell에서는 Get-Clipboard로 다시 읽습니다.
dir | clip
Get-ChildItem -Name | Set-Clipboard
ls | xclip -selection clipboard

객체 파이프 vs 텍스트 파이프

작업CMD(명령 프롬프트)PowerShellBash(Linux/macOS)
열 / 속성 고르기 #
PowerShell은 .NET 객체를 파이프로 넘기므로, 열을 파싱하는 대신 이름으로 속성을 고릅니다.
내장 명령어 없음
Get-Process | Select-Object Name, Id, WS
ps -eo comm,pid,rss
값으로 행 필터링 #
PowerShell은 500MB, 1GB 같은 리터럴을 이해합니다. awk는 6번째 열(RSS, KB 단위)을 비교합니다.
tasklist | findstr chrome
Get-Process | Where-Object WS -gt 500MB
ps aux | awk '$6 > 500000'
항목마다 작업 실행 #
$_(또는 $PSItem)는 현재 객체입니다. .bat 파일에서는 %f 대신 %%f로 쓰세요.
for %f in (*.txt) do echo %f
Get-ChildItem *.txt | ForEach-Object { $_.Name }
for f in *.txt; do echo "$f"; done
객체에 어떤 속성이 있는지 보기 #
PowerShell에서 가장 유용한 탐색 명령어입니다. | Format-List *도 써 보세요.
내장 명령어 없음
Get-Process | Get-Member
내장 명령어 없음
JSON 파싱 #
-Raw를 써야 파일이 문자열 하나로 들어옵니다. 출력할 때는 ConvertTo-Json -Depth 10(기본 깊이는 2).
내장 명령어 없음
Get-Content data.json -Raw | ConvertFrom-Json
jq . data.json
CSV 읽고 필터링 #
Import-Csv 값은 문자열이므로, 숫자 비교에는 [int]로 변환하세요.
내장 명령어 없음
Import-Csv users.csv | Where-Object { [int]$_.Age -gt 30 }
awk -F, 'NR>1 && $3 > 30' users.csv
CSV로 내보내기 #
-NoTypeInformation은 PowerShell 6 이상에서는 기본값이지만 5.1에서는 필요합니다.
내장 명령어 없음
Get-Process | Export-Csv procs.csv -NoTypeInformation
ps -eo pid,comm --no-headers | awk '{print $1","$2}' > procs.csv
개수, 합계, 평균 #
find /c /v "" file.txt
Get-ChildItem -File | Measure-Object Length -Sum -Average
ls -l | awk '{s+=$5} END {print s}'

스크립트: 변수, 조건문, 반복문, 함수

작업CMD(명령 프롬프트)PowerShellBash(Linux/macOS)
변수 설정 #
bash: = 앞뒤에 공백을 넣지 마세요(name = Ada는 name이라는 명령어를 실행합니다).
set name=Ada
$name = 'Ada'
name=Ada
문자열에서 변수 사용 #
echo Hello %name%
"Hello $name"
echo "Hello $name"
산술 연산 #
CMD와 bash는 정수 연산만 하고, PowerShell은 .NET 숫자를 씁니다.
set /a n=5*3
$n = 5 * 3
n=$((5 * 3))
사용자 입력 받기 #
set /p name=Name:
$name = Read-Host 'Name'
read -rp 'Name: ' name
스크립트 인수 #
.bat 파일에서 %~1은 바깥 따옴표를 제거합니다. PowerShell 스크립트는 param() 블록으로 이름과 형식이 있는 매개변수를 받습니다.
%1 %2 … %*
$args[0] or param($Path)
$1 $2 … "$@"
문자열 if / else #
PowerShell 비교 연산자는 단어입니다: -eq -ne -gt -lt -like -match. =와 >는 대입과 리디렉션입니다.
if "%a%"=="yes" (echo on) else (echo off)
if ($a -eq 'yes') { 'on' } else { 'off' }
if [ "$a" = "yes" ]; then echo on; else echo off; fi
숫자 비교 #
CMD: EQU NEQ LSS LEQ GTR GEQ.
if %n% GTR 5 echo big
if ($n -gt 5) { 'big' }
if (( n > 5 )); then echo big; fi
파일이 있으면 #
if exist file.txt echo yes
if (Test-Path file.txt) { 'yes' }
if [ -f file.txt ]; then echo yes; fi
마지막 프로그램의 종료 코드 #
PowerShell에서 $?는 마지막 명령어의 $true/$false이고, $LASTEXITCODE는 마지막 네이티브 프로그램의 숫자 코드입니다.
echo %ERRORLEVEL%
$LASTEXITCODE
echo $?
성공 / 실패 시에만 다음 명령어 실행 #
&&와 || 파이프라인 체인 연산자는 PowerShell 7.0에서 추가되었고, Windows PowerShell 5.1은 이를 거부합니다.
build && deploy build || echo failed
build && deploy (PowerShell 7+) build; if ($?) { deploy } (5.1)
build && deploy build || echo failed
목록 반복 #
for %i in (a b c) do echo %i
foreach ($x in 'a','b','c') { $x }
for x in a b c; do echo "$x"; done
1부터 5까지 반복 #
for /l %i in (1,1,5) do echo %i
foreach ($i in 1..5) { $i }
for i in {1..5}; do echo "$i"; done
파일의 줄마다 반복 #
for /f "usebackq delims=" %l in ("file.txt") do echo %l
foreach ($line in Get-Content file.txt) { $line }
while IFS= read -r line; do echo "$line"; done < file.txt
while 반복문 #
CMD에는 while이 없습니다. .bat 파일에서 레이블과 goto를 쓰세요.
:loop set /a i+=1 if %i% lss 5 goto loop
while ($i -lt 5) { $i++ }
while [ "$i" -lt 5 ]; do i=$((i+1)); done
함수 정의와 호출 #
PowerShell 함수는 명령어처럼 호출합니다: Greet("Ada")가 아니라 Greet Ada.
call :greet Ada goto :eof :greet echo Hello %~1 exit /b
function Greet($Name) { "Hello $Name" } Greet Ada
greet() { echo "Hello $1"; } greet Ada
명령어 출력을 변수에 저장 #
for /f "delims=" %i in ('hostname') do set h=%i
$h = hostname
h=$(hostname)
출력 버리기 #
command >nul 2>&1
command *> $null
command >/dev/null 2>&1
주석 #
rem comment :: comment
# comment <# block #>
# comment
스크립트 파일과 실행 방법 #
PowerShell은 .\ 없이는 현재 폴더의 스크립트를 실행하지 않으며, 아예 차단할 수도 있습니다. 아래 실행 정책을 참고하세요.
script.bat
.\script.ps1
chmod +x script.sh && ./script.sh

PowerShell 별칭 함정: ls, curl, wget, sc, where

PowerShell에는 Unix나 CMD 명령어처럼 보이지만 매개변수가 다른 cmdlet을 실행하는 별칭이 들어 있습니다. 어떤 별칭이 있는지는 에디션과 운영체제에 따라 다릅니다. Get-Alias name를 실행하면 현재 세션에서 그 이름이 무엇을 가리키는지 볼 수 있습니다.

입력한 명령Windows PowerShell 5.1Windows의 PowerShell 7Linux/macOS의 PowerShell 7
curl
5.1에서 진짜 curl을 쓰려면 curl.exe를 입력하세요. curl의 플래그(-X, -H, -d)는 Invoke-WebRequest에서 의미가 없습니다.
Invoke-WebRequest별칭 아님: curl.exe 실행네이티브 curl
wget
Invoke-WebRequest url -OutFile name 또는 curl.exe -LO url을 쓰세요.
Invoke-WebRequest별칭 아님(Windows에는 기본으로 wget 없음)설치되어 있으면 네이티브 wget
ls, dir
Windows에서는 ls -la 같은 플래그가 실패합니다. Get-ChildItem -Force를 쓰세요.
Get-ChildItemGet-ChildItemls = 네이티브 ls, dir = Get-ChildItem
cat, typeGet-ContentGet-Contentcat = 네이티브 cat, type = Get-Content
cp, mv, rm, rmdir
rm -rf는 올바른 PowerShell 구문이 아닙니다. Remove-Item -Recurse -Force를 쓰세요.
Copy-Item, Move-Item, Remove-Item같은 cmdlet네이티브 명령어
ps, killGet-Process, Stop-Process같은 cmdlet네이티브 명령어
sort, tee, diff
Windows의 PowerShell에서 diff a b는 두 파일의 줄이 아니라 객체를 비교합니다.
Sort-Object, Tee-Object, Compare-Object같은 cmdlet네이티브 명령어
sc
5.1에서 sc query는 query라는 파일을 만듭니다. sc.exe를 쓰세요.
Set-Content별칭 아님: sc.exe 실행해당 없음
where
프로그램을 찾으려면 where.exe나 Get-Command를 쓰세요.
Where-ObjectWhere-ObjectWhere-Object
echo
echo -n은 줄바꿈을 없애지 않습니다. Write-Host -NoNewline을 쓰세요.
Write-OutputWrite-OutputWrite-Output
manhelphelp네이티브 man

따옴표와 이스케이프

“한 셸에서는 되는데 다른 셸에서는 안 되는” 버그는 대부분 따옴표 문제입니다. 이스케이프 문자는 셸마다 다릅니다.

항목CMDPowerShellBash
리터럴 문자열(확장 없음)리터럴 따옴표 없음: "…" 안에서도 %VAR%가 확장됨'Cost: $5''Cost: $5'
변수가 들어간 문자열"Hello %name%""Hello $name, it is $(Get-Date -Format t)""Hello $name, it is $(date +%R)"
이스케이프 문자^ (예: ^& ^| ^>)` 백틱 (예: `n 줄바꿈, `t 탭, `$ 리터럴 $)\ 백슬래시
따옴표로 묶은 문자열 안의 따옴표많은 프로그램에서 "…" 안에 ""; 프로그램마다 다름'It''s' 또는 "Say `"hi`""'It'\''s' 또는 "Say \"hi\""
줄 이어 쓰기줄 끝에 ^줄 끝에 ` (또는 | 로 줄 끝내기)줄 끝에 \
스크립트의 리터럴 % 또는 $.bat 파일에서 %%작은따옴표 안의 '$' 또는 `$작은따옴표 안의 '$' 또는 \$
네이티브 프로그램에 인수를 그대로 전달(필요 없음)--%는 PowerShell이 나머지 줄을 파싱하지 않게 함(필요 없음)

네이티브 프로그램(curl.exe, git, node)에 따옴표를 넘기는 방식이 PowerShell 7.3에서 바뀌었습니다. 이제 큰따옴표가 들어간 인수는 쓴 그대로 전달되며, $PSNativeCommandArgumentPassing로 제어합니다. Windows PowerShell 5.1에서는 같은 JSON 본문의 안쪽 따옴표를 두 번 이스케이프해야 하는 경우가 많아, 많은 사람이 Invoke-RestMethod과 ConvertTo-Json으로 바꿔 씁니다.

실행 정책: “이 시스템에서 스크립트를 실행할 수 없으므로…”

실행 정책이 Restricted이면 PowerShell은 .ps1 파일을 실행하지 않습니다. Windows 클라이언트 에디션(Windows 10, 11)의 Windows PowerShell에서는 이것이 사실상 기본값입니다. Windows Server의 기본값은 RemoteSigned로, 로컬 스크립트는 실행되지만 다운로드한 스크립트는 서명되었거나 차단 해제되어야 합니다. Linux와 macOS에서는 정책이 Unrestricted이며 바꿀 수 없습니다.

  • Get-ExecutionPolicy -List는 모든 범위의 정책을 보여 줍니다. 정의된 범위 중 가장 구체적인 것이 우선합니다(그룹 정책은 모든 것보다 우선).
  • Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser를 쓰면 관리자 권한 없이 내 스크립트를 실행할 수 있습니다.
  • Unblock-File .\script.ps1는 신뢰하는 스크립트에서 “인터넷에서 다운로드됨” 표시를 지웁니다.
  • pwsh -ExecutionPolicy Bypass -File script.ps1(5.1에서는 powershell)는 한 세션에만 정책을 적용합니다.

실행 정책은 실수로 스크립트를 실행하는 것을 막는 안전장치일 뿐 보안 경계가 아닙니다. 누구든 스크립트 내용을 콘솔에 붙여 넣을 수 있습니다.

Windows PowerShell 5.1 vs PowerShell 7

  • 서로 다른 두 프로그램: powershell.exe는 Windows에 내장된 Windows PowerShell 5.1로, 더 이상 새 기능이 추가되지 않습니다. pwsh는 별도로 설치하는 크로스 플랫폼 PowerShell 7이며, 둘을 함께 설치해 쓸 수 있습니다.
  • 7.0에서 추가된 연산자: 명령어 사이의 &&와 ||, 삼항 연산자 $a ? 'yes' : 'no', null 병합 ?? / ??=.
  • 파일 인코딩: 5.1의 >와 Out-File는 UTF-16 LE로 쓰고, Set-Content는 ANSI 코드 페이지를 씁니다. PowerShell 7은 어디서나 BOM 없는 UTF-8로 쓰며, 이는 Git, Linux 도구, 대부분의 편집기가 기대하는 형식입니다.
  • 별칭: 7은 Windows에서 curl, wget, sc를 없앴고, Linux/macOS에서는 ls, cp, rm, cat, ps 등을 네이티브 명령어에 맡깁니다(위 표 참고).
  • 모듈 차이: Get-NetIPAddress, Test-NetConnection, Resolve-DnsName 같은 Windows 전용 cmdlet은 Windows의 PowerShell 7에서는 작동하지만 Linux나 macOS에는 없습니다.

Windows에서 bash 실행하기: WSL

Linux용 Windows 하위 시스템(WSL)은 실제 Linux 배포판을 Windows와 나란히 실행하므로, 오른쪽 열의 bash 명령어가 모두 쓴 그대로 작동합니다. 관리자 권한 프롬프트에서 wsl --install을 실행하면 기본으로 Ubuntu와 함께 설치됩니다(Windows 10 버전 2004 이상, Windows 11). wsl -l -v은 설치된 배포판 목록을 보여 줍니다.

  • CMD나 PowerShell에서 Linux 명령어 하나 실행: wsl ls -la, 또는 파이프로 연결: dir | wsl grep txt.
  • Windows 드라이브는 Linux 안에서 /mnt/c 아래에 나타나고, Linux 파일은 탐색기에서 \\wsl.localhost\Ubuntu(이전 빌드: \\wsl$\Ubuntu)로 접근할 수 있습니다.
  • 프로젝트는 /mnt/c가 아니라 Linux 파일 시스템(~/) 안에 두세요. 경계를 넘나드는 파일 접근은 훨씬 느립니다.

Linux 쪽을 더 자세히 보려면 Linux 명령어 치트 시트를 참고하세요.

브라우저에서 실행되는 정적 참고 자료입니다. 검색어는 어디에도 전송되지 않습니다. 모든 무료 도구 보기.

문제를 발견하셨거나 개선할 점이 있나요? 모든 메시지를 읽고 빠르게 고칩니다.

이 CMD vs PowerShell vs Bash 표는 같은 작업을 Windows 명령 프롬프트, PowerShell, bash에서 어떻게 하는지 한 행에 보여 줍니다. 파일 목록 보기와 복사, 파일에서 텍스트 찾기(grep에 해당하는 PowerShell 명령은 Select-String), 환경 변수, 프로세스, 네트워크, 서비스, 파일 내용 읽고 쓰기, 그리고 변수, 조건문, 반복문, 함수를 쓰는 스크립팅까지 다룹니다. 세 셸 중 어느 것의 명령어로 검색해도 대응하는 명령어가 복사 버튼과 함께 나옵니다.

셸을 오갈 때 흔히 생기는 문제도 정리했습니다. Unix 명령처럼 보이지만 실제로는 다른 PowerShell 별칭(Windows PowerShell 5.1의 curl과 wget, Windows 전반의 ls와 rm), 서로 다른 따옴표와 이스케이프 문자, .ps1 스크립트를 막는 실행 정책 오류, Windows PowerShell 5.1과 PowerShell 7의 차이점입니다. PowerShell 명령은 별도 표시가 없으면 두 버전 모두에서 작동하며, CMD에 대응하는 명령이 없으면 억지로 만들어 내지 않고 없다고 표시합니다.

사용 방법

  1. 알고 있는 명령어를 어느 셸의 것이든 검색하거나(예: “grep”, “findstr”, “Select-String”), 작업으로 검색하세요(“프로세스 종료”, “환경 변수”).
  2. 행을 따라 다른 두 셸의 대응 명령어를 확인하고, 필요한 명령어 옆의 복사를 클릭하세요.
  3. 작업 이름 아래의 메모를 확인하세요. 버전 차이(PowerShell 5.1 vs 7)와 Windows 전용 cmdlet을 표시해 둡니다.
  4. 명령어가 예상과 다르게 동작한다면 별칭, 따옴표, 실행 정책 섹션으로 스크롤하세요.
  5. 인쇄 / PDF로 저장을 사용해 책상에 둘 사본을 만드세요. 휴대폰에서도 볼 수 있으며, 각 행이 카드로 표시됩니다.

자주 묻는 질문

grep에 해당하는 PowerShell 명령은 무엇인가요?

Select-String입니다. 파일은 Select-String -Path app.log -Pattern error로 검색하고, 명령 출력은 ipconfig | Select-String IPv4로 필터링하세요. 기본적으로 대소문자를 구분하지 않고(-CaseSensitive 추가로 구분), .NET 정규식을 사용하며, -NotMatch가 grep -v에 해당합니다. 재귀 검색은 Get-ChildItem -Recurse -Filter *.log를 Select-String에 파이프로 연결하세요. 짧은 별칭은 sls입니다.

PowerShell에서 curl이 이상하게 동작하는 이유는 무엇인가요?

Windows PowerShell 5.1에서 curl과 wget은 Invoke-WebRequest의 별칭이라서 -X, -H, -d 같은 curl 플래그가 거부되거나 다른 의미가 됩니다. Windows 10 1803 이상에 포함된 실제 curl을 실행하려면 curl.exe라고 입력하세요. PowerShell 7에서는 이 별칭이 제거되어 curl이 curl.exe를 실행합니다. Linux와 macOS에서는 curl이 별칭이었던 적이 없습니다.

PowerShell이 CMD보다 나은가요?

프로그램 실행이나 짧은 배치 파일 이상의 작업이라면 그렇습니다. PowerShell은 텍스트 대신 구조화된 객체를 파이프로 전달하므로, 열을 파싱하는 대신 속성 이름으로 필터링하고 정렬하며(Where-Object, Sort-Object), 제대로 된 함수, 오류 처리, JSON·CSV 지원, 원격 실행 기능이 있습니다. 레거시 .bat 파일과 일부 설치 프로그램에는 여전히 CMD로 충분하며, 모든 CMD 도구(ipconfig, robocopy, netstat)는 PowerShell에서도 실행할 수 있습니다.

“이 시스템에서 스크립트를 실행할 수 없으므로…” 오류는 어떻게 해결하나요?

실행 정책 때문입니다. Windows 10과 11 클라이언트 에디션에서는 기본값이 Restricted입니다. PowerShell에서 Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser를 실행하세요(관리자 권한 불필요). 그러면 직접 만든 스크립트는 실행되고, 인터넷에서 다운로드한 스크립트는 서명되어 있거나 Unblock-File로 차단을 해제해야 합니다. Get-ExecutionPolicy -List로 어디에 무엇이 설정되어 있는지 볼 수 있으며, 그룹 정책 설정은 직접 설정한 값보다 우선합니다.

Windows에서 bash 명령을 실행할 수 있나요?

네, Linux용 Windows 하위 시스템(WSL)을 사용하면 됩니다. 관리자 권한 프롬프트에서 wsl --install을 실행하면(Windows 10 버전 2004 이상 또는 Windows 11) Ubuntu가 설치됩니다. 그런 다음 시작 메뉴에서 열거나, CMD나 PowerShell에서 wsl 뒤에 명령을 붙여(예: wsl grep -rn TODO) 단일 명령을 실행하세요. Git for Windows에도 흔한 Unix 도구가 포함된 가벼운 bash인 Git Bash가 들어 있습니다.

Windows PowerShell과 PowerShell 7은 어떻게 다른가요?

Windows PowerShell 5.1(powershell.exe)은 Windows에 내장되어 있으며 수정 사항만 제공됩니다. PowerShell 7(pwsh)은 Windows, Linux, macOS에서 실행되는 현재의 크로스 플랫폼 버전으로 별도로 설치하며, 두 버전을 함께 설치할 수 있습니다. 버전 7은 명령 사이의 &&와 ||, 삼항 연산자와 ?? 연산자를 추가했고, 기본적으로 UTF-8로 파일을 저장하며, curl과 wget처럼 혼란을 주는 일부 별칭을 없앴습니다.

객체 vs 텍스트: PowerShell을 이해하는 핵심 개념

CMD와 bash에서 파이프는 텍스트를 전달합니다. bash에서 메모리를 가장 많이 쓰는 프로세스를 찾으려면 ps 출력에서 sort -k나 awk로 알맞은 열을 골라내야 하고, 열 배치가 바뀌면 명령이 깨집니다. PowerShell에서 파이프는 이름 붙은 속성을 가진 객체를 전달하므로, 같은 작업이 Get-Process | Sort-Object WS -Descending | Select-Object -First 1이 됩니다. 아무것도 파싱하지 않으며, 속성 이름은 어느 컴퓨터에서나 같습니다.

실제로는 탐색 방식이 달라집니다. bash에서는 man 페이지를 읽어 출력 형식을 익히지만, PowerShell에서는 아무 명령이나 Get-Member에 파이프로 넘겨 객체에 어떤 속성과 메서드가 있는지 확인한 뒤, Where-Object로 필터링하고 Select-Object로 필드를 고릅니다. 출력이 화면이나 파일에 도달할 때에야 PowerShell이 이를 텍스트로 바꿉니다.

ipconfig, git, curl.exe 같은 네이티브 프로그램은 PowerShell에서도 여전히 텍스트를 출력하므로, Select-String과 -match를 grep처럼 쓸 수 있습니다. 이들의 종료 코드는 $?가 아니라 $LASTEXITCODE에 들어 있습니다.

세 셸 간에 스크립트 옮기기

간단한 스크립트는 한 줄씩 옮겨도 되지만, 거의 모든 사람이 걸려 넘어지는 차이점이 몇 가지 있습니다.

• 비교 연산자: CMD는 문자열에 ==, 숫자에 EQU, GTR, LSS를 씁니다. PowerShell은 -eq, -gt, -lt, -like, -match를 쓰며(그냥 >는 리디렉션), bash는 [ ] 안에서 문자열에 =, 숫자에 -gt나 (( ))를 씁니다.

• 변수: CMD는 %name%(setlocal EnableDelayedExpansion 이후 반복문 안에서는 !name!), PowerShell은 $name, bash는 $name이며 대입할 때 = 앞뒤에 공백을 두지 않습니다.

• .bat 파일의 반복문에서는 퍼센트 기호를 두 번 씁니다. 파일 안에서는 for %%f in (*.txt), 프롬프트에서는 for %f입니다.

• 경로: Windows의 PowerShell은 /와 \를 모두 받지만, Linux의 bash는 /만 받습니다. 환경 변수는 Windows에서는 대소문자를 구분하지 않고 Linux에서는 구분합니다.

• 오류: CMD는 %ERRORLEVEL%을 확인하지 않으면 실패 후에도 계속 진행하고, bash는 set -e가 없으면 계속 진행하며, PowerShell은 $ErrorActionPreference = 'Stop'이 아니면 종료되지 않는 오류 후에도 계속 진행합니다.

스크립트가 Windows와 Linux에서 모두 실행되어야 한다면, PowerShell 7이나 WSL의 bash를 쓰면 사본 두 개를 관리하지 않아도 됩니다.

관련 무료 도구

  • Linux 명령어 치트 시트 — 파일과 권한부터 네트워크, systemd, 텍스트 처리까지 작업별로 정리한 Linux 명령어. 모든 항목에 옵션, 복사 가능한 예시, macOS 참고 사항이 있습니다.
  • Windows 단축키 — Windows 11의 모든 단축키를 검색하고 인쇄할 수 있는 목록 하나로: Win 키, 스냅, 가상 데스크톱, 스크린샷, 파일 탐색기.
  • Mac 키보드 단축키 — ⌘ ⌥ ⌃ ⇧ 기호 설명과 함께 모든 macOS 단축키를 정리했습니다: 스크린샷, 윈도우 타일 정렬, Finder, Safari, 특수문자.
  • curl 코드 변환 — Chrome의 "cURL로 복사"를 포함한 curl 명령을 붙여 넣으면 같은 요청을 Python, JavaScript, Node, Go, PHP, Ruby, Java, C#, wget, HTTPie 코드로 만들어 줍니다.
  • Git 치트 시트 — 마지막 커밋 취소, 브랜치 이름 변경, 원격 브랜치 삭제처럼 하려는 작업별로 정리한 Git 명령어. 최신 switch/restore와 기존 명령어, 위험 배지까지 함께 보여 줍니다.