Linux shell的简单学习

shell script 其实就是纯文本档,我们可以编辑这个档案,然后讥这个档案来帮我们一次执行多个指令, 戒者是刟用一些运算不逡辑刞断来帮我们达成某些功能。

  • Linux shell的简单学习

    • 学前注意内容
  • Shell常用语法
      • 压缩文件
      • 其他命令
        • grep
        • sed 工具
        • 格式化列印 printf
        • awk
    • 正则表达式
      • 基础正规表示法
      • 延伸正规表示法
    • 开始撰写
    • 条件判断语句
      • 基本的判断语法
    • 条件循环
    • C语言执行

学前注意内容

  • 指令的执行是从上而下,从左到右的分析和执行
  • 指令、选项和参数间多个空白将被忽略掉
  • 如果读到一个Enter符号(CR),就开始尝试执行改行或该串指令
  • 内容过多,可以施工【[nter]】来延伸至下一行;
  • #为批注

Shell常用语法

1.压缩文件

在Linux癿环境中,压缩文件案癿扩展名大多是:『.tar, .tar.gz, .tgz, .gz, .Z, .bz2』。

*.Z compress 程序压缩癿档案;
*.gz gzip 程序压缩癿档案;
*.bz2 bzip2 程序压缩癿档案;
*.tar tar 程序打包癿数据,并没有压缩过;
*.tar.gz tar 程序打包癿档案,其中并且经过 gzip 癿压缩
*.tar.bz2 tar 程序打包癿档案,其中并且经过 bzip2 癿压缩

[root@www ~]# gzip [-cdtv#] 檔名
[root@www ~]# zcat 檔名.gz
选顷不参数:
-c :将压缩癿数据输出到屏幕上,可透过数据流重导向杢处理;
-d :解压缩癿参数;
-t :可以用杢检验一个压缩文件癿一致性~看看档案有无错诨;
-v :可以显示出原档案/压缩文件案癿压缩比等信息;
-# :压缩等级,-1 最忚,但是压缩比最差、-9 最慢,但是压缩比最好!预讴是 -6

[root@www ~]# bzip2 [-cdkzv#] 檔名
[root@www ~]# bzcat 檔名.bz2
选顷不参数:
-c :将压缩癿过程产生癿数据输出到屏幕上!
-d :解压缩癿参数
-k :保留源文件,而丌会删除原始癿档案喔!
-z :压缩癿参数
-v :可以显示出原档案/压缩文件案癿压缩比等信息;
-# :不 gzip 同样癿,都是在计算压缩比癿参数, -9 最佳, -1 最忚!

[root@www ~]# tar [-j|-z] [cv] [-f 建立癿檔名] filename… <==打包不压缩
[root@www ~]# tar [-j|-z] [tv] [-f 建立癿檔名] <==察看檔名
[root@www ~]# tar [-j|-z] [xv] [-f 建立癿檔名] [-C 目录] <==解压缩
选顷不参数:
-c :建立打包档案,可搭配 -v 杢察看过程中被打包癿档名(filename)
-t :察看打包档案癿内容吨有哪些档名,重点在察看『档名』就是了;
-x :解打包戒解压缩癿功能,可以搭配 -C (大写) 在特定目录解开 特别留意癿是, -c, -t, -x 丌可同时出现在一串挃令列中。
-j :透过 bzip2 癿支持迚行压缩/解压缩:此时档名最好为 *.tar.bz2
-z :透过 gzip 癿支持迚行压缩/解压缩:此时档名最好为 *.tar.gz
-v :在压缩/解压缩癿过程中,将正在处理癿文件名显示出杢! -f filename:-f 后面要立刻接要被处理癿档名!建议 -f 单独写一个选顷啰!
-C 目录 :这个选顷用在解压缩,若要在特定目录解压缩,可以使用这个选顷。

其实最简单癿使用 tar 就只要记忆底下癿方式即可:
*  压 缩:tar -jcv -f filename.tar.bz2 要被压缩癿档案戒目录名称;
*  查 询:tar -jtv -f filename.tar.bz2;
*  解压缩:tar -jxv -f filename.tar.bz2 -C 欲解压缩癿目录;

2.其他命令

#### read 要读叏杢自键盘输入癿发量,就是用 read 这个挃令了。这个指令最常被用在 shell script 癿撰写当中, 想要跟使用者对谈?用这个指令就对了。 [root@www ~]# read [-pt] variable 选项不参数: -p :后面可以接提示字符! -t :后面可以接等待癿『秒数!』这个比较有趣~不会一直等待使用者啦! 撷取命令: cut, grep就是将一段数据经过分析后,取出我们所想要癿。或者是经由分析关键词,取得我们所想要癿那一行! 不过,要注意癿是,一般来说,撷取讯息通常是针对『一行一行』来分析的。 #### cut [root@www ~]# cut -d’分隑字符’ -f fields

grep

刚刚的 cut 是将一行信息当中,取出某部分我们想要的,而 grep 则是分析一行信息, 若当中有我们所需要的信息,就将该行拿出来~简单的语法是这样的:
[root@www ~]# grep [-acinv] [–color=auto] ‘搜寻字符串’ filename
选项与参数:
-a :将 binary 文件以 text 文件的方式搜寻数据
-c :计算找到 ‘搜寻字符串’ 的次数
-i :忽略大小写的不同,所以大小写视为相同
-n :顺便输出行号
-v :反向选择,亦即显示出没有 ‘搜寻字符串’ 内容的那一行!
–color=auto :可以将找到的关键词部分加上颜色的显示喔!

范例一:将 last 当中,有出现 root 的那一行就取出来;
[root@www ~]# last | grep ‘root’

范例二:与范例一相反,只要没有 root 的就取出!
[root@www ~]# last | grep -v ‘root’

范例三:在 last 的输出信息中,只要有 root 就取出,并且仅取第一栏
[root@www ~]# last | grep ‘root’ |cut -d ’ ’ -f1
# 在取出 root 之后,利用上个命令 cut 的处理,就能够仅取得第一栏啰!

范例四:取出 /etc/man.config 内含 MANPATH 的那几行
[root@www ~]# grep –color=auto ‘MANPATH’ /etc/man.config
….(前面省略)….
MANPATH_MAP /usr/X11R6/bin /usr/X11R6/man
MANPATH_MAP /usr/bin/X11 /usr/X11R6/man
MANPATH_MAP /usr/bin/mh /usr/share/man
# 神奇的是,如果加上 –color=auto 的选项,找到的关键词部分会用特殊颜色显示喔!
* 但其实 grep 还有不少的进阶用法喔!底下我们仅列出较进阶的 grep 选项与参数给大家参考*
grep 是一个很常见也很常用的命令,他最重要的功能就是进行字串数据的比对,然后将符合使用者需求的字串列印出来。 需要说明的是『grep 在数据中查寻一个字串时,是以 “整行” 为单位来进行数据的撷取的!』也就是说,假如一个文件内有 10 行,其中有两行具有你所搜寻的字串,则将那两行显示在萤幕上,其他的就丢弃了!

