ch7 variables continued

Variables are properly referenced as
${variable}, as this allows the shell to differentiate between ${var}iable (the variable $var
followed by the text “iable”) and ${variable} (the variable $variable). This can be useful when
applying suffixes to variables, such as “${kb}Kb is $bytes bytes, or approx ${mb}Mb

an undefined variable is interpreted as an empty string. If it were being treated as a number, it would be interpreted as zero


There are not many rules about variable names; they must start with a letter or underscore and can contain letters, numbers, and underscores. Periods, commas, spaces, and any other characters are not valid in variable names. Also, the first character of the variable name must be a letter or an underscore (not a digit).

Traditionally, system variables are all uppercase,with words separated by the
underscore character: BASH_EXECUTION_STRING

when a numeric value is expected, non-numeric values are treated as zero.

Bourne shell, which do not have the builtin $((...))
syntax for simple mathematical operations, is to use expr to do calculations:
$ x=1
$ y=2
$ expr $x + $y
$3

simple math is often done using expr for portability,but the $((...)) syntax and the let keyword are also used.

$ x=hello
$ y=2
$ echo $(($x + $y))
2


if you use expr to do the calculation for you, the shell does not have any builtin knowledge
that expr, as an external tool, expects numbers, not strings, so it does not do the substitution.
$ x=hello
$ y=2
$ expr $x + $y
expr: non-numeric argument

To count the number of characters in the variable, the ${#variable} structure is used
$ myvar=hello
$ echo ${#myvar}
5

The curly brackets {} are necessary for this feature; $#myvar expands to $# and the string myvar.
$# is the number of parameters the shell has been called with, and myvar is just text, so instead of
what you may have expected, 0myvar is displayed.

Special String operator
This feature uses the [[ ... ]] syntax specific to the bash shell — it does not exist in the external /usr/bin/test program, nor in the Bourne shell, but if you are sure of using bash or ksh, this syntax can be used.

$ cat sort.sh
#!/bin/bash
if [[ “$1” > “$2” ]]; then
echo “$2 $1”
else
echo “$1 $2”
fi
$ ./sort.sh def abc
abc def


The bash (though again, not Bourne) shell provides this [[ ... ]] feature as part of its variable manipulation syntax.


$ cat diff2.sh
#!/bin/bash
diff $1 $2 | while read diffline
do
if [ “${diffline:0:2}” == “< “ ]; then
echo “-: ${diffline:2}”
fi
if [ “${diffline:0:2}” == “> “ ]; then
echo “+: ${diffline:2}”
fi
done
$ ./diff2.sh file1 file2
-: def
+: DEF
------
Dash is a smaller, faster shell than bash, but with fewer features.
Used for symbolic link to /bin/sh in Ubuntu 6.10

${variable: -4} # foobar becomes obar


Think of #*- as “strip until the first -.
$ phone=”555-456-1414”
$ echo ${phone#*-}
456-1414


Think of ##*- as “strip until the last -.
$ echo ${phone##*-}
1414

To strip out the first two sections, leaving any others in place, use the non-greedy search with the
pattern *-*-.   555-456-1414
$ echo ${phone#*-*-}
1414

Think of %-* as meaning “strip from the final - onwards.”
$ echo $phone
555-456-1414
$ echo ${phone%-*}
555-456

strip out everything from the first -* pattern in the string.
$ echo $phone
555-456-1414
$ echo ${phone%%-*}
555

This matches 456-1414, leaving the area code behind.
$ echo ${phone%-*-*}
555
$


$ cat url.sh
#!/bin/bash
getdomain()
{
   url=$1
   url_without_proto=${url#*://}
   echo “$url becomes $url_without_proto”
   domain_and_port=${url_without_proto%%/*}
   echo “$url_without_proto becomes $domain_and_port”
   domain=${domain_and_port%:*}
   echo “$domain_and_port becomes $domain”
   getent hosts $domain | head -1
}
for url in $*
do
   getdomain $url
done
$

$ ./url.sh http://flickr.com/
http://flickr.com/ becomes flickr.com/
flickr.com/ becomes flickr.com
flickr.com becomes flickr.com
68.142.214.24 flickr.com

Searching strings
sed s/Wintel/Linux/g datacenter
$ user=`grep fred /etc/passwd`

$ echo $user
fred:x:1000:1000:Fred Flintstone:/home/fred:/bin/bash

$ echo ${user/fred/wilma}
wilma:x:1000:1000:Fred Flintstone:/home/fred:/bin/bash
$

To change all instances of fred to wilma, change the first / to a double //

$ echo ${user/fred/wilma}
wilma:x:1000:1000:Fred Flintstone:/home/fred:/bin/bash

$ echo ${user//fred/wilma}
wilma:x:1000:1000:Fred Flintstone:/home/wilma:/bin/bash
$

However, the shell does not do regular expressions, and the carat (^) is used in variable modification for changing the case of a variable. The syntax for this is to use # instead of ^.

Comments

Popular posts from this blog

HAproxy logging

teamcity Automatic Agent Start under Linux

NFS mount add in fstab _netdev instead of default | firewall-cmd --list-all