shell私房菜part3

本文详细介绍如何使用Shell脚本处理复杂的数据库导出任务,包括变量赋值、函数编写、条件判断及后台执行等内容。

shell私房菜part1 传送门

 shell私房菜part2 传送门

命令行下工作的shell和写成文件的shell脚本没有本质的不同,就重用性来看,写成文件的shell当然很好,天然可重用无压力;

一条命令行shell使用后可以通过上下箭头再翻出来,还可以通过history命令找出来,history可以记录你最近执行的n条命令,我的开发机上,n=2000,so不要用shell干坏事哦。

 

当需要用shell处理的事情变得复杂,把shell写在文件里是明智的选择。此时你将使用到shell的变量赋值、判断、函数,请听我一一道来。

 

首先来看看写shell脚本文件的“起手式”

#!/bin/bash

 

Shell有多种啦,还是因为出现的时间久,大牛多,无组织无纪律很容易就搞到自成体系。

在linux系统下,默认的shell是bash,我们基本上只玩linux,那么就把bash弄明白就好。

在第一行写上这行文字目的就是告诉内核,明确用系统中的特定位置的bash来执行之后的shell脚本。

 

起手式打好,我们来说说这次的case :

  • 我当时要为“搜索引擎”准备xml数据,需要从数据库中把数据dump出来放到文件里,供后续的处理程序计算使用。
  • 店铺数据比较多啊,数据库中是分了256张表,表名从store000到store255。
  • 这个case是有效率要求的,ASAP(As Soon As Possible)。

 

从数据库dump数据要用到mysqldump命令,需要知道数据库的ip或是域名,数据库名,用户和密码,现在这些都是已知的,有0到255编号的这么些表需要dump,写个循环就好,但是ASAP怎么办?

串行的一个一个dump应该不如并行多个一起dump快,并行也要有度,弄到和网络、数据库吞吐、磁盘写入里较短的那块板一样就好。

 

不管怎样都要用到dump一个表到本地文件逻辑,那么先写这一段

 

#!/bin/bash 帅气的起手式

2

dbSever=’blablabla’    各种数据库连接参数,注意单引号啊,简单的字符串赋值就这么写

dbName=’blablabla’   注意赋值的时候“等号”两边无空隙

dbUser=’blablabla’    

dbUpsw=’blablabla’   

localFileBase=’/tmp/storedump’ 放dump文件的目录

8

tableName=’store000’              先dump第一个表看看

10 dumpFile="$ {localFileBase} /$ tableName "这里用到双引号字符串,双引号的能耐比单引号大,它能吧带$号的变量展开替换,${var}是最正规的变量引用方法,$var在无歧义的时候也可以使用,dumpFile在赋值执行完成后的值是/tmp/storedump/store000

11mysqldump –C --extended-insert=false -h${dbSever} -u${dbUser} -p${dbUpsw} ${dbName} ${ tableName} > ${dumpFile} 这是真正干活的调用,mysqldump用到的各个参数都使用变量替换好了,使用输出重定向符>将dump的内容写入$dumpFile,也就是/tmp/storedump/ store000

 

上面这11行shell脚本代码就可以完成第一张表的dump了,我这里就演练了一下shell的赋值和变量的使用,还有帅气的起手式哈。

再回头看一下这短短11行代码,3到7行是在做dump任务的那些常量的赋值,9到11行是在为具体dump第一张表写逻辑。9到11行适合包装成函数被调用——dump第n张表到本地文件。就一个输入参数n,那么我们就来包装一把。

关于shell函数的样式、调用和参数传递使用,要仔细看注释啊。

 

#!/bin/bash 

2

dbSever=’blablabla’   

dbName=’blablabla’   

dbUser=’blablabla’    

dbUpsw=’blablabla’   

localFileBase=’/tmp/storedump’ 

8

