Add bash style commands to the Windows PowerShell
As a developer that spends 99% of my time on Linux, doing things on Windows gets cumbersome trying to remember the PowerShell syntax. Here’s an easy way to add the most common bash commands to the PowerShell.
Create the file ‘bash-style-commands.ps1’ in your $HOME directory. Open PowerShell and copy/paste the following:
New-Item -Path "$HOME\bash-style-commands.ps1" -ItemType "file" -Force
To open the file in notepad:
notepad $HOME/bash-style-commands.ps1
In notepad, paste the following and save.
# Bash-style commands for PowerShell
# Claude 3.7 & Eric Hammond
# Usage: Add '. $HOME\bash-style-commands.ps1' to your PowerShell profile
# Basic Linux commands
Set-Alias -Name ls -Value Get-ChildItem -Option AllScope
Set-Alias -Name ll -Value Get-ChildItem -Option AllScope
Set-Alias -Name la -Value Get-ChildItem -Option AllScope
Set-Alias -Name cat -Value Get-Content -Option AllScope
Set-Alias -Name cp -Value Copy-Item -Option AllScope
Set-Alias -Name mv -Value Move-Item -Option AllScope
Set-Alias -Name rm -Value Remove-Item -Option AllScope
Set-Alias -Name grep -Value Select-String -Option AllScope
Set-Alias -Name which -Value Get-Command -Option AllScope
Set-Alias -Name touch -Value New-Item -Option AllScope
Set-Alias -Name clear -Value Clear-Host -Option AllScope
Set-Alias -Name pwd -Value Get-Location -Option AllScope
Set-Alias -Name df -Value Get-PSDrive -Option AllScope
Set-Alias -Name history -Value Get-History -Option AllScope
Set-Alias -Name ps -Value Get-Process -Option AllScope
Set-Alias -Name less -Value more -Option AllScope
Set-Alias -Name who -Value whoami -Option AllScope
# Enhanced linux-like commands
function mkdir-p {
param([string]$path)
New-Item -Path $path -ItemType Directory -Force
}
Set-Alias -Name mkdir -Value mkdir-p -Option AllScope
# Improved ls with colors and formatting (similar to ls -la)
function ll-linux {
param(
[Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[string]$Path = "."
)
Get-ChildItem -Path $Path -Force |
Format-Table -AutoSize Mode,
@{Label="LastWriteTime"; Expression={$_.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")}},
Length,
@{Label="Name"; Expression={
if ($_.PSIsContainer) { "$($_.Name)/" }
elseif ($_.Name -match '\.(exe|bat|cmd)$') { "$($_.Name)*" }
else { $_.Name }
}}
}
Set-Alias -Name ll -Value ll-linux -Option AllScope -Force
# ls -la equivalent
function la-linux {
param(
[Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[string]$Path = "."
)
Get-ChildItem -Path $Path -Force
}
Set-Alias -Name la -Value la-linux -Option AllScope -Force
# grep with context (like grep -A -B)
function grep-context {
param(
[Parameter(Mandatory=$true, Position=0)]
[string]$Pattern,
[Parameter(ValueFromPipeline=$true)]
[string]$InputObject,
[Parameter(Position=1)]
[string]$Path,
[int]$Context = 0
)
if ($Path) {
$result = Select-String -Pattern $Pattern -Path $Path -Context $Context,$Context
}
elseif ($InputObject) {
$result = $InputObject | Select-String -Pattern $Pattern -Context $Context,$Context
}
return $result
}
Set-Alias -Name grepc -Value grep-context -Option AllScope
# touch command that creates or updates file timestamp
function touch-linux {
param(
[Parameter(Mandatory=$true, Position=0)]
[string]$Path
)
if (Test-Path -Path $Path) {
(Get-Item -Path $Path).LastWriteTime = Get-Date
}
else {
New-Item -Path $Path -ItemType File
}
}
Set-Alias -Name touch -Value touch-linux -Option AllScope -Force
# head command
function head-linux {
param(
[Parameter(Mandatory=$true, Position=0)]
[string]$Path,
[Parameter(Position=1)]
[int]$Lines = 10
)
Get-Content -Path $Path -TotalCount $Lines
}
Set-Alias -Name head -Value head-linux -Option AllScope
# tail command
function tail-linux {
param(
[Parameter(Mandatory=$true, Position=0)]
[string]$Path,
[Parameter(Position=1)]
[int]$Lines = 10
)
Get-Content -Path $Path -Tail $Lines
}
Set-Alias -Name tail -Value tail-linux -Option AllScope
# find command (simplified)
function find-linux {
param(
[Parameter(Position=0)]
[string]$Path = ".",
[Parameter(Position=1)]
[string]$Pattern = "*"
)
Get-ChildItem -Path $Path -Recurse -Filter $Pattern
}
Set-Alias -Name find -Value find-linux -Option AllScope
# chmod (simplified permissions)
function chmod-linux {
param(
[Parameter(Mandatory=$true, Position=0)]
[string]$Mode,
[Parameter(Mandatory=$true, Position=1)]
[string]$Path
)
# This is a very simplified version that just toggles read-only
if ($Mode -match "^[+]r") {
Set-ItemProperty -Path $Path -Name IsReadOnly -Value $false
Write-Host "Made $Path writable"
}
elseif ($Mode -match "^[-]w") {
Set-ItemProperty -Path $Path -Name IsReadOnly -Value $true
Write-Host "Made $Path read-only"
}
else {
Write-Host "Simplified chmod only supports +r and -w"
}
}
Set-Alias -Name chmod -Value chmod-linux -Option AllScope
# wget equivalent
function wget-linux {
param(
[Parameter(Mandatory=$true, Position=0)]
[string]$Uri,
[Parameter(Position=1)]
[string]$OutFile = (Split-Path -Path $Uri -Leaf)
)
Invoke-WebRequest -Uri $Uri -OutFile $OutFile
Write-Host "Downloaded $Uri to $OutFile"
}
Set-Alias -Name wget -Value wget-linux -Option AllScope
# cd with pushd behavior for easier navigation
function cd-linux {
param(
[Parameter(Position=0)]
[string]$Path = "~"
)
if ($Path -eq "-") {
# cd - to go back to previous directory
$previousPath = (Get-Location -Stack).Path
if ($previousPath) {
Pop-Location
Get-Location
}
else {
Write-Host "No previous directory"
}
}
else {
Push-Location -Path $Path -StackName "CD_HISTORY"
Get-Location
}
}
Set-Alias -Name cd -Value cd-linux -Option AllScope -Force
# A function to go back in directory history
function cd-back {
param(
[int]$Steps = 1
)
for ($i = 0; $i -lt $Steps; $i++) {
if ((Get-Location -Stack -StackName "CD_HISTORY").Count -gt 0) {
Pop-Location -StackName "CD_HISTORY"
}
else {
Write-Host "Cannot go back further"
break
}
}
Get-Location
}
Set-Alias -Name back -Value cd-back -Option AllScope
# A simple 'clear terminal history' command
function clear-history {
Clear-History
Write-Host "Command history cleared!"
}
Set-Alias -Name ch -Value clear-history -Option AllScope
# Shorthand for navigating up directories
function cd-up {
param(
[int]$Levels = 1
)
$path = (Get-Location).Path
for ($i = 0; $i -lt $Levels; $i++) {
$path = Split-Path -Path $path -Parent
}
Set-Location -Path $path
Get-Location
}
Set-Alias -Name ".." -Value cd-up -Option AllScope
# For multiple levels, use: .. 2 or .. 3
# Environment variable echo like in bash
function echo-env {
param(
[Parameter(Mandatory=$true, Position=0)]
[string]$Name
)
$varName = $Name -replace '^\$'
$value = (Get-Item -Path "Env:$varName" -ErrorAction SilentlyContinue).Value
if ($value) {
Write-Output $value
}
else {
Write-Host "Environment variable $varName not found"
}
}
Set-Alias -Name echoe -Value echo-env -Option AllScope
# Print welcome message when this script is loaded
Write-Host "Bash-style commands loaded! You now have Linux-like commands in PowerShell." -ForegroundColor Green
Write-Host "Type 'bash-help' for a list of available commands." -ForegroundColor Cyan
# Help function to show available Linux-style commands
function bash-help {
Write-Host "Available Bash-style commands:" -ForegroundColor Cyan
Write-Host "--------------------------------" -ForegroundColor Cyan
Write-Host "ls, ll, la - List directory contents (with different formatting options)"
Write-Host "cat - Display file contents"
Write-Host "cp - Copy files or directories"
Write-Host "mv - Move or rename files or directories"
Write-Host "rm - Remove files or directories"
Write-Host "grep, grepc - Search for patterns (grepc adds context lines)"
Write-Host "which - Show the full path of commands"
Write-Host "touch - Create new files or update timestamps"
Write-Host "clear - Clear the terminal screen"
Write-Host "pwd - Show current directory"
Write-Host "head - Show first N lines of a file"
Write-Host "tail - Show last N lines of a file"
Write-Host "find - Search for files in a directory hierarchy"
Write-Host "chmod - Change file permissions (simplified +r/-w only)"
Write-Host "wget - Download files from the web"
Write-Host "cd - Change directory with history (cd - to go back)"
Write-Host "back - Go back in directory history"
Write-Host ".. - Go up one or more directory levels (.. 2 for two levels)"
Write-Host "echoe - Echo environment variables (e.g., echoe PATH)"
Write-Host "ch - Clear command history"
Write-Host "bash-help - Show this help message"
Write-Host ""
Write-Host "Note: These commands are simplified emulations of Linux commands." -ForegroundColor Yellow
Write-Host " Some features may work differently from their Linux counterparts." -ForegroundColor Yellow
}
Next, open your PowerShell $PROFILE in notepad:
notepad $PROFILE
Add this line at the end of your profile file and save:
. $HOME\bash-style-commands.ps1
Restart PowerShell, and you should see:
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
Bash-style commands loaded! You now have Linux-like commands in PowerShell.
Type 'bash-help' for a list of available commands.
C:\Users\user> bash-help
Available Bash-style commands:
--------------------------------
ls, ll, la - List directory contents (with different formatting options)
cat - Display file contents
cp - Copy files or directories
mv - Move or rename files or directories
rm - Remove files or directories
grep, grepc - Search for patterns (grepc adds context lines)
which - Show the full path of commands
touch - Create new files or update timestamps
clear - Clear the terminal screen
pwd - Show current directory
head - Show first N lines of a file
tail - Show last N lines of a file
find - Search for files in a directory hierarchy
chmod - Change file permissions (simplified +r/-w only)
wget - Download files from the web
cd - Change directory with history (cd - to go back)
back - Go back in directory history
.. - Go up one or more directory levels (.. 2 for two levels)
echoe - Echo environment variables (e.g., echoe PATH)
ch - Clear command history
bash-help - Show this help message
Note: These commands are simplified emulations of Linux commands.
Some features may work differently from their Linux counterparts.