Category:UNIX Shell: Difference between revisions
→Implementation: --- Noting some common differences among different shells, and the "gotchyas" that arise from them |
→Implementation: Split |
||
Line 7: | Line 7: | ||
There are many UNIX Shells and most of them can be categorized into two families. For purposes of the Rosette Code, all examples are in Bourne-compatible syntax. The other family of shells, with a markedly different syntax, are ''csh'' and it's ''tcsh'' (Tenex C Shell) "clone." Common Bourne compatible shells include the original [[Bourne Shell]] (''/bin/sh'' on most versions of UNIX), the GNU [[Bourne Again SHell]] (''bash'' --- which is linked to ''/bin/sh'' on many distributions of [[Linux]], making it their default shell), the [[Korn Shell]] (''ksh''), the [[Public Domain Korn SHell]] (''pdksh''), the [[Almquist SHell]] (''ash'') and the [[Debian Almquist SHell]] (''dash'') and the [[Z SHell]] (''zsh''). |
There are many UNIX Shells and most of them can be categorized into two families. For purposes of the Rosette Code, all examples are in Bourne-compatible syntax. The other family of shells, with a markedly different syntax, are ''csh'' and it's ''tcsh'' (Tenex C Shell) "clone." Common Bourne compatible shells include the original [[Bourne Shell]] (''/bin/sh'' on most versions of UNIX), the GNU [[Bourne Again SHell]] (''bash'' --- which is linked to ''/bin/sh'' on many distributions of [[Linux]], making it their default shell), the [[Korn Shell]] (''ksh''), the [[Public Domain Korn SHell]] (''pdksh''), the [[Almquist SHell]] (''ash'') and the [[Debian Almquist SHell]] (''dash'') and the [[Z SHell]] (''zsh''). |
||
The original Bourne shell went through a number of revisions in the early years of UNIX, and support for some features varies considerably. By the time the SUSv3 (Single Unix Specification, version 3) features stablized. All recent versions of the various Bourne-compatible shells should support a common set of features, which are referred to throughout Rosette Code examples as "SUSv3" features. The Korn shell (originally written by David Korn of AT&T) and it's "public domain" clone offer extensions (such as co-processes, and "associative arrays" --- called "hash arrays" by Perl, "dictionaries" by Python, "maps" by Lua, etc). |
|||
''Main article: [[UNIX Shell Implementations]]'' |
|||
Note that even when using a common subset of supported features there are subtle implementation differences, and in some cases parsing bugs, which can affect the portability of shell script examples. For example in ''bash'' before version 2.0 the following was tolerated: |
|||
{ echo foo; echo bar } ## Bug!!! |
|||
... though this is technically a bug in the language parsing. In ''bash'' versions newer than 2.0 this was fixed and the follow is required: |
|||
{ echo foo; echo bar; } ## Note the required semicolon |
|||
... (Or the ''}'' token can be put on a separate line) |
|||
Variations of this bug probably accounts for more "breakage" during upgrades of ''bash'' and when attempting to run ''bash'' scripts under other Bourne compatible shells than any other change in the history of Bourne-compatible shells. |
|||
Another common portability issue among different Bourne-compatible shells is a subtle matter of how pipe operations are handled. In all normal UNIX shells the '''''|''''' (pipe) operator creates a unidirectional inter-process communications (IPC) stream between one shell process and another. Thus a command like: |
|||
echo foo | read bar |
|||
... implicitly invokes a subshell (separate process) as either the producer or the consumer (writer into or reader from) this data"pipe." |
|||
The crucial different in semantics is determined by whether a given implementation of a shell creates the subshell/sub-process to the left or the right of the pipe operator. (Conceivably a shell could even create subprocesses on both sides of the operator). To demonstrate, and even test for, the difference run the following lines of code: |
|||
unset bar; echo "foo" | read bar; echo "$bar" |
|||
... shells such as ''ksh'' and ''zsh'' spawn their subshells to the left of the pipe ... so the sub-process is writing into the pipeline. This means that the existing process is reading values; thus the local shell variable "bar" is set after the second semicolon in this example. Under shells such as ''bash,'' ''ash,'' ''pdksh'' (and even in older versions of ''ksh'') the subshell is spawned on the right of the ''|'' operator. In those cases the ''read'' command is setting a value to a shell variable which ceases to exist after the second semicolon (which marks the end of that command, and thus the end of the completed sub-process. |
|||
To be portable such code must use command grouping: |
|||
unset bar; echo "foo" | { read bar; echo "$bar"; ...; } |
|||
... so that all of the commands after the pipe are executed within the same subshell. |
|||
Alternatively one could use an explicit shell sub-process (using the "parentheses" delimiters in lieu of the "brace" grouping operators), or one could re-structure the code using assignment and command substitution: |
|||
unset bar; bar=$(echo "foo"); echo "$bar" # some very old shells may require ` (backticks) instead of the $(...) syntax |
|||
Note that in all these examples the ''unset bar'' command is simply to avoid any confusion in the unlikely event that a variable named "bar" was present in the shell environment or local variable heap prior to our functional examples. This sort of difference, the implicit creation and scope of subshells and subproceses, and the underlying conceptual distinctions between shell and environment variables are at the root of many shell scripting portability issues and cause most of the confusion experienced by novices to UNIX shell scripting. |
|||
=Language= |
=Language= |
Revision as of 03:38, 13 October 2007
The UNIX Shell is a component of terminal-based UNIX-derived systems which offers both a command-line interface for running system commands, as well as programming interface for intelligently automating tasks which use system commands.
Implementation
There are many UNIX Shells and most of them can be categorized into two families. For purposes of the Rosette Code, all examples are in Bourne-compatible syntax. The other family of shells, with a markedly different syntax, are csh and it's tcsh (Tenex C Shell) "clone." Common Bourne compatible shells include the original Bourne Shell (/bin/sh on most versions of UNIX), the GNU Bourne Again SHell (bash --- which is linked to /bin/sh on many distributions of Linux, making it their default shell), the Korn Shell (ksh), the Public Domain Korn SHell (pdksh), the Almquist SHell (ash) and the Debian Almquist SHell (dash) and the Z SHell (zsh).
Main article: UNIX Shell Implementations
Language
While UNIX Shells vary in the programming languages they support, such languages carry a minimum set of features. Each language allows the programmer to execute system commands as though he were typing the commands himself, and each language allows for a header line which specifies which shell implementation is used to interpret the script.
This one tells the operating system to use the Bourne Shell:
#!/bin/sh
This line tells the operating system to use the Bourne Again SHell:
#!/bin/bash
And this one tells the operating system to use the Korn Shell:
#!/bin/ksh
Each header line consists of a hash, a bang, and the path to the interpreter binary.
Subcategories
This category has the following 5 subcategories, out of 5 total.
@
- UNIX Shell User (161 P)
- Bash User (49 P)
- Korn Shell User (11 P)
Pages in category "UNIX Shell"
The following 200 pages are in this category, out of 354 total.
(previous page) (next page)2
A
- A* search algorithm
- A+B
- ABC problem
- Accumulator factory
- Ackermann function
- Active Directory/Search for a user
- Align columns
- Anagrams
- Anagrams/Deranged anagrams
- Anonymous recursion
- Append a record to the end of a text file
- Apply a callback to an array
- Arithmetic-geometric mean
- Arithmetic/Complex
- Arithmetic/Integer
- Array concatenation
- Array length
- Arrays
- Assertions
- Associative array/Creation
- Associative array/Iteration
- Averages/Arithmetic mean
- Averages/Mode
B
C
- Caesar cipher
- Calculating the value of e
- Calendar
- Calendar - for "REAL" programmers
- Call a function
- Canonicalize CIDR
- Cartesian product of two or more lists
- Case-sensitivity of identifiers
- Character codes
- Check input device is a terminal
- Check output device is a terminal
- Check that file exists
- Chinese zodiac
- Classes
- Code Golf: Code Golf
- Collections
- Colour bars/Display
- Comma quibbling
- Command-line arguments
- Comments
- Compound data type
- Conditional structures
- Conway's Game of Life
- Copy a string
- Count in octal
- Count occurrences of a substring
- Count the coins
- Create a file
- Create a file on magnetic tape
- Create an HTML table
- CSV data manipulation
- CSV to HTML translation
D
- Date format
- Date manipulation
- Day of the week
- Days between dates
- Deal cards for FreeCell
- Deceptive numbers
- Define a primitive data type
- Delete a file
- Department numbers
- Determine if a string is numeric
- Determine if only one instance is running
- Digital root
- Dinesman's multiple-dwelling problem
- DNS query
- Doomsday rule
- Dutch national flag problem
- Dynamic variable names
E
F
- Factorial
- Factors of an integer
- Fibonacci sequence
- File input/output
- File modification time
- File size
- File size distribution
- Filter
- Find common directory path
- Find limit of recursion
- Find the last Sunday of each month
- Five weekends
- FizzBuzz
- Fork
- Four bit adder
- Four is magic
- FTP
- Function composition
- Function definition
G
H
- Hailstone sequence
- Hamming numbers
- Handle a signal
- Happy numbers
- Harshad or Niven series
- Hash from two arrays
- Hello world/Graphical
- Hello world/Line printer
- Hello world/Newline omission
- Hello world/Standard error
- Hello world/Text
- Hello world/Web server
- Here document
- Host introspection
- Hostname
- HTTP
- HTTPS
- Huffman coding
I
J
L
- Langton's ant
- Last Friday of each month
- Leap year
- Least common multiple
- Linear congruential generator
- Linux CPU utilization
- Literals/Integer
- Literals/String
- Logical operations
- Long literals, with continuations
- Long multiplication
- Long year
- Longest common prefix
- Look-and-say sequence
- Loop over multiple arrays simultaneously
- Loops/Break
- Loops/Continue
- Loops/Do-while
- Loops/Downward for
- Loops/For
- Loops/For with a specified step
- Loops/Foreach
- Loops/Infinite
- Loops/N plus one half
- Loops/Nested
- Loops/While
- Luhn test of credit card numbers