[root@www ~]# grep [-A] [-B] [–color=auto] ‘搜寻字串’ filename
选项与参数:
-A :后面可加数字,为 after 的意思,除了列出该行外,后续的 n 行也列出来;
-B :后面可加数字,为 befer 的意思,除了列出该行外,前面的 n 行也列出来;
–color=auto 可将正确的那个撷取数据列出颜色

范例一:用 dmesg 列出核心信息,再以 grep 找出内含 eth 那行
[root@www ~]# dmesg | grep ‘eth’
eth0: RealTek RTL8139 at 0xee846000, 00:90:cc:a6:34:84, IRQ 10
eth0: Identified 8139 chip type ‘RTL-8139C’
eth0: link up, 100Mbps, full-duplex, lpa 0xC5E1
eth0: no IPv6 routers present
# dmesg 可列出核心产生的信息!透过 grep 来撷取网络卡相关资讯 (eth) ,
# 就可发现如上资讯。不过没有行号与特殊颜色显示!看看下个范例吧!

范例二:承上题,要将捉到的关键字显色,且加上行号来表示:
[root@www ~]# dmesg | grep -n –color=auto ‘eth’
247:eth0: RealTek RTL8139 at 0xee846000, 00:90:cc:a6:34:84, IRQ 10
248:eth0: Identified 8139 chip type ‘RTL-8139C’
294:eth0: link up, 100Mbps, full-duplex, lpa 0xC5E1
305:eth0: no IPv6 routers present
# 你会发现除了 eth 会有特殊颜色来表示之外,最前面还有行号喔!

范例三:承上题,在关键字所在行的前两行与后三行也一起捉出来显示
[root@www ~]# dmesg | grep -n -A3 -B2 –color=auto ‘eth’
245-PCI: setting IRQ 10 as level-triggered
246-ACPI: PCI Interrupt 0000:00:0e.0[A] -> Link [LNKB] …
247:eth0: RealTek RTL8139 at 0xee846000, 00:90:cc:a6:34:84, IRQ 10
248:eth0: Identified 8139 chip type ‘RTL-8139C’
249-input: PC Speaker as /class/input/input2
250-ACPI: PCI Interrupt 0000:00:01.4[B] -> Link [LNKB] …
251-hdb: ATAPI 48X DVD-ROM DVD-R-RAM CD-R/RW drive, 2048kB Cache, UDMA(66)
# 如上所示,你会发现关键字 247 所在的前两行及 248 后三行也都被显示出来!
# 这样可以让你将关键字前后数据捉出来进行分析啦!
在关键字的显示方面,grep 可以使用 –color=auto 来将关键字部分使用颜色显示。 这可是个很不错的功能啊!但是如果每次使用 grep 都得要自行加上 –color=auto 又显的很麻烦~ 此时那个好用的 alias 就得来处理一下啦!你可以在 ~/.bashrc 内加上这行:『alias grep=’grep –color=auto’』再以『 source ~/.bashrc 』来立即生效即可喔! 这样每次运行 grep 他都会自动帮你加上颜色显示啦!

sed 工具

sed 本身也是一个管线命令,可以分析 standard input 的啦! 而且 sed 还可以将数据进行取代、删除、新增、撷取特定行等等的功能呢!很不错吧~ 我们先来了解一下 sed 的用法,再来聊他的用途好了!
[root@www ~]# sed [-nefr] [动作]
选项与参数:
-n :使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN
的数据一般都会被列出到萤幕上。但如果加上 -n 参数后,则只有经过
sed 特殊处理的那一行(或者动作)才会被列出来。
-e :直接在命令列模式上进行 sed 的动作编辑;
-f :直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的
sed 动作;
-r :sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法)
-i :直接修改读取的文件内容,而不是由萤幕输出。

动作说明: [n1[,n2]]function
n1, n2 :不见得会存在,一般代表『选择进行动作的行数』,举例来说,如果我的动作
是需要在 10 到 20 行之间进行的,则『 10,20[动作行为] 』

function 有底下这些咚咚:
a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p :列印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~
s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配
正规表示法!例如 1,20s/old/new/g 就是啦!

以行为单位的新增/删除功能
删除与新增的功能

范例一:将 /etc/passwd 的内容列出并且列印行号,同时,请将第 2~5 行删除!
[root@www ~]# nl /etc/passwd | sed ‘2,5d’
1 root:x:0:0:root:/root:/bin/bash
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
…..(后面省略)…..
如果题型变化一下,举例来说,如果只要删除第 2 行,可以使用『 nl /etc/passwd | sed ‘2d’ 』来达成, 至於若是要删除第 3 到最后一行,则是『 nl /etc/passwd | sed ‘3,d′』的啦,那个钱字号『d' 』的啦,那个钱字号『 』代表最后一行!

范例二:承上题,在第二行后(亦即是加在第三行)加上『drink tea?』字样!
[root@www ~]# nl /etc/passwd | sed ‘2a drink tea’
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
drink tea
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
…..(后面省略)…..
嘿嘿!在 a 后面加上的字串就已将出现在第二行后面罗!那如果是要在第二行前呢?『 nl /etc/passwd | sed ‘2i drink tea’ 』就对啦!就是将『 a 』变成『 i 』即可。 添加一行很简单,那如果是要增将两行以上呢?

范例三:在第二行后面加入两行字,例如『Drink tea or …..』与『drink beer?』
[root@www ~]# nl /etc/passwd | sed ‘2a Drink tea or ……\
> drink beer ?’
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
Drink tea or ……
drink beer ?
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
…..(后面省略)…..
这个范例的重点是『我们可以新增不只一行喔!可以新增好几行』但是每一行之间都必须要以反斜线『 \ 』来进行新行的添加喔!所以,上面的例子中,我们可以发现在第一行的最后面就有 \ 存在啦!那是一定要的喔!

以行为单位的取代与显示功能
刚刚是介绍如何新增与删除,那么如果要整行取代呢?看看底下的范例吧:

范例四:我想将第2-5行的内容取代成为『No 2-5 number』呢?
[root@www ~]# nl /etc/passwd | sed ‘2,5c No 2-5 number’
1 root:x:0:0:root:/root:/bin/bash
No 2-5 number
6 sync:x:5:0:sync:/sbin:/bin/sync
…..(后面省略)…..
透过这个方法我们就能够将数据整行取代了!非常容易吧!sed 还有更好用的东东!我们以前想要列出第 11~20 行, 得要透过『head -n 20 | tail -n 10』之类的方法来处理,很麻烦啦~ sed 则可以简单的直接取出你想要的那几行!是透过行号来捉的喔!看看底下的范例先:

