shell编程基础(实用)及常用linux命令

变量的声明
x=5
echo $x ---》输出5
z=$x+6
echo $z ---》输出5+6
变量的叠加:
x=123
y="$x"456
echo $y --->输出123456

set可以查看系统下所有已经生效的变量:包括系统的和认为定义的变量。

set -u
echo $a ----->输出空格或者空
如果提前输入set -u
再输入echo $a -----》调用未声明的变量时会报错。

unset 变量名 删除变量
unset name 不加$,因为删除的是变量而不是变量的值。

环境变量:
环境变量与用户自定义变量的区别?
用户自定义变量只在当前的Shell中生效
环境变量在当前Shell和这个Shell的所有子Shell中生效
环境变量是全局变量
用户自定义变量是局部变量

在当前shell中输入bash进入子shell
可以输入pstree 查看进程树:就可以看到两个bash,这说明有一个当前shell,另一个是子shell。
从子shell退出到当前shell,输入exit

对系统生效的环境变量名和变量作用是固定的。

设置环境变量:
export 变量名 变量值
或者变量名 变量值
export 变量名

查看所有变量:
set:查看所有变量
env:查看环境变量
删除环境变量:
unset 变量名

建议环境变量名字写成大写,主要是和命令区分,因为linux的命令都是小写。

常用环境变量:
HOSTNAME:主机名
SHELL:当前的shell
TERM:中断环境
HISTSIZE:历史命令条数
SSH_CLIENT:当前操作环境是用ssh连接的,这里记录客户端ip
SSH_TTY:ssh连接的终端时pts/1
USER:当前登录的用户

所有linux脚本必须以#!/bin/bash开头。然后再去定义变量。

PATH环境变量:
PATH变量:系统查找命令的路径
echo $PATH
#查看PATH环境变量
PATH="$PATH":/root/sh
#增加PATH变量的值

PS1环境变量:
PS1变量:命令提示符设置
\d:显示日期,格式为“星期 月 日”
\H:显示完整的主机名。如默认主机名“localhost.localdomain”
\t:显示24小时制时间,格式为"HH:MM:SS"
\A:显示24小时制时间,格式为"HH:MM"
\u:显示当前用户名
\w:显示当前所在目录的完整名称
\W:显示当前所在目录的最后一个目录
\$:提示符。如果是root用户会显示提示符为"#",如果是普通用户会显示提示符为"$"
例如:[root@iZ2ze57xep3rm7w9t2l85cZ src]# PS1='[\u@\A \w]\$ '
执行:[root@09:57 /usr/local/src]#
只对当前生效,重启恢复为:[root@iZ2ze57xep3rm7w9t2l85cZ logs]#
执行:echo $PS1
输出:[\u@\h \W]\$ 即为原来定义的PS1
ls \:换行,默认还没有输入完。

语系变量:当前语系查询。
locale:查看语系。
输入:locale
输出:[root@09:57 /usr/local/src]# locale
LANG=en_US.UTF-8 :美系语言版本。
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
统计分支大小命令:df -h
输出:[root@iZ2ze57xep3rm7w9t2l85cZ src] df -h
Filesystem Size Used Avail Use% Mounted on :如果是中文语系,这一行会有中文显示。
/dev/vda1 40G 4.8G 33G 13% /
devtmpfs 486M 0 486M 0% /dev
tmpfs 496M 0 496M 0% /dev/shm
tmpfs 496M 452K 496M 1% /run
tmpfs 496M 0 496M 0% /sys/fs/cgroup
tmpfs 100M 0 100M 0% /run/user/0

LANG:定义系统主语系的变量
查看系统当前语系:echo $LANG
查看Linux支持的所有语系:locale -a | more
LC_ALL:定义整体语系的变量

cat /etc/sysconfig/i18n :Linux一切皆文件,放在文件里的即为永久有效的。这里的语系即为当前linux语系,且重启或者下次开机仍为这里配置的语系。

