前言
这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题
于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。
微信小程序搜索:Python面试宝典
或可关注原创个人博客:https://lienze.tech
也可关注微信公众号,不定时发送各类有趣猎奇的技术文章:Python编程学习
Shell编程
曾经有人说过,学习Linux不知道Shell编程,那就是不懂Linux,现在细细品味确实是这样。Shell是操作系统的最外层,Shell可以合并编程语言以控制进程和文件,以及启动和控制其它程序。
Shell 通过提示您输入,向操作系统解释该输入,然后处理来自操作系统的任何结果输出,简单来说Shell就是一个用户跟操作系统之间的一个命令解释器。
Shell是用户与Linux操作系统之间沟通的桥梁,用户可以输入命令执行,又可以利用 Shell脚本编程去运行
Linux Shell种类非常多,常见的SHELL如下:
- Bourne Shell(/usr/bin/sh或/bin/sh)
- Bourne Again Shell(/bin/bash)
- C Shell(/usr/bin/csh)
- K Shell(/usr/bin/ksh)
- Shell for Root(/sbin/sh)
不同的Shell语言的语法有所不同,一般不能交换使用,最常用的shell是Bash,也就是Bourne Again Shell
Bash由于易用和免费,在日常工作中被广泛使用,也是大多数Linux操作系统默认的Shell环境。
Shell、Shell编程、Shell脚本、Shell命令之前都有什么区别呢?简单来说Shell是一个整体的概念,Shell编程与Shell脚本统称为Shell编程,Shell命令是Shell编程底层具体的语句和实现方法
HELLO-WORLD
Shell脚本编程需要如下几个事项:
- Shell脚本名称命名一般为英文、大写、小写;
- 不能使用特殊符号、空格来命名;
- Shell脚本后缀以.sh结尾;
- 不建议Shell命名为纯数字,一般以脚本功能命名。
- Shell脚本内容首行需以#!/bin/bash开头;
- Shell脚本中变量名称尽量使用大写字母,字母间不能使用“-”,可以使用“_”;
- Shell脚本变量名称不能以数字、特殊符号开头。
#!/bin/bash 固定格式,定义该脚本所使用的Shell类型
#This is my First shell #号表示注释,没有任何的意义,SHELL不会解析它
echo “Hello World ” Shell脚本主命令,执行该脚本呈现的内容
Shell脚本编写完毕,如果运行该脚本,运行用户需要有执行权限,可以使用chmod o+x first_shell.sh赋予可执行权限
然后./first_shell.sh执行即可,还可使用命令执行/bin/sh first_shell.sh直接运行脚本,不需要执行权限,最终脚本执行显示效果一样
SHELL-注释
- 以 # 开头的行就是注释,会被解释器忽略
- 多行注释可以使用EOF
:<<EOF
注释内容...
注释内容...
注释内容...
EOF
:<<'
注释内容...
注释内容...
注释内容...
'
:<<!
注释内容...
注释内容...
注释内容...
!
SHELL-括号
用于多个命令组、命令替换、初始化数组
if (date);
# 类似 `cmd`
整数扩展、运算符、重定义变量值,算术运算比较
(( 1==1 ))
(( 1+1 ))
(( a++ ))
for (( i=0;i<5;i++ ))
if []; # bash内部命令,[与test是等同的,正则字符范围、引用数组元素编号,不支持+-*/数学运算符,逻辑测试使用-a、-o
if [[ ]]; # bash程序语言的关键字,不是一个命令,[[ ]]结构比[ ]结构更加通用,不支持+-*/数学运算符,逻辑测试使用&&、||
if {}; # 主要用于命令集合或者范围,例如mkdir -p /data/201{7,8}/
{1..5}
{1,5}
SHELL-变量
Shell变量是非类型的解释型语言,不像C++、JAVA语言编程时需要事先声明变量,Shell给一个变量赋值,实际上就是定义了变量
在Linux支持的所有shell中,都可以用赋值符号(=)为变量赋值
Shell变量为弱类型,定义变量不需要声明类型,但在使用时需要明确变量的类型,可以使用Declare指定类型,Declare常见参数有
+/- "-"可用来指定变量的属性,"+"为取消变量所设的属性;
-f 仅显示函数;
r 将变量设置为只读;
x 指定的变量会成为环境变量,可供shell以外的程序来使用;
i 指定类型为数值,字符串或运算式。
Shell编程中变量分为三种,分别是系统变量、环境变量和用户变量
-
系统变量在对参数判断和命令返回值判断时使用
-
环境变量则主要是在程序运行时需要设置
-
用户变量又称为局部变量,多使用在Shell脚本内部或者临时局部使用
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
- 中间不能有空格,可以使用下划线(_)。
- 不能使用标点符号。
- 不能使用bash里的关键字(可用help命令查看保留关键字)
#!/bin/bash
var=abc
echo "this is $var"
- 注意:赋值语句必须挨着=号
for skill in Ada Coffe Action Java; do
echo "I am good at ${skill}Script"
done
花括号也可以用来隔离变量与字符
系统变量
SHELL编程常见系统变量
$0 当前脚本的名称;
$n 当前脚本的第n个参数,n=1,2,…9;
$* 当前脚本的所有参数(不包括程序本身);
$# 当前脚本的参数个数(不包括程序本身);
$? 命令或程序执行完后的状态,返回0表示执行成功;
$$ 程序本身的PID号。
环境变量
SHELL编程常见环境变量
$PATH 命令所示路径,以冒号为分割;
$HOME 打印用户家目录;
$SHELL 显示当前Shell类型;
$USER 打印当前用户名;
$ID 打印当前用户id信息;
$PWD 显示当前所在路径;
$TERM 打印当前终端类型;
$HOSTNAME 显示当前主机名。
用户变量
SHELL编程用户变量
A=123 #自定义变量A;
N_SOFT=nginx-1.12.0.tar.gz #自定义变量N_SOFT;
BACK_DIR=/data/backup/ #自定义变量BACK_DIR;
IP1=192.168.1.11 #自定义变量IP1;
IP2=192.168.1.12 #自定义变量IP2。
SHELL-变量操作
只读变量
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变
myUrl="https://www.google.com"
readonly myUrl
删除变量
使用 unset 命令可以删除变量,unset 命令不能删除只读变量
unset variable_name
SHELL-运算
Shell 和其他编程语言一样,支持多种运算符
- 算数运算符
- 关系运算符
- 布尔运算符
- 字符串运算符
- 文件测试运算符
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
expr 是一款表达式计算工具,使用它能完成表达式的求值操作
#!/bin/bash
val=`expr 2 + 2`
echo "两数之和为 : $val"
算数运算符
运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | expr $a + $b 结果为 30。 |
- | 减法 | expr $a - $b 结果为 -10。 |
* | 乘法 | expr $a \* $b 结果为 200。 |
/ | 除法 | expr $b / $a 结果为 2。 |
% | 取余 | expr $b % $a 结果为 0。 |
= | 赋值 | a=$b 将把变量 b 的值赋给 a。 |
== | 相等。用于比较两个数字,相同则返回 true。 | [ $a == $b ] 返回 false。 |
!= | 不相等。用于比较两个数字,不相同则返回 true。 | [ $a != $b ] 返回 true。 |
关系运算符
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true。 | [ $a -eq $b ] 返回 false。 |
-ne | 检测两个数是否不相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | [ $a -gt $b ] 返回 false。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | [ $a -lt $b ] 返回 true。 |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | [ $a -ge $b ] 返回 false。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ $a -le $b ] 返回 true。 |
布尔运算符
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true。 | [ ! false ] 返回 true。 |
-o | 或运算,有一个表达式为 true 则返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回 false。 |
逻辑运算符
运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑的 AND | [[ $a -lt 100 && $b -gt 100 ]] 返回 false |
|| | 逻辑的 OR | [[ $a -lt 100 || $b -gt 100 ]] 返回 true |
字符串运算符
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true。 | [ $a = $b ] 返回 false。 |
!= | 检测两个字符串是否相等,不相等返回 true。 | [ $a != $b ] 返回 true。 |
-z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
-n | 检测字符串长度是否不为 0,不为 0 返回 true。 | [ -n “$a” ] 返回 true。 |
$ | 检测字符串是否为空,不为空返回 true。 | [ $a ] 返回 true。 |
文件测试运算符
操作符 | 说明 | 举例 |
---|---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | [ -c $file ] 返回 false。 |
-d file | 检测文件是否是目录,如果是,则返回 true。 | [ -d $file ] 返回 false。 |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 | [ -f $file ] 返回 true。 |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 | [ -g $file ] 返回 false。 |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 | [ -k $file ] 返回 false。 |
-p file | 检测文件是否是有名管道,如果是,则返回 true。 | [ -p $file ] 返回 false。 |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 | [ -u $file ] 返回 false。 |
-r file | 检测文件是否可读,如果是,则返回 true。 | [ -r $file ] 返回 true。 |
-w file | 检测文件是否可写,如果是,则返回 true。 | [ -w $file ] 返回 true。 |
-x file | 检测文件是否可执行,如果是,则返回 true。 | [ -x $file ] 返回 true。 |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 | [ -s $file ] 返回 true。 |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | [ -e $file ] 返回 true。 |
SEHLL-字符串
字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了)
字符串可以用单引号,也可以用双引号,也可以不用引号
单引号
str='this is a string'
- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的
- 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用
双引号
your_name='fuck'
str="Hello, I know you are \"$your_name\"! \n"
echo -e $str
- 双引号里可以有变量
- 双引号里可以出现转义字符
获取长度
string="abcd"
echo ${#string} # 输出 4
提取子字符串
string="hello world"
echo ${string:1:4}
查看子字符串
查找字符串出现的位置
string="abcdesfg"
echo `expr index "$string" s`
SHELL-数组
bash只支持一维数组(不支持多维数组),并且没有限定数组的大小
类似于 C 语言,数组元素的下标由 0 开始编号
# 在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为
array_name=(value0 value1 value2 value3)
array_name=(
value0
value1
value2
value3
)
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
访问数组
- 索引访问某个
${数组名[下标]}
- 访问全部
echo ${array_name[@]}
echo ${array_name[*]}
获取数组长度
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}
SHELL-IF
Linux Shell编程中,if、for、while、case等条件流程控制语句用的非常多
熟练掌握以上流程控制语句及语法的实验,对编写Shel脚本有非常大的益处
If条件判断语句,通常以if开头,fi结尾。也可加入else或者elif进行多条件的判断,if表达式如下
if (表达式); then
语句1
else
语句2
fi
- 比较两数大小
#!/bin/bash
NUM=100
if (( $NUM > 4 )); then
echo "The Num $NUM more than 4."
else
echo "The Num $NUM less than 4."
fi
num1=10
if (( $num1 + 10 > 20 ))
then
echo "1"
else
echo "2"
fi
- 判断目录是否存在
#!/bin/bash
if [ ! -d /data/20140515 -a ! -d /tmp/2017/ ]; then
mkdir -p /data/20140515
fi
- 常见逻辑运算符
if [ -f filename ]; # -f判断文件是否存在
if [ -d dir]; # -d判断目录是否存在
---------------------------------------------
-eq # 等于判断,应用于整形比较
-ne # 不等于,应用于整形比较
-lt # 小于,应用于整形比较
-gt # 大于,应用于整形比较
-le # 小于或等于,应用于整形比较
-ge # 大于或等于,应用于整形比较
---------------------------------------------
-a # 前后条件都成立,and
-o # 前后条件有一成立,or
-z # 空字符串
|| # or
&& # and
SHELL-FOR
- 语法
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
for var in item1 item2 ... itemN; do command1; command2… done;
- demo
for str in 'This is a string'
do
echo $str
done
for str in 1 2 3
do
echo -e "$str\n"
done
- 循环打印1至100数字,seq表示列出数据范围
for num in `seq 1 100`
do
echo -e "$num"
done
- 1-100求和
#!/bin/bash
j=0
for ((i=1; i<=100; i++))
do
j=`expr $i + $j`
done
echo $j
SEHLL-WHILE
While循环语句与for循环功能类似,主要用于对某个数据域进行循环读取、对文件进行遍历
通常用于需要循环某个文件或者列表,满足循环条件会一直循环,不满足则退出循环
其语法格式以while…do开头,done结尾。语法格式如下
while condition
do
command
done
- 1-100求和
#!/bin/bash
j=0
i=1
while ((i<=100))
do
j=`expr $i + $j`
((i++))
done
echo $j
- 读取文件
while read line
do
echo $line
done < filename
for line in `cat filename`
do
echo ${line}
done
- 无限循环
while :
do
command
done
while true
do
command
done
SHELL-CASE
Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令
- 语法
case 值 in
模式1)
command1
;;
模式2)
command1
;;
esac
- demo
echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
1) echo '你选择了 1'
;;
2) echo '你选择了 2'
;;
3) echo '你选择了 3'
;;
4) echo '你选择了 4'
;;
*) echo '你没有输入 1 到 4 之间的数字'
;;
esac
SHELL-SELECT
Select语句一般用于选择,常用于选择菜单的创建
其语法格式以selct…in do开头,done结尾
- 语法
select i in (表达式)
do
command
done
- 输出菜单
PS3="What you like most of the open source system?"
select i in CentOS RedHat Ubuntu
do
echo "Your Select System: "$i
done
SHELL-break
break命令允许跳出所有循环,终止执行后面的所有循环
#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字:"
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的!"
break
;;
esac
done
SHELL-continue
跳出当前循环
#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字:"
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的!"
continue
;;
esac
done
SHELL-函数
shell支持函数定义,可以实现代码封装复用
[ function ] funname [()]
{
action;
[return int;]
}
function helloworld(){
echo "hello world"
}
helloworld # 调用函数无须加括号
- 判断IP
judge_ip(){
read -p "Please enter ip Address,example 192.168.0.11 ip": IPADDR
echo $IPADDR|grep -v "[Aa-Zz]"|grep --color -E "([0-9]{1,3}\.){3}[0-9]{1,3}"
}
judge_ip