范例五:仅列出 /etc/passwd 文件内的第 5-7 行
[root@www ~]# nl /etc/passwd | sed -n ‘5,7p’
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
上述的命令中有个重要的选项『 -n 』,按照说明文件,这个 -n 代表的是『安静模式』! 那么为什么要使用安静模式呢?你可以自行下达 sed ‘5,7p’ 就知道了 (5-7 行会重复输出)! 有没有加上 -n 的参数时,输出的数据可是差很多的喔!你可以透过这个 sed 的以行为单位的显示功能, 就能够将某一个文件内的某些行号捉出来查阅!很棒的功能!不是吗?

部分数据的搜寻并取代的功能
除了整行的处理模式之外, sed 还可以用行为单位进行部分数据的搜寻并取代的功能喔! 基本上 sed 的搜寻与取代的与 vi 相当的类似!他有点像这样:

sed ‘s/要被取代的字串/新的字串/g’
上表中特殊字体的部分为关键字,请记下来!至於三个斜线分成两栏就是新旧字串的替换啦! 我们使用底下这个取得 IP 数据的范例,一段一段的来处理给您瞧瞧,让你了解一下什么是咱们所谓的搜寻并取代吧!

步骤一:先观察原始信息,利用 /sbin/ifconfig 查询 IP 为何?
[root@www ~]# /sbin/ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:90:CC:A6:34:84
inet addr:192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::290:ccff:fea6:3484/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
…..(以下省略)…..
# 因为我们还没有讲到 IP ,这里你先有个概念即可啊!我们的重点在第二行,
# 也就是 192.168.1.100 那一行而已!先利用关键字捉出那一行!

步骤二:利用关键字配合 grep 撷取出关键的一行数据
[root@www ~]# /sbin/ifconfig eth0 | grep ‘inet addr’
inet addr:192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0
# 当场仅剩下一行!接下来,我们要将开始到 addr: 通通删除,就是像底下这样:
# inet addr:192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0
# 上面的删除关键在於『 ^.*inet addr: 』啦!正规表示法出现! ^_^

步骤三:将 IP 前面的部分予以删除
[root@www ~]# /sbin/ifconfig eth0 | grep ‘inet addr’ | \
> sed ‘s/^.*addr://g’
192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0
# 仔细与上个步骤比较一下,前面的部分不见了!接下来则是删除后续的部分,亦即:
# 192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0
# 此时所需的正规表示法为:『 Bcast.*$ 』就是啦!

步骤四:将 IP 后面的部分予以删除
[root@www ~]# /sbin/ifconfig eth0 | grep ‘inet addr’ | \
> sed ‘s/^.addr://g’ | sed ‘s/Bcast.$//g’
192.168.1.100
透过这个范例的练习也建议您依据此一步骤来研究你的命令!就是先观察,然后再一层一层的试做, 如果有做不对的地方,就先予以修改,改完之后测试,成功后再往下继续测试。以鸟哥上面的介绍中, 那一大串命令就做了四个步骤!对吧! ^_^

让我们再来继续研究 sed 与正规表示法的配合练习!假设我只要 MAN 存在的那几行数据, 但是含有 # 在内的注解我不想要,而且空白行我也不要!此时该如何处理呢?可以透过这几个步骤来实作看看:

步骤一:先使用 grep 将关键字 MAN 所在行取出来
[root@www ~]# cat /etc/man.config | grep ‘MAN’
# when MANPATH contains an empty substring), to find out where the cat
# MANBIN pathname
# MANPATH manpath_element [corresponding_catdir]
# MANPATH_MAP path_element manpath_element
# MANBIN /usr/local/bin/man
# Every automatically generated MANPATH includes these fields
MANPATH /usr/man
….(后面省略)….

步骤二:删除掉注解之后的数据!
[root@www ~]# cat /etc/man.config | grep ‘MAN’| sed ‘s/#.*$//g’

MANPATH /usr/man
….(后面省略)….
# 从上面可以看出来,原本注解的数据都变成空白行啦!所以,接下来要删除掉空白行

[root@www ~]# cat /etc/man.config | grep 'MAN'| sed 's/#.*$//g' | \
\> sed '/^$/d'
MANPATH /usr/man
MANPATH /usr/share/man
MANPATH /usr/local/man
....(后面省略)....

直接修改文件内容(危险动作)
你以为 sed 只有这样的能耐吗?那可不! sed 甚至可以直接修改文件的内容呢!而不必使用管线命令或数据流重导向! 不过,由於这个动作会直接修改到原始的文件,所以请你千万不要随便拿系统配置档来测试喔! 我们还是使用你下载的 regular_express.txt 文件来测试看看吧!

范例六:利用 sed 将 regular_express.txt 内每一行结尾若为 . 则换成 !
[root@www ~]# sed -i ‘s/.$/!/g’ regular_express.txt
# 上头的 -i 选项可以让你的 sed 直接去修改后面接的文件内容而不是由萤幕输出喔!
# 这个范例是用在取代!请您自行 cat 该文件去查阅结果罗!

范例七:利用 sed 直接在 regular_express.txt 最后一行加入『# This is a test』
[root@www ~]# sed -i '$a # This is a test' regular_express.txt
# 由於 $ 代表的是最后一行,而 a 的动作是新增,因此该文件最后新增罗!
sed 的『 -i 』选项可以直接修改文件内容,这功能非常有帮助!举例来说,如果你有一个 100 万行的文件,你要在第 100 行加某些文字,此时使用 vim 可能会疯掉!因为文件太大了!那怎办?就利用 sed 啊!透过 sed 直接修改/取代的功能,你甚至不需要使用 vim 去修订!很棒吧!

总之,这个 sed 不错用啦!而且很多的 shell script 都会使用到这个命令的功能~ sed 可以帮助系统管理员管理好日常的工作喔!要仔细的学习呢!

格式化列印: printf

在很多时候,我们可能需要将自己的数据给他格式化输出的! 举例来说,考试卷分数的输出,姓名与科目及分数之间,总是可以稍微作个比较漂亮的版面配置吧? 例如我想要输出底下的样式:

Name Chinese English Math Average
DmTsai 80 60 92 77.33
VBird 75 55 80 70.00
Ken 60 90 70 73.33
上表的数据主要分成五个栏位,各个栏位之间可使用 tab 或空白键进行分隔。 请将上表的数据转存成为 printf.txt 档名,等一下我们会利用这个文件来进行几个小练习的。 因为每个栏位的原始数据长度其实并非是如此固定的 (Chinese 长度就是比 Name 要多), 而我就是想要如此表示出这些数据,此时,就得需要列印格式管理员 printf 的帮忙了! printf 可以帮我们将数据输出的结果格式化,而且而支持一些特殊的字符~底下我们就来看看!

