1. 算数表达式:
let Y=(X+2)*10
Y=$(( ( X + 2 ) * 10 ))
let 命令不允许参数带有任何的空格,因为那是作为一个独立的参数传入的。
而$((...))操作符却没有这些限制。里面可以包含任何的空格等。
let X+=5 Y*=3
echo $(( X+=5 , Y*=3 ))
上述let中,2个参数之间不需要增加任何','。
2. 测试2个文件的新旧
FILE1 -nt FILE2 (is newer than)
FILE1 -ot FILE2 (is older than)
FILE1 -ef FILE2 (is identical, same device and same inode)
3. -a and -o用于连接2个条件语句
if [ -r $FILE -a -w $FILE ]
AND => -a; OR => -o
if [ -r "$FN" -a \( -f "$FN" -o -p "$FN" \) ]
括号用于改变条件测试的优先级
需要注意的是,
SHELL中逻辑条件并不会应用短路原则,所以下面的V2在空的情况下总是会被赋值的,如果V1为空的情况下。
if [ -z "$V1" -o -z "${V2:=YIKES}" ]
4. 比较操作符for 数值和字符串:
Numeric | String | Meaning |
-lt | < | Less than |
-le | <= | Less than or equal to |
-gt | > | Greater than |
-ge | >= | Greater than or equal to |
-eq | =, == | Equal to |
-ne | != | Not equal to |
这个convention来源于Fortran语言。
然而在PERL中,两者恰好相反。eq用于字符串比较,==用于数值比较。注意=而不是==比较符合POSIX标准。
5. pattern matching in if statement
if [[ "${MYFILENAME}" == *.jpg ]]
在[[..]] 操作符中,如果用==就会比在[ ]要强大的多,可以用来进行模式匹配操作。
shopt -s extglob
if [[ "$FN" == *.@(jpg|jpeg) ]]
then
# and so on
if [[ "$FN" == *.@(jpg|jpeg) ]]
then
# and so on
The shopt -s command is the way to turn on shell options. The ext globis the option
dealing with extended pattern matching (orglobbing). With this extended pattern
matching we can have several patterns, separated by the|character and grouped by
parentheses.
dealing with extended pattern matching (orglobbing). With this extended pattern
matching we can have several patterns, separated by the|character and grouped by
parentheses.
Grouping | Meaning |
@( ... ) | Only one occurrence |
*( ... ) | Zero or more occurrences |
+( ... ) | One or more occurrences |
?( ... ) | Zero or one occurrences |
!( ... ) | Not these occurrences, but anything else |
6. 支持读取用户输入和重定向文件用户输入的方法:
while read line
do
echo "$line"
done
7. Looping with Floating-Point Values
for fp in $(seq 1.0 .01 1.1)
do
echo $fp; other stuff too
done
do
echo $fp; other stuff too
done
seq 1.0 .01 1.1 | \
while read fp
do
while read fp
do
echo $fp; other stuff too
done
done
seq命令将会产生一个序列,后跟3个参数,第一个参数为起始数据,中间的为step,最后的终止数据。区别于C语言。
如果是seq命令将会产生一行一个数据的输出,然而用在SHELL的$()或者``操作符中,返回的结果将会是一个空格分隔的每项。
第二种可能会更有效率写:
In the first example, the$( )runs the command in a subshell and returns the result with
the newlines replaced by just whitespace, so each value is a string value for theforloop.
the newlines replaced by just whitespace, so each value is a string value for theforloop.
In the second example, seqis run as a command with its output piped into a while
loop that reads each line and does something with it. This would be the preferred
approach for a really long sequence, as it can run theseqcommand in parallel with
thewhile. Theforloop version has to runseqto completion and put all of its output
on the command line for theforstatement. For very large sequences, this could be
time- and memory-consuming.
8. 一个比较简单但是健壮的SHELL计算器
function calc
{
awk "BEGIN {print \"The answer is: \" $* }";
}
{
awk "BEGIN {print \"The answer is: \" $* }";
}
要知道它可以处理浮点数。
./calc.sh '(2+2-3)*4'
请注意,()和*对SHELL来说都是特别。如果不用括号括起来,就需要考虑将它们用\转义。