Windows CMD Β· PowerShell Β· Bash (Linux and macOS) Β· Git
How to read this sheet. Each row shows the same task in all three shells. Commands are in monospace; grey italics explain flags or name an alias for the same command. π needs administrator, root or sudo. β destructive; check before running. (Linux) or (macOS) marks a command that exists only on that platform. β marks the everyday essentials. Click any command to copy it.
No rows match . Try fewer letters, or check the Show toggles above.
The commands most people use every day, in short form. Click a task name for the full entry with more options and notes.
| Task | CMD | PowerShell | Bash |
|---|---|---|---|
| β Change directory | cd C:\Userscd ..\Desktop | cd "C:\Program Files"Set-Location ~\Desktop | cd /home/user/docscd ~/Desktop |
| β List files | dirdir /A (include hidden) | Get-ChildItem (alias: ls, dir, gci)ls -Force (include hidden) | lsls -la (long, incl. hidden) |
| β Copy files | copy file.txt C:\Backupcopy *.txt D:\Backup | Copy-Item file.txt ~\Backup (alias: cp)Copy-Item *.txt -Destination C:\Backup | cp file.txt ~/Backupcp -i file.txt ~/Backup (prompt before overwrite) |
| β Move or rename | move file.txt C:\Newren old.txt new.txt | Move-Item file.txt C:\New (alias: mv)Rename-Item old.txt new.txt | mv file.txt ~/new/mv old.txt new.txt |
| β Delete files | del oldfile.txtdel *.tmp | Remove-Item oldfile.txt (alias: rm, del)Remove-Item *.tmp -WhatIf (dry run) | rm oldfile.txtrm -i file.txt (confirm) |
| β View file contents | type readme.txt | Get-Content readme.txt (alias: cat, type, gc) | cat readme.txtless readme.txt (paginated; q to quit) |
| β Find files | dir /S /B *.txtwhere /R C:\Projects *.log | Get-ChildItem -Recurse -Filter *.txtgci -r -Include *.log,*.txt | find . -name "*.txt"find /home -type f -name "*.log" |
| β Search text in files | findstr "error" log.txtfindstr /S /I "text" *.* (recursive, ignore case) | Select-String -Path log.txt -Pattern error (alias: sls)sls error *.log -CaseSensitive | grep "error" log.txtgrep -ri "error" /var/log/ (recursive, ignore case) |
| β List processes | tasklisttasklist /V (verbose) | Get-Process (alias: ps, gps)Get-Process -Name chrome | ps auxps aux | grep nginx |
| β Kill process | taskkill /IM notepad.exetaskkill /PID 1234 /F (force) | Stop-Process -Name notepad (alias: kill)Stop-Process -Id 1234 -Force | kill 1234 (SIGTERM, polite)kill -9 1234 (SIGKILL, force) |
| β Ping host | ping google.com (4 packets)ping -n 10 192.168.1.1 | Test-Connection google.comTest-Connection 8.8.8.8 -Count 5 | ping google.com (until Ctrl+C)ping -c 5 google.com |
| β IP configuration | ipconfigipconfig /all (MAC, DNS, DHCP) | Get-NetIPConfigurationGet-NetIPAddress -AddressFamily IPv4 | ip addr (Linux; short form: ip a)ifconfig (macOS; deprecated on Linux) |
| β Show environment variables | setset PATH (all starting with PATH) | Get-ChildItem Env: (or: dir env:)$env:PATH | printenvenv |
| β Command history | doskey /historyF7 (popup list) | Get-History (alias: h, history)Get-Content (Get-PSReadLineOption).HistorySavePath (all sessions) | historyhistory 20 (last 20) |
| β Get help | dir /?help copy | Get-Help Get-Process -ExamplesGet-Help *-Service (search by name) | man lsls --help |
| Task | CMD | PowerShell | Bash | Notes |
|---|---|---|---|---|
| β Change directory | cd C:\Userscd ..\Desktopcd /d D:\Data (switch drive)D: (switch drive only) | cd "C:\Program Files"Set-Location ~\Desktopcd - (previous dir, PS 6+) | cd /home/user/docscd ~/Desktopcd - (previous dir)cd (home) | cd .. goes to the parent. ~ is the home directory in PowerShell and Bash. CMD needs /d to change drive and directory at once. |
| β List files | dirdir /A (include hidden)dir /S (recursive)dir /B (bare names)dir /O-D (newest first) | Get-ChildItem (alias: ls, dir, gci)ls -Force (include hidden)Get-ChildItem -Recursels *.txt | lsls -la (long, incl. hidden)ls -lh (readable sizes)ls -lt (newest first)ls -R (recursive) | |
| Show current directory | cd (no arguments)echo %CD% | Get-Location (alias: pwd)$PWD | pwd | |
| Create directory | mkdir MyReportsmd Folder1\Folder2 (nested is fine) | mkdir ~/Projects/NewNew-Item -ItemType Directory MyReports | mkdir MyReportsmkdir -p a/b/c (nested) | |
| Remove directory | rmdir OldFolder (empty only)rmdir /S /Q OldFolder (with contents, no prompt) | Remove-Item OldFolder -Recurse -ForceRemove-Item OldFolder -Recurse -WhatIf (preview) | rmdir OldFolder (empty only)rm -r OldFolderrm -rf OldFolder (no prompts) | β Recursive deletes bypass the Recycle Bin / Trash. There is no undo. |
| Directory tree | tree C:\Projectstree /F (include files) | tree /F (same tree.com as CMD)Get-ChildItem -Recurse -Name | tree ~/Projectstree -L 2 (limit depth) | tree is not preinstalled on most Linux distros or macOS: apt install tree, brew install tree. |
| β Copy files | copy file.txt C:\Backupcopy *.txt D:\Backup | Copy-Item file.txt ~\Backup (alias: cp)Copy-Item *.txt -Destination C:\Backup | cp file.txt ~/Backupcp -i file.txt ~/Backup (prompt before overwrite) | |
| Copy directories | xcopy C:\Src D:\Dst /E /Irobocopy C:\Src D:\Dst /Erobocopy C:\Src D:\Dst /MIR (mirror; deletes extras) | Copy-Item folder -Recurse -Destination dest | cp -r folder/ ~/destcp -a folder/ ~/dest (preserve attributes)rsync -av src/ dest/ | robocopy and rsync are the robust choices for large copies: both can resume and mirror. β /MIR and rsync --delete remove files at the destination. |
| β Move or rename | move file.txt C:\Newren old.txt new.txt | Move-Item file.txt C:\New (alias: mv)Rename-Item old.txt new.txt | mv file.txt ~/new/mv old.txt new.txt | |
| β Delete files | del oldfile.txtdel *.tmpdel /P file.txt (prompt) | Remove-Item oldfile.txt (alias: rm, del)Remove-Item *.tmp -WhatIf (dry run) | rm oldfile.txtrm -i file.txt (confirm)rm *.tmp | β No Recycle Bin. In PowerShell, -WhatIf previews any destructive cmdlet. |
| β View file contents | type readme.txt | Get-Content readme.txt (alias: cat, type, gc) | cat readme.txtless readme.txt (paginated; q to quit) | |
| Create empty file | type nul > notes.txtcopy con notes.txt (type text, then Ctrl+Z, Enter) | New-Item -ItemType File notes.txt (alias: ni) | touch notes.txt> notes.txt | touch also updates the timestamp of an existing file. New-Item errors if the file exists unless you add -Force. |
| β Find files | dir /S /B *.txtwhere /R C:\Projects *.log | Get-ChildItem -Recurse -Filter *.txtgci -r -Include *.log,*.txtgci -r | Where LastWriteTime -gt (Get-Date).AddDays(-1) | find . -name "*.txt"find /home -type f -name "*.log"find . -mtime -1 (modified in last day)find . -size +100M | |
| Which command runs | where python | Get-Command pythonGet-Command ls (shows what an alias points to) | which pythontype ls (shows aliases and builtins too)command -v python | |
| Compare files | fc file1.txt file2.txtfc /B a.bin b.bin (binary) | Compare-Object (Get-Content a.txt) (Get-Content b.txt) (alias: diff) | diff file1.txt file2.txtdiff -u a.txt b.txt (unified format) | PowerShell's diff alias is not Unix diff: it compares sets of objects and ignores line order unless you add -SyncWindow 0. |
| β Search text in files | findstr "error" log.txtfindstr /S /I "text" *.* (recursive, ignore case)findstr /N "text" file.txt (line numbers) | Select-String -Path log.txt -Pattern error (alias: sls)sls error *.log -CaseSensitivegci -r *.log | sls error | grep "error" log.txtgrep -ri "error" /var/log/ (recursive, ignore case)grep -n "text" file.txt (line numbers) | |
| File permissions | icacls file.txticacls file.txt /grant User:F | Get-Acl file.txtSet-Acl file.txt -AclObject $aclicacls file.txt (works here too) | chmod 755 script.shchmod +x script.shchown user:group file.txt | π Changing permissions on files you do not own needs admin or sudo. Windows uses ACLs; Unix uses rwx bits. |
| File attributes | attrib +r file.txt (read-only)attrib +h file.txt (hidden)attrib -r -h file.txt | Set-ItemProperty file.txt IsReadOnly $true(Get-Item file.txt).Attributes | chattr +i file.txt (immutable, Linux)chattr -i file.txtchflags hidden file.txt (macOS) | Unix has no hidden attribute: files whose names start with a dot are hidden by convention. |
| Symbolic links | mklink link.txt C:\target.txtmklink /D linkdir C:\target | New-Item -ItemType SymbolicLink -Path link -Target target | ln -s target linkln -s /path/to/dir linkdir | π Windows needs an admin prompt or Developer Mode to create symlinks. Bash argument order is target first, then link. |
| Compress / archive | tar -a -cf archive.zip folder (Windows 10 1803+)compact /C file.txt (NTFS compression, not an archive) | Compress-Archive -Path folder -DestinationPath archive.zip | tar -czvf archive.tar.gz folder/zip -r archive.zip folder/gzip file.txt (replaces file with file.txt.gz) | bsdtar ships with Windows 10 and later and works in both CMD and PowerShell. It reads .zip, .tar.gz, .7z and more. |
| Extract | tar -xf archive.ziptar -xf archive.tar.gzexpand archive.cab C:\dest (CAB only) | Expand-Archive archive.zip -DestinationPath dest\ | unzip archive.ziptar -xzvf archive.tar.gzgunzip file.txt.gz | |
| File hash / checksum | certutil -hashfile file.iso SHA256 | Get-FileHash file.iso (SHA256 by default)Get-FileHash file.iso -Algorithm MD5 | sha256sum file.isomd5sum file.isoshasum -a 256 file.iso (macOS) | |
| Open with default app | start report.pdfstart . (Explorer here)start https://example.com | Invoke-Item report.pdf (alias: ii)start . (alias of Start-Process) | xdg-open report.pdf (Linux)open report.pdf (macOS)open . (Finder here, macOS) | |
| Clear screen | cls | Clear-Host (alias: cls, clear)Ctrl+L | clearCtrl+L |
| Task | CMD | PowerShell | Bash | Notes |
|---|---|---|---|---|
| Free disk space | fsutil volume diskfree C:wmic logicaldisk get name,size,freespace (wmic is deprecated) | Get-PSDrive -PSProvider FileSystemGet-VolumeGet-CimInstance Win32_LogicalDisk | Select DeviceID,Size,FreeSpace | df -hdf -h /home (one filesystem) | wmic is deprecated and removed from recent Windows 11 builds. Prefer Get-CimInstance. |
| Disk and partition info | diskpart (interactive: list disk, list volume)wmic diskdrive get model,size (deprecated) | Get-DiskGet-PartitionGet-Volume | lsblk (Linux)sudo fdisk -l (Linux)diskutil list (macOS) | |
| Folder size | dir /S C:\folder (total at the end) | (Get-ChildItem -Recurse folder | Measure-Object Length -Sum).Sum / 1MB | du -sh folder/du -h --max-depth=1 . | sort -h (Linux)du -sh * | sort -h | |
| Check disk | chkdsk C:chkdsk C: /F (fix errors; system drive needs a reboot) | Repair-Volume -DriveLetter C -ScanRepair-Volume -DriveLetter C -OfflineScanAndFix | sudo fsck /dev/sda1 (unmount first)diskutil verifyVolume / (macOS) | π Requires admin or sudo. Never run fsck on a mounted filesystem. |
| Format drive | format D: /FS:NTFS /Q | Format-Volume -DriveLetter D -FileSystem NTFS | sudo mkfs.ext4 /dev/sdb1diskutil eraseDisk APFS Name disk2 (macOS) | β β Destroys everything on the volume. Double-check the drive letter or device name first. |
| Mount / map drives | net use Z: \\server\share (map network drive)net use Z: /deletemountvol (list volume mount points) | New-PSDrive -Name Z -PSProvider FileSystem -Root \\server\share -PersistMount-DiskImage file.isoDismount-DiskImage file.iso | sudo mount /dev/sdb1 /mnt/usbsudo umount /mnt/usbmount (list mounts) |
| Task | CMD | PowerShell | Bash | Notes |
|---|---|---|---|---|
| Current user | whoamiecho %USERNAME%whoami /groups | whoami$env:USERNAME[Environment]::UserName | whoamiecho $USERid (uid, gid and groups) | |
| Hostname | hostnameecho %COMPUTERNAME% | hostname$env:COMPUTERNAME | hostnamehostnamectl (Linux with systemd)scutil --get ComputerName (macOS) | |
| System information | systeminfosysteminfo | findstr /B /C:"OS Name" /C:"OS Version" | Get-ComputerInfoGet-ComputerInfo | Select OsName,OsVersion,CsTotalPhysicalMemoryGet-CimInstance Win32_OperatingSystem | uname -acat /etc/os-release (Linux)hostnamectl (Linux)sw_vers (macOS) | Get-ComputerInfo is slow (several seconds). Pick properties with Select-Object. |
| OS version | ver | [Environment]::OSVersion$PSVersionTable.PSVersion (PowerShell version) | uname -r (kernel)lsb_release -a (Debian/Ubuntu)sw_vers -productVersion (macOS) | |
| CPU | echo %NUMBER_OF_PROCESSORS%wmic cpu get name,numberofcores (deprecated) | Get-CimInstance Win32_Processor | Select Name,NumberOfCores,NumberOfLogicalProcessors | lscpu (Linux)nproc (Linux)sysctl -n machdep.cpu.brand_string (macOS) | |
| Memory | systeminfo | findstr /C:"Total Physical Memory" /C:"Available Physical Memory" | Get-CimInstance Win32_OperatingSystem | Select TotalVisibleMemorySize,FreePhysicalMemoryGet-CimInstance Win32_PhysicalMemory | Select Capacity,Speed | free -h (Linux)cat /proc/meminfo (Linux)vm_stat (macOS)top (any) | |
| Uptime | systeminfo | findstr /C:"System Boot Time"net statistics workstation | findstr "since" | (Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTimeGet-Uptime (PowerShell 6+ only) | uptimeuptime -p (pretty, Linux)uptime -s (boot time, Linux) | |
| Date and time | date /Ttime /Techo %DATE% %TIME% | Get-DateGet-Date -Format "yyyy-MM-dd HH:mm:ss"Get-Date -UFormat "%Y-%m-%d" | datedate +"%Y-%m-%d %H:%M:%S"date -u (UTC) | Without /T, CMD's date and time commands prompt you to change the clock (π admin). |
| Logged-in users | query user (alias: quser) | query userGet-CimInstance Win32_ComputerSystem | Select UserName | whow (who, plus what they are running)last (login history) |
| Task | CMD | PowerShell | Bash | Notes |
|---|---|---|---|---|
| β List processes | tasklisttasklist /V (verbose)tasklist /FI "IMAGENAME eq chrome.exe" | Get-Process (alias: ps, gps)Get-Process -Name chromeGet-Process | Sort-Object CPU -Descending | Select -First 10 | ps auxps aux | grep nginxtop (live)htop (live, nicer; needs install) | |
| β Kill process | taskkill /IM notepad.exetaskkill /PID 1234 /F (force)taskkill /F /IM chrome.exe /T (with child processes) | Stop-Process -Name notepad (alias: kill)Stop-Process -Id 1234 -Force | kill 1234 (SIGTERM, polite)kill -9 1234 (SIGKILL, force)pkill -f patternkillall firefox | β Force-killing skips cleanup and can corrupt files being written. Try the polite form first. |
| Find process using a port | netstat -ano | findstr :8080 (PID in last column) | Get-NetTCPConnection -LocalPort 8080 | Select OwningProcessGet-Process -Id (Get-NetTCPConnection -LocalPort 8080).OwningProcess | sudo lsof -i :8080sudo ss -ltnp | grep 8080 (Linux) | |
| Run in background | start /B program.exe (same window)start "" notepad.exe (new window) | Start-Process notepadStart-Job { long-task }; Get-Job; Receive-Job 1command & (PowerShell 6+) | command &nohup command & (survives logout)jobs / fg / bgCtrl+Z (suspend the foreground job) | |
| List services | sc query (running)sc query state= allnet start (running only) | Get-ServiceGet-Service | Where Status -eq RunningGet-Service -Name Spooler | systemctl list-units --type=service (Linux)systemctl list-units --type=service --state=runninglaunchctl list (macOS) | |
| Start / stop / restart service | sc start Spoolersc stop Spoolernet stop Spooler && net start Spooler(net start/stop also work) | Start-Service SpoolerStop-Service SpoolerRestart-Service Spooler | sudo systemctl start nginxsudo systemctl stop nginxsudo systemctl restart nginxsudo systemctl enable nginx (start at boot) | π Requires admin or sudo. sc and Get-Service use the service name (Spooler), not the display name (Print Spooler). |
| Service status | sc query Spoolersc qc Spooler (configuration) | Get-Service Spooler(Get-Service Spooler).Status | systemctl status nginxsystemctl is-active nginxjournalctl -u nginx -f (follow logs, Linux) | |
| Scheduled tasks | schtasks /queryschtasks /create /tn Backup /tr C:\backup.bat /sc daily /st 02:00schtasks /delete /tn Backup | Get-ScheduledTaskGet-ScheduledTask Backup | Start-ScheduledTaskRegister-ScheduledTask (see the Get-Help examples) | crontab -l (list)crontab -e (edit)0 2 * * * /path/backup.sh (daily at 02:00)launchctl (macOS launchd) | |
| Restart system | shutdown /r /t 0shutdown /a (abort a pending shutdown) | Restart-ComputerRestart-Computer -Force | sudo rebootsudo shutdown -r nowsudo shutdown -r +5 (in 5 minutes) | π Requires admin or sudo. |
| Shut down system | shutdown /s /t 0shutdown /s /t 60 (in 60 seconds)shutdown /h (hibernate) | Stop-ComputerStop-Computer -Force | sudo shutdown -h nowsudo poweroffsudo shutdown -c (cancel, Linux) | π Requires admin or sudo. |
| Task | CMD | PowerShell | Bash | Notes |
|---|---|---|---|---|
| β Ping host | ping google.com (4 packets)ping -n 10 192.168.1.1ping -t host (until Ctrl+C) | Test-Connection google.comTest-Connection 8.8.8.8 -Count 5Test-Connection host -Quiet (True/False) | ping google.com (until Ctrl+C)ping -c 5 google.com | Windows ping stops after 4 packets by default. Unix ping runs until you stop it. |
| β IP configuration | ipconfigipconfig /all (MAC, DNS, DHCP)ipconfig /release && ipconfig /renew | Get-NetIPConfigurationGet-NetIPAddress -AddressFamily IPv4 | ip addr (Linux; short form: ip a)ifconfig (macOS; deprecated on Linux)hostname -I (Linux, addresses only) | |
| Public IP | curl ifconfig.me | Invoke-RestMethod ifconfig.me | curl ifconfig.me | |
| Connections and open ports | netstat -an (all)netstat -ano (with PIDs)netstat -b (with program names, π admin) | Get-NetTCPConnectionGet-NetTCPConnection -State Listen | ss -tulpn (Linux, preferred)sudo netstat -tulpn (older Linux)sudo lsof -i -P (macOS and Linux) | netstat and ifconfig are deprecated on Linux in favour of ss and ip, but still work on macOS. |
| DNS lookup | nslookup google.comnslookup google.com 8.8.8.8 (ask a specific server)nslookup -type=MX google.com | Resolve-DnsName google.comResolve-DnsName google.com -Type MXResolve-DnsName google.com -Server 8.8.8.8 | dig google.comdig +short google.comdig MX google.comhost google.com | |
| Trace route | tracert google.comtracert -d google.com (skip DNS, faster)pathping google.com | Test-NetConnection google.com -TraceRoute | traceroute google.comtracepath google.com (Linux, no root needed)mtr google.com (live; needs install) | |
| Routing table | route printroute add 192.168.2.0 mask 255.255.255.0 192.168.1.1 | Get-NetRouteNew-NetRoute -DestinationPrefix 192.168.2.0/24 -NextHop 192.168.1.1 -InterfaceIndex 12 | ip route (Linux)sudo ip route add 192.168.2.0/24 via 192.168.1.1netstat -rn (macOS) | π Adding routes needs admin or sudo. |
| Flush DNS cache | ipconfig /flushdnsipconfig /displaydns | Clear-DnsClientCacheGet-DnsClientCache | sudo resolvectl flush-caches (Linux, systemd-resolved)sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder (macOS) | |
| ARP table | arp -a | Get-NetNeighborGet-NetNeighbor -State Reachable | ip neigh (Linux)arp -a (macOS and Linux) | |
| Download file | curl -O https://example.com/file.zipcurl -L -o out.zip URL (follow redirects, custom name)certutil -urlcache -split -f URL file.zip (legacy) | Invoke-WebRequest URL -OutFile file.zip (alias: iwr)Invoke-RestMethod URL (parses JSON) (alias: irm)curl.exe -O URL | wget URLcurl -O URLcurl -L -o out.zip URL | In Windows PowerShell 5.1, curl is an alias of Invoke-WebRequest. Type curl.exe to get the real tool. |
| Test a port | curl -v telnet://host:443telnet host 80 (optional feature, off by default) | Test-NetConnection host -Port 443 (alias: tnc)tnc host -Port 443 -InformationLevel Quiet | nc -zv host 443curl -v telnet://host:443(echo > /dev/tcp/host/443) && echo open (Bash only) | |
| SSH and remote copy | ssh user@hostscp file.txt user@host:/path/ssh -i key.pem user@host | ssh user@hostscp file.txt user@host:/path/Enter-PSSession -ComputerName host (WinRM, Windows to Windows) | ssh user@hostscp file.txt user@host:/path/rsync -avz src/ user@host:/dest/ | The OpenSSH client is built into Windows 10 1809 and later. |
| Task | CMD | PowerShell | Bash | Notes |
|---|---|---|---|---|
| β Show environment variables | setset PATH (all starting with PATH)echo %PATH% | Get-ChildItem Env: (or: dir env:)$env:PATH$env:PATH -split ';' (one per line) | printenvenvecho $PATHecho $PATH | tr ':' '\n' (one per line) | |
| Set environment variable | set MYVAR=value (this session)setx MYVAR value (permanent, new windows only)setx PATH "%PATH%;C:\tools" (β truncates at 1024 chars) | $env:MYVAR = 'value' (this session)[Environment]::SetEnvironmentVariable('MYVAR','value','User') (permanent) | export MYVAR=value (this session)MYVAR=value command (one command only)add the export line to ~/.bashrc or ~/.zshrc (permanent) | Permanent changes only affect shells opened afterwards. |
| β Command history | doskey /historyF7 (popup list) | Get-History (alias: h, history)Get-Content (Get-PSReadLineOption).HistorySavePath (all sessions) | historyhistory 20 (last 20)history | grep ssh | |
| Re-run a command | F3 or β (previous) | β (previous)Invoke-History 5 (alias: r 5) | !! (previous)!5 (history entry 5)!ssh (last command starting with ssh)sudo !! (repeat with sudo) | |
| Search history | F7 (dialog)type a prefix, then F8 (cycle matches) | Ctrl+R (reverse search)type a prefix, then F8Get-History | Where CommandLine -like '*git*' | Ctrl+R (reverse search)history | grep pattern | |
| Aliases | doskey ll=dir /B $* (this session)(persist via a startup script in the AutoRun registry key) | Set-Alias ll Get-ChildItemGet-Alias (list all)function gs { git status } (aliases cannot take arguments; use a function) | alias ll='ls -la'alias (list all)unalias ll | |
| Shell profile / startup | HKCU\Software\Microsoft\Command Processor\AutoRun (registry value) | $PROFILE (path to your profile script)notepad $PROFILE. $PROFILE (reload) | ~/.bashrc (interactive Bash)~/.bash_profile (login shells)~/.zshrc (zsh; default on macOS)source ~/.bashrc (reload) | Put aliases, functions and PATH changes in the profile so they survive between sessions. |
| Exit code of last command | echo %ERRORLEVEL%if %ERRORLEVEL% neq 0 echo failed | $? (True or False)$LASTEXITCODE (from the last native .exe) | echo $? (0 means success) | |
| Chain commands | a && b (b only if a succeeds)a || b (b only if a fails)a & b (both, regardless) | a; b (both, regardless)a && b, a || b (PowerShell 7+ only)(-and / -or are boolean operators, not chaining) | a && ba || ba; b | |
| β Get help | dir /?help copy | Get-Help Get-Process -ExamplesGet-Help *-Service (search by name)Get-Command -Noun ServiceUpdate-Help (once, π admin) | man lsls --helptldr ls (needs install) | |
| Run as admin / root | runas /user:Administrator cmd(or right-click the shell and choose Run as administrator) | Start-Process powershell -Verb RunAssudo command (Windows 11 24H2+; enable in Settings > System > For developers) | sudo commandsudo -i (root shell)su - (switch user) |
| Task | CMD | PowerShell | Bash | Notes |
|---|---|---|---|---|
| Display text | echo Hello Worldecho %PATH%echo. (blank line) | Write-Output 'Hello' (alias: echo, write)Write-Host 'Text' -ForegroundColor Red (console only, not pipeable)"Value: $var" (double quotes expand variables) | echo "Hello World"printf "%s\n" "text"echo -e "a\tb" (interpret escapes) | |
| View a page at a time | more file.txtdir /S | more | Get-Content file.txt | moreGet-Content file.txt | Out-Host -Paging | less file.txt (q quits, / searches)more file.txtcat file.txt | less | |
| First lines of a file | more +5 file.txt (skip the first 5 instead)(none; use PowerShell) | Get-Content file.txt -Head 10Get-Content file.txt | Select-Object -First 10 | head file.txt (10 lines)head -n 20 file.txthead -c 100 file.bin (bytes) | |
| Last lines of a file | (none; use PowerShell) | Get-Content file.txt -Tail 10Get-Content log.txt -Wait (follow, like tail -f) | tail file.txttail -n 20 file.txttail -f log.txt (follow) | |
| Count lines / words | find /c /v "" < file.txt (lines)type file.txt | find /c "error" (matching lines) | Get-Content file.txt | Measure-Object -Line -Word -Character(Get-Content file.txt).Count (lines) | wc -l file.txt (lines)wc -w file.txt (words)grep -c error file.txt (matching lines) | |
| Sort lines | sort file.txtsort /R file.txt (reverse)dir /B | sort | Get-Content file.txt | Sort-ObjectSort-Object -UniqueGet-Process | Sort-Object CPU -Descending | sort file.txtsort -r (reverse), -n (numeric), -u (unique)sort -k2 file.txt (by second field) | |
| Unique lines | (none; use PowerShell) | Get-Content file.txt | Sort-Object -UniqueGet-Content file.txt | Group-Object | Sort Count -Desc (with counts) | sort -u file.txtsort file.txt | uniq -c (with counts)uniq file.txt (adjacent duplicates only) | |
| Filter a stream | dir | find "txt"tasklist | findstr /I chrome | Get-Process | Where-Object Name -like 'chrome*' (alias: where, ?)Get-Process | Where CPU -gt 100gc log.txt | sls error | ps aux | grep chromegrep -v debug log.txt (invert match) | PowerShell pipes objects, not text: filter on properties with Where-Object, then shape output with Select-Object or Format-Table. |
| Find and replace | (none; use PowerShell) | (Get-Content file.txt) -replace 'old','new' | Set-Content file.txt'text' -replace '(\d+)','[$1]' (regex by default) | sed 's/old/new/g' file.txt (prints result)sed -i 's/old/new/g' file.txt (in place, Linux)sed -i '' 's/old/new/g' file.txt (in place, macOS) | The parentheses around Get-Content read the whole file first so PowerShell can safely overwrite it. |
| Extract columns / fields | for /f "tokens=2 delims=," %i in (file.csv) do @echo %i(inside a .bat file use %%i) | Import-Csv data.csv | Select-Object Name,Email'a,b,c' -split ','Get-Content f.txt | ForEach { ($_ -split '\s+')[1] } | cut -d, -f2 file.csvawk '{print $2}' file.txtawk -F: '{print $1}' /etc/passwd | |
| Shape and export output | dir /B /O-D (bare, newest first)tasklist /FO CSVtasklist /FO CSV > procs.csv | Get-Process | Select-Object Name,CPUGet-Process | Format-Table -AutoSizeGet-Process | Format-List *Get-Process | Export-Csv procs.csv -NoTypeInformationGet-Process | ConvertTo-JsonGet-Service | Out-GridView | column -t file.txt (align columns)ls -l | awk '{print $9, $5}'jq . file.json (needs install) | Format-* cmdlets must be last in a pipeline; their output is for the screen only. |
| Clipboard | dir | clip | Get-Process | Set-Clipboard (alias: scb)Get-Clipboard (alias: gcb)ls | clip | ls | pbcopy (macOS), pbpastels | xclip -selection clipboard (Linux, X11)ls | wl-copy (Linux, Wayland) |
| Task | CMD | PowerShell | Bash | Notes |
|---|---|---|---|---|
| Redirect output (overwrite) > | dir > list.txt | Get-Process > processes.txtGet-Process | Out-File -Encoding utf8 p.txtGet-Process | Set-Content p.txt | ls -la > listing.txt | Windows PowerShell 5.1 writes UTF-16 with >. Use Out-File -Encoding utf8 for files other tools will read. PowerShell 7 defaults to UTF-8. |
| Redirect output (append) >> | echo text >> file.txt | Get-Date >> log.txtAdd-Content log.txt 'line' | echo "new line" >> file.txt | |
| Redirect input < | sort < unsorted.txt | Get-Content input.txt | Sort-Object(PowerShell has no < operator) | sort < unsorted.txtcat <<EOF ... EOF (here-document)cmd <<< "string" (here-string) | |
| Pipe | | dir | find "txt"type file.txt | more | Get-Process | Sort-Object CPU -Descending | Select -First 5Get-ChildItem | Where Length -gt 1MB | ls -la | grep txtcat file.txt | sort | uniq -c | CMD and Bash pipe text. PowerShell pipes objects; $_ (or $PSItem) is the current object inside a script block. |
| Redirect errors 2> | command 2> errors.txtcommand 2>&1 (merge errors into output) | command 2> errors.txtcommand 2>&1$ErrorActionPreference = 'Stop' (make errors terminate) | command 2> errors.txtcommand 2>&1 | |
| Redirect everything | command > out.txt 2>&1 | command *> all.txtcommand 3>&1 (warnings), 4>&1 (verbose), 6>&1 (information) | command &> out.txtcommand > out.txt 2>&1 | |
| Suppress output | command > nulcommand > nul 2>&1 | command | Out-Nullcommand > $null$null = command (fastest) | command > /dev/nullcommand &> /dev/nullcommand 2> /dev/null (errors only) | |
| Tee (file and screen) | (none; use PowerShell) | Get-Process | Tee-Object -FilePath p.txtGet-Process | Tee-Object -Variable procs | Select Name | ls | tee listing.txtls | tee -a listing.txt (append)echo x | sudo tee /etc/file (write as root) | |
| Command substitution | for /f %i in ('date /T') do set today=%i | $today = Get-Date -Format yyyy-MM-ddWrite-Output "Today: $(Get-Date)"Copy-Item a.txt "backup-$(Get-Date -f yyyyMMdd).txt" | today=$(date +%F)echo "Today: $(date)"cp a.txt "backup-$(date +%F).txt" |
| Task | CMD | PowerShell | Bash | Notes |
|---|---|---|---|---|
| List users | net usernet user alice (details) | Get-LocalUserGet-LocalUser | Where Enabled | cat /etc/passwd (Linux)getent passwddscl . list /Users (macOS) | |
| Add user | net user alice * /add (prompts for password) | New-LocalUser alice -Password (Read-Host -AsSecureString)New-LocalUser alice -NoPassword | sudo adduser alice (interactive, Debian/Ubuntu)sudo useradd -m alice && sudo passwd alice | π Requires admin or sudo. Avoid typing passwords on the command line: they end up in history. |
| Delete user | net user alice /delete | Remove-LocalUser alice | sudo userdel alicesudo userdel -r alice (also remove home dir) | π Requires admin or sudo. |
| Change password | net user alice * (prompts) | Set-LocalUser alice -Password (Read-Host -AsSecureString) | passwd (your own)sudo passwd alice | |
| List groups | net localgroupnet localgroup Administrators (members) | Get-LocalGroupGet-LocalGroupMember Administrators | groups (current user)getent groupid alice | |
| Add user to group | net localgroup Administrators alice /add | Add-LocalGroupMember -Group Administrators -Member alice | sudo usermod -aG sudo alice (Debian/Ubuntu)sudo usermod -aG wheel alice (Fedora/RHEL)(log out and back in to apply) | π Requires admin or sudo. β Forgetting -a in usermod removes the user from all other groups. |
| Task | CMD | PowerShell | Bash | Notes |
|---|---|---|---|---|
| List installed | winget list | winget listchoco list (Chocolatey)Get-Module -ListAvailable (PowerShell modules) | apt list --installed (Debian/Ubuntu)dnf list installed (Fedora/RHEL)brew list (macOS)pacman -Q (Arch) | wmic product get name is deprecated and very slow; use winget instead. |
| Search | winget search vscode | winget search vscodechoco search vscodeFind-Module PSReadLine | apt search vscodednf search vscodebrew search vscode | |
| Show package info | winget show Git.Git | winget show Git.Git | apt show gitdnf info gitbrew info git | |
| Install | winget install Git.Gitwinget install --id Git.Git -e (exact id) | winget install Git.Gitchoco install git -yInstall-Module PSReadLine (PowerShell module) | sudo apt install gitsudo dnf install gitbrew install gitsudo pacman -S git | π Usually needs admin or sudo. brew and per-user winget installs are the exception. |
| Update | winget upgrade (list available)winget upgrade --all | winget upgrade --allchoco upgrade allUpdate-Module | sudo apt update && sudo apt upgradesudo dnf upgradebrew update && brew upgradesudo pacman -Syu | apt update only refreshes the package index. apt upgrade does the installing. |
| Remove | winget uninstall Git.Git | winget uninstall Git.Gitchoco uninstall gitUninstall-Module name | sudo apt remove git (keeps config)sudo apt purge git (removes config)sudo apt autoremove (orphaned dependencies)brew uninstall git |
| Task | Windows | macOS | Linux | Notes |
|---|---|---|---|---|
| Install WSL (Linux on Windows) | wsl --install (Ubuntu by default; reboot afterwards)wsl --install -d Debian (pick a distro)wsl -l -v (list distros and versions)wsl --updatewsl --shutdownwsl (open the default distro) | (not needed; macOS is already Unix) | (not needed) | π Run from an administrator prompt. Inside WSL, Windows drives are under /mnt/c and Windows tools are on the PATH, so code . opens VS Code. |
| Package manager | winget --version (built in on Windows 10 1709+ and 11)winget source update(Chocolatey is optional: see chocolatey.org/install) | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"brew doctor | (apt, dnf or pacman is already installed) sudo apt update (refresh the index first) | If winget is missing, install "App Installer" from the Microsoft Store. |
| Git | winget install --id Git.Git -egit --version | xcode-select --install (Apple's git plus compilers)brew install git (newer version) | sudo apt install gitsudo dnf install git | On Windows this also installs Git Bash. |
| GitHub CLI | winget install --id GitHub.cli -egh auth login | brew install ghgh auth login | sudo apt install gh (Ubuntu 23.04+; older distros: see cli.github.com)gh auth login | gh auth login signs in through the browser and stores credentials that git push uses too. |
| SSH key for GitHub | ssh-keygen -t ed25519 -C "you@example.com"Get-Service ssh-agent | Set-Service -StartupType Automatic; Start-Service ssh-agent (PowerShell, π admin)ssh-add $env:USERPROFILE\.ssh\id_ed25519 (PowerShell)gh ssh-key add ~/.ssh/id_ed25519.pub | ssh-keygen -t ed25519 -C "you@example.com"ssh-add --apple-use-keychain ~/.ssh/id_ed25519gh ssh-key add ~/.ssh/id_ed25519.pub | ssh-keygen -t ed25519 -C "you@example.com"eval "$(ssh-agent -s)"; ssh-add ~/.ssh/id_ed25519gh ssh-key add ~/.ssh/id_ed25519.pub | Test with ssh -T git@github.com. The Windows ssh-agent service is off by default. |
| Node.js | winget install OpenJS.NodeJS.LTSwinget install Schniz.fnm (version manager)node -v; npm -v | brew install nodebrew install fnm (version manager) | curl -fsSL https://fnm.vercel.app/install | bash (version manager)fnm install --lts(distro packages are often years old) | A version manager such as fnm or nvm lets you switch Node versions per project. |
| Python | winget install Python.Python.3.12python --versionpy -3 (launcher; picks an installed version) | brew install pythonpython3 --version | sudo apt install python3 python3-pip python3-venvpython3 --version | Per-project environment: python -m venv .venv, then .venv\Scripts\activate (Windows) or source .venv/bin/activate. |
| VS Code | winget install Microsoft.VisualStudioCodecode . (open the current folder) | brew install --cask visual-studio-codecode . (first run Shell Command: Install code from the Command Palette) | sudo snap install code --classic(or the .deb / .rpm from code.visualstudio.com) code . | |
| PowerShell 7 and Windows Terminal | winget install Microsoft.PowerShellwinget install Microsoft.WindowsTerminalpwsh (start PowerShell 7) | brew install --cask powershellpwsh | (see Microsoft's install page for your distro) pwsh | Windows PowerShell 5.1 is built in. PowerShell 7 (pwsh) is the current cross-platform version and installs alongside it. Windows 11 already includes Windows Terminal. |
| Compilers and build tools | winget install Microsoft.VisualStudio.2022.BuildTools(choose "Desktop development with C++" in the installer) | xcode-select --install | sudo apt install build-essentialsudo dnf groupinstall "Development Tools" | Needed by npm and pip packages that compile native code. |
| Docker | winget install Docker.DockerDesktopdocker run hello-world | brew install --cask dockerdocker run hello-world | curl -fsSL https://get.docker.com | shsudo usermod -aG docker $USER (then log out and in)docker run hello-world | Docker Desktop on Windows runs on WSL 2, so install WSL first. |
| Allow PowerShell scripts | Set-ExecutionPolicy RemoteSigned -Scope CurrentUser (PowerShell)Get-ExecutionPolicy -List | (not needed) | (not needed) | Fixes "running scripts is disabled on this system". RemoteSigned runs local scripts and signed downloads only. |
| Check what is installed | winget listgit --version; node -v; python --version; code -vwhere git (path to the executable) | brew listgit --version; node -v; python3 --versionwhich git | apt list --installed 2>/dev/null | grep -i gitgit --version; node -v; python3 --versionwhich git | After installing anything, open a new terminal window. Existing shells keep the old PATH. |
| Task | Command | Notes |
|---|---|---|
| One-time setup | git config --global user.name "Your Name"git config --global user.email "you@example.com"git config --global init.defaultBranch maingit config --list (show all settings) | Settings live in ~/.gitconfig. Drop --global to set them for one repository only. |
| Start a repository | git initgit clone https://github.com/user/repo.gitgit clone --depth 1 URL (latest commit only, fast) | |
| See what changed | git statusgit status -s (short form)git diff (unstaged changes)git diff --staged (what will be committed)git diff main..feature (between branches) | |
| History | git log --oneline --graph --allgit log -p file.txt (changes to one file)git log -5 --statgit show HEAD (last commit in full)git blame file.txt (who changed each line) | |
| Stage and commit | git add file.txtgit add -A (everything)git add -p (pick hunks interactively)git commit -m "Message"git commit -am "Message" (add tracked files and commit)git commit --amend (fix the last commit) | β Do not amend a commit you have already pushed; it rewrites history others may have. |
| Unstage or discard | git restore --staged file.txt (unstage, keep changes)git restore file.txt (discard local changes)git clean -fd (delete untracked files and folders)git clean -n (dry run first) | β restore and clean throw work away with no undo. Run git clean -n first. |
| Branches | git branch (list)git branch -a (include remote)git switch -c feature (create and switch)git switch maingit branch -m old new (rename)git branch -d feature (delete merged)git branch -D feature (force delete) | switch and restore replaced the overloaded checkout in Git 2.23. checkout still works everywhere. |
| Merge and rebase | git merge feature (merge into current branch)git rebase main (replay current branch onto main)git rebase -i HEAD~3 (squash or reorder last 3)git merge --abort / git rebase --abort | Merge keeps history as it happened. Rebase makes it linear. β Never rebase commits that are already pushed and shared. |
| Remotes | git remote -vgit remote add origin https://github.com/user/repo.gitgit remote set-url origin NEW_URL | |
| Push and pull | git push -u origin main (first push; sets upstream)git pushgit pull (fetch and merge)git pull --rebasegit fetch (download without merging)git push origin --delete feature (delete remote branch) | |
| Undo commits | git revert HEAD (new commit that undoes the last one; safe)git reset --soft HEAD~1 (uncommit, keep changes staged)git reset --mixed HEAD~1 (uncommit, keep changes unstaged)git reset --hard HEAD~1 (uncommit and discard changes)git reflog (find lost commits) | β reset --hard deletes work. revert is the safe choice for anything already pushed. reflog can recover a reset for about 30 days. |
| Stash | git stash (shelve changes)git stash push -m "wip" (with a name)git stash listgit stash pop (restore latest and drop it)git stash apply stash@{1}git stash drop | |
| Tags and releases | git tag (list)git tag -a v1.0 -m "Release 1.0"git push --tagsgit checkout v1.0 (look at a tag) | |
| Ignore and untrack files | git rm --cached file.txt (stop tracking, keep file)git rm -r --cached folder/git check-ignore -v file.txt (why is this ignored?)git mv old.txt new.txt (rename and stage) | Patterns in .gitignore only affect files not yet tracked. Untrack committed files with git rm --cached first. |
| Search | git grep "pattern" (search tracked files)git log -S "text" (commits that added or removed text)git log --grep "fix" (search commit messages)git log --author="Name" | |
| Who did what | git shortlog -sn (commits per author)git log --since="2 weeks ago"git bisect start / git bisect good v1.0 / git bisect bad (find the breaking commit) | |
| Help | git help commitgit commit -h (short flag list)git <command> --help |
| Action | CMD | PowerShell | Bash | Notes |
|---|---|---|---|---|
| Auto-complete | Tab | Tab (Ctrl+Space shows a menu) | Tab (press twice to list options) | |
| Previous / next command | β / β (F3 repeats the last one) | β / β | β / β or Ctrl+P / Ctrl+N | |
| Search history | F7 (list), F8 (cycle prefix matches) | Ctrl+R (backward), Ctrl+S (forward), F8 | Ctrl+R (backward), Ctrl+S (forward) | |
| Clear screen | cls (no shortcut) | Ctrl+L | Ctrl+L | |
| Cancel running command | Ctrl+C | Ctrl+C | Ctrl+C | |
| Clear current line | Esc | Esc | Ctrl+U (before cursor), Ctrl+K (after cursor) | In PowerShell, Ctrl+U and Ctrl+K also work with the default key mode. |
| Start / end of line | Home / End | Home / End (also Ctrl+A / Ctrl+E) | Ctrl+A / Ctrl+E (Home / End in most terminals) | |
| Move by word | Ctrl+β / Ctrl+β | Ctrl+β / Ctrl+β | Alt+B / Alt+F (Ctrl+β / β in many terminals) | |
| Delete word before cursor | (none) | Ctrl+Backspace | Ctrl+W | |
| Delete word after cursor | (none) | Ctrl+Delete | Alt+D | |
| Undo an edit | (none) | Ctrl+Z | Ctrl+_ or Ctrl+X Ctrl+U | |
| Paste | Ctrl+V or right-click | Ctrl+V or right-click | Ctrl+Shift+V (Cmd+V on macOS) | Copy and paste are handled by the terminal app, not the shell. In Bash Ctrl+C cancels and Ctrl+V inserts a literal key. |
| Copy | Select, then Enter or Ctrl+C | Select, then Enter or Ctrl+C | Ctrl+Shift+C (Cmd+C on macOS) | |
| Pause / resume output | Ctrl+S / Ctrl+Q | Ctrl+S / Ctrl+Q | Ctrl+S / Ctrl+Q | If the terminal seems frozen, you probably hit Ctrl+S. Press Ctrl+Q. |
| Suspend foreground job | (none) | (none) | Ctrl+Z (resume with fg or bg) | |
| Exit shell | exit | exit (Ctrl+D on an empty line) | exit or Ctrl+D | In CMD, Ctrl+Z is the end-of-file character, not exit. |