shell就是人机交互的接口,不只是命令行,windows的鼠标操作双击,等等也是shell。
是一种解释器,将人输入的和做的操作解释给内核。
查看支持的shell
[root@www gsc-test]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
一般情况下:
linux系统默认使用的是/bin/bash
unix系统默认使用的是/bin/ksh
修改用户的shell可以:
1、进入passwd文件修改。重新登录动作生效。
2、usermod -s 可以修改用户的shell
3、chsh 命令,修改使用的shell,不同的shell有不同的语法和操作。如果发现正确的命令不能使用,要确定软件是否安装,确定安装并且在$PATH中有命令,那大概就是shell 的问题 了。
环境变量:
对于计算机或者进程来说,环境就是指你使用的变量、打开的文件、使用的函数、当前路径、资源限制等等
用户可以自己搭建自己的环境变量。
通过以下几个文件:
/etc/profile
/etc/bashrc
用户家目录/.bashrc
用户家目录/.bashrc_profile
/etc/profile.d/*.sh
在这里 环境变量和PATH变量有区别:
$PATH变量是几个目录。
/usr/local/sbin ; /usr/local/bin ;/usr/sbin; /usr/bin; /root/bin
在这些目录下的命令才能直接执行,否则要加上目录。
登录shell和非登录shell
登录shell:/bin/bash ; /bin/csh ; /bin/dash ;/bin/ksh ; /bin/sh ;/bin/tcsh.
非登录shell :不能登录的shell /sbin/nologin
完全登陆shell和非完全登陆shell:
完全登陆shell,su - username 和登录操作,都是完全登陆shell,这时加载了上边说的所有配置文件。
非完全登陆shell,su username 没有读取所有的配置文件。借助了别人的环境。
一、shell变量
变量就是用一个特定的字符表示不固定的内容。
自定义变量
自定义变量:变量名=变量值。
引用变量:$变量名 或者 ${变量名}
查看变量:echo $变量名 或者 set
取消变量:unset 变量名
变量是有作用范围的,正常的变量只在当前shell有效。
如果发布变量 export 变量名
或者 export 变量名=变量值
发布之后变量就可以在当前shell和 子shell中使用。
变量一般都是在脚本中使用的,在配置文件中不能使用。
环境变量:
定义环境变量 export 变量名 ; export 变量名=变量值。
引用环境变量:$变量名 ${变量名}
查看环境变量:echo $变量名 env
取消环境变量:unset
变量作用范围 当前shell和子shell
如果想让变量在shell永久生效或者所有用户生效,就要写在配置文件中,这个 /etc/profile配置文件 。
位置变量:
$1 、 $2 、 $3 、$4 、$5 、$6 、$7 、$8 、$9 、 ${10}。
位置变量表示的是在命令中参数的位置。
${10} 要加括号 否则表示的是$1 后边加上0。
栗子:
[root@www gsc-test]# cat testlocal.sh
#!/bin/bash
echo "one $2"
echo "two $1"
echo "three $3"
echo "all $@"
echo "all2 $*"
echo "number $#"
sum=$(expr $4 + $5)
echo "$4 + $5 = $sum"
[root@www gsc-test]# ./testlocal.sh 1 2 3 4 5
one 2
two 1
three 3
all 1 2 3 4 5
all2 1 2 3 4 5
number 5
4 + 5 = 9
[root@www gsc-test]#
另外还有几个系统预制的变量:
$0 表示脚本名。
$* 所有参数
$@ 所有参数
$# 参数的个数
$! 上一个参数的后台PID
$? 上一个命令的返回值 如果为0 则表示执行成功,非零就是有问题。
$$ 当前进程的PID
栗子:
[root@www gsc-test]# ./testlocal.sh 1 2 3 4 5 6
one 2
two 1
three 3
$0 表示脚本本身:./testlocal.sh
$* 表示所有参数:1 2 3 4 5 6
$@ 表示所有参数:1 2 3 4 5 6
$# 表示参数个数:6
$! 表示上一个参数的后台PID:
$? 表示上一个命令的返回值:0
$$ 表示前进程PID:1633
[root@www gsc-test]# cat ./testlocal.sh
#!/bin/bash
echo "one $2"
echo "two $1"
echo "three $3"
echo '$0 表示脚本本身:'$0
echo '$* 表示所有参数:'$*
echo '$@ 表示所有参数:'$@
echo '$# 表示参数个数:'$#
echo '$! 表示上一个参数的后台PID:'$!
echo '$? 表示上一个命令的返回值:'$?
echo '$$ 表示前进程PID:'$$
二、变量的赋值:
显式赋值:
变量名 = 变量值
注意中间没有空格
[root@www gsc-test]# shsh=hjkl
[root@www gsc-test]# echo $shsh
hjkl
从键盘输入赋值:
read 变量名。
两种方式等价
read -s
-s选项是 使输入的内容无回显,用于保密内容的输入,比如密码。
[root@www gsc-test]# cat readsomething.sh
#!/bin/bash
#########-----1
read -p "文件名:" name
id $name
#########-----2
echo "输入名字:"
read name
id $name
[root@www gsc-test]# ./readsomething.sh
文件名:44444
id: 44444: no such user
输入名字:
root
uid=0(root) gid=0(root) groups=0(root)
read -t 5 表示5秒内不操作便继续执行。
read -n 4 表示变量数量。
“” 双引号,弱引用,在引用时会引用变量。
‘’ 单引号,强引用,引用时不获取信息,直接原样输出。
`` 反引号, 反引号内优先执行。
三、变量运算
shell做复杂运算很困难,最好别这么用
1、整数运算。
expr 1 + 2
expr $num1 + $num2
[root@www shell]# expr 1 + 2
3
//注意空格。
[root@www shell]# cat math.sh
#!/bin/bash
#expr 1 + 2
read sum1
read sum2
expr $sum1 + $sum2
[root@www shell]# sh math.sh
3
65
68
$ (($num1 + $num2))
[root@www shell]# echo $((1+2))
3
$[ 4+2]
[root@www shell]# echo $[1+2]
3
let sum=1+3 ;echo $sum
[root@www shell]# let ddd=1+3
[root@www shell]# echo $ddd
4
let i++
i++自增运算,加号在后表示先赋值在运算,加号在前表示先运算在赋值。
[root@www shell]# let i=i++
[root@www shell]# echo $i
1
[root@www shell]# let i=++i
[root@www shell]# echo $i
2
2、小数运算
echo “2*4” | bc
echo “3^5” | bc
echo " scale = 2;6/4" | bc
[root@www shell]# yum provides "bc"
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
bc-1.06.95-13.el7.x86_64 : GNU's bc (a numeric processing language) and dc (a calculator)
Repo : mnt-CentOS7iso
[root@www shell]# echo "2*4"| bc
8
[root@www shell]# echo "3^5" | bc
243
[root@www shell]# echo "3/10"| bc
0
[root@www shell]# echo "6/4" | bc
1
[root@www shell]# echo "scale=2;6/4" | bc
1.50
[root@www shell]# echo "scale=5;6/4" | bc
1.50000
变量内容的删除和替换
[root@www shell]# url=www.baidu.com.cn
[root@www shell]# echo $url
www.baidu.com.cn
[root@www shell]# echo ${#url}
16
//前边井号输出长度。
[root@www shell]# echo ${url#*.}
baidu.com.cn
//这个表示从前边截取。到第一个匹配的就截掉。
[root@www shell]# echo ${#url*.}
-bash: ${#url*.}: bad substitution
[root@www shell]# echo ${url##*.}
cn
//贪婪截取,同上,只不过截取的是最长的。
[root@www shell]# echo ${url%.*}
www.baidu.com
//%是从后边截取,与井号正好相反。
[root@www shell]# echo ${url%%.*}
www
//贪婪截取
[root@www shell]# echo ${url%%c*}
www.baidu.
//这个只是为了说是按照字符串匹配,不在乎含义
[root@www shell]# echo ${url%d*}
www.bai
[root@www shell]# echo ${url%c*}
www.baidu.com.
[root@www shell]# echo ${url:2:3}
w.b
//从第二个位置开始截取 截取三个。起点是0.1.2.3.4......
[root@www shell]# echo ${url/baidu/souhu}
www.souhu.com.cn
//替换,和文本编辑类似。这样替换只换第一个
[root@www shell]# echo ${url/w/n}
nww.baidu.com.cn
[root@www shell]# echo ${url//w/n}
nnn.baidu.com.cn
//贪婪替换,双斜杠,替换所有能匹配的
[root@www shell]# unset var //取消赋值
[root@www shell]# echo $var //没有输出
[root@www shell]# echo ${var-aaaa} //如果没有赋值就输出后边的值。
aaaa
[root@www shell]# var= //赋空值
[root@www shell]# echo $var
[root@www shell]# echo ${var-aaaa} //空值也是赋值
这种的写法只有在没有赋值是使用,有赋值 哪怕为空 ,也不使用。
四、变量的条件测试
格式1:条件表达式。
格式2: [条件表达式]
格式3:[[条件表达式]]
man test
文件测试:
[root@www ~]# test -d /etc //判断目录是否存在
[root@www ~]# echo $?
0
[root@www ~]# [ -d /etc ]
[ -d dir ]目录是否存在
[ -f file ] 文件是否存在
[ -r file ] 用户对文件是否有读权限
[ -x file ] 执行
[ -w file ] 写
[ -s file ] 判断文件是否为空
[ -e file ] 如果文件存在,则为真
[ -L file ] 如果文件为符号链接,则为真
[ -h file ] 如果文件是软链接,则为真
数值比较
整数 1 操作符 整数2
[ 1 -gt 10 ] 大于
[ 1 -lt 10 ] 小于
[ 1 -eq 10 ] 等于
[ 1 -ne 10 ] 不等于
[ 1 -ge 10 ] 大于等于
[ 1 -le 10 ] 小于等于
另一种方式,个人觉得没有上一种方便
((1<2)) ; echo $?
((1==2)) ; echo $?
((1>2)) ; echo $?
((1>=2)) ; echo $?
((1<=2)) ; echo $?
((1!=2)) ; echo $?
((`id -u` >0)) ; echo $?
(($(id -u)==0 )) ; echo $?
字符串比较
[root@www ~]# [ "$USER" == "root" ] ; echo $?
[root@www ~]# aaa=""
[root@www ~]# echo $aaa
[root@www ~]# [ -z "$aaa" ] 字符长度为0
[root@www ~]# [ -n "$aaa" ] 字符长度不为0
[root@www ~]#
字符串为空或者未定义 长度都为0
sss定义为sss ddd定义为空 fff 不定义
发现
-z 判断字符串为空,如果真的是空字符串,返回0 ,也就是正确输出。
-n 判断字符串不为空,如果为空返回非0 ,错误输出,如果不为空,返回0 ,正确输出。
[root@www shell]# sss="sss"
[root@www shell]# ddd=""
[root@www shell]#
[root@www shell]# echo $sss
sss
[root@www shell]# echo $ddd
[root@www shell]# echo $fff
[root@www shell]# [ -z "$sss" ] ;echo $?
1
[root@www shell]# [ -z "$ddd" ] ;echo $?
0
[root@www shell]# [ -z "$fff" ] ;echo $?
0
[root@www shell]# [ -f "$sss" ] ;echo $?
1
[root@www shell]# [ -f "$ddd" ] ;echo $?
1
[root@www shell]# [ -n "$sss" ] ;echo $?
0
[root@www shell]# [ -n "$ddd" ] ;echo $?
1
[root@www shell]# [ -n "$fff" ] ;echo $?
1
五、流程控制 if
if
条件测试
then
命令序列
elif
条件测试
then
命令序列
else
命令序列
fi
多重条件判断:
-a 与 &&
-o 或 ||
! 非
#!/bin/bash
read -p "请输入成绩: " s
if
[ $s -gt 100 -o $s -lt 0 ] //逻辑判断这样就好了。
then
echo "不合理成绩。"
exit
elif
[ $s -ge 90 ]
then
echo "优秀"
elif
[ $s -ge 80 ]
then
echo "良好"
elif
[ $s -ge 70 ]
then
echo "一般"
elif
[ $s -ge 60 ]
then
echo "及格"
else
echo "不及格"
fi
六、选取、排序、去重
cut 选取一个或者多个区域打印,不影响源文件
-d :指定分隔符 delimiter :分隔符
-f :指定要输出的字段 field : 区域、字段
[root@www gsc-test]# cut /etc/passwd -d: -f7
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
/sbin/shutdown
/sbin/halt
/sbin/nologin
sort 排序
-t :制定字段分隔符
-n :按照数字排序
-k 数字:指定按第几个字段排序
-r :倒叙
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
squid:x:23:23::/var/spool/squid:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
uniq 去重
只能取出相邻行,所以一般先排序,在去重
-c 显示重复行的数量。
[root@www gsc-test]# cat num.txt
111
222
111
222
111
222
111
222
111
222
333
444
333
444
333
444
333
444
[root@www gsc-test]# uniq num.txt -c
1 111
1 222
1 111
1 222
1 111
1 222
1 111
1 222
1 111
1 222
1 333
1 444
1 333
1 444
1 333
1 444
1 333
1 444