编程基础
程序:算法+数据结构(数据是程序的核心)
数据结构是数据在计算机中的类型和组织方式
算法是处理数据的方式
- 程序编程风格
①面向过程语言
做一件事情,排出个步骤,第一步干什么,第二步干什么,如果出现情况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
#!/bin/bash
#---------------------------------------------
#Filenme: hello.sh
#Vision: CentOS Linux 7
#data: 2021/08/09
#Auther: zhuyuany
#Description: This is my first script
#---------------------------------------------
echo 'hello world'
配置vim工作特性
vim /etc/vim/vimrc
set ts=4
set expandtab
set ignorecase
set autoindent
autocmd BufNewFile *.sh exec ":call SetTitle()"
func SetTitle()
if expand("%:e") == 'sh'
call setline(1,"#!/bin/bash")
call setline(2,"#")
call setline(3,"#----------------+---------------------------------------+")
call setline(4,"#Author : zhuyuany")
call setline(5,"#Email : 2298408548@qq.com")
call setline(6,"#Date : ".strftime("%Y-%m-%d"))
call setline(7,"#Filename : ".expand("%"))
call setline(8,"#Description :")
call setline(9,"#----------------+---------------------------------------+")
call setline(10,"")
endif
endfunc
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
(调试并执行)
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
逻辑运算
- true, false
1 true 0 false
- 与:&:和0相与,结果为0,和1相与,结果保留原值 1&1=1,1&0=0,0&1=0,0&0=0
- 或:|:和1相或结果为1,和0相或,结果保留原值 1|1=1 ,1|0=1 ,0|1=1 ,0|0=0
- 非:! !0=1 !1=0
- 异或:^ 相同为假,不同为真 ```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.文件测试
- 存在性测试
-a FILE:同 -e -f FILE:是否存在且为普通文件
-e FILE: 文件存在性测试,存在为真,否则为假 -h FILE 或 -L FILE:存在且为符号链接文件
-b FILE:是否存在且为块设备文件 -p FILE:是否存在且为命名管道文件
-c FILE:是否存在且为字符设备文件 -S FILE:是否存在且为套接字文件
-d FILE:是否存在且为目录文件
- 文件权限测试
-r FILE:是否存在且可读 -u FILE:是否存在且拥有suid权限
-w FILE: 是否存在且可写 -g FILE:是否存在且拥有sgid权限
-x FILE: 是否存在且可执行 -k FILE:是否存在且拥有sticky权限
- 文件属性测试
-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
说明:%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从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量,如果变量名没有指定,默认标准输入的值赋值给系统内置变量REPLYread [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登录两种方式
交互式登录
- 直接通过终端输入账号密码登录
- 使用 su - UserName 切换的用户
配置文件执行顺序:(文件之间的调用关系,写在同一个文件的不同位置,将影响文件的执行顺序 )
/etc/profile.d/*.sh → /etc/bashrc → /etc/profile → /etc/bashrc(#此文件执行两次) → ~/.bashrc → ~/.bash_profile
非交互式登录
- su UserName
- 图形界面下打开的终端
- 执行脚本
- 任何其它的bash实例
执行顺序:/etc/profile.d/*.sh → /etc/bashrc → .bashrc
按功能划分
- Profile类(为交互式登录的shell提供配置:用于定义环境变量;运行命令或脚本)
全局:/etc/profile, /etc/profile.d/*.sh
个人:~/.bash_profile
- Bashrc类(为非交互式和交互式登录的shell提供配置:定义命令别名和函数;定义本地变量)
全局:/etc/bashrc
个人:~/.bashrc
编辑配置文件生效
修改profile和bashrc文件后需生效两种方法:
- 重新启动 shell进程
- source|. 配置文件:
. ~/.bashrc
Bash 退出任务
保存在~/.bash_logout
文件中(用户),在退出登录shell时运行 (创建自动备份;清除临时文件)