**
Shell Script 脚本
**
脚本文件一般以.sh为后缀,写完脚本后,新建文件的权限需要设置 chmod 755 shell.sh
执行脚本:
直接执行
-绝对路径:/home/shell.sh
-相对路径:在/home/目录下 ./shell.shbash执行
- bash shell.sh
- sh shell.sh
脚本检查:
sh -选项 shell.sh
-n:不执行script,仅检查语法问题。
-x:将使用到的脚本内容显示到屏幕上,类似idea的debug,一步一步输出。
-v: 执行前,先将内容输出到屏幕上。
脚本基本格式:
第一行一般为:
#!/bin/bash 确定解释器
echo "xxxx" 类似java中的syso输出控制台。
exit 0 0为正常退出。
在shell脚本中 $(linux命令) 可将命令执行后的结果取出来。
echo 后如跟双引号则其中的$n 是指n变量的值
若是单引号,则就是字符$n
例如:输出 当前日期
#!/bin/bash
echo $(date+%F)
exit 0
数值运算:
格式:$((运算内容))
或者 let 后面和java代码运算一样
read -p "输入内容" num1 类似scanner 会显示双引号中的内容,输入后的值就是变量num1的值。
例如:两数相加:
#!/bin/bash
read -p "first number: " num1
read -p "second number: " num2
sum=$(($num1 + $num2))
#或者可以这样写
let sum=num1+num2
echo "$num1 + $num2 = $sum"
#输入1 2 则显示 1 + 2 = 3
判断命令:
test
使用范例: test -e demo.txt
判断文件选项:
-e 该文件是否存在
-f 该文件是否存在且为文件
-d 该文件名是否存在且为目录
-r 该文件是否存在且有可读权限
-w 该文件是否存在且有可写权限
-x 该文件是否存在且有可执行权限
-s 该文件是否为非空文件
两个文件之间比较
-nt 判断file1是否比file2新
-ot 判断file1是否比file2旧
-ef 判断两个文件是否为同一个文件
判断字符串:
-z 是否为空?若为空则为true
-n 是否非空?若为空则为false
str1 =或== str2 若相等则true
str1 != str2 若不相等则true
&& 前面成立则执行后面的
|| 前面成立则后面的不执行
例如:输入文件名,若输入空值则终止,否则判断文件是否存在
#!/bin/bash
read -p "请输入文件名:" fname
test -z $fname && echo "不能输入空值" && exit 1
test ! -e $fname && echo "$fname文件不存在" && exit 2
test -e $fname && echo "$fname文件存在" && exit 2
判断符号:
[ ] 选项基本和test相同 []与其中的命令要保持一个空格。
==和!=只能用于比较字符串
整数比较只能用-eq,-gt,-gem-lt,-le这种形式
逻辑与和逻辑或为 -a 和 -o 。
&& || < >出现再[]中会报错。
例如:输入y/n来显示不同
#!/bin/bash
read -p "请输入 Y/N :" yn
[ "$yn" == "Y" -o "$yn" == "o" ] && echo "yes" && exit 0
[ "$yn" == "N" -o "$yn" == "n" ] && echo "no" && exit 0
参数传递:
启动时输入 sh shell.sh 1 2 3 4
则传入了4个参数 1 2 3 4
在脚本中如何获得这些参数呢?
$1 代表第一个参数。$2 代表第二个参数以此类推。
$0:代表脚本本身,程序的文件名
$#:代表参数的个数,上面的例字,这里就为4
$@:代表 "$1" "$2" "$3" "$4",每个是独立的
$*:代表 "$1 $2 $3 $4"
例如:输入 sh shell.sh a b c d
#!/bin/bash
echo "第一个参数为: $1"
echo "一共有:$#个参数"
exit 0
#输出 a 4
条件判断语句if:
基本格式
#单个分支
if [ 判断条件 ]; then
命令
fi
#多个分支
if [ 判断条件 ]; then
命令
elif [ 判断条件 ]; then
命令
else
命令
fi
#注意这里的[]见上面的判断符号
例如: 传值比较连个数的大小
输入:sh shell.sh 2 4
#!/bin/bash
if [ $1 -gt $2 ]
then
echo "$1 > $2"
exit 0
elif [ $1 -lt $2 ]
then
echo "$1 < $2"
exit 0
else
echo "$1 = $2"
fi
case结构条件句:
基本格式
case $变量名称 in "值1")
程序段1
;;
"值2")
程序段2
;;
*)
程序段3
;;
esac
#*代表其他
#若有多个条件可以用,分开 如 3,5
#连续则可以输入 3-5;
例如:判断用户输入的数,显示英文星期,其他值的时候提示输入数字1-7。
#!/bin/bash
read -p "请输入数字 1-7 :" num
case $num in 1)
echo "Mon"
exit 0
;;
2)
echo "Tue"
exit 0
;;
3)
echo "Wed"
exit 0
;;
4)
echo "Thu"
exit 0
;;
5)
echo "Fir"
exit 0
;;
6-7)
echo "weekend"
exit 0
;;
*)
echo "请输入数字1-7"
exit 1
;;
esac
函数定义:
基本格式
function fname {
#命令
}
#或者
fname(){
#命令
}
函数参数传递 $1 是第一个参数。等等。
例子如下:
使用命令: sh shell.sh one
#!/bin/bash
#自定义函数
print (){
echo "今天是:$1"
#注意这里$1不是程序传递的参数,是下面调用时候传递的参数
}
case $1 in "one")
print "星期一"
;;
"two")
print "星期二"
;;
"three")
print "星期三"
;;
*)
echo "请输入 one/two/three"
exit 1
;;
esac
exit 0
#程序输出 今天是:星期一
循环语句:
写在前面,for循环取数值
{1..5} 表示 1 2 3 4 5
{a..c} 表示 a b c
10.0.0.{1..3} 表示 10.0.0.1 10.0.0.2 10.0.0.3
上述在循环中需要时可以直接写。
seq -s "分隔符" 起始 步长 终点
例如:1-100内能被3整除的数
seq -s " " 1 3 100
这个命令在循环中使用需要$()包裹或者反引号``包裹。
基本格式:
#循环条件满足则进入循环。不满足则终止
#若死循环可以直接 while true
while [ 循环条件 ]
do
#命令
done
#或者
while [ 循环条件 ]; do
#命令
done
#循环条件满足则终止,不满足进入循环
until [ 循环条件 ]
do
#命令
done
#或者
until [ 循环条件 ]; do
#命令
done
#for循环
for 变量名 in 变量取值列表(上面的取数字)
do
#命令
done
例如:1-100以内能被3整除的数的和
#!/bin/bash
#定义变量
sum=0
for num in $(seq -s " " 1 3 100)
do
let sum=sum+num
done
#输出和
echo "$sum"
exit 0
实战案例:
- 远程给多台电脑发放资料
- 需要已经完成免密登陆
- 将所有的ip写入文件ips.txt
#!/bin/bash
for ip in `cat /home/usr/ips.txt`
do
scp /root/ziliao.txt root@${ip}:/root
done
- 定时任务
- 需要打开 /usr/bin/crontab
- 里面每一行代表一个定时任务
- 里面一行的意思: 分 小时 日 月 星期 命令
- 取值范围:
- 分:0-59
- 小时:0-23
- 日:1-31
- 月:1-12
- 星期:0-6(0是星期日)
- 特殊符号:
- *:代表取值范围内的数字
- /:每
- -:某个数字到某个数字
- ,:分开几个离散的数字
例如:每1分钟给用户发送一次文件
*/1 * * * * root /home/shell.sh
其中 root 是以root用户来执行。
若定时任务没有生效,且脚本无错误,文件权限没问题,就使用一下方法:
1.使root用户的crontab生效
crontab -u root /var/spool/cron/root
2.重启crontab服务
service crond restart