原文:Shell script的语法一:基础语法
shell script 是利用 shell 的功能所写的程序 (program),这个程序使用纯文字,将一些 shell 的语法和命令(含外部命令)写在里面, 搭配正规表达式、管道命令与资料流导向等功能。
shell script 常常用在系统管理中,但是用在处理大量数据运算时, 因为 Shell scripts 的速度较慢,且使用的 CPU 资源较多,会造成主机资源分布不合理。
shell script 的执行,至少需要有 r 的权限,若需要直接执行,則需要拥有 r 和 x 的权限。
一、shell script的书写规则:
1、命令的执行是从上而下、从左至右的分析与执行。
2、命令、选项与参数间的多个空白都会被忽略掉。
3、空白行也将被忽略掉,并且 [tab] 键的空白也视为空白键。
4、如果读取一个Enter符号,就尝试开始执行该命令。
5、如果一行的内容太多,则可以使用“ \[Enter]”来延伸至下一行。
6、“#”作为注释,加在#后的内容将全部视为注释而被忽略。
7、良好的程序编写习惯中,第一行要声明 shell (#!/bin/bash) ,第二行以后则需要描述程序用途、版本、作者等。
二、执行方法:
1、直接执行命令(shell.sh ):该shell.sh 文档须要具有可读与可执行(rx)权限,然后:
1)绝对路径,使用 /home/dmtsai/shell.sh 执行命令。
2)相对路径,假设工作目录在 /home/dmtsai,则使用./shell.sh执行命令。
3)使用PATH功能:将 shell.sh 放在 PATH 指定的目录內,例如: ~/bin/
2、以 bash程序运行:通过“ bash shell.sh ”或“sh shell.sh ”來執行(ubuntu用bash)
三、简单程序编写
为方便管理,把所有程序放入自定义目录的~/bin目录中,如下命令:
[root@Test bin]$ vim hello.sh
#!/bin/bash
# Program:
# This program shows "Hello World!" in your screen.
# History:
# 2017/01/09 shu 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
执行结果:
[root@Test bin]$ sh hello.sh
Hello World !
其中:
1、 第一行使用#!/bin/bash
表明这个script 使用 shell 命令的bash语法。当这个程序被执行时,系统就能够导入bash的相关环境(一般就是 non-login shell 的 ~/.bashrc),并且执行bash,使接下来的指令能被执行(很多实际应用中,如果没有设定这一行,则该程序很可能无法执行,因为系统可能无法判断程序需要使用什么shell来执行)
2、注释
整个script中,除了第一行的#!用来表示shell外,其他的#都是注释,用于说明程序的内容与功能;版本;作者与联系方式;创建时间;历史记录;有助于未来修改与debug。
3、声明环境参数
需要将重要的环境参数设定好,path与lang是当中最重要的,这样,可以让这个程序在运行时,可以直接引用外部命令,而不需要写绝对路径。
4、主要程序部分。使用echo
5、定义返回值。可以使用exit命令让程序中断,且返回一个数值给系统。
四、对话式程序
使用read 指令完成对话式程序。如下:
#!/bin/bash
#Program:
# Usr input his first name and last name .Program shows his full name.
#History:
#209/5/19 Julian First release
########################################
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
export=PATH
read -p "Please input your first name: " firstname
read -p "Please input your first name: " lastname
echo "\nYour full name is :${firstname} ${lastname}"
使用sh showname.sh 或者 chmod a+x showname.sh;./showname.sh运行,得出以下结果:
root@Test:~/bin$ chmod a+x showname.sh;./showname.sh
Please input your first name:shu
Please input your last name:yu
Your full name is:shu yu
五、获取日期,使用date命令
如下程序:
root@Test:~/bin$ vim create_3_filename.sh
#!/bin/bash
#Program:
# Program creates three files,which named by user's input and date command.
#History:
#2017/01/09 shu First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
#1、让用户输入文档名称,并获得fileuser这个变量;
echo -e "I will see '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}"
运行结果:
root@Test:~/bin$ chmod a+x create_3_filename.sh;./create_3_filename.sh
I will see 'touch' command to create 3 files.
Please input your filename:shu
这样就在当前目录下新建了3个文件:shu20170107;shu20170108;shu20170109
六、算术运算,简单的加减乘除 +, -, *, /, %:
可以使用:declare -i total=${firstnu}*${secnu}
也可以使用:var=$((运算內容))
如下程序,完成2个数相乘:
#!/bin/bash
#Program:
# User inputs 2 integer numbers;program will cross these two nubers.
#History
#2017/01/09 shu First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "You SHOULD input 2 numbers,I will multiplying them!\n"
read -p "first number:" firstnu
read -p "second number:" secnu
total=$((${firstnu}*${secnu}))
echo -e "\nThe result of ${firstnu}* ${secnu} is ==>${total}"
运行结果:
root@Test:~/bin$ chmod a+x multlplying.sh;./multlplying.sh
You SHOULD input 2 numbers,I will multiplying them!
first number:1
second number:2
The result of 1* 2 is ==>2
使用bc可以进行小数运算,如下:
[root@Test bin]$ echo "123.123*55.9" | bc
6882.575
七、使用bc计算pi
计算pi时小数点可以一直计算,在使用该程序时必须要使用 bc -l 才行。以下程序是让用户输入一个计算小数点参数, 让pi计算更准确:
#!/bin/bash
#Program:
# User input a scale number to calculate pi number.
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "This program will calculate pi value. \n"
echo -e "You should input a float number to calculate pi value.\n"
read -p "The scale number(10~10000)?" checking
num=${checking:-"10"} #判断是否有输入数值
echo -e "Starting calculate pi value.Be patient."
time echo "scale=${num};4*a(1)"|bc -lq
#4*a(1):是bc提供的一个计算派的函数
#scale 是几位小数点
运行结果:
root@Test:~/bin$ chmod a+x cal_pl.sh;./cal_pl.sh
This program will calculate pi value.
You should input a float number to calculate pi value.
The scale number(10~10000)?10
Starting calculate pi value.Be patient.
3.1415926532
real 0m0.003s
user 0m0.002s
sys 0m0.001s
其中4*a(1) 是 bc 提供的一个计算pi的函数,scale是bc计算几个小数点位数的参数,当scale的数值越大,代表pi计算越精确,消耗时间越长。
这个函数可以应用于测试虚拟机的效率,保持虚拟机CPU一直在运行状态。
八:函数
#!/bin/bash
#Program:
# Use function to repeat information.
#History:
#2019/5/20
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
export=PATH
function printit()
{
echo "Your choice is ${0}"
echo "Your choice is ${1}"
echo "Your choice is ${2}"
echo "Your choice is ${3}"
echo "Your choice is ${4}"
}
echo "This program will print your selection!"
case ${1} in
"one")
printit ${0} ${1} ${2} ${3}
;;
"two")
printit 2
;;
"three")
printit 3
;;
*)
echo "Using ${0} {1|2|3}"
;;
esac
九:for循环
#!dash
#Program:
# Use id ,finger command to check system account's information.
#History:
#2019/5/19 Julian First relese
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
export PATH
#cut(选项)(参数):
# -d:指定字段的分隔符,默认的字段分隔符为“TAB”;
# -f:显示指定字段的内容;-f1,-f2,3 -f 2……
# /etc/passwd:(参数)
users=$(cut -d ':' -f1 /etc/passwd)
for username in ${users}
do
id ${username}
done
十:while循环
#!/bin/bash
#Program:
# Repeat qustion until input correct answer.
#History:
#2019/5/20
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
export=PATH
while [ "${yn}" != "yes" -a "${yn}" != "YES" ]
do
read -p "Please input yes/YES to stop this program: " yn
done
echo "OK! you input the correct answer."
十一:选择case
#!dash
#Program:
# Check $1 is equal to "hello"
#History:
#2019/5/19 Julian First relese
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
export=PATH
case ${1} in
"hell0")
echo "Hello, how are you ?"
;;
"")
echo "You must input parameters,ex> {${0} someword}"
;;
*)
echo "The only parameter is 'hello',ex>{${0} hello}"
;;
esac
笔记:
- 在bash中使用一个等号和两个的结果是一样的,不过在一般的惯用程序的写法中,一个等号代表“变量的设定”,两个代表“逻辑判断”。所以一般为了防止混淆都用“==”\
- num=${checking:-"10"} 这句话的意思是什么?
- var=${str:-expr}
- str 没有设定: var=expr
- str为空字符串:var=expr
- str为已设定的非空字符串: vare=$str
- 所以当checking为空字符串的时候 num = 10,借此来检验checking是否成功赋值了。
-
可以看到如果没指定就默认10位输出,要是有指定就会以你输入的位数输出
- var=${str:-expr}
- 一道编程中的思考
-
-
在进行数学运算的时候一定要有空格:expr 2 + 3
-