shell脚本学习记录—参考Linux程序设计第四版
/******************************************************************************
#!/bin/sh
exit 0
/*****************************************************************************
注意: (1)如果字符串里面包含空格,必须用引号把字符串括起来
(2)等号两边不能有空格
1.使用引号:
(1)双引号中的变量会发生替换
(2)单引号中的变量不会发生替换
(3)$特殊字符前加上\字符会取消它的特殊含义
2.环境变量
$HOME 当前用户家目录
$PATH 以冒号分隔的用来搜索命令的目录列表
$IFS 输入域分隔符,当shell读取输入时,它给出的用来分隔单词的一组字符,空格,制表符,换行
$0 shell脚本的名字
$# 传递给脚本的参数个数
$$ shell脚本的进程号
3.参数变量
$1,$2,… 脚本程序的参数
$* 在一个变量中列出所有参数,通过环境变量IFS中的第一个字符分隔
$@ $*的变体,列出所有参数,以空格分隔
4.条件
test
[ ] 中括号里面的命令和参数必须以空格隔开,包括[ 和 ],因为其类似于具体的指令
字符串比较:
string1 = string2 != -n string 不为空 -z string 为空
算数比较:
exp1 -eq exp2 =
-ne !=
-gt >
-ge >=
-lt <
-le <=
文件测试:
-d file 文件为一个目录?
-e file 文件存在?
-f file 文件为普通文件?
-s file 文件大小不为0?
-w file 文件可写?
-x file 文件可执行?
/**************************************************************************
if test -f fred.c
then
…
fi
if [ -f fred.c ]
then
…
fi
/***************************************************************************
5.控制结构
注意:
(1)在if [ $timeofday = “yes” ] 条件判断中,如果用户未输入任何字符,直接ENTER,会导致错误,
因此需要加上引号;因为([ = “yes”])非法;[ : =: unary operator expected
(2)echo命令默认会有换行符;因此想去除换行符的话,可使用printf命令;bash中可使用echo -n 命令;
/**************************************************************************
#!/bin/sh
echo “is it morning? please answer yes or no”
read timeofday
if [ “
t
i
m
e
o
f
d
a
y
"
=
"
y
e
s
"
]
t
h
e
n
e
c
h
o
"
g
o
o
d
m
o
r
n
i
n
g
"
e
l
i
f
[
"
timeofday" = "yes" ] then echo "good morning" elif [ "
timeofday"="yes"]thenecho"goodmorning"elif["timeofday” = “no” ]
then
echo “good afternoon”
else
echo “$timeofday not recognized, enter yes or no”
exit 1
fi
exit 0
/***************************************************************************
/***************************************************************************
#! /bin/sh
for file in $(ls f*.sh)
do
lpr $file
done
exit 0
/***************************************************************************
/***************************************************************************
#! /bin/sh
echo “enter password”
read trythis
while [ “$trythis” != “secret” ]
do
echo “try again”
read trythis
done
exit 0
/***************************************************************************
/***************************************************************************
#! /bin/sh
until who | grep “$1” > /dev/null
do
sleep 60
done
echo “$1 has just logged in”
exit 0
/***************************************************************************
注意:case语句statment语句执行完后要加上 (;;)代表结束
case 匹配功能:
[yY] | [Yy] [Ee] [Ss])------------限制允许出现的字母,允许多种多样的答案
/***************************************************************************
#! /bin/sh
echo “is it morning, please answer yes or no”
read timeofday
case “$timeofday” in
yes | Y | Yes | YES )
echo “good morning”
eho “…”;;
[nN]*)
…
…;;
*)
echo “”
echo “”
exit 1;;
esac
/***************************************************************************
命令列表
AND OR
/***************************************************************************
#! /bin/sh
touch file_one
rm -f file_two
if [ -f file_one ] && echo “hello” && [ -f file_two ] && echo “there”
then
echo “in if”
else
echo “in else”
fi
exit 0
/***************************************************************************
6.函数
/***************************************************************************
#! /bin/sh
yes_or_no() {
echo “is your name
@
"
w
h
i
l
e
t
r
u
e
d
o
e
c
h
o
−
n
"
e
n
t
e
r
y
e
s
o
r
n
o
"
r
e
a
d
x
c
a
s
e
"
@" while true do echo -n "enter yes or no" read x case "
@"whiletruedoecho−n"enteryesorno"readxcase"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”
else
echo “never mind”
fi
exit 0
/***************************************************************************
7.命令
break命令:内置命令,可为break命令提供一个额外的参数表明要跳出的循环层数,默认只跳出一层循环,以;结尾
(:):空命令,用于简化条件逻辑
continue:内置命令,是循环跳到下一次循环继续执行,默认;同break;可添加额外参数;表示希望继续执行的循环
嵌套层数
(.)命令:允许执行的程序修改当前环境变量;默认情况下,单一个脚本执行一条外部命令或脚本程序,会创建一个新的子shell执行,而父shell中设置
和建立的变量均会丢失,因此(.)命令指示在当前shell环境中继续执行;
echo命令:换行符echo -n 适用于Linux以及bash环境
eval命令:对参数进行求值
exec命令:
exec wall “…”:表示用wall命令替换当前的shell,后续脚本不执行,因为执行脚本的shell已经不存在了
exec 3< afile:表示文件描述符3被打开以便从文件afile中读取数据
exit n 命令:0表示成功,1-125是脚本可以使用的错误代码,其余数字具有保留含义;
export命令:将参数导出到本shell引用的子shell中去
export bar=“export value ,show in child shell”
expr命令:简单数学运算 x=expr $x + 1
or x=$(expr $x + 1)
printf命令:printf “%s %d %s” “hello here” 15 pople
另外的两个有用的命令:
(1)find命令:
find [path] [options] [tests] [actions]
[path]:文件路径,可以指定多个路径 /var /home
[options]:选项
-depth 在查看目录本身之前先搜索目录的内容
-follow 跟随符号连接
-maxdepths N 最多搜索N层目录
-mount 不搜索其他文件系统中的目录
find命令:find / -name test -print 在根目录下查找名为test的文件,并且输出完整路径
find / -mount -name test -print 不必搜索挂载的其他文件系统目录
(2)grep命令:
grep [options] pattern [files]
[options]:
-c 输出匹配行的数目,而不是输出匹配的行
-E 启用扩展表达式
-h 取消每个输出行的普通前缀,匹配查询模式的文件名
-i 忽略大小写
-l 只列出包含匹配行的文件名,而不输出真正的匹配行
-v 对匹配模式取反,即搜索不匹配的行
grep in words.txt
行内容,文字描述…
grep -c in words.txt words2.txt
words.txt:2
words2.txt:14
grep -c -v in words.txt words2.txt
words.txt:9
words2.txt:16
(3)正则表达式
^ 指向一行的开头
$ 指向一行的结尾
. 任意单个字符
[] 方括号内包含一个字符范围
{} 匹配次数
grep e$ words.txt:查找以字母e结尾的行
grep a[[:blank:]] words.txt:查找以字母a结尾的单词
grep th.[[:space:]] words.txt:查找以字母th开头,任意字符结尾的单词
grep -E [a-z]{10} words.txt:用扩展模式搜索十个字符长度的单词