Recent from talks
Nothing was collected or created yet.
Comparison of command shells
View on Wikipedia
This article needs additional citations for verification. (August 2011) |

This article catalogs comparable aspects of notable operating system shells.
General characteristics
[edit]| Shell | Usual environment
|
Usually invoked
|
Introduced
|
Default login shell in
|
Default script shell in
|
License | Source code
availability |
User interface
|
Mouse support | Unicode support |
ISO 8601 support |
Stream redirection | Configurability | Startup/shutdown scripts |
Batch scripts
|
Logging | Available as
statically linked, independent single file executable | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Thompson shell | UNIX | sh | 1971 | — | UNIX | UNIX | — | Yes | Text-based CLI | No | No | — | Yes | — | — | — | — | — | — |
| Bourne shell 1977 version | 7th Ed. UNIX | sh | 1977 | Yes[1] | 7th Ed. UNIX | 7th Ed. UNIX, | Proprietary[2] | Yes | Text-based CLI | No | No | — | Yes | Yes (arbitrary fds[citation needed]) |
Yes (via variables and options) |
Yes (.profile) |
Yes (Unix feature) |
No | Yes |
| Bourne shell current version | Various UNIX | sh | 1977 | Yes[3] | SunOS-5.x, FreeBSD[4] | SunOS-5.x | CDDL[5][better source needed] | Yes | Text-based CLI | No | Yes[nb 1][better source needed] | — | Yes | Yes (arbitrary fds[citation needed]) |
Yes (via variables and options) |
Yes (.profile) |
Yes (Unix feature) |
Yes[nb 2] | Yes |
| POSIX shell[6] | POSIX | sh | 1992[7] | — | — | POSIX | — | — | Text-based CLI | No | Yes if used by configured locale |
— | Yes | Yes (arbitrary fds[citation needed]) |
Yes (via variables and options) |
Unspecified (.profile given as an example) |
Yes (Unix feature) |
Yes | — |
| bash (v4) | POSIX | bash, sh | 1989[8] | Yes | GNU, Linux (default for root), macOS 10.3–10.14 | GNU, Linux, Haiku, macOS 10.3–10.14 | GPL | Yes | Text-based CLI | No | Yes[9][better source needed] | Yes (printf builtin) |
Yes | Yes (arbitrary fds[citation needed]) |
Yes (via variables and options) |
Yes (/etc/profile, .bash_profile, .bash_login, .profile, .bashrc) |
Yes (Unix feature) |
Yes | Yes |
| csh | POSIX | csh | 1978 | Yes | SunOS | ? | BSD | Yes | Text-based CLI | No | No | ? | Yes | Yes (stdin, stdout, stdout+stderr) |
Yes (via variables and options) |
Yes (~/.cshrc, ~/.login, ~/.logout) |
Yes (Unix feature) |
Yes | Yes |
| tcsh | POSIX | tcsh, csh | 1983[10] | Yes | FreeBSD (former default for root),[11] formerly Mac OS X | ? | BSD | Yes | Text-based CLI | No | Yes | ? | Yes | Yes (stdin, stdout, stdout+stderr) |
Yes (via variables and options) |
Yes (/etc/csh.cshrc, /etc/csh.login, ~/.tcshrc, ~/.cshrc, ~/.history, ~/.login, ~/.cshdirs) |
Yes (Unix feature) |
Yes | Yes |
| Hamilton C shell | Win32, OS/2 | csh | 1988[12] | Yes (OS/2 version no longer maintained) |
Optional | Optional | Proprietary | No | Text-based CLI | No | No | Yes (-t timestamp operator) |
Yes | Yes (stdin, stdout, stdout+stderr) |
Yes (via variables and options) |
Yes (via login.csh, startup.csh and logout.csh) |
Yes (command line option) |
Yes | Yes |
| Scsh | POSIX | scsh | 1994 | Yes | ? | ? | BSD-style | Yes | ? | ? | ? | ? | ? | Yes | ? | ? | ? | ? | Yes |
| ksh (ksh93t+) | POSIX | ksh | 1983[13][14] | Yes | AIX, HP-UX | OpenSolaris | Common Public License | Yes | Text-based CLI | No | Yes | Yes (printf builtin with %(%F)T[15]) |
Yes | Yes (fds up to 9)[15] |
Yes (via variables and options) |
Yes (system and user's profile and kshrc) |
Yes (Unix feature) |
Yes | Yes |
| pdksh | POSIX | ksh, sh | 1989? | Yes | OpenBSD[16] | OpenBSD[16] | Public domain | Yes | Text-based CLI | No | No | — | Yes | Yes (arbitrary fds[citation needed]) |
Yes (via variables and options) |
Yes (/etc/profile, .profile) |
Yes (Unix feature) |
Yes | Yes |
| zsh | POSIX | zsh | 1990 | Yes | Deepin, GoboLinux, Grml, macOS 10.15+, Kali 2020.4+ | Grml, macOS 10.15+ | MIT-style | Yes | Text-based CLI | Yes via additional code[17] |
Yes | Yes (various internal features involving the date, by using the %F strftime format[18] and the -i option for the fc builtin[19]) |
Yes | Yes (fds up to 9)[20] |
Yes (via variables, options, functions, styles, etc.) |
Yes (system and user's zshenv, zprofile, zshrc, zlogin, zlogout) |
Yes (Unix feature) |
Yes | Yes |
| ash | POSIX | sh | 1989 | Yes | Minix, BusyBox based systems | NetBSD, Minix, BusyBox based systems | BSD-style | Yes | Text-based CLI | No | Partial (for BusyBox, supported in command-line editing, but not in string handling[21]) |
— | Yes | Yes (arbitrary fds[citation needed]) |
Yes (via variables and options) |
Yes (/etc/profile, .profile) |
Yes (Unix feature) |
Yes | Yes |
| CCP | CP/M, MP/M | (CCP) | 1976 (1974) | No | CP/M (no login), MP/M | CP/M, MP/M | Freeware (originally proprietary) | Yes (originally closed-source) | Text-based CLI | No | No | No | No | No | No | Yes (automatic via $$$.SUB) | Partial (only via external SUBMIT command to update $$$.SUB) |
No | Yes |
| COMMAND.COM | DOS | COMMAND | 1980 | No (3rd party implementations, not bound to a specific DOS vendor or version, available) |
DOS, Windows 95, 98, SE, ME | DOS, Windows 95, 98, SE, ME | vendor specific, f.e. MS-EULA,[nb 3] or BSD/GPL (free clones) | No (except for OpenDOS, DR-DOS, PTS/DOS and FreeDOS) | Text-based CLI | No | No | No (except for DR-DOS) | Yes (via COMMAND con: or CTTY con:) | Yes (stdin, stdout) |
Yes (via startup parameters and environment variables, DR-DOS also supports DIR /C /R user-default switch command) | Yes (automatic \AUTOEXEC.BAT for primary shell, or explicitly via /P, /P:filename.bat or /K startup options) | Yes (via CALL command or /C and /K startup options) | No | Yes |
| OS/2 CMD.EXE | OS/2, eComStation, ArcaOS | CMD | 1987 | No | OS/2, eComStation, ArcaOS | OS/2, eComStation, ArcaOS | IBM-EULA[nb 4] | No | Text-based CLI | No | No | No | No | Yes (stdin, stdout, stderr) |
? | Partial (only via /K startup option) | Yes (via CALL command or /C and /K startup options) | No | Yes |
| Windows CMD.EXE[nb 5] | Win32 | CMD | 1993 | No | Windows NT, 2000, XP, Server 2003, Vista | Windows NT, 2000, XP, Server 2003, Vista | MS-EULA[nb 6] | No | Text-based CLI | No | Partial (CHCP 65001 for UTF-8, but program arguments are still encoded in local codepage) | No | No | Yes | Yes (via registry, startup parameters, and environment variables) | Yes (automatic via registry, or explicitly via /K startup option) | Yes (via CALL command or /C and /K startup options) | No | Yes |
| 4DOS, NDOS | DOS, Windows 95, 98, SE, ME | 4DOS, NDOS | 1989 (1986) | No (not bound to a specific OS vendor or version) |
Optional | Optional | MIT License, with restrictions | Yes | Text-based CLI with TUI extensions | Yes (popups, help system, %_MOUSE internal variable, INKEY /M command) | No | Yes | Yes (via CTTY con:, except for DRAWBOX, DRAWLINE, DRAWVLINE, LIST, SCREEN, SCRPUT, SELECT, VSCRPUT commands and file / directory coloring) | Yes (stdin, stdout, stderr, stdout+stderr) |
Yes (via 4DOS.INI/NDOS.INI file, startup parameters, environment variables, SETDOS command) | Yes (automatic \AUTOEXEC.BAT for primary shell and 4START.BTM/4START.BAT as well as 4EXIT.BTM/4EXIT.BAT for any shell, or explicitly via /P, /P:dir\filename.ext or /K startup options) | Yes (via CALL command or /C and /K startup options) | Yes | Yes |
| 4OS2 | OS/2, eComStation, ArcaOS | 4OS2 | 1992 | No (not bound to specific OS/2 versions) |
Optional (but bundled with ArcaOS) | Optional | Freeware | Yes | Text-based CLI | No | No | No | No | Yes (stdin, stdout, stderr, stdout+stderr) |
Yes (via 4OS2.INI file, startup parameters, environment variables, SETDOS command) | Yes (automatic via 4START.CMD/4START.BTM as well as 4EXIT.CMD/4EXIT.BTM files, or explicitly via /K startup.cmd option) | Yes (via CALL command or /C and /K startup options) | Yes | ? |
| TCC (formerly 4NT) |
Win32 | TCC | 1993 | No (not bound to specific NT versions) |
optional | optional | Shareware | No | Text-based CLI (Take Command: GUI) | Yes (console mouse, popups, help system, %_XMOUSE, %_YMOUSE internal variables, INKEY /M command) |
Yes | Yes | No | Yes (stdin, stdout, stderr, stdout+stderr) |
Yes (via registry, TCMD.INI/4NT.INI file, startup parameters, environment variables, SETDOS command) |
Yes (automatic via registry and TCSTART/4START as well as TCEXIT/4EXIT, or explicitly via /K startup option) |
Yes (via CALL command or /C and /K startup options) |
Yes | No |
| VMS DCL[22] | OpenVMS | Automatically for login/interactive process | 1977? | Yes | VMS | VMS | Proprietary, bundled in VMS | by special license only | Text-based CLI | with DECwindows/Motif | Yes | Yes, at least to 1988 standard | Yes | Yes (sys$input, sys$output assignment) |
Yes (via symbols, logical names, and options) |
Yes (SYS$MANAGER:SYLOGIN.COM and user defined LOGIN.COM) |
Yes | Yes | No |
| PowerShell | .NET, .NET Framework |
PowerShell | 2006 | Yes | Windows 10, 8, Server 2008, 7[nb 7] | Windows 10, 8, Server 2008, 7 | MIT-style | Yes | Graphical CLI | Yes | Yes | Yes | Yes | Yes | Yes (via variables and options) |
Yes (%USERPROFILE%\Documents \WindowsPowerShell\Microsoft.PowerShell_profile.ps1) |
Yes (PowerShell feature) |
Yes | No |
| rc | Plan 9, POSIX | rc | 1989 | Yes | Plan 9, Version 10 Unix | Plan 9, Version 10 Unix | MIT License[23] | Yes | Text-based CLI | ? | Yes | Yes | ? | Yes | Yes (via options) |
Yes ($HOME/.rcrc) |
Yes | ? | Yes |
| BeanShell | Java | ? | 2005 | Yes | ? | ? | LGPL | ? | ? | ? | Yes | ? | ? | Yes | ? | ? | ? | ? | No |
| fish | POSIX | fish | 2005[24] | Yes | GhostBSD | ? | GPL | Yes | Text-based CLI | ? | Yes | ? | ? | Yes (arbitrary fds[citation needed]) |
Yes (through environment variables and via web interface through fish_config) |
Yes (/etc/fish/config.fish and ~/.config/fish/config.fish) |
Yes (Unix feature) |
Yes (~/.config/fish/fish_history*) |
? |
| Ion | Redox, Linux | ion | 2015[25] | Yes | Redox | Redox | MIT | Yes | Text-based CLI | ? | Yes | Yes | ? | Yes (arbitrary fds[citation needed]) |
Yes (follows the XDG Base Directory spec) |
Yes (~/.config/ion/initrc) |
Yes | Yes (~/.local/share/ion/history) |
Partial (not distributed as a standalone executable, but it can be built as one) |
Interactive features
[edit]| Shell | Integrated
environment |
Snippets
|
Value
prompt |
Menu/options
prompt |
|||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Thompson shell | No | No | No | No | No | No | No | ? | ? | No | No | No | No | No | No | No | No | No | No |
| Bourne shell 1977 version | No | No | No | No | No | No | No | ? | ? | No | No | No | No | No | No | Yes | No | External | No |
| Bourne shell current version | No | Yes[nb 8] | No | No | Yes[nb 8] | No | No | Yes | Yes | No | Yes (CDPATH, pushd, popd, dirs), CDPATH since SVr4 | No | No | No | No | Yes | No | External | No |
| POSIX shell | No | No | No | No | Yes | No | No | Yes | Yes | No | Yes (CDPATH) |
No | No | No | No | Yes | No | External | No |
| bash (v4.0) | Yes | Yes | Yes | Yes[nb 9] | Yes | No | No | Yes | Yes | No | Yes (CDPATH, pushd, popd) |
optional | No | No | No | Yes | Yes | External | No |
| csh | Yes | Yes | No | No | Yes | No | No | Yes | Yes | No | Yes (cdpath, pushd, popd) |
optional | No | No | No | Yes | No | External | No |
| tcsh | Yes | Yes | when defined | No | Yes | No | No | Yes | Yes | No | Yes (cdpath, pushd, popd) |
optional | Yes | No | No | Yes | No | External | No |
| Hamilton C shell | Yes | Yes | No | Yes | Yes | No | No | Yes | Yes | No | Yes (cdpath, pushd, popd) |
No | No | No | No | Yes | No | External | No |
| Scsh | No | No | No | No | No | No | No | ? | ? | No | No | No | No | No | No | Yes | No | External | No |
| ksh (ksh93t+) | Yes (extendable) |
Yes (extendable) |
No | No | Yes | No | No | Yes | Yes | No | Yes (cdpath builtin, pushd, popd implemented as functions) |
No | No | No | No | Yes | Yes | External | No |
| pdksh | Yes | Yes | No | No | Yes | No | No | Yes | Yes | No | No | No | No | No | No | Yes | Yes | External | No |
| zsh | Yes | Yes | Yes | Yes[26] | Yes | Yes[27] | Yes (via predict-on or user-defined[28]) |
Yes | Yes | Third-party extension[29] | Yes | optional | Yes | No | when defined (as ZLE widgets) | Yes | Yes | External | Yes |
| ash | No | No | No | No | Yes | No | No | Yes | Yes | No | No | No | No | No | No | Yes | Yes | External | No |
| CCP | No | No | No | No | No | No | No | No | No | No | No | No | No | No | No | No | No | No | No |
| COMMAND.COM | No | No | No | No | No[nb 10][nb 11] | No | No | No | No (only in DR-DOS through %$ON%, %$OFF%, %$HEADER%, %$FOOTER%) | No | No | No | No | No (only single-stepping with COMMAND /Y[30]) | No | No | No (only via external CHOICE command, in DR-DOS also via SWITCH / DRSWITCH internal commands) | No | No |
| OS/2 CMD.EXE |
Yes | Yes | No | No | Yes | No | No | No | No | No | No | No | No | No | No | No | No | No | No |
| Windows CMD.EXE |
partial | partial | No | No | Yes (F8) |
No | No | No | No | No | Yes (PUSHD, POPD) |
No | No | No | No | Yes (via SET /P command) | No | No | No |
| 4DOS | Yes | Yes | Yes | Yes | Yes[nb 12][nb 13] | No | No | Yes | No | No | (via popup, extended directory searches, CDPATH, PUSHD, POPD, DIRHISTORY, DIRS, CDD, CD - commands and %@DIRSTACK[] function) | Yes | No | Yes | No | Yes (via INPUT, INKEY and ESET commands) | Yes (via @SELECT[] function, and indirectly via a combination of INKEY, INPUT, SWITCH commands) | No | Yes |
| 4OS2 | ? | ? | ? | ? | Yes | No | No | Yes | No | No | Yes | Yes | No | ? | No | ? | ? | No | Yes |
| TCC (formerly 4NT) | Yes | Yes | Yes | Yes | Yes | No | No | Yes | No | Yes | (via popup, extended directory searches, CDPATH, PUSHD, POPD, DIRHISTORY, DIRS, CDD, CD - commands and %@DIRSTACK[] function) | Yes | No | Yes | No | Yes (via INPUT, INKEY, ESET and SET /P commands) | Yes (via @SELECT[] function, and indirectly via a combination of INKEY, INPUT, SWITCH commands)[nb 14] | No | Yes |
| PowerShell | Yes | Yes | Yes | Yes | Yes (F8) |
Yes | Yes; via PSReadLine[31] module (bundled in v5.0[32]) or in ISE[33] | Third-party extension[34] | Yes[35] | Yes; via PSReadLine[31] module (bundled in v5.0) or in ISE[33] | Yes (multiple stacks; multiple location types;[36] Push-Location, Pop-Location) |
Yes, in PSReadLine[31] module | Yes, in ISE[33] | Yes, in ISE[33] | Yes | Yes[37] | Yes[38] | Yes, in ISE[33] | popup window[39] |
| rc | Yes[nb 15] | Yes[nb 15] | No | No | Yes[nb 15] | No | No | No | ? | No | No | No | No | No | No | ? | No | No | No |
| BeanShell | Yes | Yes | No | No | No | No | No | ? | ? | No | No | No | No | No | No | No | No | No | No |
| VMS DCL | Minimum uniqueness scheme | No | No | No | Yes | Yes | No | ? | ? | No | No | No | No | No | No | Yes | No | No | No |
| fish | Yes | Yes | Yes[40] | Yes[40] | Yes | No | Yes | Yes | Yes (built-in helper available[41]) |
Yes | Yes | Yes | Yes | Yes[nb 16] | Yes, using abbr command | Yes | (via fish_config command[42]) | No | No |
Background execution
[edit]Background execution allows a shell to run a command without user interaction in the terminal, freeing the command line for additional work with the shell. POSIX shells and other Unix shells allow background execution by using the & character at the end of command.
Completions
[edit]
Completion features assist the user in typing commands at the command line, by looking for and suggesting matching words for incomplete ones. Completion is generally requested by pressing the completion key (often the Tab ↹ key).
Command name completion is the completion of the name of a command. In most shells, a command can be a program in the command path (usually $PATH), a builtin command, a function or alias.
Path completion is the completion of the path to a file, relative or absolute.
Wildcard completion is a generalization of path completion, where an expression matches any number of files, using any supported syntax for file matching.
Variable completion is the completion of the name of a variable name (environment variable or shell variable). Bash, zsh, and fish have completion for all variable names. PowerShell has completions for environment variable names, shell variable names and — from within user-defined functions — parameter names.
Command argument completion is the completion of a specific command's arguments. There are two types of arguments, named and positional: Named arguments, often called options, are identified by their name or letter preceding a value, whereas positional arguments consist only of the value. Some shells allow completion of argument names, but few support completing values.
Bash, zsh and fish offer parameter name completion through a definition external to the command, distributed in a separate completion definition file. For command parameter name/value completions, these shells assume path/filename completion if no completion is defined for the command. Completion can be set up to dynamically suggest completions by calling a shell function.[43] The fish shell additionally supports parsing of man pages to extract parameter information that can be used to improve completions/suggestions. In PowerShell, all types of commands (cmdlets, functions, script files) inherently expose data about the names, types and valid value ranges/lists for each argument. This metadata is used by PowerShell to automatically support argument name and value completion for built-in commands/functions, user-defined commands/functions as well as for script files. Individual cmdlets can also define dynamic completion of argument values where the completion values are computed dynamically on the running system.
Command history
[edit]Users of a shell may find themselves typing something similar to what they have typed before. Support for command history means that a user can recall a previous command into the command-line editor and edit it before issuing the potentially modified command.
Shells that support completion may also be able to directly complete the command from the command history given a partial/initial part of the previous command.
Most modern shells support command history. Shells which support command history in general also support completion from history rather than just recalling commands from the history. In addition to the plain command text, PowerShell also records execution start- and end time and execution status in the command history.
Mandatory argument prompt
[edit]Mandatory arguments/parameters are arguments/parameters which must be assigned a value upon invocation of the command, function or script file. A shell that can determine ahead of invocation that there are missing mandatory values, can assist the interactive user by prompting for those values instead of letting the command fail. Having the shell prompt for missing values will allow the author of a script, command or function to mark a parameter as mandatory instead of creating script code to either prompt for the missing values (after determining that it is being run interactively) or fail with a message.
Automatic suggestions
[edit]
Shells featuring automatic suggestions display optional command-line completions as the user types. The PowerShell and fish shells natively support this feature; pressing the Tab ↹ key inserts the completion.
Implementations of this feature can differ between shells; for example, PowerShell[44] and zsh[45] use an external module to provide completions, and fish derives its completions from the user's command history.[46]
Directory history, stack or similar features
[edit]Shells may record a history of directories the user has been in and allow for fast switching to any recorded location. This is referred to as a "directory stack". The concept had been realized as early as 1978[47] in the release of the C shell (csh).
Command line interpreters 4DOS and its graphical successor Take Command Console also feature a directory stack.
Implicit directory change
[edit]A directory name can be used directly as a command which implicitly changes the current location to the directory.
This must be distinguished from an unrelated load drive feature supported by Concurrent DOS, Multiuser DOS, System Manager and REAL/32, where the drive letter L: will be implicitly updated to point to the load path of a loaded application, thereby allowing applications to refer to files residing in their load directory under a standardized drive letter instead of under an absolute path.[48]
Autocorrection
[edit]
When a command line does not match a command or arguments directly, spell checking can automatically correct common typing mistakes (such as case sensitivity, missing letters). There are two approaches to this; the shell can either suggest probable corrections upon command invocation, or this can happen earlier as part of a completion or autosuggestion.
The tcsh and zsh shells feature optional spell checking/correction, upon command invocation.
Fish does the autocorrection upon completion and autosuggestion. The feature is therefore not in the way when typing out the whole command and pressing enter, whereas extensive use of the tab and right-arrow keys makes the shell mostly case insensitive.
The PSReadLine[31] PowerShell module (which is shipped with version 5.0) provides the option to specify a CommandValidationHandler ScriptBlock which runs before submitting the command. This allows for custom correcting of commonly mistyped commands, and verification before actually running the command.
Progress indicator
[edit]A shell script (or job) can report progress of long running tasks to the interactive user.
Unix/Linux systems may offer other tools support using progress indicators from scripts or as standalone-commands, such as the program "pv".[49] These are not integrated features of the shells, however.
Colored directory listings
[edit]JP Software command-line processors provide user-configurable colorization of file and directory names in directory listings based on their file extension and/or attributes through an optionally defined %COLORDIR% environment variable.
For the Unix/Linux shells, this is a feature of the ls command and the terminal.
Text highlighting
[edit]The command line processors in DOS Plus, Multiuser DOS, REAL/32 and in all versions of DR-DOS support a number of optional environment variables to define escape sequences allowing to control text highlighting, reversion or colorization for display or print purposes in commands like TYPE. All mentioned command line processors support %$ON% and %$OFF%. If defined, these sequences will be emitted before and after filenames. A typical sequence for %$ON% would be \033[1m in conjunction with ANSI.SYS, \033p for an ASCII terminal or \016 for an IBM or ESC/P printer. Likewise, typical sequences for %$OFF% would be \033[0m, \033q, \024, respectively. The variables %$HEADER% and %$FOOTER% are only supported by COMMAND.COM in DR-DOS 7.02 and higher to define sequences emitted before and after text blocks in order to control text highlighting, pagination or other formatting options.
For the Unix/Linux shells, this is a feature of the terminal.
Syntax highlighting
[edit]A defining feature of the fish shell is built-in syntax highlighting, As the user types, text is colored to represent whether the input is a valid command or not (the executable exists and the user has permissions to run it), and valid file paths are underlined.[50]
An independent project offers syntax highlighting as an add-on to the Z Shell (zsh).[51] This is not part of the shell, however.
PowerShell provides customizable syntax highlighting on the command line through the PSReadLine[31] module. This module can be used with PowerShell v3.0+, and is bundled with v5.0 onwards. It is loaded by default in the command line host "powershell.exe" since v5.0.[52]
Take Command Console (TCC) offers syntax highlighting in the integrated environment.
Context sensitive help
[edit]4DOS, 4OS2, 4NT / Take Command Console and PowerShell (in PowerShell ISE) looks up context-sensitive help information when F1 is pressed.
Zsh provides various forms of configurable context-sensitive help as part of its run-help widget, _complete_help command, or in the completion of options for some commands.
The fish shell provides brief descriptions of a command's flags during tab completion.
Programming features
[edit]| Shell | Functions | Exception handling | Search & replace on variable substitutions |
Math function library | Linear arrays or lists | Pseudorandom number generation | Bytecode | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Bourne shell 1977 version | No | Yes (via trap) | No | No | No | No | No | No | No | Yes | No | No |
| Bourne shell current version | Yes since SVR2 | Yes (via trap) | No | Yes[nb 8] | No | No | No | No | No | Yes | No | No |
| POSIX shell | Yes | Yes (via trap) | No | Yes | No | No | No | No | No | Yes | No | No |
| bash (v4.0) | Yes | Yes (via trap) | Yes (via ${//} syntax) |
Yes | No | No | Yes | Yes | No | Yes | Yes ($RANDOM) |
No |
| csh | No | No | Yes (via $var:s/// syntax) |
Yes | No | No | Yes | No | No | Yes | No | No |
| tcsh | Work in progress[53] | No | Yes (via $var:s/// syntax) |
Yes | No | No | Yes | No | No | Yes | No | No |
| Hamilton C shell | Yes | No | Yes (via $var:s/// syntax) |
Yes | Yes | Yes | Yes | No | No | Yes | Yes (random utility) | No |
| Scsh | Yes | ? | Yes (via string functions and regular expressions) |
? | ? | ? | Yes | ? | Yes | Yes | Yes (random-integer, random-real) |
Yes (compiler is Scheme48 virtual machine, via scshvm) |
| ksh (ksh93t+) | Yes | Yes (via trap) | Yes (via ${//} syntax and builtin commands) |
Yes | Yes | Yes | Yes | Yes | No | Yes | Yes ($RANDOM) |
Yes (compiler is called shcomp) |
| pdksh | Yes | Yes (via trap) | No | Yes | No | No | Yes | No | No | Yes | Yes ($RANDOM) |
No |
| zsh | Yes | Yes | Yes (via ${:s//} and ${//} syntax) |
Yes | Yes | Yes (zsh/mathfunc module) |
Yes | Yes | No | Yes | Yes ($RANDOM) |
Yes (built-in zcompile command) |
| ash | Yes | Yes (via trap) | No | Yes (since 1992)[54] |
No | No | No | No | No | Yes | No | No |
| CCP | No | ? | No | No | ? | ? | No | No | No | No | No | No |
| COMMAND.COM | No | Partial (only Auto-fail (via COMMAND /F (or /N in some versions of DR-DOS)) | No | No | No | No | No | No | No | No | No | No |
| OS/2 CMD.EXE | No | No | No | ? | No | No | ? | No | No | No | No | No |
| Windows CMD.EXE | Yes (via CALL :label) |
No | Yes (via SET %varname:expression syntax) |
Yes (via SET /A)[55] |
No | No | Yes (via SET[56]) |
No | No | No | Yes (%random%) |
No |
| 4DOS | Yes | Yes (via ON command, optional Auto-fail via 4DOS /F) |
Yes (via %@Replace[...] function) |
Yes (via SET /A) |
? | ? | Yes (via ranges, include lists, @file lists and FOR command) |
No | No | Yes | Yes (%@Random[...] function) |
Yes (via BATCOMP command) |
| 4OS2 | ? | ? | ? | ? | ? | ? | ? | ? | No | Yes | Yes (%@Random[...] function) | ? |
| TCC (formerly 4NT) | Yes | Yes (via ON and various ...MONITOR commands) |
Yes (via %@Replace[...] function) |
Yes (via SET /A) |
? | ? | Yes (via ranges, include lists, @file lists and FOR command) |
? | No | Yes | Yes (%@Random[...] function) | Yes (via BATCOMP command) |
| PowerShell | Yes | Yes (Try-Catch-Finally) | Yes (-replace operator) |
Yes | Yes | [Math] class[57] | Yes | Yes | Yes[58] | Yes | Yes | Yes, automatic |
| rc | Yes | Yes | No | Yes | ? | ? | Yes | ? | No | Yes | No | No |
| BeanShell | Yes | Yes | ? | Yes | ? | ? | Yes | Yes | No | Yes | Yes | Yes |
| VMS DCL | Yes | Yes | No | Yes | No | yes, for compiled programs | Yes | No | No | No | No | No |
| fish | Yes | Yes (via trap) | Yes, via string builtin command[59] | Yes | Yes | Yes | Yes | No | No | Yes | Yes (random) |
No |
String processing and filename matching
[edit]| Shell | String processing | Alternation (Brace expansion) | Pattern matching (regular expressions built-in) | Pattern matching (filename globbing) | Globbing qualifiers (filename generation based on file attributes) | Recursive globbing (generating files from any level of subdirectories) |
|---|---|---|---|---|---|---|
| Bourne shell 1977 version | ? | No | No | Yes (*, ?, [...]) |
No | No |
| Bourne shell recent version | Partial (prefix and suffix stripping in variable expansion) | No | No | Yes (*, ?, [...]) |
No | No |
| POSIX shell | Partial (prefix and suffix stripping in variable expansion) | No | No | Yes (*, ?, [...]) |
No | No |
| bash (v4.0) | Partial (prefix and suffix stripping in variable expansion) | Yes | Yes | Yes (*, ?, [...], {...}) |
No | Yes (**/...) |
| csh | Yes (:s and other editing operators) |
Yes | No | Yes | No | No |
| tcsh | Yes (:s and other editing operators) |
Yes | Yes | Yes | No | No |
| Hamilton C shell | Yes (:s and other editing operators + substr, strlen, strindex, printf, reverse, upper, lower, concat and other builtin functions) |
Yes | No | Yes | No | Yes (via indefinite directory "..." wildcard[60]) |
| Scsh | ? | ? | Yes | Yes | No | No |
| ksh (ksh93t+) | Partial (prefix, suffix stripping and string replacement in variable expansion) | Yes[61] | Yes | Yes (*, ?, [...]) |
No | Yes (with set -G, no following of symlinks) |
| pdksh | ? | Yes[61] | No | Yes | No | No |
| zsh | Yes (through variable processing: e.g. substring extraction, various transformations via parameter expansion) | Yes | Yes | Yes (*, ?, [...], extended globbing[62]) |
Yes | Yes (**/... or ***/... to follow symlinks) |
| ash | ? | ? | No | Yes | No | No |
| CCP | No | No | No | No | No | No |
| COMMAND.COM | No | No | No | Yes (*, ?) |
No | No |
| OS/2 CMD.EXE | No | No | No | Yes (*, ?) |
Partial (only in DIR /A:... command) | No |
| Windows CMD.EXE | Partial (only through FOR /F and SET /A) | No | No[nb 17] | Yes (*, ?) |
Partial (only in DIR /A:... command) | Yes (via FOR /R command, or, where available, indirectly via /S subdir option) |
| 4DOS | Yes (through variable functions %@...[], extended environment variable processing, various string commands and FOR /F and SET /A) | No | No | Yes (*, ?, [...], extended wildcards, SELECT popup command) |
Yes (via /A:... attribute and /I"..." description options and /[S...] size, /[T...] time, /[D...] date, and /[!...] file exclusion ranges) | Yes (via FOR /R command, or indirectly via GLOBAL command or, where available, /S subdir option) |
| 4OS2 | ? | No | No | ? | ? | ? |
| TCC (formerly 4NT) | Yes (through variable functions %@...[], extended environment variable processing, various string commands and FOR /F and SET /A) | No | Yes | Yes (*, ?, [...], extended wildcards, SELECT popup command) |
Yes (via /A:... attribute and /I"..." description options and /[S...] size, /[T...] time, /[D...] date, /[O...] owner, and /[!...] file exclusion ranges) | Yes (via FOR /R command, or indirectly via GLOBAL command or, where available, /S subdir option) |
| PowerShell | Yes (Concat/Substring/Insert/Remove/Replace, ToLower/ToUpper, Trim/TrimStart/TrimEnd, Compare, Contains/StartsWith/EndWith, Format, IndexOf/LastIndexOf, Pad/PadLeft/PadRight, Split/Join, regular expression functions and other .NET string functions) |
Range operator for numbers[63] | Yes (full regex support)[nb 18] |
Yes (*, ?, [...]) |
? | ? |
| rc | ? | ? | No | Yes | No | No |
| BeanShell | ? | ? | Yes | ? | ? | ? |
| VMS DCL | Yes | No | No | Yes | No | Yes (via [SUBDIR...]) |
| fish | Yes (builtin string function) |
Yes | Yes (via builtin string match and string replace functions) |
Yes (*, ?, {...}) |
No | Yes (**/...) |
Inter-process communication
[edit]| Shell | Pipes | Command substitution | Process substitution | Subshells | TCP/UDP connections as streams | Keystroke stacking |
|---|---|---|---|---|---|---|
| Bourne shell | bytes concurrent | Yes | No | Yes | No | N/A[nb 19] |
| POSIX shell | bytes concurrent | Yes | No | Yes | No | N/A[nb 19] |
| bash (v4.0) | bytes concurrent | Yes | Yes (if system supports /dev/fd/⟨n⟩ or named pipes) |
Yes | Yes (client only) |
N/A[nb 19] |
| csh | bytes concurrent | Yes | No | Yes | No | N/A[nb 19] |
| tcsh | bytes concurrent | Yes | No | Yes | No | N/A[nb 19] |
| Hamilton C shell | bytes concurrent | Yes | No | Yes | No | ? |
| Scsh | text | ? | ? | ? | Yes | N/A[nb 19] |
| ksh (ksh93t+) | bytes (may contain serialized objects if print -C is used) concurrent | Yes ($(...) and ${<space>...;}) |
Yes (if system supports /dev/fd/⟨n⟩) |
Yes | Yes (and SCTP support, client only) |
N/A[nb 19] |
| pdksh | bytes concurrent | Yes | No | Yes | No | N/A[nb 19] |
| zsh | bytes concurrent | Yes | Yes | Yes | Yes (client and server, but only TCP) |
N/A[nb 19] |
| ash | bytes concurrent | Yes | No | Yes | No | N/A[nb 19] |
| CCP | No | No | No | No | No | No |
| COMMAND.COM | text sequential temporary files | No | No | Partial (only under DR-DOS multitasker via COMMAND.COM /T) | No | No |
| OS/2 CMD.EXE | text concurrent | No | No | ? | No | No |
| Windows CMD.EXE | text concurrent | Yes (via FOR /F command) |
No | Yes (Backtick: ` in FOR /F usebackq) |
No | No |
| 4DOS | text sequential temporary files | Yes (via FOR /F command) |
? | Partial (via %@EXECSTR[] and %@EXEC[], or via SET /M, ESET /M and UNSET /M and %@MASTER[...]) | No | Yes (via KEYSTACK and KSTACK)[64] |
| 4OS2 | text concurrent | ? | ? | ? | No | Yes (via KEYSTACK) |
| TCC (formerly 4NT) | text concurrent | Yes (via FOR /F command) |
? | Partial (via %@EXECSTR[] and %@EXEC[]) | Yes (via FTP, TFTP, FTPS, SFTP, HTTP, HTTPS and IFTP, client only) | Yes (via KEYSTACK) |
| PowerShell | objects concurrent | Yes | No | Yes | Yes | ? |
| rc | text concurrent | Yes | Yes (via: <{cmd} if system supports /dev/fd/⟨n⟩) |
Yes | No | ? |
| BeanShell | not supported | ? | ? | ? | Yes | ? |
| VMS DCL | text (via PIPE command) | Yes | No | Yes (spawn) |
Yes (server TCP only) |
No |
| fish | bytes concurrent | Yes (...) | No (broken)[65] | No | No | N/A[nb 19] |
Keystroke stacking
[edit]In anticipation of what a given running application may accept as keyboard input, the user of the shell instructs the shell to generate a sequence of simulated keystrokes, which the application will interpret as a keyboard input from an interactive user. By sending keystroke sequences the user may be able to direct the application to perform actions that would be impossible to achieve through input redirection or would otherwise require an interactive user. For example, if an application acts on keystrokes, which cannot be redirected, distinguishes between normal and extended keys, flushes the queue before accepting new input on startup or under certain conditions, or because it does not read through standard input at all. Keystroke stacking typically also provides means to control the timing of simulated keys being sent or to delay new keys until the queue was flushed etc. It also allows to simulate keys which are not present on a keyboard (because the corresponding keys do not physically exist or because a different keyboard layout is being used) and therefore would be impossible to type by a user.
Security features
[edit]This section may contain information not important or relevant to the article's subject. (July 2014) |
| Shell | Secure (password) prompt | File/directory passwords | Execute permission | Restricted shell subset | Safe data subset |
|---|---|---|---|---|---|
| Bourne shell | via stty[nb 20] | ? | N/A[nb 21] | Yes | No |
| POSIX shell | via stty[nb 20] | ? | N/A[nb 21] | No | No |
| bash (v4.0) | read -s
|
? | N/A[nb 21] | Yes | No |
| csh | via stty[nb 20] | ? | N/A[nb 21] | Yes | No |
| tcsh | via stty[nb 20] | ? | N/A[nb 21] | Yes | No |
| Hamilton C shell | No | No | No | No | No |
| Scsh | via stty[nb 20] | ? | N/A[nb 21] | No | No |
| ksh (ksh93t+) | via stty[nb 20] | ? | N/A[nb 21] | Yes | No |
| pdksh | via stty[nb 20] | ? | N/A[nb 21] | Yes | No |
| zsh | read -s
|
? | N/A[nb 21][nb 22] | Yes | No |
| ash | via stty[nb 20] | ? | N/A[nb 21] | Yes | No |
| CCP | No | No | No | No | No |
| COMMAND.COM | Partial (only under DR-DOS, prompts for password if file/directory is protected) | Partial (only under DR-DOS via \dirname;dirpwd\filename;filepwd syntax)[nb 23]
|
Partial (only under DR-DOS, if files are password-protected for read and/or execute permission)[nb 24] | No | No |
| OS/2 CMD.EXE | No | No | No | No | No |
| Windows CMD.EXE | No | No | No | No | No |
| 4DOS | Yes (via INPUT /P or INKEY /P)[nb 25]
|
Partial (only under DR-DOS via \dirname;;dirpwd\filename;;filepwd syntax)[nb 23]
|
Partial (only under DR-DOS, if files are password-protected for read and/or execute permission)[nb 24] | No | No |
| 4OS2 | ? | No | No | No | No |
| TCC (formerly 4NT) | Yes (via INPUT /P, INKEY /P or QUERYBOX /P)[nb 25]
|
No | No | No | No |
| PowerShell | Yes[nb 26] | No | No[nb 27] | Yes[nb 28] | Yes[66] |
| rc | via stty[nb 20] | ? | N/A[nb 21] | Yes[67] | No |
| BeanShell | ? | ? | ? | ? | ? |
| VMS DCL | Yes | No | Yes | Yes | No |
| fish | read -s
|
? | N/A[nb 21][nb 22] | Yes (via fish -l)
|
? |
Secure prompt
[edit]Some shell scripts need to query the user for sensitive information such as passwords, private digital keys, PIN codes or other confidential information. Sensitive input should not be echoed back to the screen/input device where it could be gleaned by unauthorized persons. Plaintext memory representation of sensitive information should also be avoided as it could allow the information to be compromised, e.g., through swap files, core dumps etc.[68]
The shells bash, zsh and PowerShell offer this as a specific feature.[69][70] Shells which do not offer this as a specific feature may still be able to turn off echoing through some other means. Shells executing on a Unix/Linux operating system can use the stty external command to switch off/on echoing of input characters.[71] In addition to not echoing back the characters, PowerShell's -AsSecureString option also encrypts the input character-by-character during the input process, ensuring that the string is never represented unencrypted in memory where it could be compromised through memory dumps, scanning, transcription etc.
Execute permission
[edit]Some operating systems define an execute permission which can be granted to users/groups for a file when the file system itself supports it.
On Unix systems, the execute permission controls access to invoking the file as a program, and applies both to executables and scripts.
As the permission is enforced in the program loader, no obligation is needed from the invoking program, nor the invoked program, in enforcing the execute permission – this also goes for shells and other interpreter programs.
The behaviour is mandated by the POSIX C library that is used for interfacing with the kernel. POSIX specifies that the exec family of functions shall fail with EACCESS (permission denied) if the file denies execution permission (see – System Interfaces Reference, The Single UNIX Specification, Version 5 from The Open Group).
The execute permission only applies when the script is run directly. If a script is invoked as an argument to the interpreting shell, it will be executed regardless of whether the user holds the execute permission for that script.
Although Windows also specifies an execute permission, none of the Windows-specific shells block script execution if the permission has not been granted.
Restricted shell subset
[edit]Several shells can be started or be configured to start in a mode where only a limited set of commands and actions is available to the user. While not a security boundary (the command accessing a resource is blocked rather than the resource) this is nevertheless typically used to restrict users' actions before logging in.
A restricted mode is part of the POSIX specification for shells, and most of the Linux/Unix shells support such a mode where several of the built-in commands are disabled and only external commands from a certain directory can be invoked.[72][73]
PowerShell supports restricted modes through session configuration files or session configurations. A session configuration file can define visible (available) cmdlets, aliases, functions, path providers and more.[74]
Safe data subset
[edit]Scripts that invoke other scripts can be a security risk as they can potentially execute foreign code in the context of the user who launched the initial script. Scripts will usually be designed to exclusively include scripts from known safe locations; but in some instances, e.g. when offering the user a way to configure the environment or loading localized messages, the script may need to include other scripts/files.[75] One way to address this risk is for the shell to offer a safe subset of commands which can be executed by an included script.
Notes
[edit]- ^ Since mid 1990s.
- ^ if compiled with -DACCT.
- ^ MS-DOS and Windows component – covered by a valid license for MS-DOS or Microsoft Windows.
- ^ OS/2 component – covered by a valid license for OS/2.
- ^ Command extensions enabled, or "CMD /X".
- ^ Windows component – covered by a valid license for Microsoft Windows.
- ^ Microsoft PowerShell is installed by default on Windows 7 and later. It is an optional download for users of Windows Vista or Windows XP.
- ^ a b c current versions from Jörg Schilling.
- ^ Alt-Shift-8 or Alt-* will expand to the full matching list of filenames.
- ^ Available through the DOSKEY add-on.
- ^ Available in DR-DOS through HISTORY.
- ^ Alternatively available through the DOSKEY add-on as well.
- ^ Alternatively available in DR-DOS through HISTORY as well.
- ^ TCC has special prompt functions for Yes, No, Cancel, Close, Retry.
- ^ a b c Handled by rio, GNU readline, editline or vrl.
- ^ The fish shell is an interactive character based input/output surface.
- ^ Not available as a shell built-in. External FINDSTR /R command is available in most Windows releases.
- ^ PowerShell leverages the full .NET regular expression engine which features named captures, zero-width lookahead/-behind, greedy/non-greedy, character classes, level counting etc.
- ^ a b c d e f g h i j k xautomation and xdotool can be used to generate keystrokes under X Window System; or a program can be run in a pseudoterminal to be able to control it (as with the expect tool).
- ^ a b c d e f g h i The shell can use the stty utility to suppress echoing of typed characters to the screen. This requires multiple steps: 1. reading the current echo state, 2. switching echo off, 3. reading the input, 4. switching echo state back to the original state.
- ^ a b c d e f g h i j k l The execute permission is enforced by a separate program, the program loader, by refusing to invoke the interpreter (possibly a shell) specified by the script's hashbang. The interpreter does not enforce the execute permission if invoked directly as the program loader would, with the file as an argument; this only requires read permission, as does piping the file as input to the interpreter, in which case the interpreter cannot see the execute permission.
- ^ a b The zsh and fish shells also honor the execute permission for command completion.
- ^ a b Under DR-DOS the password separator for file and directory passwords is a semicolon. This is also supported under 4DOS for as long as the command does not support include lists. Under 4DOS, the password separator must be doubled for all commands supporting include lists in order to distinguish passwords from include lists. Commands not supporting include lists accept both forms. DR-DOS 7.02 and higher optionally accept a doubled semicolon as well, so that doubled semicolons work under both COMMAND.COM and 4DOS regardless of the command executed.
- ^ a b DR-DOS supports file passwords for read/write/delete and optionally execute permissions. Files are not protected by default, but the system can be set up so that f.e. batch scripts require a password to read.
- ^ a b
INPUT /PandINKEY /Pechoes back asterisks for each typed character. - ^
Read-Host -AsSecureStringreads a string of characters from the input device into an encrypted string, one character at a time thus ensuring that there is no memory image of the clear text which could be gleaned from scanning memory, or from crash dumps, memory dumps, paging files, log files or similar. - ^ PowerShell script files (.ps1 files) are by default associated with the Notepad editor, not with the PowerShell execution engine. Invoking a .ps1 file will launch Notepad rather than executing the script.
- ^ Startup scripts per computer/user can import modules and expose a subset the commands/functions available in the modules.
References
[edit]- ^ A platform independent version based on the historical UNIX V7 original source code is available from Geoff Collyer
- ^ The historic UNIX V7 version is available under a BSD-style license through The Unix Heritage Society and others.
- ^ A platform independent version based on the SVr4/Solaris source code is available from Jörg Schilling
- ^ Ferrell, John, "Chapter 2. Default Shell", FreeBSD Quickstart Guide for Linux Users, The FreeBSD Documentation Project, retrieved 2015-07-24
- ^ "SchilliX-ON / SchilliX-ON Mercurial / [b1d9a2] /usr/src/cmd/sh". Sourceforge.net. Retrieved 2015-07-02.
- ^ IEEE and The Open Group (2008). IEEE 1003.1 Standard for Information Technology – Portable Operating System Interface (POSIX): Shell and Utilities, Issue 7.
- ^ As part of IEEE Std.1003.2-1992 (POSIX.2); integrated into IEEE Std.1003.1 with the 2001 revision.
- ^ Fox, Brian (1989-06-07). Tower Jr., Leonard H. (ed.). "Bash is in beta release!". Newsgroup: gnu.announce. Usenet: 8906080235.AA01983@wheat-chex.ai.mit.edu. Retrieved 2010-10-28.
- ^ Cooper, Mendel, "Chapter 37.3.2. Bash, version 4.2", Advanced Bash-Scripting Guide, The Linux Documentation Project, retrieved 2015-04-30, "Bash now supports the \u and \U Unicode escape."
- ^ Greer, Ken (1983-10-03). "C shell with command and filename recognition/completion". Newsgroup: net.sources. Retrieved 2010-12-29.
- ^ "FreeBSD Quickstart Guide for Linux® Users". FreeBSD Documentation Portal. Retrieved 2024-02-04.
- ^ Sussman, Ann (1988-12-26). "Hamilton C Shell Speeds Development Of OS/2 Applications" (PDF). PC Week (1988-12-26 - 1989-01-02): 37. Retrieved 2010-11-22.
- ^ Gomes, Ron (1983-06-09). "Toronto USENIX Conference Schedule (tentative)". Newsgroup: net.usenix. Retrieved 2010-12-29.
- ^ Harris, Guy (1983-10-10). "csh question". Newsgroup: net.flame. Retrieved 2010-12-29.
- ^ a b ksh93(1) man page
- ^ a b Default shell in OpenBSD is ksh (pdksh).
- ^ The zsh command line editor is fully configurable and can allow mouse support in various ways such as with Stéphane Chazelas's mouse.zsh.
- ^ zsh(1) man page and subpages
- ^ zshbuiltins(1) man page
- ^ Lefevre, Vincent (2015-02-11). "multi-digit file descriptors". zsh-users (Mailing list). Retrieved 2021-12-23.
- ^ "#782228 - busybox sh doesn't support multibyte characters in string handling - Debian Bug report logs". Bugs.debian.org. 2015-04-09. Retrieved 2015-07-02.
- ^ "HP OpenVMS DCL Dictionary". Archived from the original on 2007-03-25. Retrieved 2009-03-23.
- ^ Larabel, Michael (2021-03-23). "Plan 9 Copyright Transferred To Foundation, MIT Licensed Code Released". Phoronix. Retrieved 2021-03-28.
- ^ Liljencrantz, Axel (2005-05-17). "Fish - The friendly interactive shell". Retrieved 2013-04-08.
- ^ Soller, Jeremy (2015-11-15). "d79c8f511573fb7710abc63b4236a40022914520". Retrieved 2019-08-03.
- ^ "[Z Shell] Completion System". Zsh.sourceforge.io. Retrieved 2015-02-24.
- ^ This applies only on reserved words and other syntactic features.
- ^ e.g. via 3rd party such as zsh-autosuggestions
- ^ zsh does not feature syntax highlighting, but a 3rd party project exists which offers this capability as an add-on: zsh-syntax-highlighting
- ^ Paul, Matthias R. (1997-10-02) [1997-09-29]. "Caldera OpenDOS 7.01/7.02 Update Alpha 3 IBMBIO.COM - README.TXT and BOOT.TXT - A short description of how OpenDOS is booted". Archived from the original on 2003-10-04. Retrieved 2009-03-29. [1]
- ^ a b c d e Shirk, Jason (2018-02-15). "PSReadLine: A bash inspired readline implementation for PowerShell" – via GitHub.
- ^ "Windows PowerShell 5.0". Archived from the original on 17 September 2016. Retrieved 8 September 2016.
- ^ a b c d e "Windows PowerShell Integrated Scripting Environment (ISE)". Microsoft Technet. Retrieved 2015-09-12.
- ^ "Get-ChildItemColor". GitHub. 2022-03-18.
- ^ sdwheeler. "Write-Host (Microsoft.PowerShell.Utility) - PowerShell". docs.microsoft.com. Retrieved 2022-01-18.
- ^ Push-Location (with alias
pushd) and Pop-Location (with aliaspopd) allows multiple location types (directories of file systems, organizational units of Active Directory, nodes of Windows Registry etc) to be pushed onto and popped from location stacks. - ^ The $host.ui.PromptForChoice function allows for a menu-style prompt for choices. The prompt works from background jobs as well as from remote sessions, displaying the menu prompt on the console of the controlling session.
- ^ The Write-Progress cmdlet writes a progress bar which can indicate percentage, remaining seconds etc. The progress bar messages work from background jobs or remote sessions in addition to interactive scripts, i.e. the progress bar is displayed on the console of the controlling session, not as part of the regular output.
- ^ The Show-Command cmdlet inspects the command definition and opens an interactive windows with a named input field for each parameter/switch
- ^ a b "fish: Documentation". Section Tab completion. Retrieved 2016-01-10.
- ^ "set_color - set the terminal color — fish-shell 3.1.2 documentation". fishshell.com. Archived from the original on 2020-02-17. Retrieved 2021-02-23.
- ^ "abbr - manage fish abbreviations — fish-shell 3.1.2 documentation". fishshell.com. Retrieved 2021-02-23.
- ^ "zsh: 20. Completion System". Zsh.sourceforge.io. 2013-03-06. Retrieved 2013-08-18.
- ^ sdwheeler. "What's New in the PowerShell 5.0 ISE - PowerShell". docs.microsoft.com. Retrieved 2021-07-25.
- ^ "GitHub - marlonrichert/zsh-autocomplete: 🤖 Real-time type-ahead completion for Zsh. Asynchronous find-as-you-type autocompletion". GitHub. Retrieved 2021-07-25.
- ^ "Interactive use — fish-shell 3.3.1 documentation". fishshell.com. Retrieved 2021-07-25.
- ^ Hahn, Harley (2009). Harley Hahn's guide to Unix and Linux. Boston: McGraw-Hill Higher Education. ISBN 978-0-07-313361-4. OCLC 184828059.
- ^ Concurrent DOS 386 - Multiuser/Multitasking Operating System - User Guide (PDF). Digital Research.
- ^ "pv(1): monitor progress of data through pipe - Linux man page". Linux.die.net. Retrieved 2015-02-24.
- ^ "fish: Tutorial". fishshell.com. Retrieved 2022-10-21.
- ^ "zsh-users/zsh-syntax-highlighting: Fish shell like syntax highlighting for Zsh". GitHub. Retrieved 2013-08-18.
- ^ sdwheeler. "PSReadLine Module - PowerShell". learn.microsoft.com. Retrieved 2023-04-26.
- ^ Introduce 'function' built-in by Matheus Garcia
- ^ "Ash Variants". Archived from the original on 2010-03-10. Retrieved 2014-12-15.
- ^ "Set - Environment Variable - Windows CMD". SS64.com. Retrieved 2015-02-24.
- ^ "How to loop through array in batch?". Stack Overflow. Retrieved 2015-02-24.
- ^ The .NET System.Math class defines mathematical functions that can be used through the shortcut [Math], e.g. [Math]::Sin for the sinus function.[2]
- ^ "Get closure with GetNewClosure". devblogs.microsoft.com. 2009-03-27. Retrieved 2022-09-12.
- ^ "string - manipulate strings — fish-shell 3.1.2 documentation". fishshell.com. Retrieved 2021-02-23.
- ^ Hamilton C shell Language reference: Wildcarding and pattern matching, Hamilton Laboratories, retrieved 2013-10-29,
... Indefinite Directory: match any number of directory levels – zero or more – whatever it takes to make the rest of the pattern match.
- ^ a b Seebach, Peter (2008-11-21). Beginning Portable Shell Scripting: From Novice to Professional. Expert's voice in open source. Apress (published 2008). p. 149. ISBN 9781430210436. Retrieved 2014-09-17.
Brace expansion is available in ksh93, pdksh, bash, and zsh.
- ^ Zsh offers a variety of globbing options.
- ^ sdwheeler. "about Operators - PowerShell". docs.microsoft.com. Retrieved 2022-01-18.
- ^ Brothers, Hardin; Rawson, Tom; Conn, Rex C.; Paul, Matthias R.; Dye, Charles E.; Georgiev, Luchezar I. (2002-02-27). 4DOS 8.00 online help.
- ^ "find a way to make 'psub --fifo' safe from deadlock · Issue #1040 · fish-shell/fish-shell". GitHub.
- ^ "About Data Sections". Technet.microsoft.com. Retrieved 2015-02-24.
- ^ "Ubuntu Manpage: rc - shell". Manpages.ubuntu.com. 2003-07-17. Retrieved 2015-02-24.
- ^ Provos, Niels. "Encrypting Virtual Memory". Center for Information Technology Integration, University of Michigan. Retrieved 2012-12-20.
- ^ "bash - GNU Bourne-Again SHell".
read -s Silent mode. If input is coming from a terminal, characters are not echoed.
- ^ "Using the Read-Host Cmdlet".
By adding the -assecurestring parameter you can mask the data entered at the prompt
- ^ "Linux / Unix Command: stty". Linux.about.com. Archived from the original on 2015-02-25. Retrieved 2015-02-24.
- ^ "man sh - shell, the standard command language interpreter / posix" (in French). Pwet.fr. Archived from the original on 2014-12-21. Retrieved 2013-08-18.
- ^ "Bash Reference Manual: The Restricted Shell". Gnu.org. 2010-12-28. Retrieved 2013-08-18.
- ^ "New-PSSessionConfigurationFile". Technet.microsoft.com. Retrieved 2013-08-18.
- ^ Albing, Carl; Vossen, J. P.; Newham, Cameron (2007). Bash cookbook (1st ed.). Sebastopol, California, USA: O'Reilly Media. ISBN 978-0-596-52678-8.
[...] is hardly what one thinks of as a passive list of configured variables. It can run other commands (e.g., cat) and use if statements to vary its choices. It even ends by echoing a message. Be careful when you source something, as it's a wide open door into your script.
External links
[edit]- Nasarek, Marcus (May 2007). "Article" (PDF). Comparing Bash with the Windows Vista shell: Shell Games. Linux Magazine. Archived (PDF) from the original on 2014-10-10.
- "Shell and Utilities". IEEE Standard for Information Technology 1003.1™-2024 – Portable Operating System Interface POSIX™.1-2024 — The Open Group Base Specifications Issue 8 (2024 ed.). The IEEE and The Open Group. 2024-08-08.
Comparison of command shells
View on GrokipediaGeneral Characteristics
Operating System and Platform Support
Command shells are intrinsically linked to their host operating systems, with native support determining their primary deployment environments, while portability mechanisms enable broader compatibility across platforms. Traditional shells like cmd.exe are confined to Windows ecosystems, whereas Unix-like shells such as Bash and Zsh originated in POSIX-compliant systems but have been extended through emulation layers. Modern developments, including cross-platform redesigns and subsystems, have enhanced interoperability, allowing shells to operate on diverse architectures like x86_64 and ARM64. The following table summarizes the primary operating system and platform support for selected command shells, focusing on native environments and key cross-platform capabilities:| Shell | Native OS Support | Cross-Platform Support | Architecture Support |
|---|---|---|---|
| cmd.exe | Windows NT family (e.g., Windows 10/11, Server 2016+) | None; Windows-exclusive | Primarily x86, x86_64; limited ARM via Windows on ARM |
| PowerShell | Windows (all versions); cross-platform since PowerShell Core 6.0 (released January 10, 2018) | macOS, Linux (Ubuntu, Debian, RHEL, Fedora, Alpine); via .NET | x86_64, ARM64 on supported OS |
| Bash | Unix-like (Linux distributions, macOS, BSD) | Windows via Cygwin or WSL; portable to other POSIX systems | x86, x86_64, ARM, others via compilation |
| Zsh | Unix-like (Linux, macOS—default since macOS Catalina 10.15 in 2019, BSD) | Windows via Cygwin, WSL, or MSYS2 | x86_64, ARM64, others via source build |
| Fish | Unix-like (Linux distributions, macOS) | Windows via WSL or Cygwin | x86_64, ARM64 on Linux/macOS |
Licensing, Development, and Availability
Command shells vary significantly in their licensing models, which range from open-source permissive licenses to proprietary software tied to operating systems. For instance, Bash, developed by Brian Fox for the GNU Project, has been released under the GNU General Public License (GPL) version 3 since 2009, ensuring free redistribution and modification while requiring derivative works to adopt the same license. In contrast, Fish, initiated by Axel Liljencrantz in 2005, operates under the GNU GPL version 2, emphasizing user-friendly interactivity with obligations for source code availability in distributions.[16] Zsh, created by Paul Falstad in 1990, uses a permissive license inspired by the MIT License, allowing broad reuse without copyleft restrictions, which has facilitated its integration into various systems. Tcsh, an enhanced version of the C shell developed by Ken Greer starting in 1981, is distributed under the BSD 3-Clause License, promoting flexibility in commercial and open-source adaptations.[17] Proprietary shells like Microsoft's Cmd.exe, introduced with MS-DOS 1.0 in 1981 and evolved into the Windows NT command interpreter by 1993, are licensed under Microsoft's End User License Agreement (EULA), restricting modification and redistribution outside of Windows ecosystems. PowerShell, originally released by Microsoft in 2006 as a task automation framework, transitioned to an open-source model in 2016 under the MIT License for its cross-platform versions (PowerShell Core and later), while Windows PowerShell remains proprietary. Newer entrants like Nushell, launched in 2019 by a community led by Andres Naggar, adopt the MIT License, enabling easy forking and integration in modern development workflows. Development of these shells often involves dedicated projects or corporate teams, with community contributions playing a key role in open-source variants. The GNU Project maintains Bash through collaborative efforts, with Chet Ramey as the primary steward since the early 1990s.[3] Zsh's development is coordinated via SourceForge and GitHub, with ongoing enhancements from a global contributor base. Fish and Nushell rely on GitHub-hosted repositories for version control and issue tracking, fostering rapid iteration through pull requests. Tcsh's maintenance occurs through a dedicated organization on GitHub, focusing on stability and compatibility.[18] Microsoft handles PowerShell's evolution internally, with open-source aspects managed via the .NET Foundation, while Cmd.exe receives updates as part of Windows servicing. Availability is influenced by distribution methods, making shells accessible via native installations or third-party channels. On Linux, Bash and Zsh are typically pre-installed or available through package managers like apt (Debian/Ubuntu) and yum/dnf (Red Hat/Fedora), with Fish and Nushell installable similarly.[3] macOS includes Zsh as the default since 2019, while Bash and others can be added via Homebrew.[11] Windows features Cmd.exe and PowerShell built-in, with cross-platform PowerShell downloadable from GitHub releases or the Microsoft Store; Nushell and Fish are obtainable via Winget or Chocolatey. Tcsh is commonly bundled in BSD systems like FreeBSD and installable on Unix-like platforms via ports or packages.[17]| Shell | License | Key Developer/Project | First Release | Primary Availability Channels |
|---|---|---|---|---|
| Bash | GPL v3 | GNU Project (Brian Fox) | 1989 | Linux distros (apt, yum), macOS (Homebrew), source tarballs |
| Zsh | Zsh (MIT-like) | Paul Falstad / Community | 1990 | Built-in on macOS, Linux package managers, Homebrew |
| Fish | GPL v2 | Axel Liljencrantz / GitHub | 2005 | Package managers (apt, brew, chocolatey), GitHub releases |
| Tcsh | BSD 3-Clause | Ken Greer / tcsh-org | 1983 | BSD systems (built-in), Linux/Unix packages, source |
| Cmd.exe | Microsoft EULA | Microsoft | 1981 (MS-DOS) | Built-in on Windows |
| PowerShell | MIT (Core/7+) | Microsoft / .NET Foundation | 2006 | Built-in on Windows, GitHub/MS Store for cross-platform |
| Nushell | MIT | Andres Naggar / Community | 2019 | Package managers (winget, brew, cargo), GitHub |
Interactive User Interface Features
Command Input and Editing
Command input and editing in command shells primarily involve keyboard-driven mechanisms for composing, modifying, and correcting commands before execution. Most modern shells provide line editing capabilities inspired by either Emacs or Vi editor keybindings, allowing users to navigate, insert, delete, and manipulate text on the command line in real-time. These features enhance usability by reducing typing errors and enabling efficient command construction, often integrated with underlying libraries or built-in editors.[19] Line editing modes vary across shells but commonly support both Emacs-style (non-modal, with Ctrl-based shortcuts for movement and editing) and Vi-style (modal, with insert and command modes using HJKL navigation and i/Esc toggles) keybindings. In Bash, the GNU Readline library—integrated since its initial release with Bash 1.0 in June 1989—provides these modes, defaulting to Emacs-style while enabling Vi mode viaset -o vi, which maps keys like h/l for left/right movement in command mode and i for insertion. Zsh employs its own Zsh Line Editor (ZLE), supporting Emacs mode by default (bindkey -e) with shortcuts like Ctrl-A for line start and Vi mode (bindkey -v) featuring modal editing similar to Vim, including 0/$ for line boundaries and b/w for word jumps.[20] Tcsh, an enhanced C shell, includes a built-in command-line editor with configurable Emacs or Vi emulation, where Vi mode uses Esc to enter command state for operations like d to delete characters.[21] PowerShell leverages the PSReadLine module for advanced editing, supporting both modes—Emacs by default (e.g., Ctrl-B/F for backward/forward) and Vi via Set-PSReadLineOption -EditMode Vi—with Vi mode providing insert/normal states and yank/paste via y/p.[22] In contrast, the Windows CMD shell offers rudimentary editing without full modes, relying on arrow keys for navigation, F2 for partial recall, and Quick Edit mode for mouse-based selection and pasting, lacking programmable keybindings.
Autocorrection features assist in real-time error mitigation during input. Zsh's built-in spelling correction, enabled via setopt correct, scans commands and arguments against a dictionary, prompting users to confirm corrections like changing "ech o" to "echo" before execution.[20] Fish shell provides autosuggestions that predict and display potential corrections or completions in gray text as users type, based on history and paths; these can be accepted with right-arrow or Ctrl-F, effectively suggesting fixes for incomplete or erroneous inputs without interrupting workflow.[23] Bash and Tcsh lack native spellchecking but offer basic correction through tab-completion and history integration, where misspelled commands may resolve via fuzzy matching in Readline or Tcsh's programmable completion.[21]
Some shells implement implicit directory changes to streamline navigation without explicit cd invocation. In Zsh, the autocd option treats a lone directory path as a cd command, changing the working directory upon entering a valid path like /usr/bin.[20] The 4NT shell from JP Software similarly supports implicit CD, where typing a directory name alone effects the change, a feature carried over from its predecessor 4DOS for enhanced interactivity in DOS environments.[24] PowerShell requires explicit cd or Set-Location but can alias paths for shorthand, without true implicit behavior.
Mandatory argument prompts ensure completeness by querying users interactively for omissions. Eshell, the Emacs-integrated shell, uses customizable variables like eshell-rm-interactive-query to prompt for confirmation on destructive actions (e.g., "Delete file? (y or n)"), and built-ins like cd without arguments default to home while others (e.g., mv with insufficient paths) may defer to Emacs prompts or error with requests for input, integrating seamlessly with Emacs' minibuffer for missing details.[25] This Lisp-based approach allows extensible prompting, unlike non-interactive shells where missing arguments typically result in silent failures or usage messages.
Output Display and Formatting
Command shells vary in their approaches to output display and formatting, employing techniques such as colorization, highlighting, and structured rendering to improve readability and convey information efficiently. These features leverage terminal capabilities like ANSI escape sequences to differentiate elements like file types, errors, or data structures, reducing cognitive load during interactive sessions. While traditional shells like Bash rely on external utilities and aliases for enhancements, modern shells such as Fish and PowerShell integrate more native support for visual aids directly into their core functionality.[26][23][27] Colored directory listings represent a foundational enhancement in output formatting, particularly in Unix-like shells. In Bash, thels command from GNU Coreutils supports colorized output via the --color option, which uses ANSI escape sequences to distinguish file types (e.g., directories in blue, executables in green) when the output is directed to a terminal. This feature, configurable through the dircolors utility that generates the LS_COLORS environment variable, has been available since the 1990s and is often enabled by default via aliases in distributions like those using Bash. For instance, eval "$(dircolors -b)" sets up the color database, allowing users to customize schemes for attributes like symlinks or archives.[26]
Text and syntax highlighting further refine output presentation by providing real-time visual feedback. The Fish shell offers built-in syntax highlighting that colors commands, parameters, quotes, and errors as the user interacts, with potential mistakes (e.g., undefined commands) marked in red by default; this is achieved through parsing the command line on-the-fly and applying configurable colors via variables like fish_color_error. Similarly, PowerShell's console host has incorporated enhancements since PowerShell 5.0 in 2016, including syntax coloring for scripts and output via the PSReadLine module, with expanded ANSI support in PowerShell 7.0 (released 2020) enabling richer 24-bit color rendering for elements like error messages and object properties. These capabilities extend to output streams, where commands like Get-ChildItem can display colored file listings when piped to formatters.[23][28]
Progress indicators provide dynamic visual cues for ongoing operations, helping users gauge task completion without additional monitoring. In traditional shells, tools like wget display a progress bar in interactive verbose mode (--progress=bar), showing download percentage, speed, and ETA as an ASCII thermometer-style graphic, which can be forced even in non-verbose contexts with --show-progress. Modern shells like Nushell introduce custom spinners and bars for built-in commands.[29]
Structured output formats prioritize data organization over raw text dumps, facilitating analysis in interactive environments. PowerShell excels here with the Format-Table cmdlet, which arranges object properties into aligned columns with options for auto-sizing (-AutoSize), grouping (-GroupBy), and wrapping long text; since PowerShell 7.2, table headers support colorization via $PSStyle.Formatting.TableHeader for better distinction. In shells integrated with JSON processing, tools like jq enable pretty-printing by default, indenting nested structures with two spaces and adding line breaks for readability—e.g., piping output to jq . reformats compact JSON into a hierarchical view, commonly used in Bash or Zsh pipelines for API responses.[27][30]
Navigation and Context Assistance
Command shells provide various mechanisms to facilitate navigation between directories and contexts, as well as on-the-fly assistance for users without requiring command execution. These features enhance efficiency by maintaining a stack of previously visited directories and offering predictive or contextual guidance during input. In Unix-like shells such as Bash and Zsh, directory stacks enable quick switching, while modern shells like Fish and PowerShell incorporate advanced suggestion systems tied to user behavior and command semantics.[31][32] Directory history and stacks allow users to manage a list of recent directories for rapid navigation. In Bash, thepushd builtin adds the current directory to a stack and changes to a new one, while popd removes the top entry and returns to the previous directory; stack entries can be accessed via +N (from the top) or -N (from the bottom) in commands like cd or pushd.[31] Similarly, Zsh supports pushd and popd with identical core functionality, but extends access through the ~N notation, where ~1 refers to the first stack entry below the current directory (counting from 1), enabling shorthand like cd ~2 to jump to the third position.[32] The dirs builtin in both shells displays the stack, with Zsh offering options like -v for numbered output to aid selection.[32] PowerShell lacks a native directory stack but provides Push-Location and Pop-Location cmdlets that mimic this behavior, storing locations in a stack accessible via indices.
Completion systems assist users by suggesting valid inputs as they type, often triggered by the Tab key. Most Unix shells, including Bash and Zsh, support tab completion for commands, paths, and arguments through programmable interfaces; Bash relies on the Readline library for basic filename and command matching, while Zsh's compsys offers more granular control with completers for contexts like options or expansions.[33] PowerShell's tab completion is highly contextual, using argument completers to suggest values based on the cmdlet and prior parameters—for instance, typing Get-Process - followed by Tab lists relevant properties like Name or Id, with support for dynamic scripting via Register-ArgumentCompleter.[34] Completions often integrate with filename expansion to suggest valid paths during directory navigation.[33]
Automatic suggestions provide proactive guidance by predicting likely continuations. Fish shell features built-in autosuggestions that display faded previews of commands from history or completions as users type, accepted via right-arrow or Ctrl-F for the full suggestion, or Alt-right for the next word; this is based on frequency and prefix matching without requiring plugins.[23] Zsh achieves similar functionality through its menu-select mode in the completion system, enabled by loading the zsh/complist module and setting the menu style to select; pressing Tab cycles through a selectable list of matches, with options for long lists or incremental search.[35] PowerShell, via the PSReadLine module (version 2.1+), offers predictive IntelliSense that suggests full commands from history in a dropdown, configurable for inline display and extensible with plugins.[34]
Context-sensitive help delivers targeted documentation directly in the shell. Bash's help builtin provides summaries for its own builtins, such as help cd outputting usage and options; it supports patterns for listing related commands but is limited to shell internals.[36] PowerShell's Get-Help cmdlet offers comprehensive, cmdlet-specific assistance, including syntax, parameters, and examples—e.g., Get-Help Get-Process -Examples displays practical usage scenarios like filtering processes by name; it also supports -Online for web-based help and -Full for detailed notes.[37] Zsh extends this with run-help, which invokes man pages or custom handlers for external commands, while Fish uses a unified help command that opens interactive documentation or examples for functions and builtins.[38] These tools prioritize immediate, non-executable aid to reduce errors during interactive sessions.
Command Execution and Management
Background and Asynchronous Execution
Command shells provide mechanisms for executing commands asynchronously, allowing users to continue interacting with the shell while long-running tasks proceed in the background. This capability prevents the foreground session from blocking and enhances productivity, particularly for resource-intensive operations like file processing or network requests. Early Unix shells introduced these features to manage multiple processes efficiently within a single terminal session.[39] In Unix-like shells derived from the Bourne shell, background execution is initiated by appending an ampersand (&) to the command, a feature present since the Bourne shell's release in 1977. For example,sleep 60 & launches the sleep command asynchronously, returning control to the shell immediately with a job ID for later reference. The Bourne shell, developed by Stephen Bourne at Bell Labs, established this syntax as a foundational element of POSIX-compliant shells, enabling non-blocking execution without requiring separate terminals. Modern derivatives like Bash and Zsh retain this operator, integrating it with job control for managing multiple concurrent tasks.[39][40]
PowerShell offers background job launching via the Start-Job cmdlet, which executes a script block or command in a separate process without interrupting the current session. Introduced in PowerShell 2.0, Start-Job -ScriptBlock { Get-Process } creates a job object that can be monitored or retrieved later, providing object-oriented handling suitable for administrative scripting. Unlike the simple & operator, PowerShell jobs support remote execution and structured output, making them more robust for enterprise environments.[41]
The Windows Command Prompt (cmd.exe) supports basic background execution through the start /b command, which runs an executable without creating a new window and returns control promptly, as in start /b notepad.exe. However, cmd.exe lacks native job control, limiting users to external tools like Task Manager for monitoring or termination, which contrasts with the integrated management in Unix shells and PowerShell. This design reflects cmd.exe's focus on sequential batch processing rather than interactive multitasking.
Job suspension and resumption allow pausing foreground commands to free the terminal, then resuming them in the foreground or background. In Bash and compatible shells, pressing Ctrl+Z sends a SIGTSTP signal to suspend the current process, after which fg brings it to the foreground or bg resumes it asynchronously. This job control system, built on POSIX.1-1988 standards, maintains a table of jobs for easy switching, with commands like jobs listing active or stopped processes. Job control was added to Bourne shell derivatives such as the Korn shell (1983) and Bash (1989), evolving from earlier Thompson shell limitations.[39]
PowerShell supports job suspension through its job objects, but interactive suspension like Ctrl+Z is handled at the console level rather than natively by the shell; users can stop jobs with Stop-Job and resume via Start-Job on saved states. Cmd.exe offers no built-in suspension or resumption, requiring manual process termination via taskkill or external intervention, which underscores its simpler, non-interactive architecture compared to Unix shells' comprehensive job management.[42]
Parallel execution extends asynchronous capabilities by running multiple instances concurrently, leveraging multicore processors. In GNU tools integrated with Unix shells, xargs -P n processes input lines across up to n parallel invocations of a command, such as find . -name "*.txt" | xargs -P 4 -I {} grep "pattern" {} to search files simultaneously. This option, part of GNU findutils since the early 2000s, optimizes bulk operations by distributing workload without shell-specific extensions.
PowerShell 7 introduced the -Parallel parameter for ForEach-Object, enabling concurrent script block execution across input objects using runspaces, as in 1..10 | ForEach-Object -Parallel { $_ * 2 } -ThrottleLimit 5. Released in March 2020, this feature provides controlled parallelism with throttling to avoid resource exhaustion, surpassing cmd.exe's lack of any native parallel support.[43]
Notification mechanisms alert users to job completion without constant monitoring. Bash enables immediate status reporting via set -o notify, which prints messages like "[44]+ Done" upon background job termination, rather than deferring until the next prompt. This option, available since Bash 1.0, integrates with the shell's job table for real-time updates.
PowerShell facilitates job completion notifications through event handlers, such as registering Register-ObjectEvent on a job's StateChanged event to trigger custom actions like logging or alerts when the job reaches a completed state. Cmd.exe provides no such built-in notifications, relying on external polling or tools for status checks. These features briefly integrate with process monitoring tools like ps in Unix or Get-Process in PowerShell for oversight.[42]
| Feature | Unix-like Shells (e.g., Bash) | PowerShell | Cmd.exe |
|---|---|---|---|
| Background Launch | command & | Start-Job | start /b |
| Suspension/Resumption | Ctrl+Z, fg/bg | Stop-Job/Start-Job (limited interactive) | None |
| Parallel Support | [xargs](/page/Xargs) -P | ForEach-Object -Parallel (7+) | None |
| Completion Notification | set -o notify | Event handlers (e.g., StateChanged) | None |
History, Recall, and Reuse
Command history in shells refers to the recording of previously executed commands, enabling users to recall, edit, and reuse them efficiently. This feature enhances productivity by reducing repetitive typing and supporting session continuity. Most modern shells maintain history through persistent storage, with variations in implementation across Unix-like (e.g., Bash, Zsh, Fish) and Windows environments (e.g., PowerShell, cmd.exe). In Bash, history is stored in a plain-text file named.bash_history in the user's home directory, appended to upon shell exit or via the history -a command. PowerShell, starting with version 5.0 in 2016, relies on the PSReadLine module for history management, which saves commands to a JSON-formatted file at the path specified by Get-PSReadLineOption -HistorySavePath, defaulting to ConsoleHost_history.txt in the PowerShell user profile directory, supporting structured logging for later analysis. Zsh stores history in ~/.zsh_history by default, with options for compression and timestamping enabled via the EXTENDED_HISTORY option. Fish uses a binary database file in ~/.local/share/fish/fish_history for efficient querying and storage. In contrast, cmd.exe in Windows maintains an in-memory history buffer that is not persistently stored across sessions unless third-party tools are used.
Recall mechanisms allow quick access to past commands. Bash and Zsh support arrow key navigation (up/down) through the history list, integrated via the GNU Readline library, while !! repeats the last command and !n invokes the nth entry. PowerShell uses up-arrow for sequential recall, with Get-History and Invoke-History cmdlets for indexed access. Fish provides up-arrow recall with fuzzy matching, and cmd.exe offers an F7 key to open a pop-up menu of recent commands for selection. These methods prioritize recency, with shells like Bash allowing event designators (e.g., !$ for the last argument) to extract specific parts.
Searching and editing history streamline retrieval in large logs. Bash's Readline enables incremental search with Ctrl+R, displaying matches as the user types, and Ctrl+S for forward search, while editing occurs inline before execution. Zsh extends this with fc -l for listing and editing via external editors, and its SHARE_HISTORY option synchronizes history across multiple terminal sessions in real-time. PowerShell's PSReadLine supports reverse search with Ctrl+R and forward with Ctrl+S, plus persistent history sharing across PowerShell instances via module settings. Fish integrates a dedicated history search command (history search) with substring matching and inline editing.
Persistence and size limits prevent unbounded growth while ensuring usability. Bash uses the HISTSIZE environment variable (default 500 lines in memory) and HISTFILESIZE (default 500 for the file), ignoring duplicates via HISTCONTROL=ignoredups. Zsh defaults to 30 lines via HISTSIZE but allows unlimited growth with setopt HIST_SAVE_NO_DUPS, saving to disk on exit. Fish limits history to 256,000 unique items by default through an LRU mechanism, with automatic pruning of old items and support for per-host filtering. PowerShell's PSReadLine sets a default maximum of 4096 entries, configurable via Set-PSReadLineOption -MaximumHistoryCount, with automatic saving on session end. Cmd.exe restricts in-session history to 50 commands, cleared on exit without persistence options.
| Shell | Storage File/Format | Default Size Limit | Sharing Across Sessions |
|---|---|---|---|
| Bash | ~/.bash_history (text) | 500 entries | No (manual sync) |
| Zsh | ~/.zsh_history (text/compressed) | 30 entries | Yes (SHARE_HISTORY) |
| Fish | ~/.local/share/fish/fish_history (binary) | 256,000 unique items | Yes (automatic) |
| PowerShell | PSReadLine JSON file | 4096 entries | Yes (module option) |
| cmd.exe | In-memory only | 50 entries | No |
Argument Handling and Validation
Command shells vary significantly in their approaches to handling and validating arguments during interactive use and scripting, influencing user experience and error prevention. In Bash, interactive prompts for arguments are achieved using theread builtin with the -p option, which displays a custom prompt before reading input into a variable, such as read -p "Enter filename: " filename.[45] Similarly, PowerShell employs the Read-Host cmdlet to prompt users, allowing for secure input masking with the -AsSecureString parameter if needed, as in Read-Host "Enter password" -AsSecureString. The Fish shell uses the read command with the -p or --prompt option for displayed prompts before reading input into a variable.[46] In contrast, the Windows Command Prompt (cmd.exe) uses set /p for prompted input, like set /p var=Enter value: , which reads a line and assigns it to the variable without advanced masking options.
Validation rules in shells help enforce data integrity by checking argument types, presence, or formats before execution. PowerShell provides robust, declarative validation through attributes on function parameters, such as [ValidateSet("option1", "option2")] for enumerated values or [ValidatePattern("^\d+$")] for regex-based checks, which automatically generate errors for invalid input and support type coercion like [int] for numeric arguments.[47] Bash offers lighter validation via options like set -u, which treats references to unbound variables as errors (exiting non-interactively), or manual checks with conditionals, but lacks built-in type enforcement beyond string operations.[45] Zsh mirrors Bash's set -u behavior for unset parameters while extending validation through its parameter module, allowing types like integers via zmodload zsh/parameter and typeset -i var. Fish emphasizes validation in its argparse command, where the ! modifier attaches a script to verify flag values, such as ensuring a numeric option with # prefix, and defaults to treating unknown options as errors unless specified otherwise.[48] Cmd.exe relies on batch script logic for validation, checking argument existence with if "%1"=="" or using errorlevel after commands, without native type checking.[6]
Quoting and escaping mechanisms protect arguments from unintended expansion or splitting, with differences arising from each shell's syntax rules. In Bash and Zsh, single quotes (') treat content literally without expansion, while double quotes (") permit variable ($var) and command substitution (`cmd` or $(cmd)) but prevent word splitting; backslashes (\) escape special characters like $ or spaces outside quotes.[45][49] PowerShell uses single quotes for literal strings (no variable expansion) and double quotes for expandable ones (e.g., "Hello $name"), with the backtick (`) as the escape character for quotes or newlines, differing from Unix shells' backslash.[50] Fish follows a similar pattern to Bash, with single quotes fully literal and double quotes expanding variables ($var) but limiting escapes to \", \$, and newline continuations, avoiding complex backslash sequences for portability.[51] Cmd.exe primarily uses double quotes to enclose arguments with spaces or special characters (e.g., "path with spaces"), escaping metacharacters like & or | with caret (^), and does not support single quotes for quoting, leading to simpler but less flexible handling.[6]
Default value assignments streamline argument handling by providing fallbacks for optional inputs. Fish supports defaults in functions via argparse modifiers like =? for optional values (e.g., argparse 'f/file=?default.txt' -- $argv), assigning the specified default if the flag is absent.[48] Zsh allows parameter defaults in function definitions using local param=${1-default}, or more elegantly with typeset -T for tied arrays, ensuring unset arguments receive predefined values. PowerShell declares defaults directly in parameter attributes, such as param([string]$Path = "C:\temp"), which applies if no value is provided and integrates with validation.[52] Bash achieves this through conditional assignment like file=${1:-default.txt}, using parameter expansion to substitute defaults for empty or unset values.[45] In cmd.exe, optional arguments are handled by checking positional parameters and assigning defaults manually, e.g., if "%1"=="" set file=default.txt, without syntactic sugar for automation.
| Shell | Prompt Mechanism | Key Validation Feature | Quoting Style (Single/Double) | Default Assignment Example |
|---|---|---|---|---|
| Bash | read -p | set -u for unbound vars | Literal / Expand vars | ${1:-default} |
| PowerShell | Read-Host | [ValidateSet] attributes | Literal / Expand vars | param($var = "default") |
| Fish | read -p | ! script in argparse | Literal / Limited expand | f/file=?default |
| Zsh | print -n "prompt"; read | typeset -i types | Literal / Expand vars | param=${1-default} |
| Cmd.exe | set /p | Manual if checks | N/A / Enclose spaces | if "%1"=="" set var=def |
File and String Handling
Directory Navigation Tools
Directory navigation tools in command shells extend beyond the basiccd command by providing mechanisms for efficient movement between frequently visited or previously accessed directories. These features typically include stack-based operations for temporary directory changes, bookmarking systems for quick access to named locations, intelligent jumping based on usage patterns, and support for remote directory handling via integrated protocols like SSH. Such tools enhance productivity by reducing the need for repetitive path entry, particularly in complex directory structures common in development and system administration environments.
Stack-based navigation maintains a last-in, first-out (LIFO) directory stack, allowing users to push the current directory onto the stack before changing to a new one and later pop back to previous locations. In POSIX-compliant shells like Bash and Zsh, this is implemented through the built-in pushd command to add a directory to the stack and change to it, popd to remove the top entry and return to the new top, and dirs to display the stack contents. Bash's implementation has no fixed limit on stack size (limited only by available memory), while Zsh offers similar functionality with additional options for rotating or exchanging stack positions and a configurable maximum size via the DIRSTACKSIZE parameter (no limit by default). The Fish shell provides built-in pushd, popd, and dirs commands for directory stack management. In the Windows Command Prompt (CMD), pushd and popd provide analogous stack management, integrating with drive changes. PowerShell uses Push-Location (aliased as pushd) and Pop-Location (aliased as popd) for a more flexible stack that can handle not only file system paths but also provider-based locations like registry keys, with Get-Location to view the stack.[53]
Bookmarks and aliases enable persistent shortcuts to specific directories, often through shell-specific mechanisms or user-defined functions. Zsh supports named directory bookmarks natively via the hash -d builtin, which stores paths in a hash table accessible as ~name for quick cd operations; for example, hash -d proj=~/projects/app allows navigation with cd ~proj. This feature integrates seamlessly with Zsh's parameter expansion, supporting up to the shell's hash table limits without additional configuration. In Bash, while no built-in bookmark system exists, users commonly implement custom aliases or functions for fixed directories, such as alias proj='cd ~/projects/app', or leverage PROMPT_COMMAND to dynamically update an associative array (available since Bash 4.0) for usage-based shortcuts. PowerShell offers Set-Location aliases and profile-based functions for similar persistent navigation, often combined with the $PROFILE script for initialization. Fish supports path abbreviations that can function similarly for shortcuts.
Fuzzy finding and autojump tools use algorithms to predict and jump to directories based on partial matches or historical frequency, minimizing typing for common paths. Autojump, a popular add-on for Bash and Zsh, maintains a database of visited directories weighted by access frequency and enables jumps like j partial/path via Levenshtein distance matching for fuzzy searches.[54] The z plugin, a lightweight alternative for Bash and Zsh, employs recency-frequency scoring to rank directories, allowing commands such as z proj to navigate to the most relevant match from history. Fish shell incorporates directory suggestions directly into its completion system, drawing from command history to offer fuzzy-matched paths during cd tab completion since its initial release, enhancing interactive navigation without external plugins. PowerShell can use plugins like zoxide for similar fuzzy navigation.
Remote directory handling integrates SSH for seamless navigation to directories on remote hosts, often through command chaining or shell prompts. In Unix-like shells such as Bash and Zsh, users can execute ssh user@host 'cd /remote/dir && $SHELL' to connect and start an interactive session in the specified directory, preserving the remote working context. The Fish shell supports similar SSH chaining. PowerShell supports this via Enter-PSSession or Invoke-Command with -WorkingDirectory parameters for remote path specification, enabling stack-based navigation across sessions. Some advanced shells, like Zsh, use precmd hooks to detect SSH sessions and adjust prompts for remote-aware directory displays.
| Feature | Bash | Zsh | Fish | CMD/PowerShell |
|---|---|---|---|---|
| Stack-based (pushd/popd) | Built-in (no fixed limit) | Built-in (with rotation options, DIRSTACKSIZE configurable) | Built-in (pushd/popd/dirs) | CMD: Built-in; PowerShell: Built-in (Push-Location/Pop-Location) |
| Bookmarks/Aliases | User-defined aliases/functions | Built-in (hash -d named dirs) | Abbreviations for paths | Profile-based functions/aliases |
| Fuzzy/Autojump | Plugins (autojump, z) | Plugins (autojump, z) | History-based completions | Plugins (zoxide) or custom |
| Remote Handling | SSH chaining | SSH chaining + precmd hooks | SSH chaining | Enter-PSSession with -WorkingDirectory |
Filename Matching and Expansion
Filename matching and expansion, also known as globbing, allows command shells to expand wildcard patterns into lists of matching filenames or paths before command execution. This feature simplifies operations on multiple files without explicit listing, using symbols like asterisks and question marks to represent variable characters. In Unix-like shells such as Bash and Zsh, globbing follows POSIX standards with extensions, while Windows shells like cmd.exe and PowerShell employ simpler or operator-based approaches.[55][56] In Bash, standard globbing patterns include* for any sequence of characters, ? for a single character, and [abc] for matching one of a set of characters, with [^abc] for negation. These patterns are case-sensitive by default and processed by the shell before passing arguments to commands. Zsh extends this with similar syntax but adds advanced qualifiers, such as (.) to match only regular files, enhancing precision in expansions. For example, ls *.txt in Bash expands to all .txt files in the current directory, excluding subdirectories unless combined with other patterns.[55]
Cmd.exe supports basic wildcards with * matching any sequence and ? for a single character, but lacks character classes like [ ]; instead, it relies on simple substitutions in commands like dir *.exe. PowerShell uses wildcards in cmdlets like Get-ChildItem (alias dir), where * and ? function similarly, but pattern matching often involves the -like operator for explicit comparisons, such as Get-ChildItem -Path * -Like "*.txt". This operator supports wildcards but not full regular expressions unless -match is used. Unlike cmd.exe, PowerShell's approach integrates with object-oriented pipelines, allowing filtered results to be processed further.[56][57][58]
Brace expansion generates multiple strings from comma-separated lists within braces, performed early in the expansion order. Bash supports this natively, as in echo file{1,2}.txt expanding to file1.txt file2.txt, useful for creating patterned filenames without loops. Zsh also includes brace expansion with similar syntax, often combined with globbing for complex generations. Cmd.exe lacks brace expansion entirely, requiring manual repetition or batch scripting for equivalents. PowerShell does not have built-in brace expansion in its shell syntax but can achieve similar results using arrays or ForEach-Object, such as $files = "file1.txt", "file2.txt"; Get-ChildItem $files.[55]
Recursive matching traverses subdirectories to find patterns. Zsh enables this with ** in glob patterns, where ls **/*.txt matches all .txt files recursively, including in nested directories, when the GLOB_DOTS option is set appropriately. Bash requires the globstar shell option (shopt -s globstar) to enable ** for recursion, mimicking Zsh's behavior. Cmd.exe has no native recursive globbing; commands like dir /s *.txt use the /s switch for subdirectory search, but wildcards apply only at the leaf level. In PowerShell, Get-ChildItem -Recurse -Filter "*.txt" performs recursive matching efficiently, with -Filter applying wildcards before recursion for performance gains over -Include.[59][60]
Handling of hidden files varies, affecting pattern matching for dotfiles (Unix) or attribute-hidden files (Windows). In Bash and Zsh, glob patterns like * exclude files starting with . by default, treating them as hidden; inclusion requires the dotglob option in Bash (shopt -s dotglob) or GLOB_DOTS in Zsh, allowing ls * to match .hidden alongside visible files. Cmd.exe's dir command ignores hidden files unless /a:h is specified, and wildcards like * then apply to them; for example, dir /a:h * lists all hidden items. PowerShell's Get-ChildItem excludes hidden items by default but includes them with -Force or -Hidden, enabling wildcards to match across visibility, as in Get-ChildItem -Force -Like ".*". These differences ensure shells balance convenience with security by not exposing hidden system files unintentionally.[55]
| Feature | Bash | Zsh | cmd.exe | PowerShell |
|---|---|---|---|---|
| Basic Globbing (*, ?) | Yes, plus [ ] classes | Yes, plus [ ] and qualifiers | Yes, * and ? only | Yes, via -like or -Filter |
| Brace Expansion {a,b} | Yes | Yes | No | No (simulatable with arrays) |
| Recursive Matching | ** with globstar option | ** native | /s switch in dir | -Recurse in Get-ChildItem |
| Hidden Files Inclusion | shopt -s dotglob | setopt GLOB_DOTS | /a:h in dir | -Force or -Hidden |
Built-in String Processing Commands
Command shells incorporate built-in utilities for outputting and manipulating strings, enabling text processing directly within the shell environment without invoking external programs. In POSIX-compliant shells, such as the traditional Bourne shell and its derivatives, theecho utility outputs its arguments to standard output followed by a newline, providing a simple mechanism for displaying strings or variables. Similarly, the printf utility supports formatted string output based on the C library's printf function, allowing precise control over formatting, escape sequences, and alignment, which addresses limitations in echo's variable behavior across implementations. The Windows Command Prompt (cmd.exe) uses echo for basic string output with support for environment variable expansion via %VAR%, but lacks advanced formatting like printf.[61][62]
In contrast, Microsoft's PowerShell employs Write-Output as its core cmdlet for sending objects—including strings—to the pipeline, where they can be further processed or displayed; unlike Unix equivalents, it handles rich .NET objects rather than plain text, facilitating integration with broader scripting ecosystems. For string substitution and trimming, Unix-like shells like Bash use parameter expansion operators, such as ${parameter#word} to remove the shortest matching prefix pattern from the variable's value or ${parameter%word} for suffixes, enabling pattern-based trimming without additional tools. Zsh supports similar parameter expansions to Bash. PowerShell, leveraging .NET's System.String class, provides methods like $string.Trim() to remove leading and trailing whitespace (or specified characters) from a string, returning a new string instance for immutable operations.[63][64][65]
Case conversion and length determination further differentiate shells' native capabilities. Bash, starting with version 4.0, supports uppercase conversion via ${parameter^^} (converting all characters to uppercase) and lowercase via ${parameter,,}, applying these transformations recursively to matching patterns if specified; it also yields the length of a parameter's value with ${#parameter}, counting characters post-expansion. The Fish shell introduces a dedicated string builtin command for comprehensive manipulations, including string upper and string lower for case changes, string length for character counts, and string trim for whitespace removal, enhancing readability over parameter syntax—these features were added in Fish 2.3.0 (May 2016) to streamline common text operations.[64][66]
Encoding handling varies significantly, reflecting shells' origins and design goals. POSIX shells assume a locale-defined character set, typically supporting 7-bit ASCII in the portable "C" locale but extending to multibyte encodings like UTF-8 through environment variables such as LC_ALL or LANG set to UTF-8 variants, allowing modern implementations to process international text. Bash follows this model, relying on the system's locale for UTF-8 interpretation during expansions and output. Cmd.exe primarily uses ANSI or OEM code pages, configurable via chcp, with limited UTF-8 support in newer versions. PowerShell defaults to Unicode (UTF-16 internally for strings, with UTF-8 output support) since its 1.0 release in 2006, ensuring native handling of diverse characters without locale configuration, though cmdlets like Out-File permit explicit encoding overrides. Fish shell also assumes UTF-8 by default in its configuration, aligning with contemporary Unix expectations for global text compatibility. These built-in commands often feed into pipelines for chained processing, such as formatting output before redirection.[67][64][68][69]
| Feature | POSIX sh (echo/printf) | Bash Parameter Expansion | Zsh Parameter Expansion | cmd.exe | Fish string Builtin | PowerShell Methods/Cmdlets |
|---|---|---|---|---|---|---|
| Basic Output | echo for simple args; printf for formatted | Inherits POSIX; adds expansions | Inherits POSIX; adds expansions | echo with %var% | echo; printf | Write-Output for pipeline |
| Trimming/Substitution | Limited; requires external tools | ${var#pattern}, ${var%pattern} for patterns | ${var#pattern}, ${var%pattern} for patterns | Limited (via set or external) | string trim | $str.Trim(), $str.TrimStart() |
| Case Conversion | None built-in | ${var^^} (upper), ${var,,} (lower) since 4.0 | ${var^^} (upper), ${var,,} (lower) since compatible versions | None built-in | string upper, string lower | $str.ToUpper(), $str.ToLower() |
| Length | None built-in | ${#var} | ${#var} | None built-in | string length | $str.Length |
| Default Encoding | Locale-dependent (ASCII/UTF-8 via env) | UTF-8 via locale | UTF-8 via locale | ANSI/OEM (chcp configurable) | UTF-8 | Unicode (UTF-16/UTF-8) since 1.0 |
Scripting and Programming Features
Control Structures and Logic
Command shells provide control structures to enable conditional execution, repetition through loops, pattern matching via case or switch statements, and mechanisms for handling errors during script execution. These features allow scripts to implement logic similar to procedural programming languages, though syntax and capabilities vary across shells to reflect their design philosophies—such as POSIX compliance for Unix-like shells versus object-oriented elements in PowerShell.[70][71] Conditional statements in POSIX-compliant shells, such as those based on the Bourne shell (sh) or Bash, use theif construct to evaluate a command's exit status, typically via the test command enclosed in square brackets. The syntax is if list; then list; [elif list; then list;] ... [else list;] fi, where the list after if or elif is executed only if the preceding command succeeds (exit status 0). For example, in Bash, if [ "$var" -eq 5 ]; then echo "Equal"; fi checks if a variable equals 5 using the -eq operator.[70] In contrast, PowerShell employs a more C-like syntax with if (<condition>) { <statements> } [elseif (<condition>) { <statements> } ] [else { <statements> }], where conditions use operators like -eq for equality, as in if ($var -eq 5) { Write-Output "Equal" }. This allows direct evaluation of expressions without a separate test command. Fish shell follows a block-based approach similar to Bash but without semicolons, using if CONDITION; COMMANDS...; [else; COMMANDS...;] end, integrating seamlessly with its command syntax.[71]
Looping constructs enable repetitive execution, with variations in iteration methods across shells. In POSIX shells like Bash, the for loop iterates over words or a sequence, using for name [in words]; do commands; done, such as for i in 1 2 3; do echo $i; done to print numbers. The while loop runs while commands; do commands; done as long as the condition succeeds, exemplified by while [ $i -le 3 ]; do echo $i; i=$((i+1)); done. Fish simplifies iteration with for varname in values; commands...; end for explicit lists, like for i in 1 2 3; echo $i; end, and while CONDITION; COMMANDS...; end for condition-based loops, avoiding variable increments in favor of built-in sequencing. PowerShell offers foreach ($item in $collection) { commands } for object collections and while ($condition) { commands } or do { commands } while ($condition) for conditional loops, supporting pipeline integration like 1..3 | ForEach-Object { Write-Output $_ }. These differences highlight Unix shells' word-splitting focus versus PowerShell's array and object handling.[72][73][74]
Case and switch statements facilitate multi-way branching based on pattern matching. POSIX shells use case word in [(] pattern1 | pattern2 ...) commands ;; ... esac, where patterns support globs like * for defaults, as in Bash's case $var in 1) echo "One";; *) echo "Other";; esac. This syntax, inherited from the Bourne shell, allows fall-through only via explicit patterns. PowerShell's switch statement, introduced in version 1.0 released in 2006, uses switch (<value>) { <pattern> { <statements> } ... default { <statements> } }, supporting wildcards (*), regex (-regex), and exact matches, such as switch ($var) { 1 { "One" } default { "Other" } }. Fish employs a similar switch VALUE; case PATTERN...; COMMANDS...; [case ...] end, with glob patterns but no built-in regex support, emphasizing simplicity over PowerShell's advanced matching options.[70][75]
Error handling in shells manages runtime failures, often through signal traps or exception blocks. Bash uses the trap builtin to intercept signals, including ERR for non-zero exits, with syntax trap 'commands' SIGNAL, such as trap 'echo "Error at line $LINENO"' ERR to log errors globally. This requires explicit setup and does not halt execution unless combined with set -e. PowerShell provides structured exception handling via try { <statements> } catch [<type>] { <statements> } finally { <statements> }, catching terminating errors like try { Get-Item nonexist } catch { Write-Output $_.Exception.Message }, allowing type-specific catches and cleanup in finally. Fish lacks a native try-catch but uses or for command chaining on failure and functions for custom error logic, relying on exit statuses rather than exceptions. These approaches integrate with variables for error details, such as $? in Bash or $Error in PowerShell.[76][77]
Variable Management and Data Types
In command shells, variables serve as named storage for data, enabling reuse in scripts and interactive sessions. Declaration typically involves simple assignment, though advanced shells offer typed or scoped variants. For instance, in Bash, variables are declared via assignment likevar=value without explicit typing, treating all as strings by default. Similarly, Zsh uses assignment var=value, but supports typed arrays and associative arrays via the typeset command. PowerShell requires the $ prefix for variables, as in $var = "value", and supports explicit typing like [int]$var = 42 for strong typing.[78] Nushell declares variables with let var = value or mut var = value for mutable ones, emphasizing structured data.[79] Fish employs set var value for assignment, with options for scope control.[80] In contrast, Windows CMD uses set var=value, lacking formal typing.[81]
Scoping rules determine variable visibility, often distinguishing global, local, and function scopes to prevent unintended modifications. Bash employs dynamic scoping by default for functions, where variables are visible based on the call stack, but supports static local scoping via local var or declare -l var within functions. Zsh defaults to static scoping, making function-local variables inaccessible outside unless declared global with typeset -g var. PowerShell uses lexical scoping with levels like script, global, local, and private; variables declared without modifiers are local to the current scope, accessible via modifiers like $global:var.[82] Nushell variables are block-scoped, similar to modern languages, with let creating immutable locals and mut for modifiable ones, preventing leaks to outer scopes.[79] Fish offers explicit scope control with set -l var for local (function-only) or set -g var for global, using lexical scoping to isolate function environments.[80] CMD variables are globally visible within the session unless unset, with no inherent scoping mechanisms.[81]
Data types in shells range from basic string-only support to rich structured handling, influencing scripting expressiveness. Traditional Unix shells like Bash and Zsh primarily treat variables as untyped strings, though Bash supports integer arithmetic via declare -i var and arrays (declare -a var), while Zsh extends this with associative arrays (typeset -A var) and numeric types. PowerShell, introduced in 2006, supports a wide array of .NET types including strings, integers, booleans, objects, arrays, and hashtables, enabling object-oriented pipelines.[83] Nushell focuses on structured data types like lists, records (similar to objects), tables, and primitives (int, float, string, bool), modeling data as typed values for tabular processing.[84] Fish variables hold lists or strings, with no strong typing but support for universal variables across sessions. CMD is limited to strings, with basic numeric operations via delayed expansion.[81] These types can inform control structures, such as conditional checks on variable values.
Environment variables, a subset of variables passed to child processes, are managed through export mechanisms to propagate settings like PATH. In Unix shells such as Bash and Zsh, the export var=value command marks variables for inheritance, making them available to subprocesses; unexported variables remain shell-local. PowerShell accesses environment variables via the $env: drive, setting them with $env:VAR = "value" for session-wide availability or [Environment]::SetEnvironmentVariable("VAR", "value", "Process") for process-specific persistence.[85] Nushell handles them similarly through let-env VAR = "value", integrating with structured data flows.[86] Fish uses set -gx var value to export globally, with automatic inheritance for exported vars.[80] In CMD, setx var value sets persistent environment variables, while set affects the current session.[81]
| Shell | Declaration Example | Primary Scoping | Supported Data Types | Export Method |
|---|---|---|---|---|
| Bash | var=value | Dynamic (local static) | Strings, integers, arrays | export var |
| Zsh | var=value | Static | Strings, arrays, assoc. arrays, nums | export var |
| PowerShell | $var = value | Lexical | .NET types (obj, arr, hash, etc.) | $env:VAR = value |
| Nushell | let var = value | Block | Primitives, lists, records, tables | let-env VAR = value |
| Fish | set var value | Lexical | Strings, lists | set -gx var value |
| CMD | set var=value | Global | Strings | set var=value |
Extensibility and Module Support
Command shells vary significantly in their approaches to extensibility, allowing users to customize and enhance functionality through plugins, modules, functions, aliases, API integrations, and configuration options. This enables adaptation for specific workflows, such as automation or integration with external systems. For instance, Unix-like shells like Bash and Zsh emphasize lightweight plugin frameworks and scripting extensions, while Windows-oriented shells like PowerShell prioritize structured module ecosystems tied to broader runtime environments. Plugin systems provide a modular way to add features without modifying core shell code. In Zsh, the Oh My Zsh framework, introduced in 2009, supports over 1,000 community-contributed plugins and themes that extend syntax highlighting, autosuggestions, and Git integrations through simple directory-based loading. Similarly, Fish shell offers a plugin manager like Fisher that installs extensions for tasks such as web API calls or directory jumping, leveraging its web-based configuration tool for easy management. PowerShell, on the other hand, uses the PowerShell Gallery, launched by Microsoft in 2014, as a centralized repository for modules that encapsulate cmdlets, functions, and providers; these can be installed viaInstall-Module and support versioning for enterprise-scale deployments.
Functions and aliases facilitate reusable custom commands, promoting extensibility at the user level. Bash defines functions using the function keyword or simple naming syntax, allowing multi-line scripts for tasks like file backups, which persist in configuration files like .bashrc. PowerShell employs New-Alias for short mappings (e.g., gal for Get-Alias) and New-Function or script blocks for more complex logic, integrating seamlessly with its object-oriented pipeline. In Zsh, aliases extend to global or per-host definitions via .zshrc, often combined with plugins for advanced autocompletion.
API integrations enable deeper extensibility by bridging shells with programming languages or frameworks. PowerShell leverages the .NET Framework (or .NET Core since version 6.0) for native calls to assemblies via Add-Type or Import-Module, enabling integrations with Windows APIs or cross-platform libraries without external tools. These features contrast with traditional shells like Bash, which rely on external calls to scripts or binaries for similar integrations.
Theme and configuration extensibility further customize user interfaces and behaviors. Fish provides built-in prompt customization via functions like fish_prompt, supporting colors, Git status, and dynamic elements through its configuration-driven themes. Bash uses the PS1 environment variable for prompt engineering, incorporating escape sequences for timestamps, usernames, and directory paths, often extended by functions in .bash_profile. PowerShell's prompt function allows .NET-based rendering, including Unicode support for modern terminals since version 5.0. Such options enhance usability without requiring full scripting overhauls.
Inter-Process and System Integration
Data Piping and Redirection
Data piping and redirection are fundamental features in command shells that enable the interconnection of commands by directing output from one process to the input of another, or to files and devices, facilitating modular and efficient data processing workflows.[70] In Unix-like shells adhering to POSIX standards, the pipe operator| connects the standard output of a command to the standard input of the next, a mechanism introduced in the original Unix system in 1973 by Doug McIlroy to promote command composition.[87] For example, ls | grep .txt lists directory contents and filters for files ending in .txt, processing text streams byte-by-byte without intermediate files.[70]
Redirection in POSIX-compliant shells, such as bash and zsh, uses operators like > to send standard output to a file (overwriting it), >> to append, and < to read from a file as input; these operate on file descriptors, with standard input (0), output (1), and error (2) allowing targeted handling like command 2> errors.log to capture stderr separately from stdout.[70] The tee utility extends this by duplicating output to both a file and standard output, akin to a T-junction, as in ls | tee listing.txt | [grep](/page/Grep) .txt, which saves the full list to a file while piping filtered results onward; this command reads from stdin and writes to stdout and specified files, preserving stream integrity.
In the Windows Command Prompt (cmd.exe), piping with | similarly chains text output to input, supporting basic workflows like dir | find "txt", but lacks object-oriented streaming, treating all data as plain text lines.[6] Redirection mirrors POSIX with >, >>, and <, plus 2> for stderr, enabling multi-stream control such as command > output.txt 2> error.txt; however, cmd.exe has no built-in tee equivalent, requiring workarounds like multiple redirections or third-party tools.[6]
PowerShell advances these concepts with object-based piping via |, where output objects (not just text) are passed directly to the next command's parameters, allowing rich manipulations like Get-Process | Where-Object {$_.CPU -gt 100} | Sort-Object CPU, which filters and sorts process objects by CPU usage without string parsing.[88] Redirection operators include >, >>, and stream-specific variants like 2> for errors, 3> for warnings, and 4> for verbose, with cmdlets like Out-File providing equivalent functionality for file output, as in Get-Process | Out-File processes.txt; this supports explicit stream binding for precise control.[89] The Tee-Object cmdlet splits object pipelines, saving to a file or variable while continuing downstream, exemplified by Get-Process | Tee-Object -FilePath processes.txt | Sort-Object CPU, enhancing debugging and logging in complex scripts.[90]
Across shells, these mechanisms differ in granularity: POSIX and cmd.exe emphasize text streams with file descriptor redirection for efficiency in Unix environments, while PowerShell's object model reduces errors in structured data handling, though it may introduce overhead for simple text tasks.[70][88] Multi-stream support is universal but varies in expressiveness, with PowerShell's additional streams (e.g., for debug output) offering finer isolation than the basic three in POSIX shells.[89][70]
Job Control and Process Monitoring
Job control in command shells enables users to manage multiple concurrent processes, such as suspending, resuming, or terminating background tasks without interrupting the foreground session. This feature originated in Unix-like systems and is supported variably across shells; POSIX-compliant shells like Bash provide robust built-in mechanisms, while Windows Command Prompt (CMD.exe) offers minimal support, relying instead on external tools like Task Manager for process oversight. PowerShell introduces object-oriented job management, treating jobs as .NET objects for more structured handling.[91][42][92] For job listing, Unix shells such as Bash use thejobs builtin command to display active jobs in the current session, showing job numbers, status (running or stopped), and command summaries; for example, jobs outputs lines like "[1]+ Stopped sleep 100" to track suspended processes. In contrast, PowerShell employs the Get-Job cmdlet, which retrieves detailed objects for background jobs initiated via Start-Job or the -AsJob parameter, including properties like ID, State (Running, Completed, Failed), and Location; running Get-Job without parameters lists all session jobs in a tabular format. CMD.exe lacks a native job listing command, requiring users to invoke external utilities like tasklist for a system-wide process view, which does not track shell-specific jobs.[91][93]
Signaling processes for control, such as termination or suspension, is handled in Bash through the kill builtin, which accepts job specifications like %1 or %sleep to send signals (e.g., SIGTERM via kill %1 or SIGSTOP via kill -STOP %1) to background jobs, integrating seamlessly with the shell's job table. PowerShell's Stop-Job cmdlet provides analogous functionality, stopping specified jobs by ID or name (e.g., Stop-Job -Id 1) and supporting force removal with -PassThru to return job objects for further inspection; it operates on PowerShell background jobs rather than arbitrary system processes. In CMD.exe, signaling relies on the external taskkill command (e.g., taskkill /PID 1234 /F), which targets process IDs but offers no shell-integrated job referencing, limiting interactive management.[94][42]
Disowning jobs to persist them beyond the shell session is a key feature in Unix shells; Bash's disown builtin removes jobs from the shell's table (e.g., disown %1), preventing SIGHUP signals on logout, while nohup runs commands immune to hangups by redirecting output to nohup.out (e.g., [nohup](/page/Nohup) sleep 100 &). PowerShell approximates this via Start-Process with the -NoNewWindow parameter to launch detached processes (e.g., Start-Process notepad -NoNewWindow), though it does not manage jobs post-launch like Unix shells; for true detachment, combining with Start-Job allows non-interactive execution without session ties. CMD.exe provides no direct disown equivalent, as background processes via start /B remain vulnerable to session closure, often necessitating external wrappers like start /B cmd /C for persistence.[95][96]
Process monitoring complements job control by providing visibility into resource usage; in Bash, the external ps command integrates via pipelines or scripts (e.g., ps aux | grep sleep) to display details like PID, CPU, and memory for all or filtered processes, often combined with job PIDs from jobs -p. PowerShell's Get-Process cmdlet offers richer, object-based monitoring (e.g., Get-Process | Select-Object Name, CPU, WorkingSet), retrieving properties such as handle count and start time across local or remote systems, with filtering via parameters like -Name. CMD.exe uses tasklist for basic monitoring (e.g., tasklist /V), showing columns like PID, session name, and memory usage, but lacks the programmatic extensibility of PowerShell or Bash scripting integrations.[97][98]
| Feature | Bash (Unix-like) | PowerShell (Windows) | CMD.exe (Windows) |
|---|---|---|---|
| Job Listing | jobs (shell builtins, job numbers) | Get-Job (object properties, states) | None; use tasklist (system-wide) |
| Signaling | kill %job (signals like SIGTERM) | Stop-Job -Id (job objects) | taskkill /PID (external, no jobs) |
| Disowning/Persistence | disown, nohup (SIGHUP immunity) | Start-Process -NoNewWindow (detached) | None; start /B (limited) |
| Monitoring | ps (filtered via pipes) | Get-Process (object filtering) | tasklist (basic columns) |
Event and Input Handling
Command shells vary in their approaches to event and input handling, particularly in interactive sessions where keyboard events, signals, and asynchronous inputs must be managed efficiently to provide responsive user experiences. POSIX-compliant shells like Bash and Zsh typically rely on terminal drivers and libraries such as Readline or ZLE for buffering keystrokes, allowing users to edit commands before execution. In contrast, modern shells like Fish and PowerShell incorporate more integrated event models, leveraging their runtime environments for finer-grained control over input processing. These mechanisms ensure that inputs are buffered, signals are trapped for custom responses, and asynchronous operations do not block the shell's interactivity. Keystroke stacking, or input buffering, enables shells to handle partial user input without immediate execution, supporting features like line editing and history navigation. In Bash, the GNU Readline library manages this by buffering keystrokes in a line editor mode, where characters are accumulated until a newline or special sequence (e.g., Ctrl+D for EOF) is detected, allowing Emacs- or Vi-style editing. Zsh employs its Zsh Line Editor (ZLE), which buffers keystrokes via keymaps (e.g., emacs or vicmd) and supports multibyte input with a configurable timeout (KEYTIMEOUT) for sequence completion, pushing unread input onto a stack for reprocessing if needed. Fish shell uses a custom interactive editor with thecommandline builtin to access and manipulate the current input buffer, binding sequences to functions via bind for handling partial inputs like search or completion. PowerShell, through the PSReadLine module, operates in "cooked mode" by default, where the Windows console buffers keystrokes until Enter or Tab, processing them as complete lines; raw mode can be enabled via a custom PSConsoleHostReadLine function for direct keystroke interception and event-driven editing.
Signal trapping allows shells to intercept operating system signals, such as SIGINT (generated by Ctrl+C), to perform cleanup or custom actions rather than terminating abruptly. Bash uses the trap builtin to associate commands with signals; for SIGINT, it catches the signal during foreground command waits in interactive mode, executing the trap if set while ignoring it by default to avoid interrupting loops. Zsh supports a similar trap command, but also provides TRAPINT and other TRAPSIG functions for signal-specific handling, ensuring traps execute even on interrupts like Ctrl+C without double-triggering in non-interactive scripts. Fish handles signals via the trap command or --on-signal option in function definitions, preventing default exit on trapped signals like SIGINT and allowing custom responses, such as echoing a message before continuing. In PowerShell, Ctrl+C (equivalent to SIGINT) triggers the Console.CancelKeyPress event, which can be subscribed to for asynchronous handling; the trap statement catches terminating errors including breaks, while Register-EngineEvent subscribes to engine-level events like Exiting for broader signal-like notifications.
Asynchronous input handling facilitates non-blocking reads from multiple sources, such as file descriptors or user prompts with timeouts, essential for responsive scripting. Bash's select builtin monitors multiple file descriptors for input readiness, returning when data arrives or a timeout expires, enabling polled asynchronous I/O without external tools. Zsh extends this with built-in coprocesses (coproc) for background I/O and libraries like zsh-async for task-based asynchronous input processing, allowing non-blocking reads via pseudo-terminals. Fish supports asynchronous patterns through event handlers (--on-event or emit), which can trigger on input-related events without blocking the main shell loop, though direct FD polling requires external utilities. PowerShell 7+ integrates async/await syntax for .NET tasks, enabling asynchronous input via InvokeAsync or thread jobs (e.g., Start-ThreadJob with Receive-Job -Wait), allowing scripts to await user input or FD data concurrently without halting execution.
Terminal event responses configure how the shell interacts with the underlying console for events like interrupts or flow control. In Unix-like shells (Bash, Zsh, Fish), the stty utility sets terminal attributes, such as mapping Ctrl+C to intr for SIGINT generation or Ctrl+S/Q for stop/start flow control, ensuring consistent event propagation across sessions. PowerShell, running on Windows, uses console input modes via SetConsoleMode, enabling processed input (e.g., ENABLE_PROCESSED_INPUT for line editing) or raw mode for direct keystroke events, with defaults favoring buffered handling to mimic Unix tty behavior.
Security and Restriction Mechanisms
Access Permissions and Execution Controls
Command shells enforce access permissions to ensure that users can only execute commands and access files for which they have appropriate rights, integrating with the underlying operating system's security model. In Unix-like systems, shells such as Bash rely on POSIX file permissions, where execute bits determine if a file or directory can be run or traversed. Windows-based shells like PowerShell, in contrast, leverage NTFS Access Control Lists (ACLs) for more granular control, allowing permissions based on users, groups, and inheritance. This distinction affects how shells validate and restrict execution within scripts and interactive sessions. Permission checks within shells allow scripts to verify executability before invoking commands, preventing errors or security issues. In Bash and other Unix shells, the built-intest command (or its synonym [) supports the -x option to check if a file exists and has the execute permission bit set for the current user; for example, [ -x /bin/ls ] returns true if the ls binary is executable. This check respects the file's mode bits as defined by stat(2). In PowerShell, there is no direct equivalent to test -x, but scripts can use Test-Path to confirm existence and then inspect ACLs via Get-Acl to verify execute rights, such as checking if the user has GenericExecute access; alternatively, Get-Command can test resolvability and basic executability for commands in the PATH.[99] The Windows Command Prompt (cmd.exe) lacks built-in permission testing builtins, relying instead on external tools like icacls for ACL inspection or error handling from failed executions.
For elevating privileges to execute commands requiring higher access, Unix shells integrate seamlessly with tools like sudo, which allows temporary root or user delegation based on configuration in /etc/sudoers; shells invoke it directly, as in sudo apt update. PowerShell provides the Start-Process cmdlet with the -Verb RunAs parameter to launch processes with elevated credentials, prompting for User Account Control (UAC) approval, equivalent to sudo for administrative tasks; for example, Start-Process notepad.exe -Verb RunAs.[100] Since Windows 11 version 24H2, a native sudo command has been introduced for PowerShell and Command Prompt, enabling Linux-like elevation with sudo cmd to run subsequent commands as administrator.[101]
Path security mechanisms in shells mitigate risks like trojaned binaries by controlling how commands are resolved and executed. In Bash, secure PATH handling involves avoiding relative directories (e.g., excluding . from PATH to prevent local trojans) and using absolute paths or command -p to invoke builtins without PATH lookup; best practices recommend a PATH like /usr/local/bin:/usr/bin:/bin to prioritize system directories. PowerShell enhances path security through its execution policy, introduced in PowerShell 1.0 in November 2006, which restricts script execution based on signatures and sources—policies like Restricted block unsigned scripts, while RemoteSigned requires downloaded scripts to be signed, reducing risks from malicious PATH injections.[102] In cmd.exe, PATH manipulation vulnerabilities are addressed via environment variable isolation, but it lacks policy-based controls, relying on system-wide antivirus and UAC.
Default permissions for newly created files and directories are managed via umask in Unix shells, which subtracts a mask from the base mode (0666 for files, 0777 for directories) to set initial access rights. The umask builtin in Bash displays or sets this value, such as umask 022 to ensure new files are non-writable by group and others; it applies globally to the shell session and child processes.[103] PowerShell does not have a direct umask equivalent, as file creation inherits NTFS ACLs from the parent directory or uses default domain policies, but scripts can explicitly set ACLs post-creation with Set-Acl to mimic permission masking. This Unix-centric approach provides simpler, mode-based defaults, while Windows shells offer more flexible but complex ACL inheritance.
Restricted Execution Environments
Restricted execution environments in command shells provide configured modes or subsets that curtail standard capabilities, such as directory navigation, environment variable alterations, or arbitrary command invocation, to mitigate security risks in scenarios like user delegation or limited-access sessions. These mechanisms emerged to balance usability with control, often integrating with broader system isolation techniques for enhanced confinement. In Unix-like operating systems, one of the earliest implementations is the restricted Korn shell (rksh), introduced in the 1980s by AT&T Bell Laboratories as part of the KornShell (ksh) development led by David Korn. Rksh operates identically to standard ksh but enforces limitations including a fixed PATH, disabled directory changes via cd, and prohibitions on variable assignments that could enable escapes, making it suitable for controlled login environments.[104][105] The GNU Bash shell offers rbash, a restricted variant invoked via the --restricted flag or directly as rbash, which inherits Bash's syntax while imposing constraints like preventing PATH modifications, disabling the cd builtin, and restricting sourced files to the user's home directory to avert unrestricted shell invocation.[106] The Z shell (Zsh) also supports a restricted mode, invoked by naming the binary rzsh or using the -r option, which imposes similar limitations on PATH changes, directory navigation, and command execution.[107] These Unix restricted shells frequently integrate with chroot for filesystem sandboxing, where the shell runs within a jailed root directory containing only essential binaries and libraries, preventing access to the broader system as seen in Linux and BSD configurations.[108] Command whitelisting in these environments is typically enforced through a controlled PATH that limits executable directories. The /etc/shells file catalogs approved login shells to validate and restrict assignable interpreters via tools such as chsh.[109] Microsoft PowerShell, evolving from Windows PowerShell 1.0 in 2006, incorporates restricted modes, including Constrained Language Mode introduced in version 3.0 in 2012, which permits interactive commands and approved cmdlets but blocks advanced scripting elements, arbitrary .NET type usage, and code generation to reduce attack surfaces.[110] Complementing this, PowerShell's Restricted execution policy defaults on client systems and prohibits all script execution, allowing only interactive console use to enforce minimal exposure.[111] PowerShell's Just Enough Administration (JEA), debuted in version 5.0 in 2016, extends sandboxing through constrained remoting endpoints that whitelist specific commands, parameters, and roles, enabling granular delegation without granting full shell access or administrative tokens.[112] This contrasts with Unix approaches by leveraging .NET integration for finer-grained, scriptable restrictions rather than solely relying on environment lockdowns.Secure Input and Data Isolation
Command shells provide mechanisms to handle sensitive input securely, preventing exposure of data like passwords during entry, and to isolate data flows to mitigate risks such as interception or injection attacks. In Unix-like shells such as Bash and Zsh, theread builtin command supports the -s option, which turns off echoing of input characters, allowing users to enter passwords without displaying them on the screen; this is particularly useful for scripts prompting for credentials. Similarly, the Fish shell offers a read command with a -s or --silent flag that masks input, ensuring sensitive data remains hidden during interactive sessions.[46] In contrast, Windows Command Prompt (CMD) lacks a built-in method for non-echoing input; the set /p command echoes all characters, often requiring external tools or workarounds for secure prompts. PowerShell addresses this with Read-Host -AsSecureString, which not only suppresses echoing but also stores the input as a SecureString object in memory, encrypting it to prevent plaintext exposure even in process dumps.
To prevent command injection, where untrusted input could alter command execution, shells emphasize safe data handling through quoting and binding practices. In Bash and Zsh, users must manually quote variables (e.g., using single or double quotes) when passing input to commands, as unquoted expansions can lead to injection if input contains shell metacharacters like semicolons or pipes; this relies on developer diligence to isolate data from code. PowerShell's parameter binding mechanism enhances isolation by automatically parsing arguments to cmdlets as structured data rather than raw strings, reducing injection risks from direct concatenation; for instance, bound parameters treat user input as values without evaluating them as code.[113] CMD offers limited protection, primarily through basic escaping, but lacks robust binding, making it more susceptible to injection in batch scripts unless inputs are explicitly sanitized. Fish promotes safer practices with its explicit syntax for command substitutions, though it still requires quoting for untrusted data.
Excluding sensitive commands from history logs is a key isolation feature to avoid persistent storage of credentials. Bash and Zsh support the HISTIGNORE environment variable, which defines patterns (e.g., HISTIGNORE="passwd*:rm -rf") to skip commands matching those from the history file, preventing exposure upon review or accidental replay. In Fish, history exclusion can be achieved by prefixing commands with a space (if fish_history ignores leading spaces) or using history --delete post-execution, though it lacks a direct equivalent to HISTIGNORE. PowerShell, via the PSReadLine module, allows opting out of history for the session with Set-PSReadLineOption -HistorySaveStyle SaveNothing, or selectively by reading input via $host.UI.RawUI.ReadKey methods that bypass logging; this ensures sensitive interactions, like credential entry, are not saved to the console history file. CMD's doskey history can be cleared entirely with doskey /reinstall, but offers no pattern-based exclusion, limiting granular control over sensitive entries.
For audit purposes, shells include tools to record sessions without compromising security. In Bash and Zsh, the script utility captures all terminal input and output to a file (e.g., script -c command logfile), enabling post-session review while allowing secure prompts to remain masked in the log. PowerShell's Start-Transcript cmdlet logs the entire session or specified commands to a text file, including timestamps and output, but respects secure input by not revealing masked data; it supports appending to existing logs for continuous auditing. Fish provides fish -c 'command' | tee logfile for basic recording, but lacks a native transcript tool equivalent to script. CMD does not have built-in session recording, relying on external redirection or third-party tools for audits. These features collectively ensure data isolation by logging actions without exposing sensitive content.References
- The shell is the outermost layer of the operating system. Shells incorporate a programming language to control processes and files, as well as to start and ...