[root@www ~]# printf ‘列印格式’ 实际内容
选项与参数:
关於格式方面的几个特殊样式:
\a 警告声音输出
\b 倒退键(backspace)
\f 清除萤幕 (form feed)
\n 输出新的一行
\r 亦即 Enter 按键
\t 水平的 [tab] 按键
\v 垂直的 [tab] 按键
\xNN NN 为两位数的数字,可以转换数字成为字节。
关於 C 程序语言内,常见的变量格式
%ns 那个 n 是数字, s 代表 string ,亦即多少个字节;
%ni 那个 n 是数字, i 代表 integer ,亦即多少整数码数;
%N.nf 那个 n 与 N 都是数字, f 代表 floating (浮点),如果有小数码数,
假设我共要十个位数,但小数点有两位,即为 %10.2f 罗!
接下来我们来进行几个常见的练习。假设所有的数据都是一般文字 (这也是最常见的状态),因此最常用来分隔数据的符号就是 [Tab] 啦!因为 [Tab] 按键可以将数据作个整齐的排列!那么如何利用 printf 呢?参考底下这个范例:

范例一:将刚刚上头数据的文件 (printf.txt) 内容仅列出姓名与成绩:(用 [tab] 分隔)
[root@www ~]# printf ‘%s\t %s\t %s\t %s\t %s\t \n’ $(cat printf.txt)
Name Chinese English Math Average
DmTsai 80 60 92 77.33
VBird 75 55 80 70.00
Ken 60 90 70 73.33
由於 printf 并不是管线命令,因此我们得要透过类似上面的功能,将文件内容先提出来给 printf 作为后续的数据才行。 如上所示,我们将每个数据都以 [tab] 作为分隔,但是由於 Chinese 长度太长,导致 English 中间多了一个 [tab] 来将数据排列整齐!啊~结果就看到数据对齐结果的差异了!

另外,在 printf 后续的那一段格式中,%s 代表一个不固定长度的字串,而字串与字串中间就以 \t 这个 [tab] 分隔符号来处理!你要记得的是,由於 \t 与 %s 中间还有空格,因此每个字串间会有一个 [tab] 与一个空白键的分隔喔!

既然每个栏位的长度不固定会造成上述的困扰,那我将每个栏位固定就好啦!没错没错!这样想非常好! 所以我们就将数据给他进行固定栏位长度的设计吧!

范例二:将上述数据关於第二行以后,分别以字串、整数、小数点来显示:
[root@www ~]# printf ‘%10s %5i %5i %5i %8.2f \n’ $(cat printf.txt |\
> grep -v Name)
DmTsai 80 60 92 77.33
VBird 75 55 80 70.00
Ken 60 90 70 73.33
上面这一串格式想必您看得很辛苦!没关系!一个一个来解释!上面的格式共分为五个栏位, %10s 代表的是一个长度为 10 个字节的字串栏位,%5i 代表的是长度为 5 个字节的数字栏位,至於那个 %8.2f 则代表长度为 8 个字节的具有小数点的栏位,其中小数点有两个字节宽度。我们可以使用底下的说明来介绍 %8.2f 的意义:

字节宽度: 12345678
%8.2f意义:00000.00
如上所述,全部的宽度仅有 8 个字节,整数部分占有 5 个字节,小数点本身 (.) 占一位,小数点下的位数则有两位。 这种格式经常使用於数值程序的设计中!这样了解乎?自己试看看如果要将小数点位数变成 1 位又该如何处理?

printf 除了可以格式化处理之外,他还可以依据 ASCII 的数字与图形对应来显示数据喔(注3)! 举例来说 16 进位的 45 可以得到什么 ASCII 的显示图 (其实是字节啦)?

范例三:列出 16 进位数值 45 代表的字节为何?
[root@www ~]# printf ‘\x45\n’
E
# 这东西也很好玩~他可以将数值转换成为字节,如果你会写 script 的话,
# 可以自行测试一下,由 20~80 之间的数值代表的字节是啥喔! ^_^
printf 的使用相当的广泛喔!包括等一下后面会提到的 awk 以及在 C 程序语言当中使用的萤幕输出, 都是利用 printf 呢!鸟哥这里也只是列出一些可能会用到的格式而已,有兴趣的话,可以自行多作一些测试与练习喔! ^_^

Tips:
列印格式化这个 printf 命令,乍看之下好像也没有什么很重要的~ 不过,如果你需要自行撰写一些软件,需要将一些数据在萤幕上头漂漂亮亮的输出的话, 那么 printf 可也是一个很棒的工具喔

awk

awk:好用的数据处理工具
awk 也是一个非常棒的数据处理工具!相较於 sed 常常作用於一整个行的处理, awk 则比较倾向於一行当中分成数个『栏位』来处理。因此,awk 相当的适合处理小型的数据数据处理呢!awk 通常运行的模式是这样的:

[root@www ~]# awk ‘条件类型1{动作1} 条件类型2{动作2} …’ filename
awk 后面接两个单引号并加上大括号 {} 来配置想要对数据进行的处理动作。 awk 可以处理后续接的文件,也可以读取来自前个命令的 standard output 。 但如前面说的, awk 主要是处理『每一行的栏位内的数据』,而默认的『栏位的分隔符号为 “空白键” 或 “[tab]键” 』!举例来说,我们用 last 可以将登陆者的数据取出来,结果如下所示:

[root@www ~]# last -n 5 <==仅取出前五行
root pts/1 192.168.1.100 Tue Feb 10 11:21 still logged in
root pts/1 192.168.1.100 Tue Feb 10 00:46 - 02:28 (01:41)
root pts/1 192.168.1.100 Mon Feb 9 11:41 - 18:30 (06:48)
dmtsai pts/1 192.168.1.100 Mon Feb 9 11:41 - 11:41 (00:00)
root tty1 Fri Sep 5 14:09 - 14:10 (00:01)
若我想要取出帐号与登陆者的 IP ,且帐号与 IP 之间以 [tab] 隔开,则会变成这样:

[root@www ~]# last -n 5 | awk ‘{print 1"\t"1 "\t" 3}’
root 192.168.1.100
root 192.168.1.100
root 192.168.1.100
dmtsai 192.168.1.100
root Fri
上表是 awk 最常使用的动作!透过 print 的功能将栏位数据列出来!栏位的分隔则以空白键或 [tab] 按键来隔开。 因为不论哪一行我都要处理,因此,就不需要有 “条件类型” 的限制!我所想要的是第一栏以及第三栏, 但是,第五行的内容怪怪的~这是因为数据格式的问题啊!所以罗~使用 awk 的时候,请先确认一下你的数据当中,如果是连续性的数据,请不要有空格或 [tab] 在内,否则,就会像这个例子这样,会发生误判喔!

