- •Advanced Bash-Scripting Guide
- •Dedication
- •Table of Contents
- •Part 1. Introduction
- •Advanced Bash-Scripting Guide
- •Chapter 2. Starting Off With a Sha-Bang
- •2.1. Invoking the script
- •2.2. Preliminary Exercises
- •Part 2. Basics
- •Chapter 3. Exit and Exit Status
- •Chapter 4. Special Characters
- •Chapter 5. Introduction to Variables and Parameters
- •5.1. Variable Substitution
- •5.2. Variable Assignment
- •5.3. Bash Variables Are Untyped
- •5.4. Special Variable Types
- •Chapter 6. Quoting
- •Chapter 7. Tests
- •7.1. Test Constructs
- •7.2. File test operators
- •7.3. Comparison operators (binary)
- •7.4. Nested if/then Condition Tests
- •7.5. Testing Your Knowledge of Tests
- •8.1. Operators
- •8.2. Numerical Constants
- •Part 3. Beyond the Basics
- •Chapter 9. Variables Revisited
- •9.1. Internal Variables
- •9.2. Manipulating Strings
- •9.3. Parameter Substitution
- •9.4. Typing variables: declare or typeset
- •9.5. Indirect References to Variables
- •9.6. $RANDOM: generate random integer
- •9.7. The Double Parentheses Construct
- •Chapter 10. Loops and Branches
- •10.1. Loops
- •10.2. Nested Loops
- •10.3. Loop Control
- •10.4. Testing and Branching
- •Chapter 11. Internal Commands and Builtins
- •12.1. Basic Commands
- •12.2. Complex Commands
- •12.3. Time / Date Commands
- •12.4. Text Processing Commands
- •12.5. File and Archiving Commands
- •12.6. Communications Commands
- •12.7. Terminal Control Commands
- •12.8. Math Commands
- •12.9. Miscellaneous Commands
- •Chapter 13. System and Administrative Commands
- •Chapter 14. Command Substitution
- •Chapter 15. Arithmetic Expansion
- •Chapter 16. I/O Redirection
- •16.1. Using exec
- •16.2. Redirecting Code Blocks
- •16.3. Applications
- •Chapter 17. Here Documents
- •Chapter 18. Recess Time
- •Part 4. Advanced Topics
- •Chapter 19. Regular Expressions
- •19.1. A Brief Introduction to Regular Expressions
- •19.2. Globbing
- •Chapter 20. Subshells
- •Chapter 21. Restricted Shells
- •Chapter 22. Process Substitution
- •Chapter 23. Functions
- •23.1. Complex Functions and Function Complexities
- •23.2. Local Variables
- •Chapter 24. Aliases
- •Chapter 25. List Constructs
- •Chapter 26. Arrays
- •Chapter 27. Files
- •Chapter 28. /dev and /proc
- •28.2. /proc
- •Chapter 29. Of Zeros and Nulls
- •Chapter 30. Debugging
- •Chapter 31. Options
- •Chapter 32. Gotchas
- •Chapter 33. Scripting With Style
- •Chapter 34. Miscellany
- •34.2. Shell Wrappers
- •34.3. Tests and Comparisons: Alternatives
- •34.4. Optimizations
- •34.5. Assorted Tips
- •34.6. Oddities
- •34.7. Security Issues
- •34.8. Portability Issues
- •34.9. Shell Scripting Under Windows
- •Chapter 35. Bash, version 2
- •36. Endnotes
- •36.1. Author's Note
- •36.2. About the Author
- •36.3. Tools Used to Produce This Book
- •36.4. Credits
- •List of Tables
- •List of Examples
- •Bibliography
Parameter Substitution
|
Advanced Bash-Scripting Guide: |
|
Prev |
Chapter 9. Variables Revisited |
Next |
9.3. Parameter Substitution
Manipulating and/or expanding variables
${parameter}
Same as $parameter, i.e., value of the variable parameter. In certain contexts, only the less ambiguous ${parameter} form works.
May be used for concatenating variables with strings.
your_id=${USER}-on-${HOSTNAME} echo "$your_id"
#
echo "Old \$PATH = $PATH"
PATH=${PATH}:/opt/bin #Add /opt/bin to $PATH for duration of script. echo "New \$PATH = $PATH"
${parameter-default}
If parameter not set, use default.
echo ${username-`whoami`}
# Echoes the result of `whoami`, if variable $username is still unset.
This is almost equivalent to ${parameter:-default}. The extra : makes a difference only when parameter has been declared, but is null.
#!/bin/bash
username0=
#username0 has been declared, but is set to null. echo "username0 = ${username0-`whoami`}"
#Will not echo.
echo "username1 = ${username1-`whoami`}"
#username1 has not been declared.
#Will echo.
username2=
#username2 has been declared, but is set to null. echo "username2 = ${username2:-`whoami`}"
#Will echo because of :- rather than just - in condition test.
http://tldp.org/LDP/abs/html/parameter-substitution.html (1 of 10) [7/15/2002 6:35:10 PM]
Parameter Substitution
exit 0
${parameter=default}, ${parameter:=default}
If parameter not set, set it to default.
Both forms nearly equivalent. The : makes a difference only when $parameter has been declared and is null, [1] as above.
echo ${username=`whoami`}
# Variable "username" is now set to `whoami`.
${parameter+alt_value}, ${parameter:+alt_value}
If parameter set, use alt_value, else use null string.
Both forms nearly equivalent. The : makes a difference only when parameter has been declared and is null, see below.
echo "###### \${parameter+alt_value} ########"
echo
a=${param1+xyz} |
|
echo "a = $a" |
# a = |
param2= |
|
a=${param2+xyz} |
|
echo "a = $a" |
# a = xyz |
param3=123 |
|
a=${param3+xyz} |
|
echo "a = $a" |
# a = xyz |
echo
echo "###### \${parameter:+alt_value} ########"
echo
a=${param4:+xyz} |
|
|
echo "a = $a" |
# a = |
|
param5= |
|
|
a=${param5:+xyz} |
|
|
echo "a = $a" |
# a = |
|
# Different result from |
a=${param5+xyz} |
|
param6=123 |
|
|
a=${param6+xyz} |
|
|
echo "a = $a" |
# a = xyz |
http://tldp.org/LDP/abs/html/parameter-substitution.html (2 of 10) [7/15/2002 6:35:10 PM]
Parameter Substitution
${parameter?err_msg}, ${parameter:?err_msg}
If parameter set, use it, else print err_msg.
Both forms nearly equivalent. The : makes a difference only when parameter has been declared and is null, as above.
Example 9-12. Using param substitution and :
#!/bin/bash
#Check some of the system's environmental variables.
#If, for example, $USER, the name of the person at the console, is not set, #+ the machine will not recognize you.
:${HOSTNAME?} ${USER?} ${HOME?} ${MAIL?} echo
echo "Name of the machine is $HOSTNAME." echo "You are $USER."
echo "Your home directory is $HOME."
echo "Your mail INBOX is located in $MAIL." echo
echo "If you are reading this message,"
echo "critical environmental variables have been set." echo
echo
#------------------------------------------------------
#The ${variablename?} construction can also check
#+ for variables set within the script.
ThisVariable=Value-of-ThisVariable
# Note, by the way, that string variables may be set #+ to characters disallowed in their names.
: ${ThisVariable?}
echo "Value of ThisVariable is $ThisVariable". echo
echo
: ${ZZXy23AB?"ZZXy23AB has not been set."}
#If ZZXy23AB has not been set,
#+ then the script terminates with an error message.
#You can specify the error message.
#: ${ZZXy23AB?"ZZXy23AB has not been set."}
#Same result with: dummy_variable=${ZZXy23AB?}
# |
dummy_variable=${ZZXy23AB?"ZXy23AB has not been set."} |
# |
|
# |
echo ${ZZXy23AB?} >/dev/null |
http://tldp.org/LDP/abs/html/parameter-substitution.html (3 of 10) [7/15/2002 6:35:10 PM]
Parameter Substitution
echo "You will not see this message, because script terminated above."
HERE=0
exit $HERE # Will *not* exit here.
Parameter substitution and/or expansion. The following expressions are the complement to the match in expr string operations (see Example 12-6). These particular ones are used mostly in parsing file path names.
Variable length / Substring removal
${#var}
String length (number of characters in $var). For an array, ${#array} is the length of the first element in the array.
Exceptions:
${#*} and ${#@} give the number of positional parameters.
For an array, ${#array[*]} and ${#array[@]} give the number of elements in the array.
Example 9-13. Length of a variable
#!/bin/bash
# length.sh
E_NO_ARGS=65
if [ $# -eq 0 ] # Must have command-line args to demo script. then
echo "Invoke this script with one or more command-line arguments." exit $E_NO_ARGS
fi
var01=abcdEFGH28ij
echo "var01 = ${var01}"
echo "Length of var01 = ${#var01}"
echo "Number of command-line arguments passed to script = ${#@}" echo "Number of command-line arguments passed to script = ${#*}"
exit 0
${var#Pattern}, ${var##Pattern}
Remove from $var the shortest/longest part of $Pattern that matches the front end of $var.
A usage illustration from Example A-8:
http://tldp.org/LDP/abs/html/parameter-substitution.html (4 of 10) [7/15/2002 6:35:10 PM]
Parameter Substitution
#Function from "days-between.sh" example.
#Strips leading zero(s) from argument passed.
strip_leading_zero () # Better to strip possible leading zero(s)
{ |
# from day and/or month |
val=${1#0} |
# since otherwise Bash will interpret them |
return $val |
# as octal values (POSIX.2, sect 2.9.2.1). |
} |
|
Another usage illustration: |
|
|
|
echo `basename $PWD` |
# Basename of current working directory. |
echo "${PWD##*/}" |
# Basename of current working directory. |
echo |
|
echo `basename $0` |
# Name of script. |
echo $0 |
# Name of script. |
echo "${0##*/}" |
# Name of script. |
echo |
|
filename=test.data |
|
echo "${filename##*.}" |
# data |
|
# Extension of filename. |
|
|
${var%Pattern}, ${var%%Pattern}
Remove from $var the shortest/longest part of $Pattern that matches the back end of $var.
Version 2 of Bash adds additional options.
Example 9-14. Pattern matching in parameter substitution
#!/bin/bash
# Pattern matching using the # ## % %% parameter substitution operators.
var1=abcd12345abc6789
pattern1=a*c # * (wild card) matches everything between a - c.
echo |
|
|
|
echo "var1 = $var1" |
# abcd12345abc6789 |
|
|
echo "var1 = ${var1}" |
# abcd12345abc6789 |
(alternate form) |
|
echo "Number of characters in ${var1} = ${#var1}" |
|
|
|
echo "pattern1 = $pattern1" # a*c (everything between 'a' and 'c') |
|||
echo |
|
|
|
echo '${var1#$pattern1} |
=' "${var1#$pattern1}" |
# |
d12345abc6789 |
# Shortest possible match, strips out first 3 characters |
abcd12345abc6789 |
||
# |
^^^^^ |
|
|-| |
echo '${var1##$pattern1} =' "${var1##$pattern1}" |
# |
6789 |
|
# Longest possible match, strips out first 12 characters |
abcd12345abc6789 |
||
# |
^^^^^ |
|
|----------| |
http://tldp.org/LDP/abs/html/parameter-substitution.html (5 of 10) [7/15/2002 6:35:10 PM]
Parameter Substitution
echo; echo |
|
|
|
pattern2=b*9 |
# everything between 'b' and '9' |
|
|
echo "var1 = $var1" |
# Still abcd12345abc6789 |
|
|
echo "pattern2 = $pattern2" |
|
|
|
echo |
|
|
|
echo '${var1%pattern2} |
=' "${var1%$pattern2}" |
# |
abcd12345a |
# Shortest possible match, strips out last 6 characters |
abcd12345abc6789 |
||
# |
^^^^ |
|
|----| |
echo '${var1%%pattern2} =' "${var1%%$pattern2}" |
# |
a |
|
# Longest possible match, strips out last 12 characters |
abcd12345abc6789 |
||
# |
^^^^ |
|
|-------------| |
#Remember, # and ## work from the left end of string,
#% and %% work from the right end.
echo
exit 0
Example 9-15. Renaming file extensions:
#!/bin/bash |
|
# |
rfe |
# |
--- |
#Renaming file extensions.
#rfe old_extension new_extension
#Example:
#To rename all *.gif files in working directory to *.jpg,
#rfe gif jpg
ARGS=2
E_BADARGS=65
if [ $# -ne "$ARGS" ] then
echo "Usage: `basename $0` old_file_suffix new_file_suffix" exit $E_BADARGS
fi
for filename in *.$1
# Traverse list of files ending with 1st argument. do
mv $filename ${filename%$1}$2
# Strip off part of filename matching 1st argument, #+ then append 2nd argument.
done
http://tldp.org/LDP/abs/html/parameter-substitution.html (6 of 10) [7/15/2002 6:35:10 PM]
Parameter Substitution
exit 0
Variable expansion / Substring replacement
These constructs have been adopted from ksh. ${var:pos}
Variable var expanded, starting from offset pos. ${var:pos:len}
Expansion to a max of len characters of variable var, from offset pos. See Example A-14 for an example of the creative use of this operator.
${var/Pattern/Replacement}
First match of Pattern, within var replaced with Replacement.
If Replacement is omitted, then the first match of Pattern is replaced by nothing, that is, deleted. ${var//Pattern/Replacement}
Global replacement. All matches of Pattern, within var replaced with Replacement.
As above, if Replacement is omitted, then all occurrences of Pattern are replaced by nothing, that is, deleted.
Example 9-16. Using pattern matching to parse arbitrary strings
#!/bin/bash
var1=abcd-1234-defg echo "var1 = $var1"
t=${var1#*-*}
echo "var1 (with everything, up to and including first - stripped out) = $t"
#t=${var1#*-} works just the same, #+ since # matches the shortest string,
#+ and * matches everything preceding, including an empty string.
#(Thanks, S. C. for pointing this out.)
t=${var1##*-*}
echo "If var1 contains a \"-\", returns empty string... var1 = $t"
t=${var1%*-*}
echo "var1 (with everything from the last - on stripped out) = $t"
echo
#-------------------------------------------
path_name=/home/bozo/ideas/thoughts.for.today
#-------------------------------------------
echo "path_name = $path_name" t=${path_name##/*/}
echo "path_name, stripped of prefixes = $t"
http://tldp.org/LDP/abs/html/parameter-substitution.html (7 of 10) [7/15/2002 6:35:10 PM]
Parameter Substitution
# |
Same effect as |
t=`basename $path_name` in this particular case. |
# |
t=${path_name%/}; t=${t##*/} is a more general solution, |
#+ but still fails sometimes.
#If $path_name ends with a newline, then `basename $path_name` will not work, #+ but the above expression will.
#(Thanks, S.C.)
t=${path_name%/*.*}
# Same effect as t=`dirname $path_name` echo "path_name, stripped of suffixes = $t"
#These will fail in some cases, such as "../", "/foo////", # "foo/", "/".
#Removing suffixes, especially when the basename has no suffix,
#+ but the dirname does, also complicates matters.
# (Thanks, S.C.)
echo
t=${path_name:11}
echo "$path_name, with first 11 chars stripped off = $t" t=${path_name:11:5}
echo "$path_name, with first 11 chars stripped off, length 5 = $t"
echo
t=${path_name/bozo/clown}
echo "$path_name with \"bozo\" replaced by \"clown\" = $t" t=${path_name/today/}
echo "$path_name with \"today\" deleted = $t" t=${path_name//o/O}
echo "$path_name with all o's capitalized = $t" t=${path_name//o/}
echo "$path_name with all o's deleted = $t"
exit 0
${var/#Pattern/Replacement}
If prefix of var matches Pattern, then substitute Replacement for Pattern.
${var/%Pattern/Replacement}
If suffix of var matches Pattern, then substitute Replacement for Pattern.
Example 9-17. Matching patterns at prefix or suffix of string
http://tldp.org/LDP/abs/html/parameter-substitution.html (8 of 10) [7/15/2002 6:35:10 PM]
Parameter Substitution
#!/bin/bash
# Pattern replacement at prefix / suffix of string.
v0=abc1234zip1234abc |
# Original variable. |
|
|
echo "v0 = $v0" |
# abc1234zip1234abc |
|
|
echo |
|
|
|
# Match at prefix (beginning) of string. |
|
||
v1=${v0/#abc/ABCDEF} |
# abc1234zip1234abc |
|
|
|
# |-| |
|
|
echo "v1 = $v1" |
# ABCDE1234zip1234abc |
|
|
|
# |--- |
| |
|
# Match at suffix (end) of string. |
|
||
v2=${v0/%abc/ABCDEF} |
# abc1234zip123abc |
|
|
|
# |
|-| |
|
echo "v2 = $v2" |
# abc1234zip1234ABCDEF |
||
|
# |
|---- |
| |
echo |
|
|
|
# ---------------------------------------------------- |
|
|
|
# Must match at beginning / end of string, |
|
||
#+ otherwise no replacement results. |
|
||
# ---------------------------------------------------- |
|
|
|
v3=${v0/#123/000} |
# Matches, but not at beginning. |
||
echo "v3 = $v3" |
# abc1234zip1234abc |
|
|
|
# NO REPLACEMENT. |
|
|
v4=${v0/%123/000} |
# Matches, but not at end. |
||
echo "v4 = $v4" |
# abc1234zip1234abc |
|
|
|
# NO REPLACEMENT. |
|
exit 0
${!varprefix*}, ${!varprefix@}
Matches all previously declared variables beginning with varprefix.
xyz23=whatever
xyz24=
a=${!xyz*} |
# Expands to names of declared variables beginning with "xyz". |
|
echo |
"a = $a" |
# a = xyz23 xyz24 |
a=${!xyz@} |
# Same as above. |
|
echo |
"a = $a" |
# a = xyz23 xyz24 |
# Bash, version |
2.04, adds this feature. |
Notes
[1]If $parameter is null in a non-interactive script, it will terminate with a 127 exit status (the Bash error code code for "command not found").
http://tldp.org/LDP/abs/html/parameter-substitution.html (9 of 10) [7/15/2002 6:35:10 PM]
Parameter Substitution
Prev |
Home |
Next |
Manipulating Strings |
Up |
Typing variables: declare or typeset |
http://tldp.org/LDP/abs/html/parameter-substitution.html (10 of 10) [7/15/2002 6:35:10 PM]