Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
scripting:newbie_traps [2015/08/02 05:12] bill_thomson |
scripting:newbie_traps [2020/05/28 12:34] fgrose [Exporting] clarify English |
||
---|---|---|---|
Line 14: | Line 14: | ||
* no shebang | * no shebang | ||
* the interpreter used depends on the OS implementation and current shell | * the interpreter used depends on the OS implementation and current shell | ||
- | * **can** be run by calling bash withthe script name as an argument, e.g. ''bash myscript'' | + | * **can** be run by calling bash with the script name as an argument, e.g. ''bash myscript'' |
* ''#!/bin/sh'' shebang | * ''#!/bin/sh'' shebang | ||
* depends on what ''/bin/sh'' actually is, for a Bash it means compatiblity mode, **not** native mode | * depends on what ''/bin/sh'' actually is, for a Bash it means compatiblity mode, **not** native mode | ||
Line 26: | Line 26: | ||
Give it another name. The executable ''test'' already exists. | Give it another name. The executable ''test'' already exists. | ||
- | In Bash it's a builtin, with other shells it might be an executable file - either way, it's bad name choice! | + | In Bash it's a builtin. With other shells, it might be an executable file. Either way, it's bad name choice! |
Workaround: You can call it using the pathname: | Workaround: You can call it using the pathname: | ||
Line 155: | Line 155: | ||
==== Exporting ==== | ==== Exporting ==== | ||
- | Exporting a variable means to give **newly created** (child-)processes a copy of that variable. **not** copy a variable created in a child process to the parent process. The following example does **not** work, since the variable ''hello'' is set in a child process (the process you execute to start that script ''./script.sh''): | + | Exporting a variable means giving **newly created** (child-)processes a copy of that variable. It does **not** copy a variable created in a child process back to the parent process. The following example does **not** work, since the variable ''hello'' is set in a child process (the process you execute to start that script ''./script.sh''): |
<code> | <code> | ||
Line 166: | Line 166: | ||
</code> | </code> | ||
- | Exporting is one-way. The direction is parent process to child process, not the reverse. The above example **will** work, when you don't execute the script, but include ("source") it: | + | Exporting is one-way. The direction is from parent process to child process, not the reverse. The above example **will** work, when you don't execute the script, but include ("source") it: |
<code> | <code> | ||
$ source ./script.sh | $ source ./script.sh | ||
Line 186: | Line 186: | ||
grep ^root: /etc/passwd >/dev/null 2>&1 | grep ^root: /etc/passwd >/dev/null 2>&1 | ||
- | if [ $? -neq 0 ]; then | + | if [ $? -ne 0 ]; then |
echo "root was not found - check the pub at the corner" | echo "root was not found - check the pub at the corner" | ||
fi | fi | ||
Line 207: | Line 207: | ||
See also: | See also: | ||
* [[scripting:basics#exit_codes | Exit codes]] | * [[scripting:basics#exit_codes | Exit codes]] | ||
+ | |||
+ | ==== Output vs. Return Value ==== | ||
+ | |||
+ | It's important to remember the different ways to run a child command, and whether you want the output, the return value, or neither. | ||
+ | |||
+ | When you want to run a command (or a pipeline) and save (or print) the **output**, whether as a string or an array, you use Bash's ''$(command)'' syntax: | ||
+ | <code> | ||
+ | $(ls -l /tmp) | ||
+ | newvariable=$(printf "foo") | ||
+ | </code> | ||
+ | |||
+ | When you want to use the **return value** of a command, just use the command, or add ( ) to run a command or pipeline in a subshell: | ||
+ | <code> | ||
+ | if grep someuser /etc/passwd ; then | ||
+ | # do something | ||
+ | fi | ||
+ | |||
+ | if ( w | grep someuser | grep sqlplus ) ; then | ||
+ | # someuser is logged in and running sqlplus | ||
+ | fi | ||
+ | </code> | ||
+ | |||
+ | Make sure you're using the form you intended: | ||
+ | <code> | ||
+ | # WRONG! | ||
+ | if $(grep ERROR /var/log/messages) ; then | ||
+ | # send alerts | ||
+ | fi | ||
+ | </code> | ||
+ | |||
+ | Please see: | ||
+ | * [[syntax:ccmd:intro]] | ||
+ | * [[syntax:expansion:cmdsubst]] | ||
+ | * [[syntax:ccmd:grouping_subshell]] |