位置参数变量:
$n:n为数字,$0代表命令本身,$1-$9代表第一到第九个参数,十以上的参数需要用大括号包括如${10}
例子1:
#!/bin/bash
num1=$1
num2=$2
sum=$(($num1+$num2)) #num1的值时$1,num2的值是$2
echo $sum :打印变量sum的值
执行去赋予权限:chmod 755 **.sh
1.文件所有者可读可写可执行 6:可读可写
2.与文件所有者同属一个用户组的其他用户可读可执行
3.其它用户组可读可执行
执行:./**.sh 10 11
输出:21
以上适合开发者使用,不适合第三方使用。
$*:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体
$@:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待
$#:这个变量代表命令行中所有参数的个数

for x in "$*"
do
echo $x
done

for y in "$@"
do
echo $y
done
[root@iZ2ze57xep3rm7w9t2l85cZ local]# chmod 755 zhaopeng.sh
[root@iZ2ze57xep3rm7w9t2l85cZ local]# ./zhaopeng.sh 1 2 3
1 2 3
1
2
3
假设$*有四个数字,那么把四个数字看成一个整体,所以只有一次循环
而$@会有4次循环。

预定义变量:
$?:最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。
$$:当前进程的进程号(PID)
$!:后台运行的最后一个进程的进程号(PID)

接受键盘输入:read
read [选项] [变量名]
选项:
-p "提示信息":在等待read输入时,输出提示信息
-t 秒数:read命令会一直等待用户输入,使用此选项可以指定等待时间
-n 字符数:read命令只接受指定的字符数,就会执行
-s :隐藏输入的数据,适用于机密信息的输入
写一个脚本read.sh:
#!/bin/bash
read -p "please input your name: " -t 30 name
echo $name
执行时输出:please input your name: 123
123
如果等待30秒还没有输入,系统自动结束脚本命令。
read -p "please input your passwd: " -s password
echo -e "\n" :换行
echo $password
执行时输出:在输入时不会显示密码明文。

read -p "please input your sex [M/F]: " -n 1 sex :只允许输入一个字符。M或者N
echo -e "\n" :换行
echo $sex

按照文件类型进行判断
-b 文件:判断该文件是否存在,并且是否为块设备文件(是块设备文件为真)
-c 文件:判断该文件是否存在,并且是否为字符设备文件(是字符设备文件为真)
-d 文件:判断该文件是否存在,并且是否为目录文件(是目录为真) 常用
-e 文件:判断该文件是否存在(存在为真) 常用
-f 文件:判断该文件是否存在,并且是否为普通文件(是普通文件为真) 常用
-L 文件:判断该文件是否存在,并且是否为符号链接文件(是符号链接文件为真)
-p 文件:判断改文件是否存在,并且是否为管道文件(是管道文件为真)
-s 文件:判断该文件是否存在,并且是否为非空(非空为真)
-S 文件:判断该文件是否存在,并且是否为套接字文件(是套接字文件为真)
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -e zhaopeng.sh ]
[root@iZ2ze57xep3rm7w9t2l85cZ local]# echo $?
0 为真,存在
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -e zhaopeng.sh ] && echo yes || echo no
yes
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -e zhaopeng1.sh ] && echo yes || echo no
no
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -f zhaopeng.sh ] && echo yes || echo no
yes
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -d zhaopeng.sh ] && echo yes || echo no
no
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -d etc ] && echo yes || echo no
yes

按照文件权限进行判断:
-r 文件:判断该文件是否存在,并且是否该文件拥有读权限(有读权限为真)
-w 文件:判断该文件是否存在,并且是否该文件拥有写权限(有写权限为真)
-x 文件:判断该文件是否存在,并且是否该文件拥有执行权限(有执行权限为真)
-u 文件:判断该文件是否存在,并且是否该文件拥有SUID权限(有SUID权限为真)
-g 文件:判断该文件是否存在,并且是否该文件拥有SGID权限(有SGID权限为真)
-k 文件:判断该文件是否存在,并且是否该文件拥有SBit权限(有SBit权限为真)
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -w zhaopeng.sh ]
[root@iZ2ze57xep3rm7w9t2l85cZ local]# echo $?
0
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -r zhaopeng.sh ]
[root@iZ2ze57xep3rm7w9t2l85cZ local]# echo $?
0
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -x zhaopeng.sh ]
[root@iZ2ze57xep3rm7w9t2l85cZ local]# echo $?
0
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -u zhaopeng.sh ]
[root@iZ2ze57xep3rm7w9t2l85cZ local]# echo $?
1
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -g zhaopeng.sh ]
[root@iZ2ze57xep3rm7w9t2l85cZ local]# echo $?
1
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -k zhaopeng.sh ]
[root@iZ2ze57xep3rm7w9t2l85cZ local]# echo $?
1
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]#
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -w zhaopeng1.sh]
-bash: [: missing `]'
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ -w zhaopeng1.sh ]
[root@iZ2ze57xep3rm7w9t2l85cZ local]# echo $?

两个文件之间进行比较
文件1 -nt 文件2:判断文件1的修改时间是否比文件2的新(如果新则为真)
文件1 -ot 文件2:判断文件1的修改时间是否比文件2的旧(如果旧则为真)
文件1 -ef 文件2:判断文件1是否和文件2的lnode号一致,可以理解为两个文件是否为同一个文件。
这个判断用于判断硬链接是很好的方法

两个整数之间比较:
整数1 -eq 整数2:判断整数1是否和整数2相等(相等为真)
整数1 -ne 整数2:判断整数1是否和整数2不相等(不相等为真)
整数1 -gt 整数2:判断整数1是否大于整数2(大于为真)
整数1 -lt 整数2:判断整数1是否小于整数2(小于为真)
整数1 -ge 整数2:判断整数1是否大于等于整数2(大于等于为真)
整数1 -le 整数2:判断整数1是否小于等于整数2(小于等于为真)

字符串的判断:
-z 字符串:判断字符串是否为空(为空返回真)
-n 字符串:判断字符串是否为非空(非空返回真)
字符串1==字符串2:判断字符串1是否和字符串2相等(相等返回真)
字符串1!=字符串2:判断字符串1是否和字符串2不相等(不相等返回真)
[root@iZ2ze57xep3rm7w9t2l85cZ local]# name=fengjie
[root@iZ2ze57xep3rm7w9t2l85cZ local]# name2=jjj
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ "$name" == "$name2" ] && echo yes || echo no
no
[root@iZ2ze57xep3rm7w9t2l85cZ local]# [ "$name" != "$name2" ] && echo yes || echo no
yes
多重条件判断:
判断1 -a 判断2:逻辑与,判断1和判断2都成立,最终的结果才为真
判断1 -o 判断2:逻辑或,判断1和判断2有一个成立,最终的结果就为真
!判断:逻辑非,使原始的判断式取反

以上内容[]即为test命令,但是一般常用的都是[]

流程控制语句:
单分支if条件语句
if [ 条件判断式 ];then
程序
fi
或者:
if[ 条件判断式 ]
then
程序
fi
单分支条件语句需要注意几个点
1、if语句使用fi结尾,和一般语言使用大括号结尾不同
2、[ 条件判断式 ]就是使用test命令判断,所以中括号和条件判断式之间必须有空格
3、then后面跟符合条件之后执行的程序,可以放在[]之后,用";"分割。也可以换行写入,就不需要";"了

例子1:判断登陆的用户是否root
查看当前用户:whoami后者env 下的USER即为当前用户
env | grep "USER" :查看的是带有USER的一行数据。
cut -d "=" -f 2 :以等号为分隔符,截取第二个字符。-d用来定义分隔符,默认为tab键,-f表示需要取得哪个字段

[root@iZ2ze57xep3rm7w9t2l85cZ local]# more testzhao.sh
#!/bin/bash
#查出当前用户,截取到当前用户,将当前用户名赋予test
test=$(env | grep "USER" | cut -d "=" -f 2)
#获取到test的值和root进行字符串匹配,如果相等,输出dangqian yonghu shi root
if [ "$test" == root ]
then
echo "dangqian yonghu shi root"
fi
[root@iZ2ze57xep3rm7w9t2l85cZ local]# ./testzhao.sh
dangqian yonghu shi root

判断分区使用率
#查看系统分支:
[root@iZ2ze57xep3rm7w9t2l85cZ ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 4.8G 33G 13% /
devtmpfs 486M 0 486M 0% /dev
tmpfs 496M 0 496M 0% /dev/shm
tmpfs 496M 484K 496M 1% /run
tmpfs 496M 0 496M 0% /sys/fs/cgroup
tmpfs 100M 0 100M 0% /run/user/0
#查看根分支
[root@iZ2ze57xep3rm7w9t2l85cZ ~]# df -h | grep "vda1"
/dev/vda1 40G 4.8G 33G 13% /
#输出第五列
[root@iZ2ze57xep3rm7w9t2l85cZ ~]# df -h | grep "vda1" | awk '{print $5}'
13%
#输出第五列的同时以%为分隔符,截取第一个字符
[root@iZ2ze57xep3rm7w9t2l85cZ ~]# df -h | grep "vda1" | awk '{print $5}' | cut -d "%" -f 1
13

#!/bin/bash
#截取根分支的使用率,以%分割
rate=$(df -h | grep "vda1" | awk '{print $5}' | cut -d "%" -f 1)
#判断rate的值小于80则输出genmulu。。。。否则输出busuanda。
if [ "$rate" -le 80 ]
then
echo "genmulu shiyong guo da"
else
echo "busuanda"
fi

双分支if条件语句
if [ 条件判断式 ]
then
条件成立时,执行的程序
else
条件不成立时,执行的另一个程序
fi

例子:判断输入的是不是目录
#!/bin/bash
read -p "请输入一个目录:" -t 30 dir
if [ -d "$dir" ] #判断输入的信息是否存在并且是否是一个目录文件
then
echo "您输入的是一个目录"
else
echo "nononono"
fi

判断apache服务是否运行 ps aux :查看所有正在运行的程序
#!/bin/bash
tomzhao=$(ps -ef | grep tomcat | grep -v grep)
if [ -n "$tomzhao" ]
then echo "$(date) tomcat正在运行......" >> /usr/local/zhaopeng.log
else
/usr/local/tomcat/apache-tomcat-8.5.45/bin/startup.sh & > /dev/null
echo "$(date) tomcat已经重启......" >> /usr/local/zhaopengerr.log
fi

多分支if条件语句
if[ 条件判断式1 ]
then
当条件判断式1成立时,执行程序1
elif [ 条件判断式2 ]
then
当条件判断式2成立时,执行程序2
...省略更多条件...
else
当所有条件都不成立时,最后执行此程序
fi

seq 1 10:用于产生从某个数到另外一个数之间的所有整数
   例一:
   # seq 1 10
   结果是1 2 3 4 5 6 7 8 9 10

[root@iZ2ze57xep3rm7w9t2l85cZ local]# for i in $(seq 1 10)
> do
> echo i=$(seq 1 10)
> done
i=1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10
i=1 2 3 4 5 6 7 8 9 10

[root@iZ2ze57xep3rm7w9t2l85cZ local]# for i in $(seq 1 10)
> do
> echo $i
> done
1
2
3
4
5
6
7
8
9
10

多分支case条件语句:
case语句和if elif...else语句一样都是多分支条件语句,不过和if多分支条件语句不同的是,case语句只能
判断一种条件关系,而if语句可以判断多种条件关系。

case $变量名 in
“值1”)
如果变量的值等于值1,则执行程序1
;;
“值2”)
如果变量的值等于值2,则执行程序2
;;
...省略其他分支...
*)
如果变量的值不是以上的值,则执行此程序
;;
esac

例子:输入yes或者no,来判断输入的是否符合yes或者no或者输入错误
read -p "please choose yes/no:" -t 30 cho
case $cho in
"yes")
echo "you choosed yes!you are right!"
;;
"no")
echo "you choosed no!you are right!"
;;
*)
echo "you are wrong!!"
;;
esac


解压多个文件,用for循环实现:
#!/bin/bash
#进入到对应要操作的目录
cd /usr/local/testdir
#查看.tar.gz结尾的压缩文件数量并记录到ll.log中
ls *.tar.gz > ll.log
#查看ll.log中的压缩文件个数和名称并循环赋值给i
for i in $(cat ll.log)
do
#执行解压缩操作(后台执行,不打印日志和信息
tar -zxf $i & > /dev/null
done
#删除掉临时日志文件ll.log
rm -rf /usr/local/testdir/ll.log

while循环:
while循环是不定循环,也称作条件循环。只要条件判断式成立,循环就会一直继续,知道条件判断式不成立,循环才会停止。这就和for的固定循环不太一样了。

while [ 条件判断式 ]
do
程序
done

ctrl键的妙用:
ctrl+a:回到当前输入/便在行首插入字符,不用按住方向键了。
ctrl+e:与上个组合相反,回到行尾。
ctrl+l:清空当前的终端界面,效果等同于clear命令。
ctrl+u:清空当前输入行的所有输入。假设你输入了aa bb,按下这个组合键,aa bb就被删掉了。
ctrl+y:就是把ctrl+u删除的字符串粘贴回来。
ctrl+r:历史命令搜索。按下ctrl+r后,会搜索包含你输入的字符串的命令。
ctrl+c:终止当前终端正在运行的程序。
ctrl+d:推送当前终端。
ctrl+z:把终端当前正在运行的程序放到后台运行。

猜你喜欢

转载自www.cnblogs.com/zp123456/p/12161614.html