另外,由上面这个例子你也会知道,在每一行的每个栏位都是有变量名称的,那就是 1,1, 2… 等变量名称。以上面的例子来说, root 是 1,因为他是第一栏嘛!至於192.168.1.100是第三栏,所以他就是1 ,因为他是第一栏嘛!至於 192.168.1.100 是第三栏, 所以他就是 3 啦!后面以此类推~呵呵!还有个变量喔!那就是 0,0 ,0 代表『一整列数据』的意思~以上面的例子来说,第一行的 $0 代表的就是『root …. 』那一行啊! 由此可知,刚刚上面五行当中,整个 awk 的处理流程是:

  1. 读入第一行,并将第一行的数据填入 0,0, 1, $2…. 等变量当中;
  2. 依据 “条件类型” 的限制,判断是否需要进行后面的 “动作”;
  3. 做完所有的动作与条件类型;
  4. 若还有后续的『行』的数据,则重复上面 1~3 的步骤,直到所有的数据都读完为止。

经过这样的步骤,你会晓得, awk 是『以行为一次处理的单位』, 而『以栏位为最小的处理单位』。好了,那么 awk 怎么知道我到底这个数据有几行?有几栏呢?这就需要 awk 的内建变量的帮忙啦~

变量名称 代表意义
NF 每一行 ($0) 拥有的栏位总数
NR 目前 awk 所处理的是『第几行』数据
FS 目前的分隔字节,默认是空白键

我们继续以上面 last -n 5 的例子来做说明,如果我想要:

  • 列出每一行的帐号(就是 $1);
  • 列出目前处理的行数(就是 awk 内的 NR 变量)
  • 并且说明,该行有多少栏位(就是 awk 内的 NF 变量)

则可以这样:

[root@www ~]# last -n 5| awk '{print $1 "\t lines: " NR "\t columns: " NF}'
root     lines: 1        columns: 10
root     lines: 2        columns: 10
root     lines: 3        columns: 10
dmtsai   lines: 4        columns: 10
root     lines: 5        columns: 9
\# 注意喔,在 awk 内的 NR, NF 等变量要用大写,且不需要有钱字号 $ 啦!

Tips:
要注意喔,awk 后续的所有动作是以单引号『 ’ 』括住的,由於单引号与双引号都必须是成对的, 所以, awk 的格式内容如果想要以 print 列印时,记得非变量的文字部分,包含上一小节 printf 提到的格式中,都需要使用双引号来定义出来喔!因为单引号已经是 awk 的命令固定用法了!

awk 的逻辑运算字节
既然有需要用到 “条件” 的类别,自然就需要一些逻辑运算罗~例如底下这些:

运算单元 代表意义
> 大於
< 小於
>= 大於或等於
<= 小於或等於
= 等於
!= 不等於

值得注意的是那个『 == 』的符号,因为:

逻辑运算上面亦即所谓的大於、小於、等於等判断式上面,习惯上是以『 == 』来表示;
如果是直接给予一个值,例如变量配置时,就直接使用 = 而已。
好了,我们实际来运用一下逻辑判断吧!举例来说,在 /etc/passwd 当中是以冒号 “:” 来作为栏位的分隔, 该文件中第一栏位为帐号,第三栏位则是 UID。那假设我要查阅,第三栏小於 10 以下的数据,并且仅列出帐号与第三栏, 那么可以这样做:

[root@www ~]# cat /etc/passwd | \
> awk ‘{FS=”:”} 3<10print$1"\t"$3′root:x:0:0:root:/root:/bin/bashbin1daemon2….(以下省略)….有趣吧!不过,怎么第一行没有正确的显示出来呢?这是因为我们读入第一行的时候,那些变量3 1, $2… 默认还是以空白键为分隔的,所以虽然我们定义了 FS=”:” 了, 但是却仅能在第二行后才开始生效。那么怎么办呢?我们可以预先配置 awk 的变量啊! 利用 BEGIN 这个关键字喔!这样做:

[root@www ~]# cat /etc/passwd | \
\> awk 'BEGIN {FS=":"} $3 < 10 {print $1 "\t " $3}'
root     0
bin      1
daemon   2

……(以下省略)……
很有趣吧!而除了 BEGIN 之外,我们还有 END 呢!另外,如果要用 awk 来进行『计算功能』呢?以底下的例子来看, 假设我有一个薪资数据表档名为 pay.txt ,内容是这样的:

Name 1st 2nd 3th
VBird 23000 24000 25000
DMTsai 21000 20000 23000
Bird2 43000 42000 41000
如何帮我计算每个人的总额呢?而且我还想要格式化输出喔!我们可以这样考虑:

第一行只是说明,所以第一行不要进行加总 (NR==1 时处理);
第二行以后就会有加总的情况出现 (NR>=2 以后处理)
[root@www ~]# cat pay.txt | \
> awk ‘NR==1{printf “%10s %10s %10s %10s %10s\n”,1,1,2,3,3,4,”Total” }
NR>=2{total = 2+2 + 3 + 4printf“4 printf “%10s %10d %10d %10d %10.2f\n”, 1, 2,2, 3, $4, total}’
Name 1st 2nd 3th Total
VBird 23000 24000 25000 72000.00
DMTsai 21000 20000 23000 64000.00
Bird2 43000 42000 41000 126000.00
上面的例子有几个重要事项应该要先说明的:

awk 的命令间隔:所有 awk 的动作,亦即在 {} 内的动作,如果有需要多个命令辅助时,可利用分号『;』间隔, 或者直接以 [Enter] 按键来隔开每个命令,例如上面的范例中,鸟哥共按了三次 [enter] 喔!
逻辑运算当中,如果是『等於』的情况,则务必使用两个等号『==』!
格式化输出时,在 printf 的格式配置当中,务必加上 \n ,才能进行分行!
与 bash shell 的变量不同,在 awk 当中,变量可以直接使用,不需加上 $ 符号。
利用 awk 这个玩意儿,就可以帮我们处理很多日常工作了呢!真是好用的很~ 此外, awk 的输出格式当中,常常会以 printf 来辅助,所以, 最好你对 printf 也稍微熟悉一下比较好啦!另外, awk 的动作内 {} 也是支持 if (条件) 的喔! 举例来说,上面的命令可以修订成为这样:

[root@www ~]# cat pay.txt | \
> awk ‘{if(NR==1) printf “%10s %10s %10s %10s %10s\n”,1,1,2,3,3,4,”Total”}
NR>=2{total = 2+2 + 3 + 4printf“4 printf “%10s %10d %10d %10d %10.2f\n”, 1, 2,2, 3, $4, total}’
你可以仔细的比对一下上面两个输入有啥不同~从中去了解两种语法吧!我个人是比较倾向於使用第一种语法, 因为会比较有统一性啊! ^_^

