shell简介
shell 与内核沟通的界面、应用程序等。用于将用户操作传递给内核执行。
shell是面向过程 的若类型的解释性语言,不需要编译即可直接执行,常用于作脚本
Linux中的shell
在/etc/shells文件中 存储Linux包含的shell。
最常用的是bash,tcsh,csh,sh,nologin等shell
bash 基于GNU框架下发展出的shell
csh c语言语法的shell
tcsh 整合csh,有更多功能
sh 已被bash替代
nologin 可以让用户无法登录主机
/bin/bash是大多数Linux版本采用的默认shell
为什么系统上合法的shell要写入shells这个文件?
因为系统会检查那些用户能够使用shell,而这些shell的查询就是藉由/etc/shells文件
用户什么时候可以取得shell来工作?用户默认获得哪一个shell?
用户登录时,系统就会给一个shell使用,给的哪个shell根据/etc/passwd文件的设置。
编写shell脚本的规范
1)脚本声明 #!/bin/bash
2)注释信息 行首以#号开头定义注释信息,被注释的行内容将不会被执行
3)可执行语句 编写要执行的脚本代码,如echo命令,输出“ ”之间的字符串vim /root/firsh.sh #!/bin/bash cd /boot echo "当前目录位于" pwd echo "vml开头文件包括" ls -lh vml*
运行shell脚本
1)用绝对/相对路径指定脚本文件运行,需要执行用户拥有执行权限x
脚本会在子shell环境中运行
chmod +x /root/first.sh #指定绝对路径 /root/first.sh #指定相对路径 ./first.sh
2)用 bash/sh 程序指定脚本文件运行,不需要执行权限
脚本会在子shell环境中运行
#指定shell解释脚本 sh first.sh bash first.sh
3)用 source/. 指定脚本文件运行脚本会在当前shell环境中运行(会影响当前所在目录、变量的值 等因素)
#通过source运行 source first.sh . first.sh
重定向与管道操作
重定向
标准输入 /dev/stdin 0 默认设备为键盘 标准输出 /dev/stdout 1 默认设备为屏幕 标准错误输出 /dev/stderr 2 默认设备为屏幕
重定向输入 < 从文件读取数据,而不是键盘 重定向输出 >
>>
输出正常信息到文件中,并覆盖原内容
输出正常信息到文件中,从源文件内容追加内容
重定向错误输出 2>
2>>
输出错误信息到文件中,并覆盖原内容
输出错误信息到文件中,从源文件内容追加内容
混合输出 &>
&>>
2>&1
输出正常和错误信息到文件中,并覆盖原内容
输出正常和错误信息到文件中,从源文件内容追加内容
输出正常和错误信息到文件中,并覆盖原内容
输出正常信息到文件中 echo 'abc' > 1.txt #覆盖内容 echo 'abc' >> 1.txt #追加内容 [root@xue xue]# cat 1.txt abc 输出错误信息到文件中 qwerfdaszecho 'abc' 2> 1.txt #覆盖错误内容 qweasdzccecho 'abc' 2>> 1.txt #追加错误内容 [root@xue xue] cat 1.txt bash: qwerfdaszecho: 未找到命令... 混合输出 正确和错误都会输出 echo 'abc' &> 1.txt #覆盖内容 echo 'abc' &>> 1.txt #追加内容 echo 'abc' > 1.txt 2>&1 #覆盖内容 echo 'abc' >> 1.txt 2>&1 #追加内容
ls -lh > log.txt 2>&1 等于 ls -lh &> log.txt
本来1--->屏幕,执行>log后,输出到屏幕的数据重定向到log.txt。随后又执行了2>&1,2的错误数据重定向到1,而1指向log.txt,于是正确与错误一同混合输入log.txt
管道符号 |将左侧命令结果作为右侧命令的输入
ps aux | wc -l #统计进程 echo 'abc123' | passwd --stdin zhangsan #管道符号输入的字符通过标准输入转换免交互设置密码 find -name 123 type -f | xargs rm -r #若右边命令需要参数运行,需要加上xargs #找名称带有123的文件删除
变量
定义变量
- 变量名=变量的值
- read [-p "提示信息"] 变量名 (从键盘输入获取值赋给变量)
NAME=xue read -p "输入年龄" AGE
输出变量值
echo $NAME $AGE echo $NAME$AGE #echo $NAMEAGE 错误写法,会认为变量为NAMEAGE echo ${NAME}${AGE}
引号的使用
双引号: 会把 $ 当作特殊符号去引用变量的值
单引号: 会把 $ 等特殊符号是为普通字符去使用
反撇号: 获取里面的命令执行后的输出结果,`...` 等同于 $(...)echo "$NAME" echo '$NAME' echo `which mkdir` echo $(which mkdir) ldd `which sshd`
局部变量 全局变量
普通的变量赋值都为局部变量 如果需要设置全局变量,使用export
export abc export abc=123
注意 重启后全局变量会失效。若是设置永久全局变量,设置/etc/profile
vim /etc/profile export abc=123
shell整数运算
加法 +
减法 -
乘法 \*
除法 /
求余 %
expr
expr 变量1 运算符 变量2 expr 10 - 5 a=10 b=5 expr $a - $b #变量运算
echo输出结果的三种写法
echo $(expr 10 + 20) echo $((10 + 20)) echo $[10 + 20]
let
let i=10+20 echo $i let i++ i-- 相当于 i=$[i + 1] 或 $[i - 1] i+=2 i-=2 相当于 i=$[i + 2] 或 $[i - 2]
特殊的变量
PATH 系统命令搜索路径
echo $PATH
若需要添加自定义的脚本,在bash中可以直接调用
方法1 创建软链接/user/local/bin/
ln -s /opt/* /user/local/bin/ #创建软链接 #将opt文件夹的所有文件在bin中创建软链接
方法2 将环境变量写入/etc/profile
vim /etc/profile export PATH=$PATH:/opt #$PATH:/opt 前面的path表示路径中的其他文件,再冒号分隔加上opt中的文件
若没有加前面的path导致全部指令都不能使用,可以指定绝对路径访问命令再修改回来
PWD 当前所在目录
pwd echo $PWD
USER 当前登录用户
echo $USER
HOME 当前登录用户的家目录
echo $HOME
SHELL 当前登录用户的shell环境
echo $SHELL
LANG 当前系统的语言和字符集编码
echo $LANG
HISTSIZE 历史命令条数
echo $HISTSIZE
env 查看当前系统环境变量
env
只读变量
变量不允许被修改,只有关机才能清除变量。
name=xue readonly name name=xuexue #不能重新赋值 unset name #不能被删除
位置变量
vim 1.sh echo $0 echo $1 #显示命令中第一个变量 echo $2 #显示命令中第二个变量 echo $3 #显示命令中第三个变量 echo $4 echo $5 echo $6 echo $7 echo $8 echo $9 echo $10 #显示命令中第1个变量,后面加上0。不是个位数都需要按下面加上大括号 echo ${10} #显示命令中第10个变量
chmod +x ./1.sh #脚本添加权限 ./1.sh 1 2 3 4 5 6 7 8 9 10 #调用观察结果
$1 ~ $9 第一个到第九个位置变量,代表脚本后面跟的以空格相间隔的参数
${10} 第十个位置变量$0 代表脚本本身
$# 代表脚本后面跟的以空格相间隔的参数的数量
$? 代表上一条命令执行是否正常/成功,命令执行正常返回0,非0值均代表命令执行异常$* 不加双引号时,代表脚本后面跟的以空格相间隔的所有参数;加上双引号后,会把脚本后面跟的以空格相间隔的所有参数当作一个整体
$@ 不加双引号时,代表脚本后面跟的以空格相间隔的所有参数;加上双引号后,效果不变,仍然会把每个参数当作一个个体vim addnum.sh #通过位置变量完成数字相加 num1=$1 num2=$2 sum=$(($num1+$num2)) echo $num ./addnum.sh 12 34 $0 $1 $2
预定义变量
$* $@
无" "
$* $@ 都表示命令与脚本要处理的参数
有" "
''$*'' 把所有参数看成以空格分隔的一个字符串整体(单字符串)返回,代表"$1 $2 $3 $4”。
''$@'' 把各个参数加上双引号分隔成n份的参数列表,每个参数作为一个字符串返回,代表"$1" "$2" "$3" "$4"
$0: 表示当前执行的脚本或命令的名称。
$#: 表示命令或脚本要处理的参数的个数。(当前脚本有x个参数)
$?:表示前一条命令或脚本执行后的返回状态码,返回值为0表示执行正确,返回任何非0值均表示执行出现异常。也常被用于shell脚本中return退出函数并返回的退出值。
vim mybak.sh #!/bin/bash time=backup-`date +%F`.tgz tar zcf $time $* & > /dev/nul #/dev/null表示的是一个黑洞文件,通常用于丢弃不需要的数据输出 echo"已执行 $0 脚本," echo"共完成 $# 个对象的备份" echo"具体内容包括: $*" chmod +x mybak.sh ./mybak.sh /etc/passwd /etc/shadow