函数
当一个函数被调用时,脚本程序的位置参数( ∗ 、 *、 ∗、@、$#、$1、$2 等)会被替换为函数的参数。
以下演示了函数的参数是如何传递的,以及函数如何返回一个 true 或 false 值。
需使用一个参数调用该脚本程序,该参数是要使用的名字。
执行到 if 语句时,$1 会被替换为脚本程序的第一个参数,在把它作为参数传递给函数 yes_or_no。
#!/bin/sh
yes_or_no()
{
echo "Is your name $* ?"
while true
do
echo -n "Enter yes or no: "
read x
case "$x" in
y | yes) return 0;;
n | no) return 1;;
*) echo "Answer yes or no"
esac
done
}
echo "Original parameters are $*"
if yes_or_no "$1"
then
echo "Hi $1, nice name"
else
echo "Never mind"
fi
exit 0
结果:
yjp@yjp-VirtualBox:~/shell$ /bin/sh test Tom
Original parameters are Tom
Is your name Tom ?
Enter yes or no: y
Hi Tom, nice name
命令
: 命令
冒号是一个空命令,相当于 true 的一个别名。
#!/bin/sh
rm -rf fred
if [ -f fred ]; then
:
else
echo file fred did not exist
fi
exit 0
结果:
file fred did not exist
eval 命令
eval 命令允许对参数求值。它是 shell 的内置命令,通常不会以单独命令的形式存在。
#!/bin/sh
foo=10
x=foo
y='$'$x
echo $y
foo=10
x=foo
eval y='$'$x
echo y
结果:
$foo
y
expr 命令
expr 命令将它的参数当作一个表达式来求值。
#!/bin/sh
x=1
x=$(expr $x + 1)
echo $x
结果:
2
find 命令
用于搜索文件的命令。
语法:
find [path] [options] [tests] [actions]
从根目录开始查找名为 test 的文件,并输出该文件的完整路径:
# find / -name test -print
结果:
/home/yjp/engine/test
/home/yjp/engine/test/test
... ...
指定 -mount 选项,不搜索挂载的其它文件系统的目录:
# find / -mount -name test -print
在当前目录下搜索比文件 while2 要新的文件:
# find . -newer while2 -print
在当前目录下搜索比文件 while2 要新的文件,不包含目录:
# find . -newer while2 -type f -print
在当前目录(.)中搜索以下划线开头(-name “_*”)或(or)比 while2 新的文件(-newer while2),
然后测试该文件是否是一个普通文件(-type f)。最后,用 -print 确认搜索到的文件。
# find . \( -name "_*" -or -newer while2 \) -type f -print
-exec command,执行一条命令,该动作以 ; 字符对结束。
魔术字符串 {} 是 -exec 或 -ok 命令的一个特殊类型的参数,它将被当前文件的完整路径取代。
# find . -newer try_var -type f -exec ls -l {} \;
结果:
-rw-rw-r-- 1 yjp yjp 40 2月 18 16:22 ./test
grep 命令
在文件中搜索字符串。
一种常见用法是在使用 find 命令时,将 grep 作为传递给 -exec 的一条命令。
如果没有提供文件名,则 grep 命令将搜索标准输入。
grep [options] PATTERN [FILES]
在文件 test 中搜索字符串“bi”
# grep bi test
结果:
#!/bin/sh
在文件 test、try_var 中搜索字符串“bi”,并输出匹配行的数目(-c):
# grep -c bi test try_var
结果:
test:1
try_var:1
-v:不匹配的行数
# grep -c -v bi test try_var
结果:
test:4
try_var:14
在文件 test 中搜索以 h 结尾的行:
# grep h$ test
结果:
#!/bin/sh
在文件 try_var 中寻找以 e 结尾的单词,[[:blank:]] 测试空格或制表符:
# grep e[[:blank:]] try_var
结果:
echo "The second parameter was $2"
echo "The first parameter was $1"
echo "The parameter list was $*"
echo "The user's home directory is $HOME"
echo "Please enter a new greetion"
echo "The script is now complete"
在文件 try_var 中查找以 ech 开头且长度为 4 的单词,. 匹配一个字符,[[:space:]] 划定单词结尾:
# grep ech.[[:space:]] try_var
结果:
echo $salutation
echo "The second parameter was $2"
echo "The first parameter was $1"
echo "The parameter list was $*"
echo "The user's home directory is $HOME"
echo "Please enter a new greetion"
echo $salutation
echo "The script is now complete"
搜索只有 10 个字符长的全部由小写字母组成的单词:
# grep -E [a-z]\{10\} try_var
结果:
salutation="Hello"
echo $salutation
read salutation
echo $salutation
命令的执行
算术扩展
把准备求值的表达式放在 $((…)) 中更能有效地完成简单的算术运算。
#!/bin/sh
x=0
while [ "$x" -ne 10 ]; do
echo $x
x=$(($x+1))
done
exit 0
结果:
0
1
2
3
4
5
6
7
8
9
参数扩展
将变量放在 {} 中。
处理名为 1_tmp 和 2_tmp 两个文件:
#!/bin/sh
for i in 1 2
do
echo ${i}_tmp
done
结果:
1_tmp
2_tmp
#!/bin/sh
unset foo
echo ${foo:-bar}
foo=fud
echo ${foo:-bar}
foo=/usr/bin/X11/startx
echo ${foo#*/} # 从头部开始删除与 / 匹配最短的部分 usr/bin/X11/startx
echo ${foo##*/} # 从头部开始删除与 / 匹配最长的部分 startx
bar=/usr/local/etc/local/networks
echo ${bar%local*} # 从尾部开始删除与 local 匹配最短的部分 /usr/local/etc/
echo ${bar%%local*} # 从尾部开始删除与 local 匹配最长的部分 /usr/
exit 0
结果:
bar
fud
usr/bin/X11/startx
startx
/usr/local/etc/
/usr/
源码:《Linux 程序设计》