除此之外, awk 还可以帮我们进行回圈计算喔!真是相当的好用!不过,那属於比较进阶的单独课程了, 我们这里就不再多加介绍。如果你有兴趣的话,请务必参考延伸阅读中的相关连结喔 (注4)。

正则表达式

基础正规表示法

正规表示法是处理字串的一种表示方式,那么对字节排序有影响的语系数据就会对正规表示法的结果有影响!

特殊符号 代表意义
[:alnum:] 代表英文大小写字节及数字,亦即 0-9, A-Z, a-z
[:alpha:] 代表任何英文大小写字节,亦即 A-Z, a-z
[:blank:] 代表空白键与 [Tab] 按键两者
[:cntrl:] 代表键盘上面的控制按键,亦即包括 CR, LF, Tab, Del.. 等等
[:digit:] 代表数字而已,亦即 0-9
[:graph:] 除了空白字节 (空白键与 [Tab] 按键) 外的其他所有按键
[:lower:] 代表小写字节,亦即 a-z
[:print:] 代表任何可以被列印出来的字
[:punct:] 代表标点符号 (punctuation symbol),亦即:” ’ ? ! ; : # $…
[:upper:] 代表大写字节,亦即 A-Z
[:space:] 任何会产生空白的字节,包括空白键, [Tab], CR 等等
[:xdigit:] 代表 16 进位的数字类型,因此包括: 0-9, A-F, a-f 的数字与字节

例题一、搜寻特定字串
例题二、利用中括号 [] 来搜寻集合字节。
其实 [] 里面不论有几个字节,他都谨代表某『一个』字节
[root@www ~]# grep -n ‘t[ae]st’ regular_express.txt
8:I can’t finish the test.
9:Oh! The soup taste good.
可以利用在集合字节的反向选择 [^] 来达成:
[root@www ~]# grep -n ‘[^g]oo’ regular_express.txt
2:apple is my favorite food.
3*Foo*ball game is not use feet only.
18:google is the best *too*ls for search keyword.
19:g*oooooo*gle yes!
例题三、行首与行尾字节 ^ $
如果我不想要开头是英文字母,则可以是这样:
[root@www ~]# grep -n ‘^[^a-zA-Z]’ regular_express.txt
1:”Open Source” is a good mechanism to develop programs.
21:# I am VBird
# 命令也可以是: grep -n ‘^[^[:alpha:]]’ regular_express.txt
例题四、任意一个字节 . 与重复字节
. (小数点):代表『一定有一个任意字节』的意思;
* (星星号):代表『重复前一个字节, 0 到无穷多次』的意思,为组合形态
例题五、限定连续 RE 字符范围 {}
因为 { 与 } 的符号在 shell 是有特殊意义的,因此, 我们必须要使用跳脱字符 \ 来让他失去特殊意义才行。 至於 {} 的语法是这样的,假设我要找到两个 o 的字串,可以是:
[root@www ~]# grep -n ‘o{2}’ regular_express.txt
1:”Open Source” is a good mechanism to develop programs.
2:apple is my favorite food.
3:Football game is not use feet only.
9:Oh! The soup taste good.
18:google is the best tools for search keyword.
19:goooooogle yes!
假设我们要找出 g 后面接 2 到 5 个 o ,然后再接一个 g 的字串,他会是这样:
[root@www ~]# grep -n ‘go{2,5}g’ regular_express.txt
18:google is the best tools for search keyword.
嗯!很好!第 19 行终於没有被取用了(因为 19 行有 6 个 o 啊!)。 那么,如果我想要的是 2 个 o 以上的 goooo….g 呢?除了可以是 gooo*g ,也可以是:
[root@www ~]# grep -n ‘go{2,}g’ regular_express.txt
18:google is the best tools for search keyword.
19:goooooogle yes!

经过了上面的几个简单的范例,我们可以将基础的正规表示法特殊字符汇整如下:

RE 字符 意义与范例
^word
意义:待搜寻的字串(word)在行首!

范例:搜寻行首为 # 开始的那一行,并列出行号

grep -n ‘^#’ regular_express.txt

word
意义:待搜寻的字串(word)在行尾!

范例:将行尾为 ! 的那一行列印出来,并列出行号

grep -n ‘!$’ regular_express.txt

.
意义:代表『一定有一个任意字节』的字符!

范例:搜寻的字串可以是 (eve) (eae) (eee) (e e), 但不能仅有 (ee) !亦即 e 与 e 中间『一定』仅有一个字节,而空白字节也是字节!

grep -n ‘e.e’ regular_express.txt

\
意义:跳脱字符,将特殊符号的特殊意义去除!

范例:搜寻含有单引号 ’ 的那一行!

grep -n \’ regular_express.txt

*
意义:重复零个到无穷多个的前一个 RE 字符

范例:找出含有 (es) (ess) (esss) 等等的字串,注意,因为 * 可以是 0 个,所以 es 也是符合带搜寻字串。另外,因为 * 为重复『前一个 RE 字符』的符号, 因此,在 * 之前必须要紧接著一个 RE 字符喔!例如任意字节则为 『.』 !

grep -n ‘ess’ regular_express.txt

[list]
意义:字节集合的 RE 字符,里面列出想要撷取的字节!

范例:搜寻含有 (gl) 或 (gd) 的那一行,需要特别留意的是,在 [] 当中『谨代表一个待搜寻的字节』, 例如『 a[afl]y 』代表搜寻的字串可以是 aay, afy, aly 即 [afl] 代表 a 或 f 或 l 的意思!

grep -n ‘g[ld]’ regular_express.txt

[n1-n2]
意义:字节集合的 RE 字符,里面列出想要撷取的字节范围!

范例:搜寻含有任意数字的那一行!需特别留意,在字节集合 [] 中的减号 - 是有特殊意义的,他代表两个字节之间的所有连续字节!但这个连续与否与 ASCII 编码有关,因此,你的编码需要配置正确(在 bash 当中,需要确定 LANG 与 LANGUAGE 的变量是否正确!) 例如所有大写字节则为 [A-Z]

grep -n ‘[A-Z]’ regular_express.txt

[^list]
意义:字节集合的 RE 字符,里面列出不要的字串或范围!

范例:搜寻的字串可以是 (oog) (ood) 但不能是 (oot) ,那个 ^ 在 [] 内时,代表的意义是『反向选择』的意思。 例如,我不要大写字节,则为 [^A-Z]。但是,需要特别注意的是,如果以 grep -n [^A-Z] regular_express.txt 来搜寻,却发现该文件内的所有行都被列出,为什么?因为这个 [^A-Z] 是『非大写字节』的意思, 因为每一行均有非大写字节,例如第一行的 “Open Source” 就有 p,e,n,o…. 等等的小写字

grep -n ‘oo[^t]’ regular_express.txt

{n,m}
意义:连续 n 到 m 个的『前一个 RE 字符』