dumpTable2File() {                           函数名(){函数体}这就是shell中函数标识,我把函数命名为dumpTable2File,我期望它被调用的时候跟一个参数n,用来表示需要dump的表的序号。但是和其他语言不一样,参数的规定或是声明不出现在这里,应该这样说,函数需要的参数不用规定和声明。

11          tableName=”store$1”                  这行和前一个示例就不太一样,首先用的双引号,然后用$1引用了第一个参数,嗯,就是这么简单粗暴,不讲道理。很少有程序语言这样处理参数。$2是第二个参数,$3是第三个,类推就好。如果你想知道实际传递的参数的个数,用$#就好了。

12         dumpFile="$ {localFileBase} /$ tableName "

13          mysqldump –C --extended-insert=false -h${dbSever} -u${dbUser} -p${dbUpsw} ${dbName} ${ tableName} > ${dumpFile}           函数中可以引用shell中的其他的变量哦,在函数外定义的其他的变量可以看做就是全局可见的了,如果你修改了,跳出函数它们的值也是跟着变的。

14 }                                                               函数结束,大括号闭合

 

15 for index in `seq 0 255`                         循环串行遍历0到255个数据表,调用dumpTable2File函数

16 do

17         dumpTable2File $index                函数的调用,需要传递的参数$index直接跟在函数名的后面,留个空格就好,如果要跟第二个参数,打一个空格继续写,如果参数中就有空格,把它装在单引号中。

18 done                    

 

上面这18行代码其实基本上可以串行地完成dump工作了。

 

我演练了shell函数的组织和调用。它看起来怪怪的,基于约定的,严肃的程序员可能要吐槽参数的传递怎么如此草率,没有规矩。我简单替大牛们辩解一下,shell是解释执行的,shell要KISS力求简单,参数的传递基于约定(虽然是一堆难看的变量)能work,够简单。

 

上面代码其实还是无法工作的,原因在于第11行tableName=”store$1”,回忆一下我们的case,表的名字是从store000到store255。所以循环中,当$index是0到99的时候,tableName的赋值是不对的,缺少了一些字符’0’。See,我们需要store000当index等于0的时候我们得到store0。那么我终于讲到if了,在写了快7000字之后才讲到它,挺怪异的哈,因为shell的if确实是个怪东西。

 

逻辑很简单,我们在函数dumpTable2File里用if,判断两个逻辑。

其一保证参数是至少有一个的;

其二参数1的值在小于10的时候补2个字符’0’,在小于100的时候补1个’0’。

 

注释已经很难说清楚if了,所以先概述一下,再上代码

if语句其实本来的面目是这样的

