程序:算法+数据结构
数据:是程序的核心
数据结构:数据在计算机中的类型和组织方式
算法:处理数据的方式
过程式:以指令为中心,数据服务于指令
对象式:以数据为中心,指令服务于数据
计算机:运行二进制指令
编程语言:人与计算机之间交互的语言
低级编程语言:
机器:二进制的0和1的序列,称为机器指令。与自然语言差异太大,难懂、难写
汇编:用一些助记符号替代机器指令,称为汇编语言
如:ADD A,B 将寄存器A的数与寄存器B的数相加得到的数放到寄存器A中
汇编语言写好的程序需要汇编程序转换成机器指令
汇编语言稍微好理解,即机器指令对应的助记符,助记符更接近自然语言
高级编程语言:
编译:高级语言-->编译器-->机器代码-->执行
C,C++
解释:高级语言-->执行-->解释器-->机器代码
shell,python,php,JavaScript,perl
顺序执行
循环执行
选择执行
编程语言的基本结构:
各种系统命令的组合
数据存储:变量、数组
表达式:例如 a + b
语句:例如if ,for
包含一些命令或声明,并符合一定格式的文本文件
格式要求:首行shebang机制
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl
自动化常用命令
执行系统管理和故障排除
创建简单的应用程序
处理文本或文件
#后缀改为txt打开192.168.0.2/hello.txt路径则可以在网站上直接查看,后缀为sh则会把它下载下来
scp /data/script/hello.sh 192.168.0.2:/var/www/html
输入口令:
curl http://192.168.0.2/hello.sh |bash
#这样就可远程直接运行这个脚本了
#!SHEBANG
CONFIGURATION_VARIABLES
FUNCTION_DEFINITIONS
MAIN_CODE
bash -n /path/to/some_script
bash -x /path/to/some_script
1、不能使程序中的保留字:例如if, for
2、只能使用数字、字母及下划线,且不能以数字开头
3、见名知义
4、统一命名规则:驼峰命名法 :利用下划线或者每个名称开头都大写等等
1、变量名大写
2、局部变量小写
3、函数名小写
4、用英文名字,并体现出实际作用
根据变量的生效范围等标准划分下面变量类型
局部变量:生效范围为当前shell进程;对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效
环境变量:生效范围为当前shell进程及其子进程
本地变量:生效范围为当前shell进程中某代码片断,通常指函数
位置变量:$1, $2, ...来表示,用于让脚本在脚本代码中调用通过命令行传递给它的参数
特殊变量:$?, $0, $*, $@, $#,$$
18:26[root@centos7 /data]# which init
/usr/sbin/init
18:26[root@centos7 /data]# ll /usr/sbin/init
lrwxrwxrwx. 1 root root 22 Mar 5 21:16 /usr/sbin/init -> ../lib/systemd/systemd
18:02[root@centos7 /data]# Userinfo=" --1 `who` "
18:03[root@centos7 /data]# echo $Userinfo
--1 root pts/0 2019-03-16 08:56 (gateway) root pts/1 2019-03-16 17:58 (gateway)
18:03[root@centos7 /data]# echo "$Userinfo"
--1 root pts/0 2019-03-16 08:56 (gateway)
root pts/1 2019-03-16 17:58 (gateway)
18:03[root@centos7 /data]# Num1=10
18:06[root@centos7 /data]# Num2=20
18:06[root@centos7 /data]# Num3=Num1+Num2
18:06[root@centos7 /data]# echo $Num3
Num1+Num2
18:06[root@centos7 /data]# Num3=$Num1+$Num2
18:07[root@centos7 /data]# echo $Num3
10+20
19:49[root@centos7 /data/lintst]# (name=zhang;echo $name)
zhang
19:50[root@centos7 /data/lintst]# echo $name
19:50[root@centos7 /data/lintst]# (name=zhang;echo $name);echo $name
zhang
19:51[root@centos7 /data/lintst]# name=duan;(name=zhang;echo $name);echo $name
zhang
duan
但是如果
19:52[root@centos7 /data/lintst]# name=duan;(echo $name);echo $name
duan
duan
详细一点:
19:56[root@centos7 /data/lintst]# name=duan;echo 1$name;(name=zhang;echo 2$name);echo 3$name
1duan
2zhang
3duan
19:57[root@centos7 /data/lintst]# name=duan;echo 1$name;(echo 2$name);echo 3$name
1duan
2duan
3duan
19:57[root@centos7 /data/lintst]#
更详细一点:
19:57[root@centos7 /data/lintst]# echo $name
duan
19:58[root@centos7 /data/lintst]# (echo $name)
duan
19:58[root@centos7 /data/lintst]# (name=zhang; echo $name)
zhang
19:59[root@centos7 /data/lintst]# echo $name
duan
19:59[root@centos7 /data/lintst]# (echo $name)
duan
经过测试发现,当不进行变量写入(赋值)的时候,并未开启子进程
20:06[root@centos7 /data/lintst]# echo $name;echo a$$;(echo b$$;echo $name);echo $name;echo c$$;sleep 200
duan
a16131
b16131
duan
duan
c16131
但是这样的话:
echo $name;echo a$BASHPID;(echo b$BASHPID;echo $name;);echo $name;echo c$$;sleep 200
duan
a16131
b40122
duan
duan
c16131
PATH
SHELL
USER
UID
HOME
PWD
SHLVL :shell嵌套的深度,也就是开了几个shell
LANG
MAIL
HOSTNAME
HISTSIZE
_ 下划线 :上一个命令的最后一个字符串(或参数,以空格为分隔符来判断)
echo ###### | passwd --stdin zhang
scp -r zhang@###.###.##.### /data/scripts /data/cpdir/
$1, $2, ... 对应第1、第2等参数,shift [n]换位置
$0 命令本身
$* 传递给脚本的所有参数,全部参数合为一个字符串
$@ 传递给脚本的所有参数,每个参数为独立字符串
$# 传递给脚本的参数的个数
0 代表成功,1-255代表失败
$? 变量保存最近的命令退出状态
exit [n]:可以自定义退出状态码
ping -c1 -w1 ###.###.###.### &>/dev/null
echo $?
18:07[root@centos7 /data]# W=$[X*Y]
18:08[root@centos7 /data]# echo $W
12
18:08[root@centos7 /data]# W=$[$X-$Y]
18:09[root@centos7 /data]# echo $W
-1
echo -e "\033[$[RANDOM%7+31]mCOLOR\033[0m"
或者 echo -e "\033[${NCUM}mCOLOR\033[0m"
18:10[root@centos7 /data]# x=10;y=8;x=$[x^y];let y=x^y;x=$((x^y));echo $x $y
8 10
18:31[root@centos7 /data]# x=10;y=8;temp=$x;x=$y;y=$temp;echo $x $y
8 10
test EXPRESSION : test $name1 = $name2
[ EXPRESSION ] :和上面相同,精确匹配,不支持正则表达式和通配符
[[ EXPRESSION ]] :支持扩展正则表达式和通配符,可以模糊匹配
-v VAR
变量VAR是否设置 :这个就是用来判断变量是否存在,比如var="", 虽然它是空值,但是它仍然赋值设置过已经存在了,[ -v var ] ,echo $? =0 结果为真
数值测试:
-gt 是否大于
-ge 是否大于等于
-eq 是否等于
-ne 是否不等于
-lt 是否小于
-le 是否小于等于
= 是否等于
\> ascii码是否大于ascii码,字符串从左往右一个一个比较
< 是否小于
13:58[root@centos7 /data]# AAA="abc$"
13:58[root@centos7 /data]# BBB="abc#"
13:58[root@centos7 /data]# [ $AAA \> $BBB ]
13:58[root@centos7 /data]# echo $?
0
13:58[root@centos7 /data]# BBB="abc%"
13:58[root@centos7 /data]# [ $AAA \< $BBB ]
13:58[root@centos7 /data]# echo $?
0
!= 是否不等于
== 或者!= ,后面匹配的是partern通配符,而不是正则表达式
=~ 左侧字符串是否能够被右侧的正则表达式ReExPression所匹配
-z "STRING“ 字符串是否为空,空为真,不空为假 :[-z "$str"] ([-z $str]也可使用,但最好不要这样写)
-n "STRING“ 字符串是否不空,不空为真,空为假 : [ $awdfc ] ,echo $?=1 (awdfc没赋值和定义)
如果两个变量都是空的
[ $wadc = $wvaf ] ;echo &?=0
[ "$wadc" = "$wvaf" ] ;echo &?=0
但是如果一个变量是空的,一个变量是非空的则会报错
[ "$wadc" = "$wvaf" ] ;
-bash: [: wad: unary operator expected
echo &?=2
因此字符串比较都要加上引号
注意:如果把数字看做字符串来进行比较,也可以用 [ "##" = "##" ], 但此时需要注意两边都要加上引号变为字符串, 但加上引号之后就不能再用 -eq等命令了。
12:44[root@centos7 /data]# num="<123>"
12:44[root@centos7 /data]# [[ "$num" =~ \<[0-9]+\> ]]
12:44[root@centos7 /data]# echo $?
0
12:46[root@centos7 /data]# num=/123/
12:46[root@centos7 /data]# [[ "$num" =~ \<[0-9]+\> ]]
12:46[root@centos7 /data]# echo $?
1
12:48[root@centos7 /data]# num="123>"
12:48[root@centos7 /data]# [[ "$num" =~ \<[0-9]+\> ]]
12:48[root@centos7 /data]# echo $?
1
12:52[root@centos7 /data]# num="\<123\>"
12:52[root@centos7 /data]# [[ "$num" =~ \\\<[0-9]+\\\> ]]
12:52[root@centos7 /data]# echo $?
0
反斜杠\b也用不了:
13:01[root@centos7 /data]# [[ `echo 123` =~ \b[0-9]+\b ]]
13:03[root@centos7 /data]# echo $?
1
13:03[root@centos7 /data]# [[ `echo b123` =~ \b[0-9]+\b ]]
13:03[root@centos7 /data]# echo $?
1
13:03[root@centos7 /data]# [[ `echo b123b` =~ \b[0-9]+\b ]]
13:03[root@centos7 /data]# echo $?
0
13:03[root@centos7 /data]# [[ `echo \b123\b` =~ \b[0-9]+\b ]]
13:04[root@centos7 /data]# echo $?
0
13:16[root@centos7 /data]# [[ `echo b123rb` =~ \b[0-9]+\b ]]
13:17[root@centos7 /data]# echo $?
1
13:17[root@centos7 /data]# [[ `echo b123\b` =~ \b[0-9]+\b ]]
13:17[root@centos7 /data]# echo $?
0
但是用grep命令可以,看下面的例子:
11:58[root@centos7 /data/scriptest]# num=123; [[ $num =~ ^[0-9]+$ ]]
11:59[root@centos7 /data/scriptest]# echo $?
0
11:59[root@centos7 /data/scriptest]# num=123; [[ $num =~ \<[0-9]+\> ]]
11:59[root@centos7 /data/scriptest]# echo $?
1
但是用grep命令可以:
12:19[root@centos7 /data]# echo /123/ |egrep "\<[0-9]+\>"
/123/
12:19[root@centos7 /data]# echo 123/ |egrep "\<[0-9]+\>"
123/
12:19[root@centos7 /data]# echo a123b | egrep "\<[0-9]+\>"
12:20[root@centos7 /data]# echo 123b | egrep "\<[0-9]+\>"
12:20[root@centos7 /data]# num=123
12:20[root@centos7 /data]# [[ "$num" =~ "\<[0-9]+\>" ]]
12:20[root@centos7 /data]# echo $?
1
12:21[root@centos7 /data]# echo $num
123
12:56[root@centos7 /data]# [[ `echo "123"` =~ ".*" ]]
12:57[root@centos7 /data]# echo $?
1
12:57[root@centos7 /data]# [[ `echo ".*"` =~ ".*" ]]
12:59[root@centos7 /data]# echo $?
0
12:59[root@centos7 /data]# [[ `echo "".*""` =~ ".*" ]]
12:59[root@centos7 /data]# echo $?
1
12:59[root@centos7 /data]# [[ `echo "".*""` =~ "".*"" ]]
13:00[root@centos7 /data]# echo $?
0
num=123
12:26[root@centos7 /data]# [[ "$num" =~ "^[0-9]+$" ]]
12:26[root@centos7 /data]# echo $?
1
12:26[root@centos7 /data]# [[ "$num" =~ ^[0-9]+$ ]]
12:26[root@centos7 /data]# echo $?
0
同时还需要注意,不论怎样都无法用次首词尾来判断:
12:28[root@centos7 /data]# num=/123/
12:28[root@centos7 /data]# [[ "$num" =~ \<[0-9]+\> ]]
12:28[root@centos7 /data]# echo $?
1
但是grep中可以,但注意grep后面判断部分是最好加引号,否则无法将反斜杠\,以及<>重定向符号转义来来进行判断,因为会把它看作是新的一行来输入:
12:29[root@centos7 /data]# echo $num | egrep \<[0-9]+\>
12:31[root@centos7 /data]# echo $num | egrep "\<[0-9]+\>"
/123/
12:31[root@centos7 /data]# echo $num | egrep [0-9]+
/123/
但可以转义它,不过太过于复杂,所以还是加上引号比较好:
12:36[root@centos7 /data]# echo $num | egrep \\\<[0-9]+\\\>
/123/
-a FILE:同-e
-e FILE: 文件存在性测试,存在为真,否则为假
-b FILE:是否存在且为块设备文件
-c FILE:是否存在且为字符设备文件
-d FILE:是否存在且为目录文件
-f FILE:是否存在且为普通文件
-h FILE 或 -L FILE:存在且为符号链接文件
-p FILE:是否存在且为命名管道文件
-S FILE:是否存在且为套接字文件
-r FILE:是否存在且可读
-w FILE: 是否存在且可写
-x FILE: 是否存在且可执行
-u FILE:是否存在且拥有suid权限
-g FILE:是否存在且拥有sgid权限
-k FILE:是否存在且拥有sticky权限
-s FILE: 是否存在且非空
-t fd: fd 文件描述符是否在某终端已经打开
-N FILE:文件自从上一次被读取之后是否被修改过
-O FILE:当前有效用户是否为文件属主
-G FILE:当前有效用户是否为文件属组
FILE1 -ef FILE2: FILE1是否是FILE2的硬链接
FILE1 -nt FILE2: FILE1是否新于FILE2(mtime)
FILE1 -ot FILE2: FILE1是否旧于FILE2
[ EXPRESSION1 -a EXPRESSION2 ] 并且
[ EXPRESSION1 -o EXPRESSION2 ] 或者
[ ! EXPRESSION ]
COMMAND1 && COMMAND2 并且,短路与,代表条件性的AND THEN
COMMAND1 || COMMAND2 或者,短路或,代表条件性的OR ELSE
! COMMAND 非
如:[ -f “$FILE” ] && [[ “$FILE”=~ .*\.sh$ ]]
判断有没有用户:
grep -q no\_such\_user /etc/passwd || echo 'No such user
No such user
判断一个IP是否连通:
ping -c1 -W2 station1 &> /dev/null && echo "station1 is up" || (echo 'station1 is unreachable'; exit 1)
station1 is up
13:31[root@centos7 /data/scriptest]# ( hostname ; exit 101 )
centos7.6test
15:09[root@centos7 /data/scriptest]# echo $?
101
(umask 066 ;touch f1)
-n N 指定输入的字符长度N:只要达到这个长度,命令就退出了
-d ‘字符’ 输入结束符:只要输入这个字符,命令也就退出了
-t N TIMEOUT为N秒
例子:
read -p “Enter a filename: “ FILE
15:09[root@centos7 /data/scriptest]# echo a b c | read x y z
15:29[root@centos7 /data/scriptest]# echo $x $y $z
15:34[root@centos7 /data/scriptest]# echo a b c | (read x y z;echo $x $y $z;)
a b c
15:30[root@centos7 /data/scriptest]# echo a b c | { read x y z;echo $x $y $z; }
a b c
case 变量引用(word) in
PAT1)
分支1
;;
PAT2)
分支2
;;
...
*)
默认分支
;;
esac
*: 任意长度任意字符
?: 任意单个字符
[]:指定范围内的任意单个字符
a|b: a或b
转载于:https://blog.51cto.com/14228129/2366162