ksh - Korn Shell¶
Die Korn Shell (ksh) ist eine mächtige Unix Shell entwickelt von David Korn in Bell Labs, die erst 1983 veröffentlicht wurde. Als Superset der Bourne Shell (sh) kombiniert ksh die POSIX-Compliance mit erweiterten Programmierfunktionen und macht sie besonders beliebt in Unternehmensumgebungen und bei Systemadministratoren, die robuste Skriptfunktionen benötigen. Die Korn Shell bietet überlegene Leistung, umfangreiche integrierte Funktionalität und anspruchsvolle Programmierkonstrukte unter Beibehaltung der Rückwärtskompatibilität mit traditionellen Shell-Skripten. Es dient als Brücke zwischen der Einfachheit von POSIX sh und den fortschrittlichen Funktionen in modernen Schalen gefunden.
Installation und Inbetriebnahme¶
Korn Shell Varianten¶
```bash
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" ```_
Installation von Korn Schale¶
```bash
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 ```_
ksh als Standard Shell¶
```bash
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 ```_
Grundkonfiguration¶
```bash
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 Eigenschaften und Syntax¶
Variable Arten und Erklärungen¶
```bash
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 ```_
Erweiterte Parametererweiterung¶
```bash
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 und assoziative Arrays¶
```bash
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 ```_
Arithmetische und mathematische Operationen¶
```bash
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 ```_
Fortgeschrittene I/O und Umleitung¶
```bash
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 ```_
Steuerungsstrukturen und Durchflussregelung¶
Verbesserte bedingte Aussagen¶
```bash
[[ ]] 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¶
```bash
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 ```_
Außergewöhnliche Handhabung¶
```bash
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 ```_
Funktionen und erweiterte Programmierung¶
Funktion Definition und Merkmale¶
```bash
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 ```_
Erweiterte Funktionen¶
```bash
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-Prozesse und Hintergrund Jobs¶
```bash
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 ```_
Eingebaute Kommandos und Dienstprogramme¶
Ksh Eingebaute Befehle¶
```bash
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¶
```bash
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 ```_
Datei und Verzeichnis Operationen¶
```bash
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 ```_
Konfiguration und Anpassung¶
Umwelt und Shell Optionen¶
```bash
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 ```_
Alias und Funktionen¶
```bash
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 ```_
Fertigstellung und Bearbeitung¶
```bash
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 ```_
Leistung und Optimierung¶
Leistungsmerkmale¶
```bash
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 ```_
Speicherverwaltung¶
```bash
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 und Profiling¶
```bash
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 und Advanced Techniques¶
Schriftstruktur¶
```bash
!/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 "$@" ```_
Fehler Handling Muster¶
```bash
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
\\} ```_
Sicherheitsüberlegungen¶
```bash
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 ```_
Der Korn Shell steht als leistungsfähige und reife Shell, die traditionelle Unix Shell-Programmierung mit modernen Skriptanforderungen überbrückt. Seine Kombination aus POSIX-Compliance, fortschrittlichen Programmierfunktionen und exzellenter Leistung macht es besonders wertvoll in Unternehmensumgebungen, in denen Zuverlässigkeit und Portabilität überwiegen. Obwohl es nicht die umfangreichen Plugin-Ökosysteme moderner Shells wie Zsh haben kann, machen kshs integrierte Fähigkeiten, mathematische Funktionen und robuste Skripting-Funktionen es zu einer ausgezeichneten Wahl für Systemverwaltung, Automatisierung und komplexe Shell-Programmierungsaufgaben.