Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
scripting:obsolete [2019/01/22 23:37]
bignose Correct formatting markup.
scripting:obsolete [2019/08/30 16:01] (current)
ersen
Line 20: Line 20:
 ^  Syntax ​ ^  Replacement ​ ^  Description ​ ^ ^  Syntax ​ ^  Replacement ​ ^  Description ​ ^
 |Unquoted expansions, [[syntax:​expansion:​wordsplit]],​ and [[syntax:​expansion:​globs]] ​ |[[http://​mywiki.wooledge.org/​Quotes | Proper quoting]], Ksh/​Bash-style [[syntax:​arrays | arrays]], The "​$@"​ expansion, [[commands:​builtin:​read]] ​ |//Quoting errors// are a broad category of common mistakes brought about by a few unintuitive features carried over from the Bourne shell due to complaints of broken scripts and changes in previously documented behavior. Most of the important expansions are performed at the same time from left to right. However, a few expansions, most notably word-splitting and globbing, and in shells other than Bash, [[syntax:​expansion:​brace | brace expansion]],​ are performed **on the results of previous expansions, by default, unless they are quoted.** This means that the act of expanding an unquoted variable in an ordinary argument context, depending on the value of the variable, can yield different results depending on possibly uncontrolled side-effects like the value of ''​IFS'',​ and the names of files in the current working directory. You can't get globbing without word-splitting,​ or vice versa (without ''​set -f''​). [[http://​mywiki.wooledge.org/​BashFAQ/​050 | You can't store a command or character-delimited list in a variable and safely evaluate it with unquoted expansion]]. If possible, always choose a shell that supports Korn shell arrays such as Bash. They are a vital but non-standard feature for writing clean, safe scripts. Well-written scripts don't use word-splitting. A few exceptions are listed on the [[syntax:​expansion:​wordsplit | word splitting page]]. A significant proportion of the issues on the famous [[http://​mywiki.wooledge.org/​BashPitfalls | Pitfalls list]] fall under this category. See also: //​[[http://​mywiki.wooledge.org/​DontReadLinesWithFor | Don't read lines with for!]]// | |Unquoted expansions, [[syntax:​expansion:​wordsplit]],​ and [[syntax:​expansion:​globs]] ​ |[[http://​mywiki.wooledge.org/​Quotes | Proper quoting]], Ksh/​Bash-style [[syntax:​arrays | arrays]], The "​$@"​ expansion, [[commands:​builtin:​read]] ​ |//Quoting errors// are a broad category of common mistakes brought about by a few unintuitive features carried over from the Bourne shell due to complaints of broken scripts and changes in previously documented behavior. Most of the important expansions are performed at the same time from left to right. However, a few expansions, most notably word-splitting and globbing, and in shells other than Bash, [[syntax:​expansion:​brace | brace expansion]],​ are performed **on the results of previous expansions, by default, unless they are quoted.** This means that the act of expanding an unquoted variable in an ordinary argument context, depending on the value of the variable, can yield different results depending on possibly uncontrolled side-effects like the value of ''​IFS'',​ and the names of files in the current working directory. You can't get globbing without word-splitting,​ or vice versa (without ''​set -f''​). [[http://​mywiki.wooledge.org/​BashFAQ/​050 | You can't store a command or character-delimited list in a variable and safely evaluate it with unquoted expansion]]. If possible, always choose a shell that supports Korn shell arrays such as Bash. They are a vital but non-standard feature for writing clean, safe scripts. Well-written scripts don't use word-splitting. A few exceptions are listed on the [[syntax:​expansion:​wordsplit | word splitting page]]. A significant proportion of the issues on the famous [[http://​mywiki.wooledge.org/​BashPitfalls | Pitfalls list]] fall under this category. See also: //​[[http://​mywiki.wooledge.org/​DontReadLinesWithFor | Don't read lines with for!]]// |
-|''​`COMMANDS`'' ​ |''​$(COMMANDS)'' ​ |This is the older Bourne-compatible form of the [[syntax:​expansion:​cmdsubst | command substitution]]. Both the ''​`COMMANDS`''​ and ''​$(COMMANDS)''​ syntaxes are specified by POSIX, but the latter is _greatly_ ​preferred, though the former is unfortunately still very prevalent in scripts. New-style command substitutions are widely implemented by every modern shell (and then some). The only reason for using backticks is for compatibility with a real Bourne shell (like Heirloom). Backtick command substitutions require special escaping when nested, and examples found in the wild are improperly quoted more often than not. See: //​[[http://​mywiki.wooledge.org/​BashFAQ/​082 | Why is $(...) preferred over `...` (backticks)?​]]//​.|+|''​`COMMANDS`'' ​ |''​$(COMMANDS)'' ​ |This is the older Bourne-compatible form of the [[syntax:​expansion:​cmdsubst | command substitution]]. Both the ''​`COMMANDS`''​ and ''​$(COMMANDS)''​ syntaxes are specified by POSIX, but the latter is __greatly__ ​preferred, though the former is unfortunately still very prevalent in scripts. New-style command substitutions are widely implemented by every modern shell (and then some). The only reason for using backticks is for compatibility with a real Bourne shell (like Heirloom). Backtick command substitutions require special escaping when nested, and examples found in the wild are improperly quoted more often than not. See: //​[[http://​mywiki.wooledge.org/​BashFAQ/​082 | Why is $(...) preferred over `...` (backticks)?​]]//​.|
 |''​[\ EXPRESSION\ ]''​\ and\ ''​test\ EXPRESSION'' ​ |''<​nowiki>​[[</​nowiki>​\ EXPRESSION\ <​nowiki>​]]</​nowiki>'' ​ |''​test''​ and ''​[''​ are the Bourne/​POSIX commands for evaluating test expressions (they are almost identical, and ''​[''​ is somewhat more common). The expressions consist of regular arguments, unlike the Ksh/Bash ''<​nowiki>​[[</​nowiki>''​ command. While the issue is analogous to ''​let''​ vs ''<​nowiki>​((</​nowiki>'',​ the advantages of ''<​nowiki>​[[</​nowiki>''​ vs ''​[''​ are even more important because the arguments/​expansions aren't just concatenated into one expression. With the classic ''​[''​ command, the number of arguments is significant. If at all possible, use the [[syntax:​ccmd:​conditional_expression | conditional expression]] ("new test command"​) ''<​nowiki>​[[ EXPRESSION ]]</​nowiki>''​. Unless there is a need for POSIX compatibility,​ there are only a few reasons to use ''​[''​. ''<​nowiki>​[[</​nowiki>''​ is one of the most portable and consistent non-POSIX ksh extensions available. See: [[syntax:​ccmd:​conditional_expression]] and //​[[http://​mywiki.wooledge.org/​BashFAQ/​031 | What is the difference between test, [ and [[ ?]]// | |''​[\ EXPRESSION\ ]''​\ and\ ''​test\ EXPRESSION'' ​ |''<​nowiki>​[[</​nowiki>​\ EXPRESSION\ <​nowiki>​]]</​nowiki>'' ​ |''​test''​ and ''​[''​ are the Bourne/​POSIX commands for evaluating test expressions (they are almost identical, and ''​[''​ is somewhat more common). The expressions consist of regular arguments, unlike the Ksh/Bash ''<​nowiki>​[[</​nowiki>''​ command. While the issue is analogous to ''​let''​ vs ''<​nowiki>​((</​nowiki>'',​ the advantages of ''<​nowiki>​[[</​nowiki>''​ vs ''​[''​ are even more important because the arguments/​expansions aren't just concatenated into one expression. With the classic ''​[''​ command, the number of arguments is significant. If at all possible, use the [[syntax:​ccmd:​conditional_expression | conditional expression]] ("new test command"​) ''<​nowiki>​[[ EXPRESSION ]]</​nowiki>''​. Unless there is a need for POSIX compatibility,​ there are only a few reasons to use ''​[''​. ''<​nowiki>​[[</​nowiki>''​ is one of the most portable and consistent non-POSIX ksh extensions available. See: [[syntax:​ccmd:​conditional_expression]] and //​[[http://​mywiki.wooledge.org/​BashFAQ/​031 | What is the difference between test, [ and [[ ?]]// |
 |''​set -e'',​ ''​set -o errexit''​\\ and the ''​ERR''​ trap  |proper control flow and error handling ​ |''​set -e''​ causes untested non-zero exit statuses to be fatal. It is a debugging feature intended for use only during development and should not be used in production code, especially init scripts and other high-availability scripts. Do not be tempted to think of this as "error handling";​ it's not, it's just a way to find the place you've //​forgotten//​ to put error handling.\\ Think of it as akin to ''​use strict''​ in Perl or ''​throws''​ in C++: tough love that makes you write better code. Many guides recommend avoiding it entirely because of the apparently-complex rules for when non-zero statuses cause the script to abort. Conversely, large software projects with experienced coders may recommend or even mandate its use.\\ Because it provides no notification of the location of the error, it's more useful combined with ''​set -x''​ or the ''​DEBUG''​ trap and other Bash debug features, and both flags are normally better set on the command line rather than within the script itself.\\ Most of this also applies to the ''​ERR''​ trap, though I've seen it used in a few places in shells that lack ''​pipefail''​ or ''​PIPESTATUS''​. The ''​ERR''​ trap is not POSIX, but ''​set -e''​ is. ''​failglob''​ is another Bash feature that falls into this category (mainly useful for debugging).\\ **The ''​set -e''​ feature generates more questions and false bug reports on the Bash mailing list than all other features combined!** Please do not rely on ''​set -e''​ for logic in scripts. If you still refuse to take this advice, make sure you understand **exactly** how it works. See: //​[[http://​mywiki.wooledge.org/​BashFAQ/​105 | Why doesn'​t set -e (or set -o errexit, or trap ERR) do what I expected?​]]//​ and [[http://​www.fvue.nl/​wiki/​Bash:​_Error_handling]] | |''​set -e'',​ ''​set -o errexit''​\\ and the ''​ERR''​ trap  |proper control flow and error handling ​ |''​set -e''​ causes untested non-zero exit statuses to be fatal. It is a debugging feature intended for use only during development and should not be used in production code, especially init scripts and other high-availability scripts. Do not be tempted to think of this as "error handling";​ it's not, it's just a way to find the place you've //​forgotten//​ to put error handling.\\ Think of it as akin to ''​use strict''​ in Perl or ''​throws''​ in C++: tough love that makes you write better code. Many guides recommend avoiding it entirely because of the apparently-complex rules for when non-zero statuses cause the script to abort. Conversely, large software projects with experienced coders may recommend or even mandate its use.\\ Because it provides no notification of the location of the error, it's more useful combined with ''​set -x''​ or the ''​DEBUG''​ trap and other Bash debug features, and both flags are normally better set on the command line rather than within the script itself.\\ Most of this also applies to the ''​ERR''​ trap, though I've seen it used in a few places in shells that lack ''​pipefail''​ or ''​PIPESTATUS''​. The ''​ERR''​ trap is not POSIX, but ''​set -e''​ is. ''​failglob''​ is another Bash feature that falls into this category (mainly useful for debugging).\\ **The ''​set -e''​ feature generates more questions and false bug reports on the Bash mailing list than all other features combined!** Please do not rely on ''​set -e''​ for logic in scripts. If you still refuse to take this advice, make sure you understand **exactly** how it works. See: //​[[http://​mywiki.wooledge.org/​BashFAQ/​105 | Why doesn'​t set -e (or set -o errexit, or trap ERR) do what I expected?​]]//​ and [[http://​www.fvue.nl/​wiki/​Bash:​_Error_handling]] |
  • scripting/obsolete.txt
  • Last modified: 2019/08/30 16:01
  • by ersen