1月23号


一、初识shell
文件描述符与输出重定向:
在 shell 程式中,最常使用的 FD (file descriptor) 大概有三个, 分别是: 
0: Standard Input (STDIN)
1: Standard Output (STDOUT)
2: Standard Error Output (STDERR)
在标准情况下, 这些FD分别跟如下设备关联:
stdin(0): keyboard 键盘输入,并返回在前端
stdout(1): monitor 正确返回值 输出到前端
stderr(2): monitor 错误返回值 输出到前端
>a.txt
1>a.txt
2>a.txt
&>a.txt
1>&2
2>&1
一般来说, "1>" 通常可以省略成 ">".
1>&2 正确返回值传递给2输出通道 &2表示2输出通道,之前如果有定义标准错误重定向到某log文件,那么标准输出也重 定向到这个log文件,如果此处错写成 1>2, 就表示把1输出重定向到文件2中.
2>&1 错误返回值传递给1输出通道, 同样&1表示1输出通道. nginx -V
例子. 当前目录下只有a.txt,没有b.txt
[root@redhat box]# ls a.txt b.txt 1>file.out 2>&1
[root@redhat box]# cat file.out
ls: b.txt: No such file or directory
a.txt
现在, 正确的输出和错误的输出都定向到了file.out这个文件中, 而不显示在前端 =================================
[root@redhat tmp]# cat >> b.txt <<!
> ni hao a hahafvs
>!
[root@redhat tmp]# cat b.txt
ni hao a haha
补全   bash-completion # 增加补全
历史   history
别名   alias
快捷键  
前后台作业
管道
命令排序执行
; && || 
; 命令分割,在一行中执行多条语句
&& 一行中执行多条语句,前成功后面再执行
|| 一行中执行多条语句,前面不成功,后面再执行
通配符
{} ?*
正则表达式 脚本
查看历史命令
        history                         /etc/profile 下的historysize 可以修改
调用历史命令  
    上下健
    esc . 上一条命令的最后一个参数
    Ctrl+r 在历史命令中查找,输入关键字调出之前的命令 
别名
        查看别名
            alias
        设置别名 
            临时设置
      # alias aa='df -Th'
      # aa
        永久设置
      # vim /root/.bashrc
小小技巧:显示历史命令执行时间 
        1.设置变量:
            HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S" 
        2.再次执行history查看结果
二、shell 脚本规范

[root@newrain ~]# vim helloworld.sh   ---.sh代表这个文件是个shell脚本,第一个原因,让别人认的这个是shell脚本,sh后缀有高亮显示。
拓展名后缀,如果省略.sh则不易判断该文件是否为shell脚本
1. #!/usr/bin/env bash ---shebang蛇棒, 解释器, 翻译 2. #
3. #
3. # Author: newrain
4. # Email: newrain@163.com           ---这就是注释, 你没看错
5. # Github: https://github.com/newrain001
6. # Date: 2019/**/**
7. printf "hello world\n"
​
功能说明:打印hello world
[root@newrain ~]# sh helloworld.sh
hello world
[root@newrain ~]# chmod +x helloworld.sh 
[root@newrain ~]# ./helloworld.sh 
[root@newrain tmp]# /tmp/helloworld.sh 
hello world
​
# 执行脚本方式
1、 sh 脚本.sh
2、 bash 脚本.sh
3、 ./脚本.sh  # 需要执行权限
4、 .  脚本.sh
5、 source 脚本.sh
第一行: “#!/usr/bin/env bash”叫做shebang, shell语法规定shell脚本文件第一行为整个文件的解释器
第二行: 为“#”开头的行为注释行默认不会被程序所读取, 用来说明文件及标定所属人员使用, 也可用来解释程序 第七行: 为格式化打印语句printf, printf可以把后面的“hello world”打印到指定的终端中, \n 为换行符

三、变量的类型

  • 变量

  • bash作为程序设计语言和其它高级语言一样也提供使用和定义变量的功能
  • 预定义变量、环境变量、自定义变量、位置变量

预定义变量
$? 最后一次执行的命令的返回状态。如果这个变量的值为 0,则证明上一条命令正确执行;如果这个变量的值为非 0 ,则 证明上一条命令执行错误
$$ 当前进程的进程号(PID)
$! 后台运行的最后一个进程的进程号(PID)
​
[root@newrain sh]# ls
count.sh hello.sh parameter2.sh parameter.sh  #ls命令正确执行
[root@newrain sh]# echo $?
0
#预定义变量"$?"的值是0,证明上一条命令正确执
​
[root@newrain sh]# vim variable.sh 
#!/bin/bash
echo "The current process is $$" 
#输出当前进程的PID 
#这个PID就是variable.sh脚本执行时生成的进程的PID
​
[root@newrain sh]# sleep 3000 & 
[1] 12165 
#符号"&"的意思是把命令放入后台执行 
[root@newrain sh]# echo $!
12165

