Bash位置参数
有两种简单的方法可以将用户输入读入bash中的变量。第一个方法是使用read提示用户输入(使用-p选项)并将其直接存储到一个或多个变量。
交互式
read -p ‘Enter your first and last name: ’ FIRST LAST
-p表示显示交互内容,如不显示则在最后加-s(可用于密码输入不回显)
[root@localhost ~]# read -p 'please give me a num: ' a
please give me a num: 2
[root@localhost ~]# echo $a
2
[root@localhost ~]# read -p 'please give me a num: ' -s a
please give me a num: [root@localhost ~]# echo $a
24
位置参数
另一个方法是使用位置参数来读取传递给脚本的命令行参数或选项输入。
指定的位置参数总数:$#
位置参数自身:$0、$1、$2、$3….
所有位置参数: $@、$*
退出状态
Linux命令完成时,将返回退出状态。成功完成程序时,将返回0的推出状态。这被bash当作逻辑True值。非零退出状态通常表示发生了错误,并且被bash当作逻辑False值。
例如:grep的退出状态的含义:
0 – 在指定的文件中找到了模式
1 – 在指定的文件中未找到模式
>1 – 一些其他错误(无法打开文件、错误的搜索表达式等)
推出状态的值被存储在”?”中,可以使用以下命令查看:
echo $?
test条件判断
test命令可用于评估bash脚本中的表达式。它评估其参数所指定的表达式,如果表达式
为true,返回零退出状态,如果表达式为false,则返回非零退出状态。
非零或零长度字符串运算符
{-n | -z}
-n表示不为0
-z表示为0
[root@localhost ~]# a=1
[root@localhost ~]# test -n "$a" ;echo $?
0
[root@localhost ~]# test -z "$a" ;echo $?
1
[root@localhost ~]# [ -n "$a" ]&& echo yes || echo no ##若a不为0则显示yes,否则显示no
yes
[root@localhost ~]# [ -z "$a" ]&& echo yes || echo no ##若a为0则显示yes,否则显示no
no
字符串比较运算符:= !=
[root@localhost ~]# a=1
[root@localhost ~]# b=2
[root@localhost ~]# [ "$a" = "$b" ]&& echo yes || echo no ##a=b则显示yes,否则显示no
no
[root@localhost ~]# b=1
[root@localhost ~]# [ "$a" = "$b" ]&& echo yes || echo no
yes
[root@localhost ~]# [ "$a" != "$b" ]&& echo yes || echo no
no
[root@localhost ~]# b=2
[root@localhost ~]# [ "$a" != "$b" ]&& echo yes || echo no
yes
[root@localhost ~]# [ ! "$a" = "$b" ]&& echo yes || echo no ##当!在条件语句前表示条件不成立,这里表示若a=b不成立则显示yes,否则显示no
yes
数字比较运算符
-eq 等于(=)
-ne 不等于(!=)
-lt 小于
-le 小于等于
-gt 大于
-ge 大于等于
[root@localhost ~]# a=1
[root@localhost ~]# b=4
[root@localhost ~]# [ "$a" -eq "$b" ]&& echo yes || echo no
no
[root@localhost ~]# b=1
[root@localhost ~]# [ "$a" -eq "$b" ]&& echo yes || echo no
yes
[root@localhost ~]# b=2
[root@localhost ~]# [ "$a" -ne "$b" ]&& echo yes || echo no
yes
[root@localhost ~]# [ "$a" -lt "$b" ]&& echo yes || echo no
yes
[root@localhost ~]# [ "$a" -gt "$b" ]&& echo yes || echo no
no
文件状态运算符
-b 块文件
-c 字符文件
-e 文件存在
-f 常规文件
-d 目录
-r 可读文件
-w 可写
-x 可操作
-s 大小不为0的文件
-S 套接字文件
-L 链接文件
二进制文件运算符
file1 -ef file2文件在同一个端口或设备
**file1 -nt file2**file1比file2新
**file1 -ot file2**file1比file2旧
逻辑运算符
-o or或者
-a and和
! 非
&& 正确则
|| 错误则
if语句
if命令检查if后面的命令或列表的退出值。如果第一个命令评估为true/零,则运行then之后的命令列表,直至任一else。如果第一个命令评估为false/非零,则运行else与fi之间的命令列表(反向平写if,标记if块的结束)。
语法:
(1)
if command; then command; command2; else command3; fi
(2)
if command; then command; elif command2;then commend3; else command4; fi
例:
#!/bin/bash
read -p "please input your num: " a
if [ -z "$a" ]
then
echo no a
elif [ "$a" = "1" ]
then
echo hello world $a
else
echo i have no idea
fi
测试:
case语句
case语句 :它能够把变量的内容与多个模板进行匹配,再根据成功匹配的模板去决定应该执行哪
部分代码。
case .. in
..) ##条件1
;;
..) ##条件2
;;
esac ##结束点
例:
#!/bin/bash
case $1 in
start)
systemctl start firewalld
;;
stop)
systemctl stop firewalld
;;
esac
expect语句
在shell中利用expect实现自动应答脚本。
例:
利用自动应答脚本实现ssh自动连接
#!/usr/bin/expect
这一行告诉操作系统脚本里的代码使用那一个shell来执行。
spawn是expect的内部命令,作用是给后面的shell指令加个壳,用来传递交互指令
expect eof
作用是在输出中搜索文件结束符,如果没有这一行,脚本会立即退出,得不到正确结果。
interact
执行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了。否则退出登录。
$argv 参数数组
expect脚本可以接受从bash传递过来的参数.可以使用[lindex $argv n]获得,n从0开始,分别表示第
一个,第二个,第三个….参数。
#!/usr/bin/expect
set IP [ lindex $argv 0] ##定义命令后的输入的第一个字符为IP
set PASS [ lindex $argv 1] ##定义命令后的输入的第二个字符为PASS
spawn ssh root@$IP
expect {
"yes/no" {send "yes\r";exp_continue}
"password:" {send "$PASS\r"}
}
interact
测试:
环境变量
shell和脚本使用变量来存储数据 ,有些变量可以连同它们的内容传递给子进程,这些
变量我们称之为环境变量。
使用env命令显示所有环境变量
使用set命令现实所有本地定义的shell变量
系统环境变量文件/etc/profile
用户环境变量文件~/.bash_profile
Bash启动脚本
(1)修改系统环境变量__用于系统
(2)修改用户环境变量——仅用于本用户
(3)当系统环境变量和用户环境变量设定不一样时,按最后读取的环境变量即用户环境变量。
使用别名
alias命令可以用来自定义属于自己的系统命令,写入~/.bashrc 文件永久生效
(1)添加别名
(2)删除别名
删除文件中的别名
unalias 别名
使用函数
函数名 () {
commends
}
脚本示例
check_ip主机检测
存在则显示丿,否则显示down
且没有给出ip时会提示
#!/bin/bash
while [ "$#" -eq "0" ]
do
echo "please input a IP address!!!"
exit 1
done
ping -c1 $1 &>/dev/null && echo "the $1 is up" || echo "the $1 is down"
测试:
check_ip.sh主机检测
check_ip主机检测的另一种实现
#!/bin/bash
[ -n "$1" ]&& (
ping -c1 -w1 $1 &> /dev/null && echo "$1 is up " || echo "$1 is down")||(echo "please give me a address!")
测试:
ip_check本机地址的查看
实现可以查看本地的ip地址,且会显示可查看的设备
awk ‘{print $1}‘ 表示取出输入的第一串字符
-F : 表示不取出:符号
#!/bin/bash
echo "you can input these interface: "
ifconfig | grep flags | awk -F: '{print $1}'
read -p "please give me a interface: " a
ifconfig $a | grep netmask | awk '{print $2}'
测试:
check_file.sh检测文件的类型
实现可以检测文件的类型
#!/bin/bash
while [ -z "$*" ]
do
echo "please give me a file or directory"
exit 0
done
if [ -e "$1" ]
then
while [ -b "$1" ]
do
echo "It's a block file "
exit 1
done
while [ -c "$1" ]
do
echo "It's a character file "
exit 1
done
while [ -d "$1" ]
do
echo "It's a directory "
exit 1
done
while [ -S "$1" ]
do
echo "It's a socket file "
exit 1
done
while [ -L "$1" ]
do
echo "It's a link file "
exit 1
done
while [ -f "$1" -a ! -L "$1" ]
do
echo "It's a file "
exit 1
done
while [ -x "$1" ]
do
echo "the file can be exced "
exit 1
done
else
echo "It's not exists"
exit 1
fi
测试:
用户建立
(1)create_user.sh
建立用户并设置密码为westos
已建立的用户提示已存在
#!/bin/bash
if [ -z "$*" ]
then
echo "please give me a user file"
elif [ ! -e "$*" ]
then
echo "$1 is not exist"
else
for USER in `cat $1`
do
id $USER &> /dev/null && (
echo "$USER is exist,$USER's passwd is changing"
echo westos | passwd --stdin $USER &> /dev/null) || (
useradd $USER
echo westos | passwd --stdin $USER &> /dev/null
echo "$USER is creating")
done
fi
测试:
(2)ctrl_user.sh
完善create_user.sh,使可以提示没有文件时的情况,可以批量删除用户
#!/bin/bash
if [ "$1" = "create" ]
then
if [ -z "$2" ]
then
echo "please give me a user file"
elif [ ! -e "$2" ]
then
echo "$2 is not exist"
else
for USER in `cat $2`
do
id $USER &> /dev/null && (
echo "$USER is exist"
echo westos | passwd --stdin $USER &> /dev/null) || (
useradd $USER
echo westos | passwd --stdin $USER &> /dev/null)
done
fi
elif [ "$1" = "delete" ]
then
if [ -z "$2" ]
then
echo "please give me a user file"
elif [ ! -e "$2" ]
then
echo "$2 is not exist"
else
for USER in `cat $2`
do
userdel -r $USER &> /dev/null
echo "$USER is not exist "
done
fi
else
echo "USAGE: /mnt/ctrl_user.sh [ create|delete ] userfile "
fi
测试:
(3)ctrl_user
ctrl_user.sh的利用函数实现的另一种方式
#!/bin/bash
ACTION () {
if [ -z "$4" ]
then
echo "please give me a user file"
elif [ ! -e "$4" ]
then
echo "$4 is not exist"
else
for NAME in `cat $4`
do
USER=`getent passwd $NAME`
if [ $1 "$USER" ]
then
$2 $NAME
[ "$2" = "useradd" ]&&(echo westos | passwd --stdin $NAME &> /dev/null)
else
echo "$NAME is exist"
fi
done
fi
}
if [ "$1" = "create" ]
then
ACTION -z "useradd" "exist" $2
elif [ "$1" = "delete" ]
then
ACTION -n 'userdel -r' 'not exist' $2
else
echo "USAGE: /mnt/ctrl_user.sh [ create|delete ] userfile "
fi
测试:
check_num.sh比较两个数的和是否大于10
#!/bin/bash
while [ -z "$1" -o -z "$2" ]
do
echo "please give me two number"
exit 1
done
let A=$1+$2
[ "$A" -le "10" ] && echo "$1+$2's sum is equal or lesser than 10,and the sum is $A" || echo "$1+$2's sum is larger than 10"
测试: