Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h3>Parameter Expansion</h3> <p>The obvious answer is to use one of the special forms of parameter expansion:</p> <pre><code>: ${STATE?"Need to set STATE"} : ${DEST:?"Need to set DEST non-empty"} </code></pre> <p>Or, better (see section on 'Position of double quotes' below):</p> <pre><code>: "${STATE?Need to set STATE}" : "${DEST:?Need to set DEST non-empty}" </code></pre> <p>The first variant (using just <code>?</code>) requires STATE to be set, but STATE="" (an empty string) is OK &mdash; not exactly what you want, but the alternative and older notation.</p> <p>The second variant (using <code>:?</code>) requires DEST to be set and non-empty.</p> <p>If you supply no message, the shell provides a default message.</p> <p>The <code>${var?}</code> construct is portable back to Version 7 UNIX and the Bourne Shell (1978 or thereabouts). The <code>${var:?}</code> construct is slightly more recent: I think it was in System III UNIX circa 1981, but it may have been in PWB UNIX before that. It is therefore in the Korn Shell, and in the POSIX shells, including specifically Bash.</p> <p>It is usually documented in the shell's man page in a section called <a href="http://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion" rel="noreferrer">Parameter Expansion</a>. For example, the <code>bash</code> manual says:</p> <blockquote> <pre><code>${parameter:?word} </code></pre> <p>Display Error if Null or Unset. If parameter is null or unset, the expansion of word (or a message to that effect if word is not present) is written to the standard error and the shell, if it is not interactive, exits. Otherwise, the value of parameter is substituted.</p> </blockquote> <h3>The Colon Command</h3> <p>I should probably add that the colon command simply has its arguments evaluated and then succeeds. It is the original shell comment notation (before '<code>#</code>' to end of line). For a long time, Bourne shell scripts had a colon as the first character. The C Shell would read a script and use the first character to determine whether it was for the C Shell (a '<code>#</code>' hash) or the Bourne shell (a '<code>:</code>' colon). Then the kernel got in on the act and added support for '<code>#!/path/to/program</code>' and the Bourne shell got '<code>#</code>' comments, and the colon convention went by the wayside. But if you come across a script that starts with a colon, now you will know why.</p> <hr> <h3>Position of double quotes</h3> <p><a href="https://stackoverflow.com/users/320399/blong">blong</a> asked in a <a href="https://stackoverflow.com/questions/307503/whats-the-best-way-to-check-that-environment-variables-are-set-in-unix-shellscr/307735?noredirect=1#comment53771660_307735">comment</a>:</p> <blockquote> <p>Any thoughts on this discussion? <a href="https://github.com/koalaman/shellcheck/issues/380#issuecomment-145872749" rel="noreferrer">https://github.com/koalaman/shellcheck/issues/380#issuecomment-145872749</a></p> </blockquote> <p>The gist of the discussion is:</p> <blockquote> <p>… However, when I <code>shellcheck</code> it (with version 0.4.1), I get this message:</p> <pre><code>In script.sh line 13: : ${FOO:?"The environment variable 'FOO' must be set and non-empty"} ^-- SC2086: Double quote to prevent globbing and word splitting. </code></pre> <p>Any advice on what I should do in this case? </p> </blockquote> <p>The short answer is "do as <code>shellcheck</code> suggests":</p> <pre><code>: "${STATE?Need to set STATE}" : "${DEST:?Need to set DEST non-empty}" </code></pre> <p>To illustrate why, study the following. Note that the <code>:</code> command doesn't echo its arguments (but the shell does evaluate the arguments). We want to see the arguments, so the code below uses <code>printf "%s\n"</code> in place of <code>:</code>.</p> <pre><code>$ mkdir junk $ cd junk $ &gt; abc $ &gt; def $ &gt; ghi $ $ x="*" $ printf "%s\n" ${x:?You must set x} # Careless; not recommended abc def ghi $ unset x $ printf "%s\n" ${x:?You must set x} # Careless; not recommended bash: x: You must set x $ printf "%s\n" "${x:?You must set x}" # Careful: should be used bash: x: You must set x $ x="*" $ printf "%s\n" "${x:?You must set x}" # Careful: should be used * $ printf "%s\n" ${x:?"You must set x"} # Not quite careful enough abc def ghi $ x= $ printf "%s\n" ${x:?"You must set x"} # Not quite careful enough bash: x: You must set x $ unset x $ printf "%s\n" ${x:?"You must set x"} # Not quite careful enough bash: x: You must set x $ </code></pre> <p>Note how the value in <code>$x</code> is expanded to first <code>*</code> and then a list of file names when the overall expression is not in double quotes. This is what <code>shellcheck</code> is recommending should be fixed. I have not verified that it doesn't object to the form where the expression is enclosed in double quotes, but it is a reasonable assumption that it would be OK.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload