如果有一系列你经常使用的Linux命令,你可以把它们存储在一个文件里,shell可以读取这个文件并顺序执行其中的命令,这样的文件被称为脚本文件。shell 脚本按行解释。
#!/bin/bash
#!/bin/sh
#!/bin/csh
#!/bin/bash
# This is the first Bash shell program
# ScriptName: greetings.sh
echo
echo –e "Hello $LOGNAME, \c"
echo "it's nice talking to you."
echo "Your present working directory is:"
pwd # Show the name of present directory
echo
echo –e "The time is `date +%T`!. \nBye"
echo
如上一个简单的shell脚本,使用
bash greeting.sh
或者
chmod +x greetings.sh
./greetings
运行这个脚本
可以看到例1中有很多echo命令,下面本文从echo开始,介绍shell脚本编写常用命令。
echo:
例2
#!/bin/bash
# This script is to test the usage of read
# Scriptname: ex4read.sh
echo "=== examples for testing read ==="
echo -e "What is your name? \c"
read name
echo "Hello $name"
echo
echo -n "Where do you work? "
read
echo "I guess $REPLY keeps you busy!"
echo
read -p "Enter your job title: "#自动读给REPLY
echo "I thought you might be an $REPLY."
echo
echo "=== End of the script ==="
read x y #可同时读取多个变量
read #自动读给REPLY
read –p “Please input: ”
#自动读给REPLY
条件测试可以根据某个特定条件是否满足,来选择执行相应的任务。
Bash 中允许测试两种类型的条件:
命令成功或失败,表达式为真或假
任何一种测试中,都要有退出状态(返回值),退出状态为 0 表示命令成功或表达式为真,非0 则表示命令失败或表达式为假。
状态变量 $? 中保存命令退出状态的值,如例3所示:
例3
grep $USER /etc/passwd
echo $?
grep hello /etc/passwd; echo $?
表达式测试包括字符串测试、整数测试和文件测试。
通常用 test 命令来测试表达式的值,如例4所示:
例4
x=5; y=10
test $x -gt $y
echo $?
test 命令可以用 方括号 来代替,如例5:
例5:
x=5; y=10
[ $x -gt $y ]
echo $?
注意:方括号前后要留空格!
例如:
name=Tom; [ -z $name ]; echo $?
name2=Andy; [ $name = $name2 ] ; echo $?
方法一:[ "$name" = "" ]
方法二:[ ! "$name" ]
方法三:[ "X${name}" != "X" ]
例6:
if expr1 # 如果expr1 为真(返回值为0)
then # 那么
commands1 # 执行语句块 commands1
elif expr2 # 若expr1 不真,而expr2 为真
then # 那么
commands2 # 执行语句块 commands2
... ... # 可以有多个 elif 语句
else # else 最多只能有一个
commands4 # 执行语句块 commands4
fi # if 语句必须以单词 fi 终止
几点说明:
1. elif 可以有任意多个(0 个或多个)
2. else 最多只能有一个(0 个或 1 个)
3. if 语句必须以 fi 表示结束
4. expr 通常为条件测试表达式;也可以是多个命令,以最后一个命令的退出状态为条件值。
5. commands 为可执行语句块,如果为空,需使用 shell 提供的空命令 “ : ”,即冒号。该命令不做任何事情,只返回一个退出状态 0
6. if 语句可以嵌套使用
例7:使用if语句比较标准输入中两个数的大小
#!/bin/bash
# scriptname: ex4if.sh
#
echo -n "Please input x,y: "
read x y
echo "x=$x, y=$y"
if (( x > y )); then
echo "x is larger than y"
elif (( x == y)); then
echo "x is equal to y"
else
echo "x is less than y"
fi
例8:if语句判断文件及其权限
#!/bin/bash
# Using the new style test command: [[ ]]
# filename: perm_check2.sh
#
file=./testing
if [[ -d $file ]]
then
echo "$file is a directory"
elif [[ -f $file ]]
then
if [[ -r $file && -w $file && -x $file ]]
then # nested if command
echo "You have read,write,and execute permission on $file."
fi
else
echo "$file is neither a file nor a directory. "
fi
例9:判断某个文件中是否存存在某个字符串
#!/bin/bash
# Using the new style test command: [[ ]]
# filename: perm_check2.sh
#
file=./testing
if [[ -d $file ]]
then
echo "$file is a directory"
elif [[ -f $file ]]
then
if [[ -r $file && -w $file && -x $file ]]
then # nested if command
echo "You have read,write,and execute permission on $file."
fi
else
echo "$file is neither a file nor a directory. "
fi
语法结构
case expr in # expr 为表达式,关键词 in 不要忘!
pattern1) # 若 expr 与 pattern1 匹配,注意括号
commands1 # 执行语句块 commands1
;; # 跳出 case 结构
pattern2) # 若 expr 与 pattern2 匹配
commands2 # 执行语句块 commands2
;; # 跳出 case 结构
... ... # 可以有任意多个模式匹配
*) # 若 expr 与上面的模式都不匹配
commands # 执行语句块 commands
;; # 跳出 case 结构
esac # case 语句必须以 esac 终止
几点说明
1. 表达式 expr 按顺序匹配每个模式,一旦有一个模式匹配成功,则执行该模式后面的所有命令,然后退出 case。
2. 如果 expr 没有找到匹配的模式,则执行缺省值 “ ) ” 后面的命令块 ( 类似于 if 中的 else ); “ ) ” 可以不出现。
3.所给的匹配模式 pattern 中可以含有通配符和“ | ”
4. 每个命令块的最后必须有一个双分号,可以独占一行,或放在最后一个命令的后面。
例9:case语句举例
#!/bin/bash
# test case
# scriptname: yes_no.sh
#
echo -n "Do you wish to proceed [y/n]: "
read ans
case $ans in
y|Y|yes|Yes)
echo "yes is selected"
;;
n|N|no|No)
echo "no is selected"
;;
*)
echo "`basename $0`: Unknown response"
exit 1
;;
esac
语法结构:
for variable in list
# 每一次循环,依次把列表 list 中的一个值赋给循环变量
do # 循环开始的标志
commands # 循环变量每取一次值,循环体就执行一遍
done # 循环结束的标志
几点说明
列表 list 可以是命令替换、变量名替换、字符串和文件名列表 ( 可包含通配符 )
for 循环执行的次数取决于列表 list 中单词的个数
for 循环体中一般要出现循环变量,但也可以不出现
循环执行过程:
执行第一轮循环时,将 list 中的第一个词赋给循环变量,并把该词从 list 中删除,然后进入循环体,执行 do 和 done 之间的命令。下一次进入循环体时,则将第二个词赋给循环变量,并把该词从 list 中删除,再往后的循环也以此类推。当 list 中的词全部被移走后,循环就结束了。