shell环境
- Shell的环境和功能
- 1. Shell的概述
- 2. 命令补全
- 3. 命令历史
- 4. 命令别名
- 5. 通配符
- 6. 命令后台发送与作业控制
- Shell变量
- Shell变量的概念
- 自定义变量
- 环境变量
- 预定义变量
- 位置变量
- 管道与重定向
- 1. 标准设备文件
- 2. 管道
- 3. 重定向
- 4. 管道与重定向的应用
- Shell脚本
- 1. 脚本的概述
- 2. 脚本的控制结构
- 3. 脚本的使用示例
- Shell脚本的高级主题
- 案例讲解
Shell的环境和功能
1. Shell的概述
Shell是操作系统与用户进行交互操作的界面
2. 命令补全
TAB单击补全命令
TAB双击列示推测可能的命令
命令补全通常补全系统的命令路径下的命令
命令补全部分的补全命令行的命令参数(操作参数)
3. 命令历史
history //历史查看
history -c //历史清空
使用上下逐条调阅最近的命令历史
用!调用前端字符匹配的最近使用过的命令立即执行
4. 命令别名
alias //命令别名查看
alias myls='ls -a' //设置命令别名 (把ls -a别名为myls)
例子:
alias
type ls //查看ls
which ls //查看ls这命令在哪(/bin/ls)
/bin/ls //可以用这个ls
alias myls='ls -ld --color=auto' //设置自己的个性命令别名
myls
5. 通配符
* //代表任意多个 0~n
? //代表任意一个字符 1
[] //某到某之间范围中的一个字符
例子:
ls -l *.out
touch test.
ls -l test.*
ls -l test.??
ls -l test[0-9].sh
touch testa.sh
ls -l test[0-9,a-z].sh
ls -l test[0-5]*.???
touch test2.txt
touch test35.txt
touch test258.txt
touch test888.bat
!ls //运行最近一次的ls命令
6. 命令后台发送与作业控制
在原有命令的末端使用“&”符号可将命令发送至后台运行
jobs //查看当前的后台作业任务
bg //将当前命令作业切换到后台
fg //将最近一个后台作业切换回前台
例子:
jobs //查看当前后台作业任务
gedit //打开文本编辑器
前台被占用
gedit& //后台运行文本编辑器
fg //切换第一个到前台
Ctrl C //结束
jobs
fg %3 //切换3的后台到前台
结束3的进程才能继续前台
sleep 1000& //把sleep1000这作业发送到后台,前台显示后台的作业序号1和pid 28354
jobs //查看后台作业任务
kill -19 28354 //发送19号信息给sleep1000这任务(19挂起)
bg %1 //把sleep1000这任务唤醒
jobs
Shell变量
Shell变量的概念
= //变量的设置(写入)
$ //变量的引用(读取)
例子:
COLOR=red //变量设置
echo $(COLOR) //变量读取
echo ${COLOR}ball //用大括号,读取并连接
echo $COLOR ball //用空格分开,读取并连接
自定义变量
= //自定义变量(大坨峰命名法)
$ //变量读取
例子:
Day=Sunday //设置变量
echo $Day //读取变量
echo "Today is ${Day}" //一串东西显示连着读取
环境变量
环境变量命名(全大写)
export //将当前Shell环境中的环境变量导出到子Shell中
~/.bashrc //保存配置文件,供固话的长期使用
PATH变量 //存储系统命令的所在路径,通常为绝对路径
PS*变量
PS1 //存储命令行的提示符
PS2 //存储命令行的换行符
例子:iotek为用户
env //查看当前所有的环境变量
less /etc/bash.bashrc //查看配置文件
less /etc/profile //全局环境变量
less ~/.profile //自己的环境变量
less ~/.bashrc
vim ~/.bashrc
添加PS1='\u@\w\$:'
tail ~/.bashrc
. ~/.bashrc
echo $PS1 //查看变量
export PS1 //导出变量
bash //新建一个Shell
· echo $PATH //显示当前系统环境变量
/bin/ls
cp /bin/ls ils
ls -l ils
ils //此时不能运行ils
pwd
/home/iotek/ils //此时可以运行ils
./ils //此时可以运行ils
PATH=/home/iotek:$(PATH)//添加环境变量
echo $(PATH)
ils //此时可以运行ils
echo $PS1
PS1='\u:@\$' //\u表示当前用户
echo $PS2
ls -l \ //换行符
test* //显示test*
预定义变量
预定义变量是由Shell程序提供的内置变量
用来存储Shell程序运行过程中的状态信息
预定义变量无需设置,只能引用
$$ //存储当前进程的进程号信息
$0 //存储当前进程的进程名信息
$? //存储当前命令的返回信息
$! //存储最近一个后台进程的进程号信息
例子:
echo $$
echo $0
kill -9 $$ //自杀
echo $$ $0
echo $? //返回0代表成功 非0代表失败
ls -l test* //存在test.c
echo $?
ls -l 5641456 //不存在5641456
echo $?
sleep 1000& //发送到后台 返回序号和进程号
echo &! //查看最近一个后台进程的进程号
kill -9 $! //杀死最近一个后台进程
jobs //查看后台进程
位置变量
位置变量是由Shell程序提供的变量,可用来引用传递给程序的参数
位置变量通过该程序参数在传递给程序时的位置顺序来引用
$1,$2,...$9 //位置变量
shift //位置变量的切取(从前往后切,后面的前移动)
例子:
vim test.txt
//添加ls -ld $1
// ls -l $1
. test.txt /home // . 运算符
. test.txt /home/iotek
vim test.txt
//继续添加ls $2
. test.txt /home/iotek/new /var
ls /var
vim test.txt
//继续添加(在ls $2的前面添加)shift
. test.txt /home /var
. test.txt /home /usr /var
管道与重定向
1. 标准设备文件
stdin //标准输入设备文件为/dev/stdin,文件描述符为0
stdout //标准输出设备文件为/dev/stdout,文件描述符为1
stderr //标准错误设备文件为/dev/stderr,文件描述符为2
例子:
ls /dev/std //查看标准设备文件
ls -l //查看当前目录详细信息 stdout 1
ls -l ffffff //无此文件 stderr 2
2. 管道
管道是系统提供的用于命令间传递信息的设备
管道的信息传递是由前往后单向的传递
管道仅将前一命令程序的标准输出传递给后一命令
| //管道符 | 来进行管道操作
| | //管道的级联
例子:
ps aux
ps aux | grep "bash"
ps aux | grep "bash" | grep -v "grep"
ls -l ned nnn | grep test //在存在的ned文件和不存在的nnn文件中查找test
3. 重定向
重定向是指将原本关联输入或输出到标准设备文件的信息重新定向到指定的磁盘文件的举措
> //标准输出的覆盖重定向
>> //标准输出的追加重定向
2> //标准出错的覆盖重定向
2>> //标准出错的追加重定向
&> //合并重定向是指合并标准输出和标准错误的信息输出
< //标准输入重定向
<< //here document技术
例子:
ls -l
ls -l >output.txt //标准输出的覆盖重定向
less output.txt
ls -l fffff 2>output.txt //文件fffff不存在,标准出错的覆盖重定向
less output.txt
ls -l fffff 2>>output.txt` //文件fffff不存在,标准出错的追加重定向
less output.txt
ls -l >>output.txt //标准输出的追加重定向
head output.txt
cat
Ctrl d //结束
cat
4. 管道与重定向的应用
管道过滤信息的重定向输出
重定向拷贝文件
here document使用
例子:
ls -l
ls -l | grep bencai >output.txt //管道过滤信息的重定向输出
head output.txt
cat
Shell脚本
1. 脚本的概述
脚本是指以解释执行方式的程序语句集合体
脚本用途:批量的顺序处理命令语句以实现命令应用需求
非交互式的命令使用方式可以提升命令执行效率
脚本使用:脚本文件的合法编写是脚本使用的程序基础
脚本文件的正确执行是脚本使用的运行实例
2. 脚本的控制结构
程序的控制结构使得程序语句的执行顺序能有条件的智能改变
控制结构有顺序结构、分支结构和循环结构
例子:顺序
vim test.sh
ls -l /home
echo "hello"
echo $0 $$
. test.sh //脚本放到当前Shell测试运行
echo $0 $$
chmod u+x test.sh //为脚本test.sh添加可执行权限
./test.sh //执行test.sh,和当前Shell无关
/hoem/test.sh //全路径运行
例子:分支
&& || //符合级联,0表示成功,1表示失败
if-else
case //多值分支
/*级联方式*/
ls -l test01.sh //假设此时test01.sh有可执行权限
vim test.sh
test -x test01.sh && echo "ok" || echo "failure"
./test.sh //运行,测试可执行权限
/*if-else方式*/
vim test.sh
if [ -x test2.sh] //测试可执行权限
或if [ -x $1] //$1为位置变量
then
echo "ok"
elif [ -x $2];then
echo "$2 exectable"
else
echo "fail"
fi
./test.sh test3.sh test.sh
/*case方式*/
vim test.sh
Value=$3
case $Value in
a)
echo "A"
;;
b)
echo "B"
;;
*) //默认分支
ehco "C"
;;
esac
./test.sh test3.sh test.sh a //运行
循环结构根据条件判断的真假来确定是否执行循环体内的语句
循环结构的实现方式
while 语句 //条件为真执行循环体
until语句 //条件为假执行循环体
for-in语句
例子:
/*while 语句*/
vim test.sh
Count=1
while [ -x $1 ] //条件为真执行,-x表示可执行,$1表示位置变量
do
[ $Count -ge 5 ] && break //-le表示小于等于,-ge表示大于等于,&&表示那么
echo "running..."
let Count++
done
ls -l test.sh
chmod u+x test.sh //加上可执行权限
./test.sh test.sh
/*until 语句*/
vim test.sh
Count=1
until [ -x $1 ] //条件为假执行,-x表示可执行,$1表示位置变量
do
[ $Count -ge 5 ] && break //-le表示小于等于,-ge表示大于等于,&&表示那么
echo "running..."
let Count++
done
ls -l test.sh
chmod u+x test.sh //加上可执行权限
./test.sh test0.sh
/*for-in 语句*/
vim test.sh
Count=1
for Var in aa bb cc dd
do
echo "loop $Count"
echo "$Var running..."
let Count++
done
./test.sh
3. 脚本的使用示例
例子:
脚本程序需求:
从给定的自然数开始,循环输出10个数,其皆为3的倍数
脚本实现要求:
程序设计中包含输入的友好提示和对于输入合法性的验证判断
输出: 10个数,皆为3的倍数
输入:某个给定自然数
处理:算法实现需求
1接收输入 //输入格式(友好)
//输入检查(合法)
2筛选10个数 //从给定自然数 开始
//至10个3的倍数 结束
两个技术 //循环计数
//取余算法 //为0 3倍数
//非0 非3倍数
3输出(人性化)
vi suanshu.sh
read -p "请输入一个自然数:" Input //read输入 -p提示 Input变量
if [ $Input -gt 0 ] 2>/dev/null ;then //2>/dev/null异常重定向到(无底洞)
echo "你输入的是自然数,从自然数开始的10个3的倍数为" //-gt大于 ||假
else
echo "你输入的不是自然数,程序异常退出。"
exit
fi
Count=0
Num=$Input
while [ $Count -lt 10 ]
do
let Num2=$Num%3
if [ $Num2 -eq 0 ] ;then //-eq等于
echo "$Num"
let Count++
fi
let Num++
done
chmod u+x xuanshu.sh
./xuanshu.sh
Shell脚本的高级主题
1. Shell函数
例子:
vim test.sh
hello() //函数定义方式1
{
echo "hello"
}
function nihao() //函数定义方式2
{
echo "$1 你好" //$1位置变量来传参
echo "nihao"
}
hello //函数调用
nihao 歌 //函数调用,“歌”传参
或nihao $1 取 //$1 取 两个合并成$1传递进函数
chmod u+x test.sh //添加可执行权限
./test.sh
Shell函数的参数传递
Shell脚本的函数参数依靠位置变量来传递
function nihao(){
echo $1 "你好" //$1位置变量
}
Shell脚本的函数参数传递时按顺序书写在函数名的后面即可
nihao 你好
2. Shell变量的替换
缺省替换:${Var:-value}
若Var变量未被设置,则临时设值为value
强制替换:${Var:+value}
若Var变量已被设置,则临时设值为value,没设置为空
例子:
echo ${Day:-sunday} //临时sunday
echo $Day //空
echo ${Day:+monday} //空
Day=saturday
echo ${Day:+monday} //临时monday
echo $Day //saturday
缺省赋值替换:${Var:=value}
若Var变量未被设置,则永久设值为value
缺值错误替换:${Var:?string}
若Var变量未被设置,则错误输出为string
例子:
unset Today //删除一个变量
echo $Today //空
echo ${Today:=friday} //friday
echo $Today //friday
unset Torrow
echo ${Torrow:?"no set value"} //bash:Torrow:no set value
Torrow=sunday
echo ${Torrow:?"no set value"} //sunday
单次匹配替换${Var/pattern/string}
若Var变量匹配pattern存在,则单次替换输出为string
全局匹配替换${Var//patter/string}
若Var变量匹配pattern多次,则全部替换输出为string
例子:
unset Torrow
Torrow=sunday
echo $Torrow //sunday
echo ${Torrow/sun/Sun} //单个临时替换Sunday
echo $Torrow //sunday
Torrow=${Torrow}sunday
echo $Torrow //sundaysunday
echo ${Torrow/sun/Sun} //单个临时替换Sundaysunday
echo ${Torrow/sun/Sun} //全局临时替换SundaySunday
案例讲解
实现猜拳游戏的脚本程序设计
案例介绍:
用脚本实现游戏:
石头,剪刀和布PK,三局两胜
案例设计:
循环接受用户的“出招”输入;
比较判断胜方为用户还是电脑,并输出胜方;
统计胜利次数,率先赢得两次,即最终或胜。
Input()
{
while : // : 表示空语句
do
echo "请输入剪刀(J),石头(S)或布(B)"
read Choice
case $Choice in
J | j )
echo -n "你选择的是\"$Choice\"剪刀,"
userChoice=0
break
;;
S | s )
echo -n "你选择的是\"$Choice\"石头,"
userChoice=1
break
;;
B | b )
echo -n "你选择的是\"$Choice\"布匹"
userChoice=2
break
;;
esac
done
}
function Judge()
{
let Num=$RANDOM%3
[ $Num -eq 0 ] && echo "电脑选择的是\"J\"剪刀"
[ $Num -eq 1 ] && echo "电脑选择的是\"S\"石头"
[ $Num -eq 2 ] && echo "电脑选择的是\"B\"布匹"
let ${User:=0}; let ${Comp:=0}
if [ $1 -eq $Num ];then
echo "本局平局!"
elif [ $1 -eq 0 ];then
if [ $Num -eq 2 ];then
echo "本局你赢了!";let User++
else
echo "本局你输了!";let Comp++
fi
elif [ $Num -eq 0 ];then
if [ $1 -eq 2 ];then
echo "本局你输了!";let Comp++
else
echo "本局你赢了!";let User++
fi
elif [ $1 -gt $Num ];then
echo "本局你赢!";let User++
else
echo "本局你输!";let Comp++
fi
}
clear;echo "欢迎来到剪刀石头布游戏!"
sleep 2;User=0;Comp=0;Round=1
while [ $Round -le 3 ] ;do
sleep 2;clear
echo ">> 剪刀 石头 布 第$Round回合比赛<<"
Input
Judge $userChoice
let Round++
[ $User -ge 2 ] && echo "恭喜,你赢了整个比赛!"\
&& exit
[$ Comp -ge 2 ] && echo "遗憾,电脑赢得整个比赛!"\
&& exit
done
echo "不错,你平了整个比赛。"