编程基础

程序:算法+数据结构(数据是程序的核心)
数据结构是数据在计算机中的类型和组织方式
算法是处理数据的方式

  • 程序编程风格

①面向过程语言
做一件事情,排出个步骤,第一步干什么,第二步干什么,如果出现情况A,做什么处理,如
果出现了情况B,做什么处理
问题规模小,可以步骤化,按部就班处理
以指令为中心,数据服务于指令
C,shell
②面向对象语言
一种认识世界、分析世界的方法论。将万事万物抽象为各种对象
类是抽象的概念,是万事万物的抽象,是一类事物的共同特征的集合
对象是类的具象,是一个实体
问题规模大,复杂系统
以数据为中心,指令服务于数据
java,C#,python,golang等

  • 编程语言

编程语言:人与计算机之间交互的语言
①低级编程语言
机器:二进制的0和1的序列,称为机器指令
汇编:用一些助记符号替代机器指令,称为汇编语言
②高级编程语言
编译:高级语言—>编译器—>机器代码文件—>执行,如:C,C++
解释:高级语言—>执行—>解释器—>机器代码,如:shell,python,php,JavaScript,perl

  • 编程逻辑处理方式

顺序执行:程序按从上到下顺序执行
选择执行:程序执行过程中,根据条件的不同,进行选择不同分支继续执行
循环执行:程序执行过程中需要重复执行多次某段语句

第一个脚本

编程语言的基本结构:

  • 各种系统命令的组合
  • 数据存储:变量、数组
  • 表达式:a + b
  • 控制语句:if

shell脚本编程:是基于过程式、解释执行的语言
shell脚本:包含一些命令或声明,并符合一定格式的文本文件

第①步:使用文本编辑器来创建文本文件

第一行必须包括shell声明序列:#!(首行shebang机制)
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl

  1. #!/bin/bash
  2. #---------------------------------------------
  3. #Filenme: hello.sh
  4. #Vision: CentOS Linux 7
  5. #data: 2021/08/09
  6. #Auther: zhuyuany
  7. #Description: This is my first script
  8. #---------------------------------------------
  9. echo 'hello world'
  10. 配置vim工作特性
  11. vim /etc/vim/vimrc
  12. set ts=4
  13. set expandtab
  14. set ignorecase
  15. set autoindent
  16. autocmd BufNewFile *.sh exec ":call SetTitle()"
  17. func SetTitle()
  18. if expand("%:e") == 'sh'
  19. call setline(1,"#!/bin/bash")
  20. call setline(2,"#")
  21. call setline(3,"#----------------+---------------------------------------+")
  22. call setline(4,"#Author : zhuyuany")
  23. call setline(5,"#Email : 2298408548@qq.com")
  24. call setline(6,"#Date : ".strftime("%Y-%m-%d"))
  25. call setline(7,"#Filename : ".expand("%"))
  26. call setline(8,"#Description :")
  27. call setline(9,"#----------------+---------------------------------------+")
  28. call setline(10,"")
  29. endif
  30. endfunc
  31. autocmd BufNewFile * normal G

第②步:加执行权限

给予执行权限,在命令行上指定脚本的绝对或相对路径

[root@CentOS /data]$ chmod +x hello.sh

第③步:运行脚本

