Shell编程入门总结(语法篇)
前言:
最近看鸟哥的linux学习了一下shell编程,一时上手感觉还是比较生疏,所以特地把一些基本常用的知识做了一个总结,总结中并没有涵盖鸟哥书中所有的内容,当然更高级的shell编程也没有涉及,如果对这些内容有兴趣的话可以自行去看看鸟哥的书或者一些相关shell编程的书,在这里博主还是以基础为主。
一、简单的Shell Script
1.1 首先当然是最简单的Hello World
程序如下:
#!/bin/bash
# Program:
# This program shows "Hello World!" in your screen.
# History:
# 2005/08/23 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "Hello World! \a \n"
exit 0
A.第一行#!/bin/bash声明这个script使用的shell名称
B.程序内容的说明,整个script当中,除了第一行的”#!”外都是”批注”
C.主要环境变量声明,建议务必将一些重要的环境变量设置好,如此一来则可以让我们这个程序在进行时可以直接执行一些外部命令,而不必写绝对路径。
D.主要程序部分。
E. 告知执行结果,即最后的exit 0,0就是最后返回的执行结果。
PS:为了之后程序看起来比较简洁后面的程序一律省略A、B、C项
1.2 利用日期进行文件的创建
# 1. 让使用者输入文件名称,并取得 fileuser 这个变量;
echo -e "I will use 'touch' command to create 3 files." # 纯粹显示资讯
read -p "Please input your filename: " fileuser # 提示使用者输入
# 2. 为了避免使用者随意按 Enter ,利用变量功能分析档名是否有配置?
filename=${fileuser:-"filename"} # 开始判断有否配置档名
# 3. 开始利用 date 命令来取得所需要的档名了;
date1=$(date --date='2 days ago' +%Y%m%d) # 前两天的日期
date2=$(date --date='1 days ago' +%Y%m%d) # 前一天的日期
date3=$(date +%Y%m%d) # 今天的日期
file1=${filename}${date1} # 底下三行在配置档名
file2=${filename}${date2}
file3=${filename}${date3}
# 4. 将档名创建吧!
touch "$file1" # 底下三行在创建文件
touch "$file2"
touch "$file3"
exit 0
1.3 补充一个用法
$((运算内容))可以进行数值运算,效果和declare –I var=运算内容是一样的。
1.4 script的执行方法区别(source,sh script,./script)
其中source是在父进程bash中运行,而sh script或者是用”chmod a+x script”命令处理后的./script都是在子进程的bash中运行的。顺带一提,sh并不是在所有版本的linux中都表示bash,目前Ubuntu14.10中的sh指代的是dash这个shell。
二、判断式
2.1 test命令
测试的标志 | 代表意义 |
1. 关於某个档名的『文件类型』判断,如 test -e filename 表示存在否 | |
-e | 该『档名』是否存在?(常用) |
-f | 该『档名』是否存在且为文件(file)?(常用) |
-d | 该『档名』是否存在且为目录(directory)?(常用) |
-b | 该『档名』是否存在且为一个 block device 装置? |
-c | 该『档名』是否存在且为一个 character device 装置? |
-S | 该『档名』是否存在且为一个 Socket 文件? |
-p | 该『档名』是否存在且为一个 FIFO (pipe) 文件? |
-L | 该『档名』是否存在且为一个连结档? |
2. 关於文件的权限侦测,如 test -r filename 表示可读否 (但 root 权限常有例外) | |
-r | 侦测该档名是否存在且具有『可读』的权限? |
-w | 侦测该档名是否存在且具有『可写』的权限? |
-x | 侦测该档名是否存在且具有『可运行』的权限? |
-u | 侦测该档名是否存在且具有『SUID』的属性? |
-g | 侦测该档名是否存在且具有『SGID』的属性? |
-k | 侦测该档名是否存在且具有『Sticky bit』的属性? |
-s | 侦测该档名是否存在且为『非空白文件』? |
3. 两个文件之间的比较,如: test file1 -nt file2 | |
-nt | (newer than)判断 file1 是否比 file2 新 |
-ot | (older than)判断 file1 是否比 file2 旧 |
-ef | 判断 file1 与 file2 是否为同一文件,可用在判断 hard link 的判定上。 主要意义在判定,两个文件是否均指向同一个 inode 哩! |
4. 关於两个整数之间的判定,例如 test n1 -eq n2 | |
-eq | 两数值相等 (equal) |
-ne | 两数值不等 (not equal) |
-gt | n1 大於 n2 (greater than) |
-lt | n1 小於 n2 (less than) |
-ge | n1 大於等於 n2 (greater than or equal) |
-le | n1 小於等於 n2 (less than or equal) |
5. 判定字串的数据 | |
test -z string | 判定字串是否为 0 ?若 string 为空字串,则为 true |
test -n string | 判定字串是否非为 0 ?若 string 为空字串,则为 false。 注: -n 亦可省略 |
test str1 = str2 | 判定 str1 是否等於 str2 ,若相等,则回传 true |
test str1 != str2 | 判定 str1 是否不等於 str2 ,若相等,则回传 false |
6. 多重条件判定,例如: test -r filename -a -x filename | |
-a | (and)两状况同时成立!例如 test -r file -a -x file,则 file 同时具有 r 与 x 权限时,才回传 true。 |
-o | (or)两状况任何一个成立!例如 test -r file -o -x file,则 file 具有 r 或 x 权限时,就可回传 true。 |
! | 反相状态,如 test ! -x file ,当 file 不具有 x 时,回传 true |
示例如下:
# 1. 让使用者输入档名,并且判断使用者是否真的有输入字串?
echo -e "Please input a filename, I will check the filename's type and \
permission. \n\n"
read -p "Input a filename : " filename
test -z $filename && echo "You MUST input a filename." && exit 0
# 2. 判断文件是否存在?若不存在则显示信息并结束脚本
test ! -e $filename && echo "The filename '$filename' DO NOT exist" && exit 0
# 3. 开始判断文件类型与属性
test -f $filename && filetype="regulare file"
test -d $filename && filetype="directory"
test -r $filename && perm="readable"
test -w $filename && perm="$perm writable"
test -x $filename && perm="$perm executable"
# 4. 开始输出资讯!
echo "The filename: $filename is a $filetype"
echo "And the permissions are : $perm"
exit 0
2.2 判断符号
除了直接使用test命令之外,还可以使用[]来进行判断,方法就是把test的参数和内容全放在[]里面就是了,不过在中括号和每个参数之间都要用空格隔开,不然就是错误的表达方式。
示例如下:
read -p "Please input (Y/N): " yn
[ "$yn" == "Y" -o "$yn" == "y" ] && echo "OK, continue" && exit 0
[ "$yn" == "N" -o "$yn" == "n" ] && echo "Oh, interrupt!" && exit 0
echo "I don't know what your choice is" && exit 0
2.3 默认变量
默认变量可以通过命令后面加参数的方式在程序开始时就实现与用户的交互,对应关系如下:
/path/to/scriptname opt1 opt2 opt3 opt4
$0 $1 $2 $3 $4
执行脚本文件名就是$0变量,后面的参数就一次是$1$2…,另外$#代表参数的个数,$@和$*代表所有用空格隔开的所有参数。
三、条件判断式
3.1 if…then
if [条件判断式]; then
动作内容,满足条件执行
fi
多个条件判断时可以用&&(AND)和||(OR)隔开每个条件判断,如下例:
read -p "Please input (Y/N): " yn
if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
echo "OK, continue"
exit 0
fi
if [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
echo "Oh, interrupt!"
exit 0
fi
echo "I don't know what your choice is" && exit 0
3.2 多重、复杂条件判断式
#一个条件判断,分成功进行与失败进行 (else)
if [条件判断式]; then
当条件判断式成立时,可以进行的命令工作内容;
else
当条件判断式不成立时,可以进行的命令工作内容;
fi
#多个条件判断 (if ... elif ...elif ... else)分多种不同情况运行
if [条件判断式一]; then
当条件判断式一成立时,可以进行的命令工作内容;
elif [条件判断式二]; then
当条件判断式二成立时,可以进行的命令工作内容;
else
当条件判断式一与二均不成立时,可以进行的命令工作内容;
fi
3.3 利用case…esac判断
case $变量名称in <==关键字为 case,还有变量前有钱字号
"第一个变量内容") <==每个变量内容建议用双引号括起来,关键字则为小括号 )
程序段
;; <==每个类别结尾使用两个连续的分号来处理!
"第二个变量内容")
程序段
;;
*) <==最后一个变量内容都会用 *来代表所有其他值
不包含第一个变量内容与第二个变量内容的其他程序运行段
exit 1
;;
esac
四、function&&循环
4.1 function功能
function fname() {
程序段
}
将多次重复执行的程序段写在函数中可以简化编程,执行函数直接使用函数名就可以了,function也是拥有内置变量的,他的内置变量与shell script很类似,函数名称代表示$0,而后续接的变量也是以$1, $2...来取代的。
4.2 while do done,until do done (不定循环)
while [condition] <==中括号内的状态就是判断式
do <==do是循环的开始
程序段落
done
当满足判断式时进入循环
until [ condition]
do
程序段落
done
当满足判断式时退出循环
4.3 for…do…done(固定循环)
for varin con1 con2 con3 ...
do
程序段
done
第一次循环时$var是con1,第二次是con2,依次类推
4.4 for…do…done的数值处理
for ((初始值;限制值;运行步阶))
do
程序段
done
例如:
read -p "Please input a number, I will count for 1+2+...+your_input: " nu
s=0
for (( i=1; i<=$nu; i=i+1 ))
do
s=$(($s+$i))
done
echo "The result of '1+2+3+...+$nu' is ==> $s"
exit 0
五、调试追踪
sh [-nvx] script.sh
-n:不要执行script,仅查询语法问题
-v:在执行script前,先将script的内容输出到屏幕上(整体)
-x:将使用到的script内容显示到屏幕上(单步)
本文固定链接:http://blog.csdn.net/fyfmfof/article/details/45015041转载请注明出处