Linux学习Day6:编写Shell脚本
Shell脚本命令的工作方式有两种:
交互式(Interactive):用户每输入一条命令就立即执行。
批处理(Batch):由用户事先编写好一个完整的Shell脚本,Shell会一次性执行脚本中诸多的命令。
一、编写简单的脚本
一个Shell脚本主要由三部分组成:脚本声明、脚本注释、脚本命令。
- 脚本声明:告诉系统使用哪种Shell解释器来执行该脚本,比如:#!/bin/bash
- 脚本注释:以#开头,主要是介绍脚本的功能和某些命令
- 脚本命令:需要被执行的Linux命令。
Shell脚本的名称可以任意,但为了方便用户辨认,建议加上.sh后缀以表示这是一个脚本文件。下面通过Vim编辑器简单编写一个Shell脚本:
[root@linuxprobe ~]# vim example.sh
#!/bin/bash //脚本声明
# for example by xuliang //脚本注释
pwd //脚本命令
ls -al
可以通过bash命令直接运行脚本文件,也可以通过输入完整路径的方式来执行,但是需要先对脚本文件添加可执行权限。
[root@linuxprobe ~]# bash example.sh //通过bash命令执行脚本文件
/root
total
dr-xr-x---. root root Feb : .
drwxr-xr-x. root root Feb : ..
drwxr-xr-x. root root Feb : a
-rw-------. root root Feb anaconda-ks.cfg
-rw-------. root root Feb : .bash_history
---------------------省略部分输出内容------------------------------
[root@linuxprobe ~]# ./example.sh //通过完整路径执行脚本文件,需要可执行权限
-bash: ./example.sh: Permission denied
[root@linuxprobe ~]# chmod u+x example.sh //添加可执行权限
[root@linuxprobe ~]#
[root@linuxprobe ~]# ./example.sh //脚本执行成功
/root
total
dr-xr-x---. root root Feb : .
drwxr-xr-x. root root Feb : ..
drwxr-xr-x. root root Feb : a
-rw-------. root root Feb anaconda-ks.cfg
-rw-------. root root Feb : .bash_history
-------------------省略部分输出内容-----------------------------
二、接收用户的参数
上面的脚本只能执行一些预先定义好的命令,未免太过于死板了。为了增加Shell脚本的灵活性,必须让脚本可以接收用户输入的参数。Linux系统中的Shell脚本语言已经内设了用于接受参数的变量,变量之间使用空格间隔,相关变量如下所示:
- $0:表示当前Shell脚本的名称;
- $#:表示总共有几个参数;
- $*:表示所有位置的参数值
- $1、$2、$3、$4.....:表示第N个位置的参数值。
“百闻不如一见,看书不如实践”,接下来通过编写一个脚本,引用上面的变量参数来看一下实际效果:
[root@linuxprobe ~]# vim example.sh
#!/bin/bash
# for example by xuliang
echo "当前脚本名称$0"
echo "总共有$#个参数,分别是$*"
echo "第一个参数为$1,第3为$3"
[root@linuxprobe ~]# bash example.sh 6 //传入6个参数
当前脚本名称example.sh
总共有6个参数,分别是1
第一个参数为1,第3为3
三、判断用户的参数
接下来学习如何处理接收到的用户参数。Shell脚本中的条件测试语法可以判断表达式是否成立,若条件成立则返回数字0,否则返回其他随机数字(一般都是返回1),条件测试语句的执行格式如下所示。切记,条件表达式两边必须要有一个空格。
按照测试对象来划分,条件测试语句可以分为4种:
- 文件测试语句;
- 逻辑测试语句;
- 整数值比较语句;
- 字符串比较语句。
1、文件测试语句
指使用指定条件来判断文件是否存在或权限是否满足等情况的运算符,具体参数如下所示:
运算符 | 作用 |
-d | 测试文件是否为目录类型 |
-e | 测试文件是否存在 |
-f | 判断是否为一般文件 |
-r | 测试当前用户是否有权限读取 |
-w | 测试当前用户是否有权限写入 |
-x | 测试当前用户是否有权限执行 |
实验1:使用文件测试语句判断/etc/fstab是否为一个目录类型文件,然后通过Shell解释器的内设$?变量来显示上一条命令执行后的返回值。如果上一条命令执行成功,则$?变量的数值为0;反之则为一个非零值(一般都是1)。
[root@linuxprobe ~]# [ -d /etc/fstab ]
[root@linuxprobe ~]# echo $? //显示上条命令执行结果
1 //非零值表示执行失败
[root@linuxprobe ~]#
实验2:使用条件测试语句判断/etc/fstab是否为一个一般文件。
[root@linuxprobe ~]# [ -f /etc/fstab ]
[root@linuxprobe ~]# echo $?
0 //执行成功
[root@linuxprobe ~]#
2、逻辑测试语句
指对测试结果进行逻辑分析,根据测试结果实现不同的效果。主要有3种逻辑运算符,如下所示:
运算符 | 作用 |
逻辑与(&&) | 表示前面的命令执行成功后,才执行后面的命令 |
逻辑或(||) | 表示前面的命令执行失败后,才执行后面的命令 |
逻辑非(!) | 表示把条件测试语句中的判断结果取相反值 |
实验1:判断/dev/cdrom文件是否存在,若存在则输出Exist字样。
[root@linuxprobe ~]# [ -e /dev/cdrom ] && echo "Exist" //逻辑与
Exist
实验2:判断当前登录的用户是否为管理员身份:
[root@linuxprobe ~]# su - linuxprobe //切换至linuxprobe用户
Last login: Mon Feb :: BNT on pts/
[linuxprobe@linuxprobe ~]$
[linuxprobe@linuxprobe ~]$ [ $USER = root ] || echo "not root" //逻辑或
not root
实验3:判断当前登录用户为非管理员身份:
[linuxprobe@linuxprobe ~]$ su - root //切换至root用户
Password:
Last login: Mon Feb :: BNT on pts/
[root@linuxprobe ~]# [ ! $USER = root ] || echo "It's root" //逻辑非
It's root
实验4:判断当前登录的用户,若是普通用户则输出“user”,若是管理员用户则输出“root”
[root@linuxprobe ~]# [ ! $USER = root ] && echo "user" || echo "It's root"
It's root //root用户
[root@linuxprobe ~]# su - linuxprobe //切换至linuxprobe用户
Last login: Mon Feb :: BNT on pts/
[linuxprobe@linuxprobe ~]$ [ ! $USER = root ] && echo "user" || echo "It's root"
user //普通用户
3、整数比较运算符
仅仅是对数字的操作,即运算符的两边必须是数字,不能将数字与字符串、文件等内容一起操作,而且一定要使用规范的整数比较运算符来进行操作。整数比较运算符如下所示:
运算符 | 作用 |
-eq | 是否等于 |
-ne | 是否不等于 |
-gt | 是否大于(greater than) |
-lt | 是否小于(less than) |
-le | 是否等于或小于 |
-ge | 是否大于或等于 |
实验:判断当前主机空闲内存是否小于1024M,若小于1024M,则输出“Insufficient Memory”的字样。
[linuxprobe@linuxprobe ~]$ FreeMem=`free -m | grep Mem: | awk '{print $4}'` //获取当前主机空闲内存值,注意赋值号的两边不能有空格
[linuxprobe@linuxprobe ~]$
[linuxprobe@linuxprobe ~]$ [ $FreeMem -lt ] && echo "Insuficient Memory"
Insuficient Memory
4、字符串比较语句
用于判断测试字符串是否为空值,或两个字符串是否相同,常见的字符串运算符如下所示:
运算符 | 作用 |
= | 比较字符串的内容是否相同 |
!= | 比较字符串的内容是否不同 |
-z | 判断字符串的内容是否为空 |
实验1:判断变量String是否空值,即判断是否定义了该变量。
[linuxprobe@linuxprobe ~]$ [ -z $String ]
[linuxprobe@linuxprobe ~]$ echo $?
0
实验2:判断当前LANG环境变量值是否为“en.US”。
[linuxprobe@linuxprobe ~]$ echo $LANG
en_US.UTF-
[linuxprobe@linuxprobe ~]$ [ $LANG = "en.US" ] || echo "Not en.US"
Not en.US
四、流程控制语句
在Shell脚本中,我们可以通过if、for、while、case这4中流程控制语句来编写难度更大、功能更强的脚本,来匹配实际的生产需求。
1、if条件测试语句
if条件测试语句分为单分支结构、双分支结构、多分支结构,下面逐一进行介绍:
(1)单分支结构
由if、then、fi关键词组成,只有在判断条件成立之后才执行预设的命令,相当于口语的“如果........那么........”。语法格式如下所示:
实验:判断/root/test目录文件是否存在,如存在则结束Shell脚本,否则创建该目录。
[root@linuxprobe ~]# vim mkcdrom.sh
#!/bin/bash
DIR="/root/test"
if [ ! -e $DIR ]
then
mkdir -p $DIR
fi [root@linuxprobe ~]# bash mkcdrom.sh //执行脚本
[root@linuxprobe ~]# ls -d /root/test/ //检查目录是否创建成功
/root/test/
(2)多分支结构
由if、then、else、fi关键词组成,它进行一次条件匹配判断,若匹配成功,则执行预设的命令,否则去执行匹配失败时的预设命令。语法格式如下所示:
实验:用户自行输入IP地址,并判断该主机是否在线。
[root@linuxprobe ~]# vim chkhost.sh
#!/bin/bash
ping -c -i 0.2 -w $ &> /dev/null ###其中参数表示ping3次、每次间隔0.2秒、等待超时时间为3秒
if [ $? -eq ]
then
echo "Host $1 is On-line"
else
echo "Host $1 is Off-line"
fi [root@linuxprobe ~]# bash chkhost.sh 192.168.134.10
Host 192.168.134.10 is On-line //主机在线
[root@linuxprobe ~]# bash chkhost.sh 192.168.134.20
Host 192.168.134.20 is Off-line //主机不在线
[root@linuxprobe ~]#
(3)多分支结构
由if、then、else、elif、fi关键词组成,它进行多次条件匹配判断,这么多次判断中的任一项匹配成功都会执行相应的预设命令,相当于口语的“如果.....那么......如果.......那么.....”。多分支语句可以多次嵌套,语法格式如下所示:
实验:判断用户输入的分数在哪个区间,然后输出Excellent、Pass、Fail等提示信息。
[root@linuxprobe ~]# vim chkscore.sh
#!/bin/bash
read -p "Enter your score(0-100):" GRADE
if [ $GRADE -ge ] && [ $GRADE -le ]
then
echo "Excellent"
elif [ $GRADE -ge ] && [ $GRADE -le ]
then
echo "Pass"
else
echo "Fail"
fi [root@linuxprobe ~]# bash chkscore.sh
Enter your score(-):
Excellent
[root@linuxprobe ~]# bash chkscore.sh
Enter your score(-):
Pass
[root@linuxprobe ~]# bash chkscore.sh
Enter your score(-):
Fail
2、for条件循环语句
for循环语句允许脚本一次性读取多个信息,然后逐一对信息进行操作处理。当要处理有范围的数据时,使用for循环语句再适合不过了,其语法格式如下所示:
实验1:从列表文件中读取多个用户名,然后为其逐一创建用户账号并设置密码。
[root@linuxprobe ~]# vim users.txt //首先创建包含用户名称的文件
zhangsan
lisi
wangwu
zhaoliu [root@linuxprobe ~]# vim CreateUser.sh //编写脚本
#!/bin/bash
read -p "Enter the Users Password:" PASSWD
for UNAME in `cat users.txt`
do
id $UNAME &> /dev/null
if [ $? -eq ]
then
echo "Already Exists"
else
useradd $UNAME &> /dev/null ##添加用户
echo "$PASSWD" | passwd --stdin $UNAME &> /dev/null
if [ $? -eq ]
then
echo "$UNAME create success"
else
echo "$UNAME create failure"
fi
fi
done [root@linuxprobe ~]# bash CreateUser.sh //执行脚本
Enter the Users Password:
zhangsan create success
lisi create success
wangwu create success
zhaoliu create success
[root@linuxprobe ~]#
补充:假如用户名文件users.txt内容写成以下形式(即所有用户名写成一行,用空格分开),CreateUser.sh脚本同样执行成功。
[root@linuxprobe ~]# cat users.txt
andy barry carl
[root@linuxprobe ~]#
[root@linuxprobe ~]# bash CreateUser.sh
Enter the Users Password:
andy create success
barry create success
carl create success
实验2:读取文件中的主机列表,然后逐个测试这些主机是否在线。
[root@linuxprobe ~]# vim ipaddrs.txt //创建主机列表文件
192.168.134.10
192.168.134.20
192.168.134.30
192.168.134.40 [root@linuxprobe ~]# vim chkhosts.sh //编写脚本
#!/bin/bash
HLIST=$(cat ~/ipaddrs.txt) //其中$(命令)相当于`命令`
for IP in $HLIST
do
ping -c -i 0.2 -w $IP &> /dev/null
if [ $? -eq ] ; then
echo "$IP is On-line"
else
echo "$IP is Off-line"
fi
done [root@linuxprobe ~]# bash chkhosts.sh //运行脚本
192.168.134.10 is On-line
192.168.134.20 is Off-line
192.168.134.30 is Off-line
192.168.134.40 is Off-line
3、while条件循环语句
while条件语句是一种让脚本根据某些条件来重复执行命令的语句,它的循环结构往往在执行前并不确定最终执行的次数,它通过判断条件测试的真假来决定是否继续执行命令,条件为真就继续执行,为假就结束循环,语法结构如下所示:
实验:编写一个猜数的脚本,若用户输入的数值与脚本随机生成的数值一致,则结束游戏。
[root@linuxprobe ~]# vim guess.sh
#!/bin/bash
PRICE=$(expr $RANDOM % ) ##获取一个1000以内的随机数
TIMES=
echo "商品的实际价格为0-999之间,请猜猜看是多少?"
while true
do
read -p "请输入你猜测的价格:" INT
let TIMES++ ##TIMES变量自增1
if [ $INT -eq $PRICE ] ; then
echo "恭喜你猜对啦,实际价格为 $PRICE"
echo "您总共猜了 $TIMES 次"
exit
elif [ $INT -gt $PRICE ] ; then
echo "您猜高了"
else
echo "您猜低了"
fi
done [root@linuxprobe ~]# bash guess.sh
商品的实际价格为0-999之间,请猜猜看是多少?
请输入你猜测的价格:
您猜低了
请输入你猜测的价格:
您猜高了
-------------------省略部分内容---------------------
您猜高了
请输入你猜测的价格:
您猜低了
请输入你猜测的价格:
恭喜你猜对啦,实际价格为
您总共猜了 次
4、case条件测试语句
case语句是在多个范围内匹配数据,若匹配成功则执行相关命令并结束整个条件测试;如果数据在所列的范围内,则会去执行星号(*)中所定义的默认命令,语法结构如下所示:
实验:判断用户输入的数据是字母、数字还是其他字符。
[root@linuxprobe ~]# cat chkkeys.sh
#!/bin/bash
read -p "请输入一个字符:" KEY
case "$KEY" in
[a-z]|[A-Z])
echo "您输入的是字母"
;;
[-])
echo "您输入的是数字"
;;
*)
echo "您输入的是特殊字符"
esac
[root@linuxprobe ~]# bash chkkeys.sh
请输入一个字符:
您输入的是数字
[root@linuxprobe ~]# bash chkkeys.sh
请输入一个字符:s
您输入的是字母
[root@linuxprobe ~]# bash chkkeys.sh
请输入一个字符:`
您输入的是特殊字符
[root@linuxprobe ~]#
补充:上述关于检查字符的脚本是有缺陷的,当用户输入两位及以上的数字或字母时,会提示输入的是特殊字符。
[root@linuxprobe ~]# bash chkkeys.sh
请输入一个字符:
您输入的是特殊字符
解决方法:修改匹配条件,如下所示。但是当输入三位数字时,依然提示输入的是特殊字符,需要继续修改匹配条件。所以该方法只能算打补丁,不能算真正的解决方法。
[root@linuxprobe ~]# cat chkkeys.sh
#!/bin/bash
read -p "请输入一个字符:" KEY
case "$KEY" in
[a-z]|[A-Z])
echo "您输入的是字母"
;;
[-]|[-][-]) ##匹配一位或两位数字
echo "您输入的是数字"
;;
*)
echo "您输入的是特殊字符"
esac
[root@linuxprobe ~]# bash chkkeys.sh
请输入一个字符:
您输入的是数字
四、计划任务服务程序
在实际的运维工作中,需要在指定的时间段自动启动或停止某些服务或命令,从而实现运维的自动化。接下来介绍如何设置服务器的计划任务服务,把周期性、规律性的工作交给系统自动完成。
计划任务分为一次性任务和长期性任务,如下所示:
- 一次性计划任务:比如今晚11点30分开启网站服务。
- 长期性计划任务:比如每周一的凌晨3点30分把/home/www目录的文件打包备份为backup.tar.gz。
1、一次性计划任务
顾名思义,一次性计划任务只执行一次,一般用于满足临时的工作需求,可以用at命令实现这种功能,相关功能如下所示:
- at 时间 :表示创建一个一次性计划任务。
- at -l :表示查看已经设置好但未执行的一次性计划任务。
- atrm 任务序号 : 表示删除一个一次性计划任务。
实验1:设置在今天11:24重启系统主机
[root@linuxprobe ~]# at :
at> reboot
at> <此处按下Ctrl+d组合键来结束编写计划任务>
job at Sat Feb ::
[root@linuxprobe ~]# at -l
Sat Feb :: a root
[root@linuxprobe ~]#
实验2:at命令默认采用交互式的方式,接下使用非交互式的方法创建一个一次性计划任务。
[root@linuxprobe ~]# echo "systemctl restart network" | at :
job at Sat Feb ::
[root@linuxprobe ~]#
[root@linuxprobe ~]# at -l
Sat Feb :: a root //其中"4"就是任务序号
实验3:删除一个一次性计划任务。
[root@linuxprobe ~]# atrm
[root@linuxprobe ~]# at -l
[root@linuxprobe ~]#
2、长期性计划任务
Linux系统中默认启动的crond服务能够周期性地、有规律地执行某些具体的任务,相关地命令如下所示:
命令 | 作用 |
crontab -e | 创建、编辑计划任务 |
crontab -l | 查看当前地计划任务 |
crontab -r | 删除某条计划任务 |
crontab -u | 编辑他人的计划任务(必须是root身份) |
使用crond服务设置计划任务时,语法格式为“分 时 日 月 星期 命令”。需要注意的是,如果有些字段没有设置,则必须使用星号(*)占位,如下图所示:
使用crond设置任务的参数字段说明,如下表所示:
字段 | 说明 |
分 | 取值为0~59的整数 |
时 | 取值为0~23的任意整数 |
日 | 取值为0~31的任意整数 |
月 | 取值1~12的任意整数 |
星期 | 取值0~7的任意整数,其中0与7均为星期日 |
命令 | 要执行的命令或脚本(必须要用绝对路径来写) |
实验1:设置在每周一、三、五的凌晨3点25分,使用tar命令打包网站的数据。
[root@linuxprobe ~]# crontab -e //默认进入Vim编辑器界面
no crontab for root - using an empty one
crontab: installing new crontab
[root@linuxprobe ~]# crontab -l
* * ,, /usr/bin/tar -czvf backup.tar.gz /home/wwwroot
[root@linuxprobe ~]#
补充说明:这里补充几点关于时间周期的设置,如下所示:
- 用逗号(,)来表示多个时间段,如“星期”字段“1,3,5”表示周一、周三和周五。
- 用减号(-)来表示一段连续的时间周期,如“月”字段“8-12”表示8~12月。
- 用除号(/)来表示执行任务的间隔时间,如“分”字段“*/2”表示每隔2分钟执行一次任务。
crond服务可以包含多条计划任务,注意每条计划任务占一行。比如我们要增加一条计划任务,它的功能是每周一至周五的凌晨1点自动清空/tmp目录内的所有文件。
[root@linuxprobe ~]# whereis rm //使用whereis命令查询绝对路径
rm: /usr/bin/rm /usr/share/man/man1/rm..gz /usr/share/man/man1p/rm.1p.gz
[root@linuxprobe ~]#
[root@linuxprobe ~]# crontab -e
crontab: installing new crontab
[root@linuxprobe ~]# crontab -l
* * ,, /usr/bin/tar -czvf backup.tar.gz /home/wwwroot
* * - /usr/bin/rm -rf /tmp/*
注意事项:
(1)在Vim编辑器中配置计划任务时,可以以#号开头写上注释信息。
(2)计划任务中的“分”字段必须有数值,绝对不能为空或*号。
(3)“日”和“星期”字段不能同时使用,否则会发生冲突。
Linux学习Day6:编写Shell脚本的更多相关文章
- Linux学习-->如何通过Shell脚本实现发送邮件通知功能?
1.安装和配置sendmail 不需要注册公网域名和MX记录(不需要架设公网邮件服务器),通过Linux系统自带的mail命令即可对公网邮箱发送邮件.不过mail命令是依赖sendmail的,所以我们 ...
- linux环境下编写shell脚本实现启动停止tomcat服务
第一步:以管理员的身份进入控制台,在指定目录下新建一个shell脚本,我这里命名为tomcat.sh 第二步:编写shell脚本 #!/bin/bash tomcat_home=/usr/tomcat ...
- Linux学习笔记:Shell脚本学习
概念 真正能够控制计算机硬件(CPU.内存.显示器等)的只有操作系统内核(Kernel),图形界面和命令行只是架设在用户和内核之间的一座桥梁. 由于安全.复杂.繁琐等原因,用户不能直接接触内核(也没有 ...
- linux下如何编写shell脚本
我对shell脚本的认识,除了执行过同事写的shell 脚本外,其他一无所知,为了让自己强大,我决定自己研究shell脚本,也许在你看来很简答,没必要说这么多废话,但是我希望在我的技术log里记录下来 ...
- Linux学习总结《shell脚本》知识点关键-用好“过滤器”
- Git学习-->如何通过Shell脚本实现 监控Gitlab备份整个过程并且通过邮件通知得到备份结果?
一.背景 Git学习–>如何通过Shell脚本自动定时将Gitlab备份文件复制到远程服务器? http://blog.csdn.net/ouyang_peng/article/details/ ...
- linux 的基本操作(编写shell 脚本)
终于到shell 脚本这章了,在以前笔者卖了好多关子说shell脚本怎么怎么重要,确实shell脚本在linux系统管理员的运维工作中非常非常重要.下面笔者就带你正式进入shell脚本的世界吧. 到现 ...
- linux的基本操作(shell 脚本的基础知识)
shell 脚本的基础知识 日常的linux系统管理工作中必不可少的就是shell脚本,如果不会写shell脚本,那么你就不算一个合格的管理员.目前很多单位在招聘linux系统管理员时,shell脚本 ...
- 编写shell脚本遇到的问题
运行shell脚本提示“syntax error near unexpected token for((i=0;i<$length;i++))”: 原因是因为Linux下的换行符是 \n 而你在 ...
随机推荐
- Windos下的一些命令集合
由于在CMD模式下(也就是命令行)有较多的有用的命令.以下是自己平时所记录下来的以帮助平时的任务. 1. 显示计算机的操作系统 wmic os get osarchitecture /value
- 使用postman测试接口
1.什么是接口测试 其实接口测试就和普通功能测试没什么区别,区别就是功能测试是在页面上点点点,在页面上输入值,提交数据看结果,而接口测试没有页面,通过接口规范文档上的调用地址.请求参数,拼接报文,然后 ...
- equals()和hashCode()使用总结
equals()和hashCode()使用总结 equals() Object类中的equals方法和"=="是一样的,没有区别,即俩个对象的比较是比较他们的栈内存中存储的内存地址 ...
- python中Threadlocal变量
在多线程环境下,每个线程都有自己的数据.一个线程使用自己的局部变量比使用全局变量好,因为局部变量只有线程自己能看见,不会影响其他线程,而全局变量的修改必须加锁. 不加锁就会出现变量会被修改的问题,进而 ...
- 当你的程序在朋友的机器上显示丢失msvcr100d.dll的时候
0. 给朋友发了个DEMO,收到提示:丢失 msvcr100d.dll 1. 一看是运行库文件,赶紧让朋友下载并安装vc++ 2010 redistribution,朋友反馈还是提示丢失这个dll文件 ...
- BZOJ 1042 [HAOI2008]硬币购物(完全背包+容斥)
题意: 4种硬币买价值为V的商品,每种硬币有numi个,问有多少种买法 1000次询问,numi<1e5 思路: 完全背包计算出没有numi限制下的买法, 然后答案为dp[V]-(s1+s2+s ...
- (三)Mybatis类型转换器,接口传参类型,一对一,一对多查询resultMap配置
Mybatis类型转换器 首先明白什么时候用到它,当数据库的字段类型和java字段类型无法默认匹配时候进行转换,比如现在数据库类型是INTEGER,而java当中类型是Boolean,true表示1, ...
- Generator - Python 生成器
Generator, python 生成器, 先熟悉一下儿相关定义, generator function 生成器函数, 生成器函数是一个在定义体中存有 'yield' 关键字的函数. 当生成器函数被 ...
- Python LEGB (Local, Enclosing, Global, Build in) 规则
Local 一个函数定义了一个 local 作用域; PyFrameObject 中的 f_local 属性 Global 一个 module 定义了一个 global 作用域; PyFrameObj ...
- [Effective Java 读书笔记] 第二章 创建和销毁对象 第三 四条
第三条 用私有构造器或者枚举类型强化singleton属性 singleton指只能被实例化一次的类,即将构造器设置为私有,使用公有静态成员来实例化,且只实例化一次对象 第四条 通过私有构造器强化不可 ...