交互式:(命令行)人工干预,执行效率底
非交互式:(脚本)安静地在后台执行,执行效率高,方便写脚本
安装ksh======cat /etc/shells
ksh回车体验ls / ; cd / ; pwd
- 快捷键:
Ctrl + A 将光标移至行首
Ctrl + E 将光标移至行尾
Ctrl + D 一般为结束输入
Ctrl + U 删除光标至行首的所有内容
Ctrl + W 删除光标前面的一个单词(空格分隔)
Alt + . 使用前一个命令的最后一个词
上下键 历史命令
Tab键 补全
==============================================
历史命令的容量。
默认记录1000条,通过全局变量HISTSIZE设置,对所有用户有效
vim /etc/profile
HISTSIZE=10
ls -A
> .bash_history #清空记录文件
history -c #清空历史记录
history | wc-l #统计多少条历史记录
!21 #执行历史第21条命令
!sys #执行最近以sys开头的命令
别名:alias ll='ls -l --color=auto' #ls -l --color显示带颜色
别名设置一般存放在用户的.bashrc文件内
取消别名 unalias god
查询别名 alias god
重定向:> 将命令执行的正常输出重定向到文件, 操作会覆盖目标文件(先清空、再写入)
>> 可实现追加重定向输出
2> 可重定向错误信息
2>> 可实现追加输出(错误信息)
&> 将正常输出、错误输出重定向同一个文件
&>> 将正常输出、错误输出追加重定向到一个文件
< 重定向标准输入。
管道:借助于管道符“|”,可以将一条命令的标准输出交给另一条命令处理,在一条命令行内可依次使用多个管道。
yum list | grep cluster
ls -l /etc | wc -l
================================================
编写shell规范
- 1.声明解释器#!/bin/bash
- 2.#注释文本
- 3.可执行代码
chmod +x 脚本文件 #赋予执行权限
或 bash 脚本文件 #直接运行脚本,开启子进程(解释器)
或 source 脚本文件 #直接运行脚本,不开启子进程(解释器)
source可以以 . 代替
另开终端pstree查看sshd─┬─sshd───bash───sh───sleep
└─sshd───bash───pstree
快速装配vsftpd服务的Shell脚本
vim /root/ftpon.sh
#!/bin/bash
rm -rf /etc/yum.repos.d/*.repo
echo '[rhel]
name=redhat
baseurl=file:///misc/cd >>>yum地址仓库
gpgcheck=0
' > /etc/yum.repos.d/rhel.repo
yum -y install vsftpd &> /dev/null
systemctl start vsftpd
systemctl enable vsftpd
cp /etc/hosts /var/ftp/pub
#拷贝一个文件,放到FTP共享目录下
[root@svr5 ~]# chmod +x /root/ftpon.sh
================================================
-
Shell变量
系统变量:1.定义/赋值/查看变量
2.环境/预定义/位置变量的应用,大部分是系统已经定义好了直接使用
自定义变量:使用大小写字母,数字,下划线,不能数字开头,不能使用特殊符号
默认情况下,自定义的变量为局部变量,只在当前Shell环境中有效,而在子Shell环境中无法直接使用。比如已定义的SCHOOL变量,当进入到sh或bash子Shell后,变量SCHOOL将处于未定义的状态:
若希望定义的变量能被子进程使用,可以使用export命令将其发布为全局变量。使用export发布时,只需指定变量名(可以有多个)即可,也可以通过export命令直接设置新的全局变量:
export yy //发布已定义的变量
export XX="1234" //发布新变量
环境变量:echo $PWD/$USER/$SHELL/$UID/$HOSTNAME/$PATH
/当前位置/当前用户名//当前用户解释器/当前用户UID/主机名
$PATH>>/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
#系统命令所在地
test=11
echo $变量名 可输出变量值
unset test 撤销已有的变量
echo $PS1='[\u@\h \W]\$' #一级提示符
\u 用户名、\h 主机名、\W 工作目录、\$ 权限标识
echo $PS2='>' #二级提示符
出现在强制换行、at任务编辑等场合
echo $0 脚本的名称
echo $1 第一个参数(位置变量)
echo $* 显示所有位置变量的值
echo $# 统计位置变量个数
echo $$ 当前程序进程号
echo $? 上一条指令的执行结果,0正常非0异常
全局文件为/etc/profile,对所有用户有效;用户文件为~/.bash_profile,仅对指定的用户有效。
当前用户的环境变量USER记录了用户名、HOME记录了宿主目录、SHELL记录了登录Shell、 HOSTNAME记录主机名、UID是用户的id号:
环境变量PS1表示Shell环境的一级提示符,即命令行提示符(\u 用户名、\h 主机名、\W 工作目录、 \$ 权限标识):
环境变量PS2表示二级提示符,出现在强制换行、at任务编辑等场合
创建用户脚本
vim /opt/nsd01
#!/bin/bash
useradd $1 &>> /opt/error #将提示信息重定向到文件中
echo $2 | passwd --stdin $1 #非交互式改密码
env 可查看所有环境变量
set 可查看所有变量(包括env能看到的环境变量)
可接 | grep 目标
================================================
' '单引号:用来界定范围。可以屏蔽特殊符号的作用
" "双引号:用来界定范围
反斜线\ :去除一个单个字符的特殊意义
反撇号``or $() :将命令执行的标准输出作为字符串存储.称为命令替换。
read命令从键盘读取变量值
-p
read命令 -p(提示语句) -n(字符个数) -t(等待时间) -s(不回显)
将回显功能关闭(stty -echo),
将回显功能恢复(stty echo)。
vim /opt/test0
#!/bin/bash
read -p "请输入账户名:" u
stty -echo
read -p "请输入密码:" p
stty echo
useradd $U &>> /opt/error
echo $p | passwd --stdin $u
使用export命令将其发布为全局变量。使用export发布时, 只需指定变量名(可以有多个)即可,也可以通过export命令直接设置新的全局变量:
]# export xx=1234
-
运算
- 1.expr运算工具
格式: expr 整数1 运算符 整数2
只进行运算,并不会改变变量的值、bash内建机制仅支持整数值运算
expr $x + $y
+ expr 1 + 1
- expr 1 - 1
\* expr 1 \* 1 #乘法操作采用、*转义,避免被作为shell通配符
/ expr 1 / 1
% expr 1 % 1 #取余数
- 2. $[ ]或$(())表达式
乘法操作*无需转义,运算符两侧可以无空格;
引用变量可省略 $ 符号;不支持有小数点的运算,
计算结果替换表达式本身,可结合echo命令输出。
格式: $[整数1 运算符 整数2...]
echo $[1+1]
变量 的自增/减等操作:使用$[ ] 替换、或let命令来完成
- 3. let 针对变量 定义变量的值、无需$符号、不显示结果
可以直接对变量值做运算再保存新的值,结合echo命令来查看
a=10
echo $a
let b=a+1 echo $b #定义新变量,此时b=10+1
主流写法
let b++ echo $b #(b=b+1)
let b-- echo $b #(b=b-1)
let b-=2 echo $b #(b=b-2)
let b+=2 echo $b #(b=b+2)
let b*=2 echo $b #(b=b*2)
let b/=3 echo $b #(b=b/3)
let b%=3 echo $b #(b=b%3)
- 4. bc计算器
支持高精度的数值运算,直接运行bc可进入交互式运算界面,quit退出
结合管道向bc发送表达式,多个表达式以分号分割隔
通过echo命令+管道传递要计算的表达式
echo 'scale=N;表达式;表达式' | bc #bc非交互式运算,scale=N 约束小数位的长度
echo "scale=4;$a*56.789;5/3" | bc
条件测试的基本用法
使用“test 表达式”或者[ 表达式 ]都可以,表达式两边至少要留一个空格
条件测试操作本身不显示出任何信息。
测试的条件是否成立主要体现在命令执行后的返回状态(即 $?),
所以可以在测试后查看变量$?的值来做出判断,
或者结合&&、||等逻辑操作显示出结果(或作其他操作) 。
[ $USER == root ]
echo $?
字符串测试
1)== 比较两个字符串是否相同
[ $USER == "root" ]
echo $?
!= 比较两个字符串是否不相同
[ $USER != "root" ]
a && b //仅当A命令执行成功,才执行B命令
a || b //仅当A命令执行失败,才执行B命令
a ; b //执行A命令后执行B命令,两者没有逻辑关系
A && B || C
-z 检查变量的值是否未设置(空值)
a=10
[ ! -z $a ] #是否为非空
格式:整数值1 操作符 整数值2
-gt 大于 (Greater Than)
-ge 大于等于 Greater or Equal)
-eq 等于 (Equal)
-ne 不等于 (Not Equal)
-lt 小于 (Lesser Than)
-le 小于等与 (Lesser or Equal)
对root用户无效
-e 判断对象是否存在(不管是目录还是文件)
-d 判断对象是否为目录(存在且是目录)
-f 判断对象是否为文件(存在且是文件)
-r 判断对象是否可读
-w 判断对象是否可写
-x 判断对象是否具有可执行权限
逻辑分隔符
&& 给定条件必须成立,整个测试结果才为真
|| 只要其中一个条件成立,则整个测试结果为真
X=20 //设置X变量的值为20
[ $X -gt 10 ] && [ $X -lt 30 ] && echo "YES"
YES
[ -w "/tmp/" ] || [ -w "/var/spool/" ] && echo "OK"
OK
$[RANDOM] #随机数
$[RANDOM%11] #10以内的随机数
脚本案例
#!/bin/bash
read -p "请输入用户名:" u
[ -z $u ] && exit
useradd $u
---------------------------------------------------------------
#!/bin/bash
a=`who | wc -l` #当前几个用户登陆系统
[ $a -gt 3 ] && echo "报警,已超三人登陆系统" | mail -s "紧急" root
赋予x权限
书写定时任务 crontab -e -u root
* * * * * 脚本绝对路径
if判断
if双分支
ping只发送3个测试包(-c 3)、缩短发送测试包的间隔秒数(-i 0.2)、等待反馈的超时秒数(-W 1)。
#!/bin/bash
ping -c 3 -i 0.2 -W 1 $1 &> /dev/null
if [ $? -eq 0 ];then
echo "可以通信"
else
echo "不可以通信"
fi
---------------------------------------------------------------------------------------------
#!/bin/bash
n=$[RANDOM%11]
read -p "请输入你猜的数字(0-10):" a
[ -z $a ] && exit #若无输入则退出
if [ "$a" -eq "$n" ];then
echo "恭喜猜对了"
exit
elif [ "$a" -gt "$n" ];then
echo "对不起,猜多了"
else
echo "不好意思,猜少了"
fi
read -p "请输入你猜的数字(0-10):" a
[ -z $a ] && exit
if [ "$a" -eq "$n" ];then
echo "恭喜猜对了"
exit
elif [ "$a" -gt "$n" ];then
echo "对不起,猜多了"
else
echo "不好意思,猜少了"
fi
read -p "请输入你猜的数字(0-10):" a
[ -z $a ] && exit
if [ "$a" -eq "$n" ];then
echo "恭喜猜对了"
exit
elif [ "$a" -gt "$n" ];then
echo "对不起,猜多了"
else
echo "不好意思,猜少了"
fi
#三次机会猜数
-----------------------------------------------------------------------------------------------------------------
大于等于90 神功绝世
大于等于80,小于90 登峰造极
大于等于70,小于80 炉火纯青
大于等于60,小于70 略有小成
小于60 初学乍练
#!/bin/bash
read -p "你的长度(0-100):" j
[ -z $j ] && exit
if [ $j -ge 90 ];then
echo "神功绝世"
elif [ $j -ge 80 ];then
echo "登峰造极"
elif [ $j -ge 70 ];then
echo "炉火纯青"
elif [ $j -ge 60 ];then
echo "略有所成"
else
echo "初学咋练"
fi
#赋予x权限
------------------------------------------------------------------------------------------------------------------
for循环
for循环关心2个点:
- 1,循环次数
- 2,循环过程中使用的变量
格式:for 变量名 in 变量值1...
do
命令序列
done
{1..10} #造数工具
seq 10 # 预设的外部命令,一般用作一堆数字的简化写法。
n=$[RANDOM%101]
while : #死循环 :表示不知道什么时候结束循环
或while 条件测试
do
命令序列
done
read -s(输入的数据不显示在命令终端上) -p "..." x
-p (输入前打印提示信息)
case分支
case 变量 in
模式1|a|b|c)
命令序列;;
模式2|a|b|c)
命令序列;;
...可以n个
*)
(默认命令序列)显示服务脚本用法
esac
---------------------------------------------------------------------------------------
格式1
function 函数名 {
命令序列
}
格式2
函数名(){
命令序列
...
}
颜色
echo -e "\033[33mABC\033[0m"
break 退出循环,继续执行之后的任务
continue 退出当前循环,继续下一次循环
exit 退出脚本
脚本案例----------------------------------------------------------------------------------
[root@svr5 ~]# vim chkhosts.sh
#!/bin/bash
cecho(){
echo -e "\033[$1m$2\033[0m"
}
#函数(变颜色)
a=0
b=0
#赋值
for i in {1..254} #1-254数字循环ping
do
ping -c 3 -i 0.2 -W 1 192.168.4.$i &> /dev/null
# -c 指定ping的次数 -W 等待指定时间后停止ping -i 指定发送数据包时间间隔
if [ $? -eq 0 ] ; then #如果ping成功则执行以下输出
cecho 32 "Host 192.168.4.$i is up." #函数参与 32为颜色
let a++ #每成功执行一次+1
else #如果ping失败则报错误信息
cecho 31"Host 192.168.4.$i is down." #函数参与 31为颜色
let b++ #每成功执行一次加1记为次数
fi
done
echo "$a 台成功通了, $b 台失败了"
[root@svr5 ~]# chmod +x chkhosts.sh
----------------------------------------------------------------------------------------------------
C语言风格的for循环语法格式
#!/bin/bash
for ((i=1;i<=5;i++)) #i=1 如果i<=5就执行循环,每成功执行一次+1,第二次i=2,i<=5以此类推
do
echo $i
done
--------------------------------------------------------------------------------------------------------------
#!/bin/bash
for i in $(cat $1) #cat $1 内容赋予i身上
do
useradd $i
echo 123456 | passwd --stdin $i #为文件里的用户设置默认密码123456
done
-----------------------------------------------------------------------------------------------------------
[root@svr5 ~]# vim while01.sh
#!/bin/bash
i=1 #值不变,一直小于等于5导致死循环
while [ $i -le 5 ]
do
echo "$i"
done
----------------------------------------------------------------------------------------------------------------
#!/bin/bash
while : #死循环
do
echo "hello world"
done
----------------------------------------------------------------------------------------------------------------
[root@svr5 ~]# vim while02.sh
#!/bin/bash
i=1 #值会根据let而改变,直到等于5脚本结束
while [ $i -le 5 ]
do
echo "$i"
let i++ #上一条执行成功赋予+1
done
---------------------------------------------------------------------------------------------------------------
#!/bin/bash
num=$[RANDOM%100+1] #随机数
i=0
while : #:不考虑这的条件就一直死循环
do
read -p "随机数1-100,你猜:" guess #键盘输入值赋予guess
let i++ //猜一次,计数器加1,统计猜的次数
if [ $guess -eq $num ];then #如果输入值等于随机数则输出并退出脚本
echo "恭喜,猜对了"
echo "你猜了$i次" #提醒猜的次数
exit
elif [ $guess -gt $num ];then #如果大于随机数给予提示
echo "猜大了"
else #反之,以上不成立执行以下输入提示
echo "猜小了"
fi
------------------------------------------------------------------------------------------------------------------------
#!/bin/bash
i=1
while [ $i -le 254 ] #如果i不小于等于254就终止
do
IP="192.168.4.$i" #赋予IP值
ping -c 3 -i 0.2 -W 1 $IP &> /dev/null #过程信息丢到黑洞
if [ $? -eq 0 ] ; then #ping成功了就执行以下
echo "Host $IP is up."
else
echo "Host $IP is down."
fi
let i++
done
----------------------------------------------------------------------------------------------
#!/bin/bash
case $1 in #$1和 xx)匹配、为真则执行哪个相应的命令序列
redhat)
echo "fedora";;
fedora)
echo "redhat";;
*) //以上不成立则默认输出脚本用法
echo "用法: $0 {redhat|fedora}"
esac
--------------------------------------------------------------------------------------------
[root@svr5 ~]# vim test.sh
#!/bin/bash
for i in {1..5}
do
[ $i -eq 3 ]&& break //这里将break替换为continue,exit分别测试脚本执行效果 echo $i
done
echo "Game Over"
-----------------------------------------------------------------------------------------------------
[root@svr5 ~]# vim sum.sh
#!/bin/bash
SUM=0
while :
do
read -p "请输入整数(0表示结束):" x
[ $x -eq 0 ] && break
SUM=$[SUM+x]
done
echo "总和是:$SUM"
------------------------------------------------------------------------------------------------------------------
[root@svr5 ~]# vim test.sh
#!/bin/bash
for i in {1..20} i值为1-20,循环每个值
do
[ $[i%6] -ne 0 ] && continue #1%6(取余数)的计算结果不等于0则跳过此循环继续下个循环
echo $[i*i]
done