意义:若为 {n} 则是连续 n 个的前一个 RE 字符,

意义:若是 {n,} 则是连续 n 个以上的前一个 RE 字符! 范例:在 g 与 g 之间有 2 个到 3 个的 o 存在的字串,亦即 (goog)(gooog)

grep -n ‘go{2,3}g’ regular_express.txt

延伸正规表示法

事实上,一般读者只要了解基础型的正规表示法大概就已经相当足够了,不过,某些时刻为了要简化整个命令操作, 了解一下使用范围更广的延伸型正规表示法的表示式会更方便呢!

熟悉了正规表示法之后,到这个延伸型的正规表示法,你应该也会想到,不就是多几个重要的特殊符号吗? ^^y 是的~所以,我们就直接来说明一下,延伸型正规表示法有哪几个特殊符号?由於底下的范例还是有使用到 regular_express.txt ,不巧的是刚刚我们可能将该文件修改过了 @@,所以,请重新下载该文件来练习喔!

RE 字符 意义与范例
+
意义:重复『一个或一个以上』的前一个 RE 字符

范例:搜寻 (god) (good) (goood)… 等等的字串。 那个 o+ 代表『一个以上的 o 』所以,底下的运行成果会将第 1, 9, 13 行列出来。

egrep -n ‘go+d’ regular_express.txt

?
意义:『零个或一个』的前一个 RE 字符

范例:搜寻 (gd) (god) 这两个字串。 那个 o? 代表『空的或 1 个 o 』所以,上面的运行成果会将第 13, 14 行列出来。 有没有发现到,这两个案例( ‘go+d’ 与 ‘go?d’ )的结果集合与 ‘go*d’ 相同? 想想看,这是为什么喔! ^_^

egrep -n ‘go?d’ regular_express.txt


意义:用或( or )的方式找出数个字串

范例:搜寻 gd 或 good 这两个字串,注意,是『或』! 所以,第 1,9,14 这三行都可以被列印出来喔!那如果还想要找出 dog 呢?

egrep -n ‘gd▌good’ regular_express.txt

egrep -n ‘gd▌good▌dog’ regular_express.txt

()
意义:找出『群组』字串

范例:搜寻 (glad) 或 (good) 这两个字串,因为 g 与 d 是重复的,所以, 我就可以将 la 与 oo 列於 ( ) 当中,并以▌来分隔开来,就可以啦!

egrep -n ‘g(la▌oo)d’ regular_express.txt

()+
意义:多个重复群组的判别

范例:将『AxyzxyzxyzxyzC』用 echo 叫出,然后再使用如下的方法搜寻一下!

echo ‘AxyzxyzxyzxyzC’▌ egrep ‘A(xyz)+C’

上面的例子意思是说,我要找开头是 A 结尾是 C ,中间有一个以上的 “xyz” 字串的意思~

开始撰写

运行前必须搞清shell的运行方式和shell版本,最好在每个shell文件注明写下信息

script 的功能;
script 的版本信息;
script 的作者不联绚方式;
script 的版权宣告方式;
script 的 History (历叱纪录);
script 内较特殊的指令,使用『绛对路径』的方式来下达;
script 运作时需要的环境变量预先宣告不讴定。

* shell中经常用到变量用法*
变量设定

变量设定方式 str 没有讴定 str 为空字符串 str 已设定非为空字符串
var=${str-expr} var=expr var= var=$str
var=${str:-expr} var=expr var=expr var=$str
var=${str+expr} var= var=expr var=expr
var=${str:+expr} var= var= var=expr

var=${str=expr}

var=${str:=expr}


str=expr var=expr

str=expr var=expr


str 不变 var=

str=expr var=expr


str 不变 var=$str

str 不变 var=$str

var=${str?expr} expr 输出至 stderr var= var=$str
var=${str:?expr} expr 输出至 stderr expr 输出至 stderr var=$str

变量裁剪

