Appearance
ksh - Korn Shell
The Korn Shell (ksh) is a powerful Unix shell developed by David Korn at Bell Labs, first released in 1983. As a superset of the Bourne shell (sh), ksh combines POSIX compliance with advanced programming features, making it particularly popular in enterprise environments and among system administrators who require robust scripting capabilities. The Korn shell offers superior performance, extensive built-in functionality, and sophisticated programming constructs while maintaining backward compatibility with traditional shell scripts. It serves as a bridge between the simplicity of POSIX sh and the advanced features found in modern shells.
Installation and Setup
Korn Shell Variants
ksh
# Check which ksh variant is installed
echo $KSH_VERSION
# Output examples:
# Version AJM 93u+ 2012-08-01 (ksh93)
# Version JM 93t+ 2010-03-05 (ksh93)
# Common ksh implementations
which ksh # System ksh
which ksh93 # AT&T ksh93
which mksh # MirBSD Korn Shell
which pdksh # Public Domain Korn Shell
# Check shell features
print $(.sh.version) 2>/dev/null || echo "Not ksh93"
Installing Korn Shell
ksh
# Ubuntu/Debian
sudo apt update && sudo apt install ksh
# For ksh93 specifically
sudo apt install ksh93
# CentOS/RHEL/Fedora
sudo dnf install ksh
# macOS (using Homebrew)
brew install ksh93
# Arch Linux
sudo pacman -S ksh
# FreeBSD
pkg install ksh93
# From source (ksh93)
git clone https://github.com/att/ast.git
cd ast
bin/package make
Setting ksh as Default Shell
ksh
# Check ksh installation
which ksh
/bin/ksh
# Add ksh to available shells
echo /bin/ksh | sudo tee -a /etc/shells
# Set ksh as default shell
chsh -s /bin/ksh
# Verify change (restart terminal)
echo $SHELL
/bin/ksh
# Check ksh version and features
echo $KSH_VERSION
set | grep KSH
Basic Configuration
ksh
# Create .kshrc for interactive shell configuration
cat > ~/.kshrc << 'EOF'
# Korn Shell configuration
# Set environment variables
export EDITOR=vi
export PAGER=less
export HISTSIZE=1000
# Set prompt
PS1='${USER}@${HOSTNAME}:${PWD}$ '
# Aliases
alias ll='ls -l'
alias la='ls -la'
alias h='history'
# Enable vi editing mode
set -o vi
# History options
set -o trackall
EOF
# Set ENV variable to load .kshrc
export ENV=~/.kshrc
echo 'export ENV=~/.kshrc' >> ~/.profile
Ksh-Specific Features and Syntax
Variable Types and Declarations
ksh
# Integer variables
typeset -i num=10
integer count=0
count+=5 # count is now 5
# Floating point variables (ksh93)
typeset -F2 price=19.99 # 2 decimal places
float temperature=98.6
# Array variables
typeset -a fruits
fruits=(apple banana orange)
set -A colors red green blue # Alternative syntax
# Associative arrays (ksh93)
typeset -A config
config[host]=localhost
config[port]=8080
# Read-only variables
typeset -r CONSTANT="unchangeable"
readonly PI=3.14159
# Exported variables
typeset -x PATH="/usr/local/bin:$PATH"
export LANG=en_US.UTF-8
Advanced Parameter Expansion
ksh
# String manipulation
string="Hello, World!"
print ${#string} # Length: 13
print ${string#Hello} # Remove from beginning: , World!
print ${string%World!} # Remove from end: Hello,
print ${string/Hello/Hi} # Replace first: Hi, World!
print ${string//l/L} # Replace all: HeLLo, WorLd!
# Case conversion (ksh93)
print ${string^^} # Uppercase: HELLO, WORLD!
print ${string,,} # Lowercase: hello, world!
print ${string^} # Capitalize first: Hello, world!
# Substring extraction
print ${string:0:5} # First 5 characters: Hello
print ${string:7} # From position 7: World!
print ${string:(-6)} # Last 6 characters: World!
# Default values
print ${undefined:-"default"} # Use default if undefined
print ${undefined:="default"} # Set default if undefined
print ${defined:+"alternate"} # Use alternate if defined
Arrays and Associative Arrays
ksh
# Indexed arrays
typeset -a numbers
numbers=(1 2 3 4 5)
numbers[10]=100 # Sparse array
# Array operations
print ${numbers[0]} # First element
print ${numbers[@]} # All elements
print ${#numbers[@]} # Number of elements
print ${!numbers[@]} # All indices
# Array assignment
numbers+=(6 7 8) # Append elements
unset numbers[2] # Remove element
# Associative arrays (ksh93)
typeset -A person
person[name]="John Doe"
person[age]=30
person[city]="New York"
# Iterate over associative array
for key in "${!person[@]}"; do
print "$key: ${person[$key]}"
done
# Multi-dimensional arrays (ksh93)
typeset -A matrix
matrix[1,1]=a
matrix[1,2]=b
matrix[2,1]=c
matrix[2,2]=d
Arithmetic and Mathematical Operations
ksh
# Arithmetic expansion
result=$((5 + 3 * 2)) # 11
result=$((2 ** 8)) # 256 (exponentiation)
# Arithmetic with variables
typeset -i x=10 y=3
result=$((x / y)) # Integer division: 3
remainder=$((x % y)) # Modulo: 1
# Floating point arithmetic (ksh93)
typeset -F result
result=$((10.0 / 3.0)) # 3.333333
# Mathematical functions (ksh93)
result=$((sin(3.14159/2))) # Sine function
result=$((sqrt(16))) # Square root
result=$((log(10))) # Natural logarithm
result=$((exp(2))) # Exponential function
# Increment and decrement
((x++)) # Post-increment
((++x)) # Pre-increment
((x--)) # Post-decrement
((--x)) # Pre-decrement
((x += 5)) # Add and assign
Advanced I/O and Redirection
ksh
# Co-processes
print -p "command" # Send to co-process
read -p response # Read from co-process
# File descriptors
exec 3< input.txt # Open file for reading
exec 4> output.txt # Open file for writing
read line <&3 # Read from fd 3
print "data" >&4 # Write to fd 4
exec 3<&- # Close fd 3
exec 4>&- # Close fd 4
# Here strings
command <<< "input string"
# Process substitution (ksh93)
diff <(sort file1) <(sort file2)
command > >(process_output)
# Network I/O (ksh93)
exec 5<>/dev/tcp/hostname/port
print -u5 "GET / HTTP/1.0\n"
read -u5 response
Control Structures and Flow Control
Enhanced Conditional Statements
ksh
# [[ ]] conditional (preferred in ksh)
if [[ $string == pattern* ]]; then
print "String starts with pattern"
fi
if [[ $string =~ regex ]]; then
print "String matches regex"
fi
if [[ -f $file && -r $file ]]; then
print "File exists and is readable"
fi
# Pattern matching in conditionals
case $filename in
*.@(txt|doc|pdf))
print "Document file"
;;
*.@(jpg|png|gif))
print "Image file"
;;
*)
print "Unknown file type"
;;
esac
# Numeric comparisons
if (( num > 10 && num < 100 )); then
print "Number is between 10 and 100"
fi
Advanced Loop Constructs
ksh
# For loops with ranges
for i in {1..10}; do
print "Number: $i"
done
for i in {1..10..2}; do # Step by 2
print "Odd number: $i"
done
# C-style for loops
for ((i=1; i<=10; i++)); do
print "Counter: $i"
done
# For loops with arrays
for element in "${array[@]}"; do
print "Element: $element"
done
# While loops with advanced conditions
while (( count < limit )); do
print "Count: $count"
((count++))
done
# Until loops
until [[ -f ready.flag ]]; do
print "Waiting for ready flag..."
sleep 2
done
# Select loops for menus
select option in "Option 1" "Option 2" "Option 3" "Quit"; do
case $option in
"Option 1")
print "You selected option 1"
;;
"Option 2")
print "You selected option 2"
;;
"Option 3")
print "You selected option 3"
;;
"Quit")
break
;;
*)
print "Invalid selection"
;;
esac
done
Exception Handling
ksh
# Trap signals and errors
cleanup() {
print "Cleaning up..."
rm -f temp_files
exit 1
}
trap cleanup INT TERM EXIT
# Error handling with ERR trap
error_handler() {
print "Error occurred in line $1"
exit 1
}
trap 'error_handler $LINENO' ERR
set -e # Exit on error
# Try-catch equivalent using functions
try() {
"$@"
return $?
}
catch() {
case $? in
0) return 0 ;;
*)
print "Error: $1"
return 1
;;
esac
}
# Usage
if try risky_command; then
print "Command succeeded"
else
catch "Command failed"
fi
Functions and Advanced Programming
Function Definition and Features
ksh
# Basic function definition
function greet {
print "Hello, $1!"
}
# Alternative syntax
greet() {
print "Hello, $1!"
}
# Function with local variables
function calculate_stats {
typeset -i sum=0 count=0
typeset -F average
for num in "$@"; do
((sum += num))
((count++))
done
if ((count > 0)); then
((average = sum / count))
print "Sum: $sum, Count: $count, Average: $average"
fi
}
# Function with return value
function is_prime {
typeset -i num=$1 i
if ((num < 2)); then
return 1
fi
for ((i = 2; i * i <= num; i++)); do
if ((num % i == 0)); then
return 1
fi
done
return 0
}
# Usage
if is_prime 17; then
print "17 is prime"
fi
Advanced Function Features
ksh
# Function with named parameters (ksh93)
function process_file {
typeset file="$1" mode="${2:-read}" verbose="${3:-false}"
[[ $verbose == true ]] && print "Processing $file in $mode mode"
case $mode in
read)
cat "$file"
;;
write)
print "Writing to $file"
;;
*)
print "Unknown mode: $mode" >&2
return 1
;;
esac
}
# Recursive functions
function factorial {
typeset -i n=$1
if ((n <= 1)); then
print 1
else
print $((n * $(factorial $((n - 1)))))
fi
}
# Function with variable number of arguments
function sum_all {
typeset -i total=0
while (($# > 0)); do
((total += $1))
shift
done
print $total
}
# Function libraries and namespaces (ksh93)
namespace math {
function add { print $(($1 + $2)); }
function multiply { print $(($1 * $2)); }
}
# Usage
result=$(math.add 5 3)
Co-processes and Background Jobs
ksh
# Start co-process
command |&
coproc_pid=$!
# Communicate with co-process
print -p "input data"
read -p response
# Background job management
long_running_command &
job_pid=$!
# Wait for specific job
wait $job_pid
# Job control
jobs # List active jobs
fg %1 # Bring job 1 to foreground
bg %1 # Send job 1 to background
kill %1 # Kill job 1
# Disown jobs
disown %1 # Remove job from job table
Built-in Commands and Utilities
Ksh Built-in Commands
ksh
# print command (preferred over echo)
print "Simple message"
print -n "No newline"
print -r "Raw output (no escape processing)"
print -u2 "Output to stderr"
# printf for formatted output
printf "%s: %d\n" "Count" 42
printf "%-10s %5d\n" "Name" 123
# read with advanced options
read var # Read single variable
read -r line # Raw read (no backslash processing)
read -t 10 input # Read with timeout
read -s password # Silent read (no echo)
read -A array # Read into array
# typeset for variable attributes
typeset -i integer_var=10
typeset -F2 float_var=3.14
typeset -u upper_var="hello" # Uppercase
typeset -l lower_var="HELLO" # Lowercase
typeset -r readonly_var="constant"
# whence command (which equivalent)
whence command # Show command type
whence -v command # Verbose output
whence -a command # Show all matches
String Processing
ksh
# String comparison and matching
[[ $string == pattern ]] # Pattern matching
[[ $string != pattern ]] # Pattern non-matching
[[ $string < other ]] # Lexicographic comparison
[[ $string > other ]] # Lexicographic comparison
# Pattern matching with extended globs
[[ $filename == *.@(txt|doc) ]] # Match .txt or .doc
[[ $string == +([0-9]) ]] # Match one or more digits
[[ $string == ?([+-])+([0-9]) ]] # Optional sign, required digits
# String manipulation functions (ksh93)
string="Hello, World!"
print ${string/World/Universe} # Replace first occurrence
print ${string//l/L} # Replace all occurrences
print ${string#*,} # Remove up to first comma
print ${string%,*} # Remove from last comma
File and Directory Operations
ksh
# File testing
[[ -e file ]] # File exists
[[ -f file ]] # Regular file
[[ -d dir ]] # Directory
[[ -L link ]] # Symbolic link
[[ -r file ]] # Readable
[[ -w file ]] # Writable
[[ -x file ]] # Executable
[[ -s file ]] # Non-empty file
# File comparison
[[ file1 -nt file2 ]] # file1 newer than file2
[[ file1 -ot file2 ]] # file1 older than file2
[[ file1 -ef file2 ]] # Same file (hard links)
# Directory operations
cd directory # Change directory
pushd directory # Push directory onto stack
popd # Pop directory from stack
dirs # Show directory stack
# File globbing with extended patterns
ls *.@(txt|doc) # Files ending in .txt or .doc
ls +([0-9]).txt # Files with numeric names
ls !(*.tmp) # All files except .tmp files
Configuration and Customization
Environment and Shell Options
ksh
# Shell options
set -o vi # Vi editing mode
set -o emacs # Emacs editing mode
set -o trackall # Track all commands for hashing
set -o monitor # Enable job control
set -o notify # Report job status immediately
set -o noglob # Disable filename expansion
set -o noclobber # Prevent output redirection from overwriting
# History options
set -o hist # Enable command history
HISTSIZE=1000 # History size in memory
HISTFILE=~/.ksh_history # History file location
# Prompt customization
PS1='${USER}@${HOSTNAME}:${PWD##*/}$ '
PS2='> ' # Continuation prompt
PS3='#? ' # Select prompt
PS4='+ ' # Debug prompt
# Advanced prompt with functions
function set_prompt {
typeset git_branch=""
if [[ -d .git ]]; then
git_branch=" ($(git branch --show-current 2>/dev/null))"
fi
PS1="${USER}@${HOSTNAME}:${PWD##*/}${git_branch}$ "
}
# Set prompt command (ksh93)
PROMPT_COMMAND=set_prompt
Aliases and Functions
ksh
# Simple aliases
alias ll='ls -l'
alias la='ls -la'
alias h='history'
alias ..='cd ..'
alias ...='cd ../..'
# Aliases with parameters (use functions instead)
function mkcd {
mkdir -p "$1" && cd "$1"
}
function extract {
case $1 in
*.tar.gz|*.tgz) tar xzf "$1" ;;
*.tar.bz2|*.tbz2) tar xjf "$1" ;;
*.zip) unzip "$1" ;;
*.rar) unrar x "$1" ;;
*) print "Unknown archive format" ;;
esac
}
# Conditional aliases
if whence -q vim; then
alias vi=vim
fi
# Platform-specific aliases
case $(uname) in
Linux)
alias ls='ls --color=auto'
;;
Darwin)
alias ls='ls -G'
;;
esac
Completion and Editing
ksh
# Command line editing
set -o vi # Vi editing mode
set -o emacs # Emacs editing mode (default)
# Key bindings (vi mode)
# Esc: Enter command mode
# i: Insert mode
# a: Append mode
# A: Append at end of line
# I: Insert at beginning of line
# dd: Delete line
# yy: Yank (copy) line
# p: Paste
# Key bindings (emacs mode)
# Ctrl+A: Beginning of line
# Ctrl+E: End of line
# Ctrl+K: Kill to end of line
# Ctrl+U: Kill to beginning of line
# Ctrl+W: Kill previous word
# Ctrl+Y: Yank (paste)
# Ctrl+R: Reverse search
# Tab completion (basic)
set -o complete # Enable completion
Performance and Optimization
Performance Features
ksh
# Built-in commands vs external commands
# Use built-ins when possible for better performance
typeset -i count=0 # Built-in integer arithmetic
((count++)) # Built-in increment
# String operations
string="Hello, World!"
print ${#string} # Built-in length
print ${string%World*} # Built-in pattern removal
# Array operations
typeset -a array=(1 2 3 4 5)
print ${#array[@]} # Built-in array length
# Avoid subshells when possible
# Slow: result=$(command)
# Fast: command | read result (when appropriate)
# Use co-processes for repeated communication
command |&
for data in "${input_data[@]}"; do
print -p "$data"
read -p result
process_result "$result"
done
Memory Management
ksh
# Unset variables when no longer needed
unset large_array
unset temporary_variable
# Use local variables in functions
function process_data {
typeset -a local_array
typeset local_var
# Process data with local variables
# Variables are automatically cleaned up
}
# Limit history size
HISTSIZE=500 # Reasonable history size
Debugging and Profiling
ksh
# Debug mode
set -x # Print commands as executed
set +x # Disable debug mode
# Verbose mode
set -v # Print input lines as read
set +v # Disable verbose mode
# Function tracing
function trace_function {
print "Entering function: ${.sh.fun}" >&2
print "Arguments: $*" >&2
}
# Performance timing
function time_function {
typeset start_time end_time
start_time=$(date +%s%N)
"$@" # Execute command
end_time=$(date +%s%N)
print "Execution time: $(((end_time - start_time) / 1000000)) ms" >&2
}
# Usage
time_function complex_operation arg1 arg2
Best Practices and Advanced Techniques
Script Structure
ksh
#!/bin/ksh
# Script description
# Author: Your Name
# Date: YYYY-MM-DD
# Strict mode
set -euo pipefail
# Global variables
typeset -r SCRIPT_NAME=${0##*/}
typeset -r SCRIPT_DIR=${0%/*}
typeset -r VERSION="1.0"
# Functions
function usage {
cat << EOF
Usage: $SCRIPT_NAME [OPTIONS] [ARGUMENTS]
OPTIONS:
-h, --help Show this help
-v, --version Show version
-d, --debug Enable debug mode
EOF
}
function main {
# Parse arguments
while (($# > 0)); do
case $1 in
-h|--help)
usage
exit 0
;;
-v|--version)
print "$SCRIPT_NAME version $VERSION"
exit 0
;;
-d|--debug)
set -x
shift
;;
-*)
print "Unknown option: $1" >&2
usage >&2
exit 1
;;
*)
break
;;
esac
done
# Main logic here
print "Script execution completed"
}
# Error handling
function cleanup {
# Cleanup code
rm -f temp_files
}
trap cleanup EXIT
# Run main function
main "$@"
Error Handling Patterns
ksh
# Robust error handling
function safe_command {
if ! command "$@"; then
print "Error: Command failed: $*" >&2
return 1
fi
}
# Input validation
function validate_file {
typeset file=$1
if [[ ! -f $file ]]; then
print "Error: File '$file' does not exist" >&2
return 1
fi
if [[ ! -r $file ]]; then
print "Error: File '$file' is not readable" >&2
return 1
fi
return 0
}
# Retry mechanism
function retry_command {
typeset -i attempts=3 delay=1
typeset command="$*"
for ((i = 1; i <= attempts; i++)); do
if eval "$command"; then
return 0
fi
if ((i < attempts)); then
print "Attempt $i failed, retrying in $delay seconds..." >&2
sleep $delay
((delay *= 2))
fi
done
print "All $attempts attempts failed" >&2
return 1
}
Security Considerations
ksh
# Input sanitization
function sanitize_input {
typeset input=$1
# Remove dangerous characters
input=${input//[;&|`$()]/}
# Validate against whitelist
if [[ $input != +([a-zA-Z0-9_.-]) ]]; then
print "Invalid input: $input" >&2
return 1
fi
print "$input"
}
# Safe temporary files
function create_temp_file {
typeset temp_file
temp_file=$(mktemp) || {
print "Failed to create temporary file" >&2
return 1
}
# Set restrictive permissions
chmod 600 "$temp_file"
print "$temp_file"
}
# Secure PATH
export PATH="/usr/local/bin:/usr/bin:/bin"
# Use full paths for critical commands
/bin/rm -f "$temp_file"
/usr/bin/find "$directory" -name "*.tmp" -delete
The Korn Shell stands as a powerful and mature shell that bridges traditional Unix shell programming with modern scripting needs. Its combination of POSIX compliance, advanced programming features, and excellent performance makes it particularly valuable in enterprise environments where reliability and portability are paramount. While it may not have the extensive plugin ecosystems of modern shells like Zsh, ksh's built-in capabilities, mathematical functions, and robust scripting features make it an excellent choice for system administration, automation, and complex shell programming tasks.