自定义变量
        定义:变量名称=值
                变量名称:只能由字母,数字,下划线组成,不能以数字开头;
                注意:应该让变量名称有意义;
                = 赋值符号 前后不能有空格 ;
                值: 所有的字符串和数字都可以;
                引用变量: $变量名 或 ${变量名}。
        示例:
            [root@newrain ~]# a=100
                [root@newrain ~]# echo $a
                100
                [root@newrain ~]# echo $aa
                                # 这里输出为空,因为解释器认为$aa是变量
                [root@newrain ~]# echo ${a}a
                100a
​
                查看变量: echo $变量名 set(所有变量:包括自定义变量和环境变量)
                取消变量: unset 变量名 仅在当前shell中有效
                作用范围: 仅在当前shell中生效

环境变量
        shell在开始执行时已经定义好的 
        env 查看所有环境变量
        set 查看所有变量 
                环境变量拥有可继承性:export之后就拥有继承性
        export 导出变量(作用范围) 
临时生效
    [root@newrain ~]# IPADDR=192.168.1.1
        [root@newrain ~]# echo $IPADDR
        192.168.1.1
永久生效
        写到4个登陆脚本中 ~/.bashrc ~/profile 更好放在/etc/profile.d/* 下建立独立的环境变量配置文件
        常用环境变量:USER UID HOME HOSTNAME PWD PS1 PATH
PATH:存储所有命令所在的路径
练习1
编写一个shell脚本,用于搜集其执行主机的信息,打印结果如下: 
    [root@tiger tmp]# ./test.sh
    2012年 05月 24日 星期四 17:07:45 CST
    当前的用户为 root
    当前用户的宿主目录为 /root 用户的标识为 0
    主机名称为 newrain
    网卡的IP地址为 192.168.1.106
##脚本源码如下
#!/usr/bin/bash
# 获取主机基本信息
time=`date +%y年%m月%d日-%H:%M`
ip=`ifconfig eth0|grep inet|awk '{print $2}'` echo "现在的时间是:" $time
echo "当前的用户是:" $USER
echo "当前的用户标识:" $UID
echo "当前的主机名称是:" $HOSTNAME
echo "当前可用网卡IP是:" $ip
取根分区剩余空间:
        # df -h /dev/sda2 |awk 'NR==2{print $4}' 371G
取当前系统剩余内存:
        # echo "现在的剩余内存是:"`free -m |awk 'NR==2{print $4}'`
        现在的剩余内存是:12813M
取当前cpu平均负载:
        # echo 现在cpu的`uptime |cut -d, -f3-` //-d指定分隔符,-f指定显示区域,3-第三列以后(包括第三列)
        现在cpu的 load average: 0.07, 0.12, 0.11
        # echo 现在cpu的`uptime |awk -F"," '{print $4,$5,$6}'`
        现在cpu的 load average: 0.00 0.04 0.1
练习2

位置变量
    $1 $2 $3 $...
    #/test.sh start
    #/test.sh 2 3 5 hello
    start是第1个位置参数
        2 是第1个位置参数
        3 是第2个 依次类推
例子:
[root@newrain shell]# cat weizhi.sh
#!/bin/bash
#...
echo 我的第一个位置参数是:$1
echo 我的第二个位置参数是:$2
echo 我的第三个位置参数是:$3
echo 我的第四个位置参数是:$4
echo 一共有 $# 个位置参数
echo 你输入的参数分别是:$*

求出第一个参数和第二个参数的和
./5.sh 4 5
9
./5.sh 10 20 30
#!/bin/bash
# 求 $1 $2 的和
x=${1:-0}
y=${2:-0}
echo $(($x+$y))

四、脚本运行

创建bash脚本(shell脚本)

1.创建脚本文件 
        指定命令解释器
        注释
        编写bash指令集合 (脚本内容)
2.修改权限 chmod +x scriptname

bash脚本执行

#./scripts
#/shelldoc/scripts
#. ./scripts 使用当前shell执行
#source ./scripts 使用当前shell执行 比如cd /tmp会改变当前shell环境,但是其他的方式不会 
#bash scripts

子shell

[root@mysql ~]# vim bash.sh
cd /opt/
pwd
[root@mysql ~]# sh bash.sh 
/opt
[root@mysql ~]# source bash.sh 
/opt
[root@mysql opt]#

bash 脚本测试

•sh –x script
     这将执行该脚本并显示所有变量的值
•sh –n script
         不执行脚本只是检查语法模式,将返回所有错误语法
•sh –v script
     执行脚本前把脚本内容显示在屏幕上

五、变量置换

命令替换

a=`date +%m%d` 
a=$(date +%m%d) 
反引号亦可用$() 代替

聚合数据

curl -k -i -d "key=********************&date=1/1" http://v.juhe.cn/todayOnhistory/queryEvent.php

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