变量设定方式 说明
${变量#关键词} 若变量内容仍头开始癿数据符合『关键词』,则将符吅癿最短数据初除
${变量##关键词} 若变量内容仍头开始癿数据符合『关键词』,则将符吅癿最长数据初除
${变量%关键词 } 若变量内容仍尾向前癿数据符合『关键词』,则将符吅癿最短数据初除
${变量%%关键词} 若变量内容仍尾向前癿数据符合『关键词』,则将符吅癿最长数据初除
${变量/旧字符串/新字符串} 若变量内容符合『旧字符串』则『第一个旧字符串会被新字符串叏代』
${变量//旧字符串/新字符串} 若变量内容符合『旧字符串』则『全部癿旧字符串会被新字符串叏代』


特殊变量列表

变量 含义
$0 当前脚本的文件名
$n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是1,第二个参数是1,第二个参数是2。
$# 传递给脚本或函数的参数个数。
$* 传递给脚本或函数的所有参数。
$@ 传递给脚本或函数的所有参数。被双引号(” “)包含时,与 $* 稍有不同,下面将会讲到。
$? 上个命令的退出状态,或函数的返回值。
$$ 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。

* 得到变量运算结果:var = $((运算内容));
* 利用sh来执行,变量为子程序shell中变量;
* 利用source来执行,为在主程序中直接执行,变量提留在主程序中;

条件判断语句

1.基本的判断语法

两个整数间比较大小 如:[ "n1" -lt "0" ]

参数 含义
-eq 两数值相等 (equal)
-ne 两数值丌等 (not equal)
-gt n1 大于 n2 (greater than)
-lt n1 小于 n2 (less than)
-ge n1 大于 等亍 n2 (greater than or equal)
-le n1 小于 等亍 n2 (less than or equal)

判定字符串的数据

参数 含义
test -z string 判定字符串是否为 0 ?若 string 为空字符串,则为 true
test -n string 判定字符串是否非为 0 ?若 string 为空字符串,则为 false。 注: -n 亦可省略
test str1 = str2 判定 str1 是否等亍 str2 ,若相等,则回传 true
est str1 != str2 判定 str1 是否丌等亍 str2 ,若相等,则回传 false

多重条件判定,例如: test -r filename -a -x filename

参数 含义
-a (and)两状况同时成立!例如 test -r file -a -x file,则 file 同时具有 r 不 x 权限时,才回传 true。

-o

!

(or)两状况任何一个成立!例如 test -r file -o -x file,则 file 具有 r 戒 x 权限时,就可回传 true。

反相状态,如 test ! -x file ,当 file 丌具有 x 时,回传 true

### 2.条件判断语句

利用if [];then elif [];then else fi来进行判断
具体如下:


if [条件判断一];then可以迚行的指令工作内容
elif [条件判断二];then可以迚行的指令工作内容;
else可以迚行的指令工作内容;
fi

利用case … in …. esac来进行判断


case $发量名称 in 

条件循环

循环可能是程序当中最重要的一环了,循环可以不断的执行某个程序段落,直到用户设定的条件达成为止。 所以,重点是那个『条件的达成』是什举。除了这种依据刞断式达成不否的不定循环之外, 还有另外种已经固定要跑多少次的循环形态,可称为固定循环的形态。

while do done, until do done (不定循环)

不固定循环的形态

while [ condition ]  <==中括号内的状态就是判断式do <==do 是循环的开始!程序段落
done  <==done 是循环的结束until [ condition ]
do程序段落
donefor...do...done (固定循环)**for var in con1 con2 con3 ...
do程序段
done

例如:

[root@www scripts]# vi sh16.sh
\#!/bin/bash # Program
\# Use id, finger command to check system account's information.
\# History # 2009/02/18 VBird first release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH
users=$(cut -d ':' -f1 /etc/passwd) # 撷取账号名称
for username in $users # 开始循环迚行!
do
id $username
finger $username
done

C语言执行

c语言中调用shell脚本返回值问题分析
c语言中调用shell脚本
C程序调用shell脚本共有三种方式:system()、popen()、exec系列函数
1)system(shell命令或shell脚本路径);
执行过程:system()会调用fork()产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令,此命令执行完后随即返回原调用的进程。在调用system()期间SIGCHLD 信号会被暂时搁置,SIGINT和SIGQUIT 信号则会被忽略。
例如:


{char cmdback[70];time_t tt;struct tm *t;int r;//1.已知logfile  //2.产生备份文件名tt=time(NULL);t=localtime(&tt);sprintf(backfile,"wtmpx%04d%02d%02d%02d%02d%02d",t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);//3.产生备份指令sprintf(cmdback,"./backup.sh %s %s",logfile,backfile);//4.调用system函数进行备份r=system(cmdback);if(WEXITSTATUS(r)==1){throw BackupException("日志拷贝错误");}if(WEXITSTATUS(r)==2){throw BackupException("日志清空错误");}printf("----备份日志成功!");
}

参考文献

[1]: 鸟哥的Linux私房菜基础篇第三版

Linux shell的简单学习相关推荐

  1. Linux shell脚本基础学习

    Linux shell脚本基础学习这里我们先来第一讲,介绍shell的语法基础,开头.注释.变量和 环境变量,向大家做一个基础的介绍,虽然不涉及具体东西,但是打好基础是以后学习轻松地前提. 1. Li ...

  2. Linux shell脚本基础学习详细介绍(完整版)2

    详细介绍Linux shell脚本基础学习(五) Linux shell脚本基础前面我们在介绍Linux shell脚本的控制流程时,还有一部分内容没讲就是有关here document的内容这里继续 ...

  3. Linux shell脚本基础学习详细介绍(完整版)一

    Linux shell脚本基础学习这里我们先来第一讲,介绍shell的语法基础,开头.注释.变量和 环境变量,向大家做一个基础的介绍,虽然不涉及具体东西,但是打好基础是以后学习轻松地前提. 1. Li ...

  4. Linux shell脚本基础学习详细介绍(完整版)

    Linux shell脚本基础学习这里我们先来第一讲,介绍shell的语法基础,开头.注释.变量和 环境变量,向大家做一个基础的介绍,虽然不涉及具体东西,但是打好基础是以后学习轻松地前提. 1. Li ...

  5. 详细介绍Linux shell脚本基础学习(一)

    2019独角兽企业重金招聘Python工程师标准>>> Linux shell脚本基础学习这里我们先来第一讲,介绍shell的语法基础,开头.注释.变量和 环境变量,向大家做一个基础 ...

  6. curl批量调用linux,shell的简单批量curl接口脚本

    shell脚本可以说作用非常大,在服务器领域,用shell操作事务可比手动点击要方便快捷得多了.虽然只是文字界面,但是其强大的处理功能,会让各种操作超乎想象.而且,也可以将这些习惯移植到日常的工作当中 ...

  7. Linux Shell脚本操作学习指南

    目录 Shell文件的规范 Shell文件的创建和运行 Shell文件语法 Shell传递参数 Shell参数校验 Shell数组 Shell运算符 Shell输出指令echo和printf Shel ...

  8. linux shell数组深入学习理解

    本文为大家介绍linux shell数组的相关知识,并提供了充足的例子供参考,这么好的东东,千万不要错过 bash shell只支持一维数组,但参数个数没有限制. 声明一个数组: declare -a ...

  9. Linux Shell脚本编程学习笔记和实战

    http://www.1987.name/141.html shell基础 终端打印.算术运算.经常使用变量 Linux下搜索指定文件夹下特定字符串并高亮显示匹配关键词 从键盘或文件里获取标准输入 [ ...

最新文章

  1. Tomcat 启动错误 org/eclipse/jdt/debug/core/JDIDebug...
  2. 【Java调试】通过SqlSessionFactory类对象获取mapper文件内的动态SQL在执行时的完整SQL及参数(2种使用方法+测试Demo及结果)
  3. SpringMVC实现文件的上传与下载
  4. boost::math::daubechies_scaling用法的测试程序
  5. 使用Docker-镜像命令
  6. 【数据结构与算法】平衡二叉树、红黑树
  7. python文件系统_你应该知道的10个Python文件系统方法
  8. bootstrap 模态框无法使用_模态窗 Modal Window - 产品中的??注意力设计
  9. asp.net mvc3 网站退出系统后使用浏览器的回退按钮依然能返回到内容页的处理方法...
  10. 100c之29:求具有abcd= ( ab + cd )^2 性质的四位数
  11. SQL Server 2008 R2 卸载教程
  12. 条码专题--条码技术应用
  13. 把Excel里的折线图另存为图片
  14. 百度自动php推送蜘蛛怎么不来访问,使用代码向百度蜘蛛主动推送链接
  15. 计算机网络期末复习(学会不挂科)
  16. 7-4 计算e的近似值 (10 分)
  17. SQL练习:表妹不在,没人帮我查表,只好自己来了
  18. 利用计算机软件温度补偿,一种计算机硬件设备专用温度补偿系统的制作方法
  19. 298day(点触验证)
  20. vue 之url拼接 根据选择条件动态修改url地址

热门文章

  1. Linux文件权限查看与修改
  2. 地铁听书系列之“看破不说破,81个为人处事潜规则”8月圆满收尾20220831
  3. python逆序输出_python倒序输出
  4. 【Spring Security入门教学】
  5. clk_mux及对应的约束
  6. 几种常见的算法求最大公约数(C语言)
  7. 新思科技网络安全研究中心分析手机中的生物识别数据泄露漏洞
  8. sqlserver函数多行数据合并成一行
  9. 【CH9434】使用CH9434移植到32单片机扩展4串口
  10. 电脑使用图片转换器打开heic图片方法