[root@CentOS ~]$ /data/hello.sh    (#绝对路径)
[root@CentOS /data]$ ./hello.sh    (#相对路径)
[root@CentOS /data]$ cp /data/hello.sh /usr/local/bin/(#放在外部命令执行路径path变量下,就可以直接执行脚本了)
[root@CentOS /data]$ ln -s /data/hello.sh /usr/bin    (#或者在/usr/bin下面建立软连接)

[root@CentOS /data]$ mkdir script
[root@CentOS /data]$ mv hello.sh script/
[root@CentOS /data]$ cd script
[root@CentOS /data/script]$ echo 'PATH=/data/script:$PATH' >> /etc/profile.d/env.sh    (#直接将脚本路径写入PATH变量中去)
[root@CentOS /data/script]$ . /etc/profile.d/env.sh (#更新)
[root@CentOS /data/script]$ echo $PATH
/data/script:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@CentOS /data/script]$ hello.sh
hello world

[root@CentOS ~]$ bash /data/hello.sh            (#没有执行权限时可用此方法执行,测试用)
[root@CentOS ~]$ cat /data/hello.sh | bash    (#工作中以实现执行远程主机的shell脚本,该脚本文件可在网络中获得)
[root@CentOS ~]$ curl http://192.168.50.146/hello.sh    (#curl可以实现命令行代替浏览器的功能)
#!/bin/bash
#---------------------------------------------
#Filenme:       hello.sh
#Vision:        CentOS Linux 7
#data:          2021/08/09
#Auther:        zhuyuany
#Description:   This is my first script
#---------------------------------------------
echo 'hello world'
[root@CentOS ~]$ curl http://192.168.50.146/hello.sh |bash    (#把程序放在网上,通过网络下载执行其他服务器的脚本。)
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   273  100   273    0     0  70872      0 --:--:-- --:--:-- --:--:-- 91000
hello world

备份脚本

#!/bin/bash
#
#----------------+---------------------------------------+
#Author        : zhuyuany
#Email           : 2298408548@qq.com
#Date           : 2021-08-07
#Filename      : /data/script/backup.sh
#Description   :this is backup shell
#
#----------------+---------------------------------------+
echo -e "\033[31mStarting backup...\033[0m"
sleep 3
cp -av /etc/ /data/etc`date +%F-%H-%M-%S`/
echo -e "\033[31mBackup finished!\033[0m"

shell 脚本调试

  • 语法错误,会导致后续的命令不继续执行,可以用bash -n 检查错误,提示的出错行数不一定是准确的
  • 命令错误,默认后续的命令还会继续执行,用bash -n 无法检查出来 ,可以使用 bash -x 进行观察
  • 逻辑错误:只能使用 bash -x 进行观察

bash -``n`` file (只检测脚本中的语法错误,但无法检查出命令错误,但不真正执行脚本)
bash -``x`` file (调试并执行)

shell中不能用别名

set 命令实现脚本安全

-u 在扩展一个没有设置的变量时,显示错误信息, 等同set -o nounset (只关心变量不关心命令,很危险!)
-e 如果一个命令返回一个非0退出状态值(失败)就退出, 等同set -o errexit (错误则退出,不再继续执行)
-x 当执行命令时,打印命令及其参数,类似 bash -x
-o option 显示,打开或者关闭选项
显示选项:set -o
打开选项:set -o 选项
关闭选项:set +o 选项

运算

算术运算

(1) let var=算术表达式
(2) ((var=算术表达式)) 和上面等价
(3) var=$[算术表达式]
(4) var=$((算术表达式))
(5) var=$(expr arg1 arg2 arg3 …)
(6) declare -i var = 数值
(7) echo ‘算术表达式’ | bc

[root@localhost ~]$ j=8
[root@localhost ~]$ k=2
[root@localhost ~]$ l=$j+$k
[root@localhost ~]$ echo $l
8+2
[root@localhost ~]$ let l=j+k    (#①shell中的算数运算,用let)
[root@localhost ~]$ echo $l
10
[root@localhost ~]$ echo $[j+k]    (#②shell中的算数运算,用$[])
10
[root@localhost ~]$ echo $[$j+$k]
10
[root@localhost ~]$ echo $[j*k]
[root@localhost ~]$ echo $((j*k))    #③shell中的算数运算,用$(())
16
[root@CentOS ~]$ expr $j + $k    (#④shell中的算数运算,用expr)
10
[root@CentOS ~]$ expr $j \* $k                           (shell中用*运算时,需要用转义符)
16
[root@CentOS ~]$ declare -i x    (#⑤shell中的算数运算,用declare)
[root@CentOS ~]$ x=j+k
[root@CentOS ~]$ echo $x
10
[root@CentOS ~]$ echo $j*$k
8*2
[root@CentOS ~]$ echo $j*$k |bc    (#⑥shell中的算数运算,用bc)
16

1、内建的随机数生成器变量:$RANDOM
(0~32767)取一定范围内的随机数

[root@CentOS ~]$ echo $[RANDOM%7+31]    (#对7取模,取31~37的随机数,0≤RANDOM%7≤7)
37
[root@CentOS ~]$ echo $[RANDOM%7+31]
34

[root@CentOS ~]$ echo -e "\033[1;$[RANDOM%7+31]mzhuyuany\033[0m"    (#取随机颜色)
zhuyuany

2、增强型赋值(let才支持)
let`` varOPERvalue
+= i+=10 相当于 i=i+10
-= i-=j 相当于 i=i-j
*=
/=
%=
++ i++,++i 相当于 i=i+1
i—,—i 相当于 i=i-1

[root@centos8 ~]#unset i j ; i=1; let j=i++; echo "i=$i,j=$j"        (#先赋值,再增强)
i=2,j=1
[root@centos8 ~]#unset i j ; i=1; let j=++i; echo "i=$i,j=$j"        (#先增强,再赋值)
i=2,j=2

逻辑运算

  1. true, false

1 true 0 false

  1. 与:&:和0相与,结果为0,和1相与,结果保留原值 1&1=1,1&0=0,0&1=0,0&0=0
  2. 或:|:和1相或结果为1,和0相或,结果保留原值 1|1=1 ,1|0=1 ,0|1=1 ,0|0=0
  3. 非:! !0=1 !1=0
  4. 异或:^ 相同为假,不同为真 ```bash [root@CentOS ~]$ echo $? (#查看上一个命令是否运行成功) 0 [root@CentOS ~]$ x=10;y=20;temp=$x;x=$y;y=$temp;echo x=$x,y=$y x=20,y=10 [root@CentOS ~]$ x=10;y=20;x=$[x^y];y=$[x^y];x=$[x^y];echo x=$x,y=$y (#x,y,temp中间值的异或关系) x=20,y=10

6. 短路运算
- 短路与

`CMD1 短路与 CMD2`<br />第一个CMD1结果为真 (1),第二个CMD2必须要参与运算,才能得到最终的结果  <br />第一个CMD1结果为假 (0),总的结果必定为0,因此不需要执行CMD2 

- 短路或

`CMD1 短路或 CMD2`<br />第一个CMD1结果为真 (1),总的结果必定为1,因此不需要执行CMD2<br />第一个CMD1结果为假 (0),第二个CMD2 必须要参与运算,才能得到最终的结果
<a name="LT6Cl"></a>
### 变量
变量表示命名的内存空间,将数据放在内存空间中,通过变量名引用,获取数据

- 变量类型:内置变量 (如:PS1,PATH,UID,HOSTNAME,$$,BASHPID,PPID,$?,HISTSIZE)

                     用户自定义变量 <br />不同的变量存放的数据不同,决定了:<br />数据存储方式<br />参与的运算<br />表示的数据范围

- 变量数据类型:

字符<br />数值:整型、浮点型,bash 不支持浮点数

- 编程语言分类

静态编译语言:使用变量前,先声明变量类型,之后类型不能改变,在编译时检查,如:java,c<br />         动态编译语言:不用事先声明,可随时改变类型,如:bash,Python<br />强类型语言:不同类型数据操作,必须经过强制转换才同一类型才能运算,如java , c# ,<br />弱类型语言:语言的运行时会隐式做数据类型转换。无须指定类型,默认均为字符型;参与运算会自动进行隐式类型转换;变量无须事先定义可直接调用如bash ,php,,

- 变量定义和引用

**普通变量**:生效范围为当前shell进程;对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效<br />**环境变量**:生效范围为当前shell进程及其子进程<br />**本地变量**:生效范围为当前shell进程中某代码片断,通常指函数


创建变量:`name='value' `<br />(直接字串:name='root'<br />   变量引用:name="$USER"<br />   命令引用:name=`COMMAND` 或者 name=$(COMMAND) )
```bash
[root@CentOS ~]$ pstree -p
[root@CentOS ~]$ echo $BASHPID    (#查看当前的shell进程)
29905
[root@CentOS ~]$ bash     (#每运行一次就生成一个子进程)
[root@CentOS ~]$ echo $BASHPID
30011
[root@CentOS ~]$ NAME=wang
[root@CentOS ~]$ TEACHER=$NAME
[root@CentOS ~]$ echo $TEACHER
wang
[root@CentOS ~]$ NAME=zhu        (#新开一个数据块)
[root@CentOS ~]$ echo $TEACHER
wang

删除变量:unset <name> (明确销毁;退出bash,自动销毁)

环境变量

可以使子进程(包括孙子进程)继承父进程的变量,但是无法让父进程使用子进程的变量 (一般只在系统配置文件中使用,在脚本中较少使用)
声明并赋值
export`` name=VALUE
declare -x`` name=VALUE
显示所有环境变量:
env
printenv
export
declare -x
删除变量
unset name
bash内建的环境变量 :
PATH
SHELL
USER
UID
HOME
PWD
SHLVL #shell的嵌套层数,即深度
LANG
MAIL
HOSTNAME
HISTSIZE
_ #下划线 表示前一命令的最后一个参数

只读变量

只读变量:只能声明定义,但后续不能修改和删除,即常量
声明只读变量
readonly`` name
declare -r`` name
查看只读变量
readonly [-p]
declare -r

位置变量

位置变量:在bash shell中内置的变量, 在脚本代码中调用通过命令行传递给脚本的参数
$1, $2, … 对应第1个、第2个等参数,shift [n]换位置
$0 命令本身,包括路径
$* 传递给脚本的所有参数,全部参数合为一个字符串
$@ 传递给脚本的所有参数,每个参数为独立字符串(注意:$@ $ 只在被双引号包起来的时候才会有差异)
*$#
传递给脚本的参数的个数

[root@CentOS ~]$ cat /data/script/args.sh
#!/bin/bash
echo "first is $1"
echo "second is $2"
echo "10th is $10"            (#需要用用括号括起来)

echo "all are $*"
echo "all are $@"

echo "all numbers  are $#"
echo "all are $*"

echo "the scriptname is $0"

[root@CentOS ~]$ bash /data/script/args.sh {a..z}
first is a    (# $1,第1个参数)
second is b    (# $2,第2个参数)
10th is a0
all are a b c d e f g h i j k l m n o p q r s t u v w x y z    (# $*,所有参数)
all are a b c d e f g h i j k l m n o p q r s t u v w x y z    (# $@,所有参数)
all numbers  are 26    (# $#,所有参数个数)
all are a b c d e f g h i j k l m n o p q r s t u v w x y z
the scriptname is /data/script/args.sh    (# $0,命令本身,包括路径)
[root@CentOS ~]$ cat /data/script/scp.sh
#!/bin/bash
#scp $* mage@172.16.0.8:/data/script            
scp $* root@192.168.50.137/data/script        (#复制本地文件到其他主机的脚本)

[root@CentOS ~]$ bash /data/script/scp.sh /data/script/scp.sh        (#复制/data/script/scp.sh到其他主机)
The authenticity of host '192.168.50.137 (192.168.50.137)' can't be established.
ECDSA key fingerprint is SHA256:OWb0Jm/suTUYICtYX1uEOksisidRFem10iHdEcr4tUs.
ECDSA key fingerprint is MD5:1d:07:3f:6c:e0:7a:90:58:be:ab:2f:86:16:ab:fc:b3.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.50.137' (ECDSA) to the list of known hosts.
root@192.168.50.137's password: 
scp.sh                                                 100%  357   121.3KB/s   00:00

退出状态码变量

进程执行后,将使用变量 $? 保存状态码的相关数字,不同的值反应成功或失败,$? 取值范例 0-255
$?的值为0 #代表成功
$?的值是1到255 #代表失败
用户可以在脚本中使用以下命令自定义退出状态码:exit [n]

[root@CentOS ~]$ ping -c1 192.168.50.137 &> /dev/null
[root@CentOS ~]$ echo $?
0
[root@CentOS ~]$ ping -c1 192.168.50.123 &> /dev/null
[root@CentOS ~]$ echo $?
1

[root@CentOS ~]$ cat /data/script/hello.sh
#!/bin/bash
exit 100
[root@CentOS ~]$ bash /data/script/hello.sh &> /dev/null
[root@CentOS ~]$ echo $?
100

展开命令行

展开命令执行顺序
把命令行分成单个命令词
展开别名
展开大括号的声明{}
展开波浪符声明 ~
命令替换$() 和 <br />再次把命令行分成命令词<br />展开文件通配*、?、[abc]等等<br />准备I/0重导向 <、><br />运行命令<br />防止扩展<br />反斜线\ 会使随后的字符按原意解释<br />单引号'' 防止所有扩展(六亲不认)<br />反引号 命令和变量都能识别(最聪明)
双引号”” 不能识别命令,但能识别变量
感叹号! 历史命令替换

条件测试命令

  • test EXPRESSION (#EXPRESSION前后必须有空白字符)
  • [ EXPRESSION ] #和test 等价,建议使用 [ ]
  • [[ EXPRESSION ]]

若真,则状态码变量 $? 返回0
若假,则状态码变量 $? 返回1

1.变量测试

判断 NAME 变量是否定义
test -v NAME
[ -v NAME ]

[root@CentOS ~]$ x=10
[root@CentOS ~]$ test -v x
[root@CentOS ~]$ echo $?
0
[root@CentOS ~]$ [ -v x ]
[root@CentOS ~]$ echo $?
0

2.数值测试

-eq 是否等于
-ne 是否不等于
-gt 是否大于
-ge 是否大于等于
-lt 是否小于
-le 是否小于等于

[root@CentOS ~]$ [ 10 -gt 8 ]
[root@CentOS ~]$ echo $?
0

3.字符串测试

test[ ] 的用法
-z STRING 字符串是否为空,没定义或空为真,不空为假,
-n STRING 字符串是否不空,不空为真,空为假
STRING 同上
STRING1 = STRING2 是否等于,注意 = 前后有空格
STRING1 != STRING2 是否不等于
> ascii码是否大于ascii码
< 是否小于
[[ expression ]] 当使用正则表达式或通配符使用[[ ]],其它情况一般使用 [ ]
() 会开启子进程,{}仅仅在当前shell中执行
== 左侧字符串是否和右侧的PATTERN相同 注意:此表达式用于[[ ]]中,PATTERN为通配符
=~ 左侧字符串是否能够被右侧的正则表达式的PATTERN所匹配 注意: 此表达式用于[[ ]]中;扩展的正则表达式

[root@CentOS ~]$ FILE=test.log
[root@CentOS ~]$ [[ "$FILE" == *.log]]
> ^C
[root@CentOS ~]$ [[ "$FILE" == *.log ]]
[root@CentOS ~]$ echo $?
0
[root@CentOS ~]$ [[ "$FILE" != *.log ]]
[root@CentOS ~]$ echo $?
1
[root@CentOS ~]$ [[ "$FILE" =~ \.log ]]
[root@CentOS ~]$ echo $?
0

[root@CentOS ~]$ [[ "$N" =~ ^[0-9]+$ ]]        (#判断是否是数字)
[root@CentOS ~]$ echo $?
0
[root@CentOS ~]$ [[ "$IP" =~ ([0-9]{1,3}.){3}[0-9]{1,3} ]]        (#判断是否是ip地址格式)
[root@CentOS ~]$ echo $?
0

4.文件测试

  1. 存在性测试

-a FILE:同 -e -f FILE:是否存在且为普通文件
-e FILE: 文件存在性测试,存在为真,否则为假 -h FILE 或 -L FILE:存在且为符号链接文件
-b FILE:是否存在且为块设备文件 -p FILE:是否存在且为命名管道文件
-c FILE:是否存在且为字符设备文件 -S FILE:是否存在且为套接字文件
-d FILE:是否存在且为目录文件

  1. 文件权限测试

-r FILE:是否存在且可读 -u FILE:是否存在且拥有suid权限
-w FILE: 是否存在且可写 -g FILE:是否存在且拥有sgid权限
-x FILE: 是否存在且可执行 -k FILE:是否存在且拥有sticky权限

  1. 文件属性测试

-s FILE #是否存在且非空 -O FILE #当前有效用户是否为文件属主
-t fd #fd 文件描述符是否在某终端已经打开 -G FILE #当前有效用户是否为文件属组
-N FILE #文件自从上一次被读取之后是否被修改过
FILE1 -ef FILE2 #FILE1是否是FILE2的硬链接
FILE1 -nt FILE2 #FILE1是否新于FILE2(mtime)
FILE1 -ot FILE2 #FILE1是否旧于FILE2

5.组合测试条件

第一种方式 [ ] -a 和 -o 需要使用测试命令进行,[[ ]] 不支持
[ EXPRESSION1 ``-a`` EXPRESSION2 ]并且,EXPRESSION1和EXPRESSION2都是真,结果才为真
[ EXPRESSION1 ``-o`` EXPRESSION2 ]或者,EXPRESSION1和EXPRESSION2只要有一个真,结果就为真
[ ``!`` EXPRESSION ]取反

[root@CentOS ~]$ [ -f $FILE -a -x $FILE ]
[root@CentOS ~]$ echo $?
0

第二种方式
COMMAND1 ``&&`` COMMAND2 #并且,短路与,代表条件性的AND THEN(如果COMMAND1 成功,将执行COMMAND2,否则,将不执行COMMAND2)
COMMAND1`` ||`` COMMAND2 #或者,短路或,代表条件性的OR ELSE (如果COMMAND1 成功,将不执行COMMAND2,否则,将执行COMMAND2)
! ``COMMAND #非,取反

[root@CentOS ~]$ id wu &> /dev/null || useradd wu            (#该账号不存在则新建一个新的账号)
[root@CentOS ~]$ getent passwd wu
wu:x:1001:1001::/home/wu:/bin/bash
[root@CentOS ~]$ [ $[RANDOM%6] -eq 0 ] && rm -rf /data/hello || echo "click"
click

#网络状态判断
[root@CentOS ~]$ cat /data/scripts/ping.sh                        (#注意:()和{}的区别:()会开启子进程,所以用{})
#!/bin/bash
ping -c1 -W1 $1 &> /dev/null && echo "$1 is up" || {  echo "$IP is 
unreachable"; exit; }
echo "script is finished"
[root@CentOS ~]$ bash /data/script/ping.sh 192.168.50.137
192.168.50.137 is up
script is finished

磁盘空间警报

[root@localhost /data]$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sda2      104806400 5969044  98837356   6% /
/dev/sda5       52403200  398468  52004732   1% /data
/dev/sda1         999320  909792     20716  98% /boot
tmpfs             184384    1168    183216   1% /run/user/42
tmpfs             184384       4    184380   1% /run/user/0
[root@localhost /data]$ cat /data/script/disk_check.sh
#!/bin/bash
WARNING=80
SPACE_USERED=`df |grep "^/dev/*" |tr -s ' ' % |cut -d% -f5 |sort -n |tail -n1`
[ "$WARNING" -ge "$SPACE_USERED" ] || echo -e "disk used is $SPACE_USERED,will be full\nplease be careful!" |mail -s "disk warning" root
[root@localhost /data]$ bash /data/script/disk_check.sh
[root@localhost /data]$ mail
disk used is 98,will be full
please be careful!

格式化输出printf

image.png

image.pngimage.png
说明:%s 中的数字代表此替换符中的输出字符宽度,不足补空格,默认是右对齐,%-10s表示10个字符宽,- 表示左对齐

[root@centos8 ~]#printf "%s\n" 1 2 3 4
1
2
3
4
[root@centos8 ~]#printf "%s %s \n" 1 2 3 4
1 2
3 4
[root@centos8 ~]#printf "%f\n" 1 2 3 4
1.000000
2.000000
3.000000
4.000000
#.2f 表示保留两位小数
[root@centos8 ~]#printf "%.2f\n" 1 2 3 4
1.00
2.00
3.00
4.00
[root@centos8 ~]#printf "(%s)" 1 2 3 4;echo 
(1)(2)(3)(4)
[root@centos8 ~]#printf " (%s) " 1 2 3 4;echo ""
 (1) (2) (3) (4) 
[root@centos8 ~]#printf "(%s)\n" 1 2 3 4
(1)
(2)
(3)
(4)
[root@centos8 ~]#printf "%s %s\n" 1 2 3 4
1 2
3 4
[root@centos8 ~]#printf "%s %s %s\n" 1 2 3 4
1 2 3
4  
#%-10s 表示宽度10个字符,左对齐
[root@centos8 ~]#printf "%-10s %-10s %-4s %s \n" 姓名 性别 年龄 体重 小明 男 20 70 小红 女 18 50
姓名     性别     年龄   体重
小明     男        20   70
小红     女        18   50
#将十进制的17转换成16进制数
[root@centos8 ~]#printf "%X" 17
11[root@centos8 ~]#
#将十六进制C转换成十进制
[root@centos8 ~]#printf "%d\n" 0xC
12
[root@centos8 ~]#VAR="welcome to Magedu";printf "\033[1;31m%s\033[0m\n" $VAR
welcome
to
Magedu
[root@centos8 ~]#VAR="welcome to Magedu";printf "\033[1;31m%s\033[0m\n" "$VAR"
welcome to Magedu

read命令接受输入

使用read来把输入值分配给一个或多个shell变量,read从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量,如果变量名没有指定,默认标准输入的值赋值给系统内置变量REPLY
read [options] [name ...]
-p 指定要显示的提示 -d ‘字符’ 输入结束符
-s 静默输入,一般用于密码 -t N TIMEOUT为N秒
-n N 指定输入的字符长度N

[root@CentOS ~]$ read
zhu        
[root@CentOS ~]$ echo $REPLY        (#变量名没有指定,默认标准输入的值赋值给系统内置变量REPLY)
zhu
[root@CentOS ~]$ read NAME TITLE
zhu cute
[root@CentOS ~]$ echo $NAME
zhu
[root@CentOS ~]$ echo $TITLE
cute
[root@CentOS ~]$ echo zhuyuany | { read NAME; echo $NAME; }        (#支持重定向管道输出,但会开启一个子进程)
zhuyuany

[root@CentOS ~]$ cat /data/script/scp.sh
#!/bin/bash
#scp $* mage@172.16.0.8:/data/script
read -p "please input copy file name: " FILE    
scp $FILE root@192.168.50.137:/data/script
[root@CentOS ~]$ bash /data/script/scp.sh        (#跨主机文件复制用read实现)
please input copy file name: /data/script/scp.sh
root@192.168.50.137's password: 
scp.sh              100%  405   249.9KB/s   00:00

范例:鸡兔同笼算法,今有雉兔同笼,上有三十五头,下有九十四足,问雉兔各几何?

bash的配置文件

bash shell的配置文件(按生效范围)
全局配置: 个人配置:
/etc/profile ~/.bash_profile
/etc/profile.d/*.sh ~/.bashrc
/etc/bashrc
shell登录两种方式
交互式登录

  1. 直接通过终端输入账号密码登录
  2. 使用 su - UserName 切换的用户

配置文件执行顺序:(文件之间的调用关系,写在同一个文件的不同位置,将影响文件的执行顺序 )
/etc/profile.d/*.sh → /etc/bashrc → /etc/profile → /etc/bashrc(#此文件执行两次) → ~/.bashrc → ~/.bash_profile
非交互式登录

  1. su UserName
  2. 图形界面下打开的终端
  3. 执行脚本
  4. 任何其它的bash实例

执行顺序:/etc/profile.d/*.sh → /etc/bashrc → .bashrc
按功能划分

  1. Profile类(为交互式登录的shell提供配置:用于定义环境变量;运行命令或脚本)

全局:/etc/profile, /etc/profile.d/*.sh
个人:~/.bash_profile

  1. Bashrc类(为非交互式和交互式登录的shell提供配置:定义命令别名和函数;定义本地变量)

全局:/etc/bashrc
个人:~/.bashrc
编辑配置文件生效
修改profile和bashrc文件后需生效两种方法:

  1. 重新启动 shell进程
  2. source|. 配置文件:. ~/.bashrc

Bash 退出任务
保存在~/.bash_logout文件中(用户),在退出登录shell时运行 (创建自动备份;清除临时文件)