if TEST-COMMANDS; then COMMANDS; [ elif TEST-COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi

if后面的TEST-COMMAND是一个shell命令,如果它的返回值为0那么执行then后面的命令。elif是else if的简写,fi是if语句的结束符号,这些关键字体现了大牛们特立独行的风格。

 

上面这句话提到了shell命令的返回值,这个要插入说一下,其实每一条shell命令执行后都会有一个返回值,它可用通过$?来引用到,你是否要吐槽发明shell的大牛明显是个无节操的,用这么偷懒的方法,和这么丑的字符,来取得返回值,颠覆了你对程序语言的认知。

还有0在很多的程序语言中等同于false,但是shell就喜欢让它等同于true。

Any way 我来示例一下$?

ls mod.sh;echo $?  我当前目录上有一个文件叫mod.sh,我去ls它,然后打印ls命令的返回值,是一个0。多个shell命令用;间隔就可以出现在一行,其实前面for循环就见过的,表示串行执行各shell命令

mod.sh                      这行是ls的输出

0                                这行是echo的输出

ls mod.shs;echo $? 当前目录上没有文件叫mod.shs,那么去ls它,再打印ls命令的返回值,是一个非0的值

ls: mod.shs: No such file or directory  这行是ls的标准错误输出

2

 

返回值得事情插入完毕,接着讲if。

其实就上面语法结构看起来if没有什么值得说的,这不是if奇怪的地方。奇怪的地方在于if后面的TEST-COMMAND可以是一些古怪的东西。

介绍一个shell内建的命令,它是[

你没看错啊,就是一个左中括号,它可不是表达式的一部分,它等同于shell的内建命令test

[空格‘a’空格=空格‘b’空格]是一个shell命令调用,’a’是第一个参数,=是第二个参数,’b’是第三个参数,而]是第4个。这里的4个空格太重要了,我不得不把它们用中文字明显地标出来,因为没有空格,[这个等同于test的命令就得不到足够的参数。

我们来试验一把

[ "a" = "a" ];echo $?                测试字符串”a”和“a”是否全等,测试完成后,打印返回值

                                             全等于是返回0

[ "a" = "b" ];echo $?                测试字符串”a”和“b”是否全等,测试完成后,打印返回值

1                                              不等于是返回1

test "a" = "a";echo $?              和[等价的shell内建命令test

0

test "a" = "b";echo $?

1

["a" = "b" ];echo $?                 如果把[和”a”之间的空格拿掉,那么就出错了,shell解释的时候认为你是要调用一个叫做[a的命令,没有这个命令,于是报错。输出如下

-bash: [a: command not found

127

 

好了,总算说清楚方括号了,它被常常用来做测试判断和if配合,能耐很大,但是显得怪异,特别是你将看到的中间的测试操作符号的时候。

测试符合有很多,有双目有单目的,有用于整数的,用于字符串的,还有用于文件目的。

上面show过的“=”就是一个用在字符串的,双目的测试符号

给一个常用的整数和字符串的测试符号表

测试操作

整数

字符

相同,双目,比如

[ $a –eq 5 ]测试变量a是否等于整数5

[ “$a” –eq “hello” ]测试变量a是否和字符串”hello”全等

-eq

=

不同,双目

-ne

!=

大于,双目

-gt

小于,双目

-lt

大于或者等于,双目

-ge

 

小于或者等于,双目

-le

 

为空(长度为零),单目,比如

[ -z “$1” ]测试第一个参数是否为空,为空返回0,表示true

 

-z

不为空(长度为非零),单目

 

-n

 

看完这个表格就知道奇怪的地方在哪里了。

我们直觉或是习惯用来做整数判断的=、!=、>、<却是用来做字符串比较的。

而用来做整数判断的是一些奇怪的缩写,eq就是equal,gt就是great then,lt就是less then,ge就是great or equal。

大牛发明的东西就是比较无语啊,大家要习惯。

 

还有就是有一些常用的单目的文件目录测试符号,也做一个列表,这些好用常用,shell和文件打交道的时候不要太多

[ -f FILE ]如果FILE存在且是一个普通文件则为真。

[ -r FILE ]如果FILE存在且是可读的则为真。

[ -w FILE ]如果FILE如果FILE存在且是可写的则为真。

[ -x FILE ]如果FILE存在且是可执行的则为真。

[ -d FILE ]如果FILE存在且是一个目录则为真。

 

花了一页半的文字解释了if和怪异的TEST-COMMAND,解决case中的问题其实就小意思了。

回忆一下case里要用if解决的两个问题:参数是至少有一个的;参数1在小于10的时候补2个字符’0’,在小于100的时候补1个’0’。

Here we go

 

dumpTable2File() {

if [ $# -lt 1 ]                               $#是输入参数啊,看看输入参数是不是比1还小啊(好装啊,直接比较0不行吗)

    then                                       

        echo 'need 1 arg'             如果输入参数是0,打印一串提示

        return                               从函数中跳出,break和continue在循环中也是能用的啊

    fi                                               判断参数个数的if语句的结束

 

    if [ $1 -lt 10 ]                             $1是第一个输入参数啊,前面已经判断过,它确实是有的,这里就好放心用了,参数1的意义是数据库表的序号,如果小于10,那么在拼表名的时候补两个0

    then                                           then是必须的不能省略

        tableName="store00$1"     双引号语法,$1被替换成一个0到9的数字,$1前面有两个0

    elif [ $1 -lt 100 ]                         如果不是小于10,但是小于100,那么在拼表名的时候补个0

    then

        tableName="store0$1"    双引号语法,$1被替换成一个10到99的数字,$1前面有一个0

    else                                                如果既不是小于10也不是小于100,那么$1直接就是三位数了直接拼出表名很合适

        tableName="store$1"         用$1直接拼出表名很合适

    fi 

   

    dumpFile="${localFileBase}/$tableName"

mysqldump -C --extended-insert=false -hh${dbSever} -u${dbUser} -p${dbUpsw} ${dbName} ${tableName} > ${dumpFile}

}

 

Ok如此我们解决了串行dump所有数据表的问题,我们演练了if的使用,那我们那个并行的怎么解决呢。

当确定好并行的个数以后(这个可以实验得出)这件事情就不困难了。方法就是做一个函数来串行处理一批表,然后并行地调用这个函数。

 

 

dumpTables(){                                   这个函数串行地dump一批表,表的序号从n到m,n由参数1指定,m有参数2指定

    for index in `seq $1 $2`               串行dump循环逻辑

    do

        dumpTable2File $index       调用dump一个表的逻辑,就是上面解释了半天的那个

    done

}

 

dumpTables 0 63 &                              调用dump一批表的函数,给参数1是0和参数2是63,表示dump表的序号从0到63。

&不是参数,是shell的基础设施,表示将函数的执行挂到后台。

如果没有&,shell调用函数后就停在这里等返回,这样就还是串行执行的,

有了&,shell调用函数后就不等返回了,接着执行下面的语句。

dumpTables是一个函数,在shell里面call它的时候,其行为其实已经类似调用一个shell命令了

dumpTables 64 127 &

dumpTables 128 191 &

dumpTables 192 255 &

 

如此我们就实现了并发数为4的dump了。

 

小结一下,这回的内容比较多一点,

第一页是变量的赋值和使用,

第二页是函数的组织和调用(还有参数啊),

第三、四页是if相关的东西,

最后show了一下后台执行(非同步调用)。

 

最后完整的程序在最后面贴一下

 

 

#!/bin/bash

 

dbSever='blablabla'

dbName='lablabla'

dbUser='lablabla'

dbUpsw='lablabla'

localFileBase='/tmp/storedump'

 

dumpTable2File() {

    if [ $# -lt 1 ]

    then

        echo 'need 1 arg'

        return

    fi 

 

    if [ $1 -lt 10 ]

    then

        tableName="store00$1"

    elif [ $1 -lt 100 ]

    then

        tableName="store0$1"

    else

        tableName="store$1"

    fi 

   

    dumpFile="${localFileBase}/$tableName"

    echo "mysqldump -C --extended-insert=false -hh${dbSever} -u${dbUser} -p${dbUpsw} ${dbName} ${tableName} > ${dumpFile}"}

 

dumpTables(){

for index in `seq $1 $2`

    do

        dumpTable2File $index

    done

}

 

dumpTables 0 63 &

dumpTables 64 127 &

dumpTables 128 191 &

dumpTables 192 255 &

代码转载自:https://pan.quark.cn/s/8ce4326d996e 对于在 CentOS 7 系统中修改网卡配置文件后无法使设置生效的情况,经过实践验证,可以通过使用 nmcli 命令来进行调整。完成修改之后,需要重新启动虚拟机以使更改生效,这样操作流程即告完成。如果设置仍然无法生效,则表明虚拟机在启动过程中所获取的 IP 地址配置并非针对 eth0,此时可以对其它网卡的配置文件进行修改或将其移除。在 CentOS 7 系统中,网络配置的管理机制与早期版本存在差异,主要体现为采用了 Network Manager 服务来负责网络接口的管理。在某些情形下,尽管修改了 `/etc/sysconfig/network-scripts` 目录下的 `ifcfg-eth0` 文件,但网络配置却未能即时生效。此类问题的发生通常源于 CentOS 7 采用了不同于以往的配置读取方法。接下来将具体阐述如何借助 nmcli 命令来处理这一挑战。 以 root 用户身份登录系统并打开终端界面。nmcli 是 Network Manager 提供的命令行界面工具,它支持在命令行环境下执行网络连接的建立、编辑、查询及管理任务。针对修改 eth0 网卡配置的需求,可以遵循以下步骤进行操作: 1. 导航至 `/etc/sysconfig/network-scripts` 目录: ``` cd /etc/sysconfig/network-scripts ``` 2. 检查该目录内是否存在 `ifcfg-eth0.bak` 文件,该备份文件可能是先前调整配置时遗留下来的,若存在可能造成冲突。若发现该文件,可以选择将其删除: ``` [root@localhost netw...
代码转载自:https://pan.quark.cn/s/46fd08fb879c 网管教程 从入门到精通软件篇 ★一。★详尽的xp修复控制台指令及其应用!!! 放入xp(2000)的光盘,安装时选择R,执行修复! Windows XP(涵盖 Windows 2000)的控制台指令是在系统遭遇某些意外状况时的一种极具效用的诊断、检测以及恢复系统功能的工具。笔者确实一直期望能够将这方面的指令进行归纳,此次由老范辛苦整理了这份极具价值的秘籍。 Bootcfg bootcfg 命令用于启动配置与故障恢复(对大多数计算机而言,即 boot.ini 文件)。 带有特定参数的 bootcfg 命令仅在运用故障恢复控制台时方可使用。能够在命令行界面下运用带有不同参数的 bootcfg 命令。 用法: bootcfg /default 设定默认引导选项。 bootcfg /add 向引导清单中增添 Windows 安装。 bootcfg /rebuild 重复整个 Windows 安装流程并让用户选择需添加的项目。 注意:运用 bootcfg /rebuild 之前,应先借助 bootcfg /copy 命令备份 boot.ini 文件。 bootcfg /scan 探查用于 Windows 安装的全部磁盘并展示结果。 注意:这些结果被静态存储,并用于当前会话。若在当前会话期间磁盘配置发生变动,为获取更新的探查结果,必须先重启计算机,然后再次探查磁盘。 bootcfg /list 列示引导清单中已有的项目。 bootcfg /disableredirect 在启动引导程序中禁用重定向。 bootcfg /redirect [ PortBaudRrate] |[ useBio...
代码下载链接: https://pan.quark.cn/s/fc524f791b68 AA制程,即Active Alignment,被理解为主动对准,是一种用于确定零部件装配中相对位置的方法。在摄像头封装阶段,涉及图像传感器、镜座、马达、镜头、线路板等多个部件的重复组装,而传统的封装设备如CSP及COB等,均是依据设备设定的参数进行零部件的移动装配,因而零部件的叠加误差会逐渐增大,最终在摄像头上表现为拍照最清晰的位置可能偏离画面中心、四边清晰度不均等现象。伴随智能手机和其他高端电子产品的普及,摄像头模组的性能正日益受到重视。高分辨率、卓越的低光表现以及稳定视频输出是现代用户所期望的。在摄像头模组的制造环节,各部件的精准定位对成像质量具有决定性作用。因此,一种名为“AA制程”(Active Alignment)的前沿技术被开发出来,成为摄像头精密对准的核心技术。 AA制程,即Active Alignment,是一种在摄像头封装过程中应用的主动对准方法。该方法在多个组件装配阶段发挥作用,涵盖图像传感器、镜座、马达、镜头和线路板等部件。传统的封装方式,例如CSP(Chip Scale Package)和COB(Chip On Board),依赖于设备预设的参数进行组装,但随着组件数量的增加,误差也会累积,最终影响摄像头的表现。例如在成像质量上可能出现中心位置偏移、四角清晰度不一致等问题。 AA制程技术的核心在于实时监测与主动调整。在组装过程中,它借助先进的检测设备持续监控半成品的状态,并根据实时信息对组装部件进行精确修正,从而显著降低装配误差。通过这种技术,能够确保摄像头模组中各组件的相对位置准确无误,从而使得最终的成像效果更加稳定,特别是在中心区域和四角的清晰度上...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值