来自:linux程序设计中文第四版
变量
变量引用
shell中,变量不需要提前声明,默认所有变量均被看做为字符串来存储
引用变量名只需要在变量名添加 $符号
variable=hello
echo $variable
hello
variable=”hello world ”
注意:
- 如果字符串里面包含空格,必须用引号括起来,另外等号两边不能有空格!
- 双引号与单引号的差别,双引号会发生变量替换,单引号则不会替换
- 被双引号包括起来的变量,变量替换不会被阻止的,所以被称为弱引用
- 被单引号包括起来的变量,变量替换就会完全禁止,因此被称为全(强)引用
”$variable” 会被替换为变量表达式
‘$variable’ 不会替换为变量表达式
参数变量
- $$ shell 本身的PID
- $! shell 最后运行的后台Process 的PID
- $? 最后运行命令的结束代码(返回值)
- $- 使用set命令设定的Flag一览
- $* 所有参数列表
- $@ $*的一种变体
- $# 添加到shell的参数个数
- $0 shell 本身的文件名
- $1-$n 添加到shell的各种参数值,$1是第一个参数。。。。。。。
read命令: 用来读取一个变量
read variable
Hello
echo $variable
Hello
变量运算符
条件&测试
test 、[]命令
eg:
if test -f hello.c (; then)
then
…
fi
或者
if [ -f hello.c ]
then
…
fi
test 命令比较主要分三种类型,字符串比较,数值比较,文件相关比较
- 字符串比较
- string1 = string2 如果两个字符串相同为真
- string1 != string2 ….不同…..
- -n string 如果字符串不为空则结果为真
- -z string 如果字符串为null 则结果为真
- 算术比较
- expression1 –eq expression2 如果两个表达式相等则结果为真
- expression1 –ne expression2 不等
- expression1 –gt expression2 如果expression1 大于 expression2 为真
- expression1 –ge expression2 大于等于
- expression1 -lt expression2 小于
- expression1 -le expression2 小于等于
- ! expression 如果表达式为假则结果为真
- 文件测试
- -d file 文件是一个目录为真
- -e file 文件存在则为真,历史上,-e选项不可移植,通常使用的是-f选项
- -f file 文件是一个普通文件则为真
- -g file 文件得set-group-id位被设置则结果为真
- -r file 文件可读则结果为真
- -s file 文件大小不为0 为真
- -u file 文件的set-user-id 位被设置则结果为真
- -w file 文件可写则为真
- -x file 文件可执行则结果为真
控制结构
if语句
if condition
then
statements
elif condition1
statements
else
statements
fi
for 语句
for variable in values
do
statements
done
有用的变量 $(commands) for 命令的参数表来自括在$()中的命令的输出结果
eg:
#!/bin/bash
for file in $(ls f*.sh); do
lpr $file
done
exit 0
while语句
while condition do
statements
done
eg:
echo “please input passwd ”
read trythis
while [ “trythis !” = “passwd” ] ; do
echo “sorry ,try again !!”
read trythis
done
exit 0
until 语句
与while相似,只是把条件测试反过来了,循环将反复执行直到条件为真,而不是在条件为真时反复执行。
until condition
do
statements
done
eg:
#!/bin/bash
until who | grep “$1” >/dev/null
do
sleep 60
done
#now ring the bell and announce the expected user.
echo –e ‘\a’
echo “****$1 has just logged in ****”
exit 0
case 语句
case variable in
pattern [ | pattern ] …) statemetns ;;
pattern [ | pattern ] …) statemetns ;;
esac
****************************************************
#!/bin/sh
echo “Is it morning ? Please answer yes or no “
read timeofday
case “$tineofday” in
yes) echo “Good Morning”;;
no) echo “Good Afternoon”;;
y ) echo “Good Morning “;;
n ) echo “Good Afternoon” ;;
* ) echo “Sorry ,answer not recognized ” ;;
esac
****************************************************
#!/bin/sh
echo “Is it morning ? Please answer yes or no “
read timeofday
case “$tineofday” in
yes|y|YES|Y) echo “Good Morning”;;
no|n|NO|N) echo “Good Afternoon”;;
* ) echo “Sorry ,answer not recognized ” ;;
esac
exit 0
****************************************************
#!/bin/sh
echo “Is it morning ? Please answer yes or no “
read timeofday
case “$tineofday” in
yes|y|YES|Y) echo “Good Morning”
echo “up bright and early this morning”
;;
no|n|NO|N) echo “Good Afternoon”
; ;
* ) echo “Sorry ,answer not recognized ”
echo “Please answer yes or no ”
exit 1 ; ;
esac
命令列表
- AND 列表
从左边开始顺序执行每条命令,如果一条命令返回的是true,右边的下一条命令才能够执行。
statement1 && statement2 && statements3 && …
eg:
#!/bin/bash
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
- OR 列表
statement1 || statement2 || statement3 || …
从左边开始顺序执行,如果一调命令返回的是false,它右边的下一条命令才能够被执行,如此持续直到有一条命令返回true,或者所有的命令执行完毕。
eg:
#!/bin/bash
rm –f file_one
if [ -f file_one ] || echo “hello” ||echo “there”
then
echo “in if”
else
echo “in else”
fi
exit 0
语句块
如果想在某些只允许使用单个语句的地方使用多条语句,可以使用花括号来构造一个语句块。
eg:
get-confirm && {
grep –v “$cdcattnum” $tracks_file > $temp_file }
函数
function_name () {
statements
}
所有的函数定义需要放在函数调用之前
eg:
#!/bin/bash
foo() {
echo “fuction foo is executing”
}
echo “script starting “
foo
echo “scripts ended”
exit 0
当一个函数被调用时,脚本程序的位置参数$*,$@,$#等会替换为函数的参数,可以用此方法来读取传递给函数的参数。
可以用local 关键字在shell函数中声明局部变量,此变量只在函数的作用范围内有效,如果一个局部变量和一个全局变量的名字相同,前者会覆盖后者。
eg:
#!/bin/bash
sample_text=”gloabel_variable”
foo() {
local sample_text=”local variable “
echo “Funcition foo is executing “
echo $sample_text
}
echo “script starting “
echo $sample_text
foo
echo “script ended”
echo $sample_text
# !/bin/bash
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
命令
break命令
用来跳出for,while或者until循环,可以为break提供一个数值参数来表示需要跳出的循环层数,但是会大大降低程序的可读性。
#!/bin/sh
rm –rf fred*
echo > fred1
echo >fred2
mkdir fred3
echo >fred4
for file in fred*
do
if [ -d “$file” ]; then
break;
fi
done
echo first directory starting fred was $file
rm –rf fred*
exit 0
: 命令
冒号: 是一个空命令,偶尔被用于简化条件逻辑,相当于true的一个别名
#!/bin/bash
rm –f fred
if [-f fred ] ;then
:
else
echo file fred did not exist
fi
exit 0
continue 命令
类似C语言的continue,进入下一次循环继续进行
#!/bin/bash
rm –rf fred*
echo > fred1
echo >fred2
mkdir fred3
echo > fred4
for file in fred*
do
if [ -d “$file” ] ; then
echo “skipping directory $file”
continue
fi
continue 可以带一个可选的参数用来表示希望继续执行的循环嵌套层数,也就是说你可以部分的跳出嵌套循环
eg :
for x in 1 2 3
do
echo before $x
continue 1
echo after $x
done
.命令与source命令
点命令用于在当前shell中执行命令;
. ./sehll_scrips
与source ,命令相似,用于在当前shell 环境中执行脚本
source命令能够使子shell中的操作改变父shell中的环境变量,如果直接运行则不能改变父shell中的环境变量
载入环境变量
echo 命令
echo –n “string to output ”
echo –e ‘\a’
eval命令 很有用????
允许对参数进行求值,
foo =10
x=foo
y=’$’$X
echo $y
输出为$foo
foo=10
x=foo
eval y=’$’$x
echo $y
输出为10
so,eval命令像一个额外的$,给出一个变量的值的值
exec命令
exec有两种不同的用法,典型用法是将当前shell替换为一个不同的程序
- exec wall “Thanks for all the fiwsh”
脚本程序中会用wall替换当前的shell程序,exec命令后的代码都不会执行,因为执行这个脚本的shell已经不存在了
exec的各种方法是修改当前文件描述符
exec 3 <afile 这种用法很少见。
exit n命令
exit命令使用脚本程序以退出码结束运行
#!/bin/bash
[ -f .profile ] && exit 0 || exit 1
export 命令
此命令将作为它参数的变量导出到子shell中,并使之在子shell中有效。默认情况下, 在一个shell中被创建的变量在这个shell调用的下级shell中是不可用的,export 命令把自己的参数创建为一个环境变量,而这个环境变量可以被当前调用的其他脚本和程序看见。
expr命令
expr命令将它的参数当做一个表达式来求值,它的最常见的用法就是进行如下形式的简单数学运算:
x=‘expr $x =1’
printf命令
和 c语言中的使用方法相似,但是不支持浮点数,因为shell中所有的算术运算都是按照整数来进行计算的。
return命令
这个命令的作用是是函数返回,可以有一个数值参数作为函数的返回值。
set命令
set命令的作用是为shell设置参数变量
eg:
得到月份
#!/bin/bash
echo the date is $(date)
set $(date)
echo The month si $2
exit 0
shift 命令
此命令将所有的参数变量左移一个位置,使$2变成$1,以此类推,原来$1的值将被丢弃,而$0的值将保持不变,如果shift命令时指定了一个数值参数,则表示所有的参数将左移一定的次数。
eg:
#!/bin/bash
while [ “$1” !=” “ ];do
echo “$1”
shift
done
exit 0
trap命令
trap命令用于指定在接收到信号后将要采取的行动。
trap command signal
HUP(1) 挂起,通常因终端或用户退出而引发
INT(2) 中断。。。。。。。。。
more man 7 signal
eg:
#!/bin/bash
trap ‘rm –f /tmp/tmp_file_$$
date > /tmp/tmp_file_$$
echo “please interupt (CTRL-C) to interrupt
while
……………..懒得敲了 linux程序设计中文第四版,page51
unset 命令
其作用是从环境中删除变量或函数,不能删除shell本身定义的只读变量(如IFS)
#!/bin/bash
foo =”Hello World”
echo $foo
unset foo
echo $foo
find和grep命令
find / -name test –print
从根目录开始查找test的文件,输出文件的完整路径
find / - mount –name test –print
这次不会搜索挂载的其他文件系统
还有好多,这里就不赘述了
grep命令使用正则表达式
-I 忽略大小写
-c 输出匹配行的数目,不输出匹配行
-l 只列出包含匹配行的文件名,不输出真正的匹配行
-v 对匹配模式取反,搜索不匹配行
等等
export命令
用于导出环境变量
/etc/profile
/etc/bashrc
$HOME/.bash_profile
$HOME/.bashrc
$HOME/.bash_logout