参考:

http://linux.vbird.org/linux_basic/0340bashshell-scripts.php#script_be

http://www.runoob.com/linux/linux-tutorial.html

12.2 简单的 shell script 练习

在第一支 shell script 撰写完毕之后,相信你应该具有基本的撰写功力了。接下来,在开始更
深入的程序概念之前,我们先来玩一些简单的小范例好了。 下面的范例中,达成结果的方式
相当的多,建议你先自行撰写看看,写完之后再与鸟哥写的内容比对, 这样才能更加深概念
喔!好!不?唆,我们就一个一个来玩吧!

12.2.1 简单范例

下面的范例在很多的脚本程序中都会用到,而下面的范例又都很简单!值得参考看看喔!
对谈式脚本:变量内容由使用者决定
很多时候我们需要使用者输入一些内容,好让程序可以顺利运行。 简单的来说,大家应该都
有安装过软件的经验,安装的时候,他不是会问你“要安装到那个目录去”吗? 那个让使用者
输入数据的动作,就是让使用者输入变量内容啦。
你应该还记得在十章 bash 的时候,我们有学到一个 read 指令吧?现在,请你以 read 指令的
用途,撰写一个 script ,他可以让使用者输入:1. first name 与 2. last name, 最后并且在屏
幕上显示:“Your full name is: ”的内容:
[dmtsai@study bin]$ vim showname.sh
#!/bin/bash
# Program:
# User inputs his first name and last name. Program shows his full name.
# History:
# 2015/07/16 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
read -p "Please input your first name: " firstname # 提示使用者输入
read -p "Please input your last name: " lastname # 提示使用者输入
echo -e "\nYour full name is: ${firstname} ${lastname}" # 结果由屏幕输出

将上面这个 showname.sh 执行一下,你就能够发现使用者自己输入的变量可以让程序所取
用,并且将他显示到屏幕上! 接下来,如果想要制作一个每次执行都会依据不同的日期而变
化结果的脚本呢?

随日期变化:

利用 date 进行文件的创建想像一个状况,假设我的服务器内有数据库,数据库每天的数据都不太一样,因此当我备份
时,希望将每天的数据都备份成不同的文件名, 这样才能够让旧的数据也能够保存下来不被
覆盖。哇!不同文件名呢!这真困扰啊?难道要我每天去修改 script ?
不需要啊!考虑每天的“日期”并不相同,所以我可以将文件名取成类似: backup.2015-07-
16.data , 不就可以每天一个不同文件名了吗?呵呵!确实如此。那个 2015-07-16 怎么来
的?那就是重点啦!接下来出个相关的例子: 假设我想要创建三个空的文件 (通过 touch)
文件名最开头由使用者输入决定,假设使用者输入 filename 好了,那今天的日期是
2015/07/16 , 我想要以前天、昨天、今天的日期来创建这些文件,亦即 filename_20150714,
filename_20150715, filename_20150716 ,该如何是好?
[dmtsai@study bin]$ vim create_3_filename.sh
#!/bin/bash
# Program:
# Program creates three files, which named by user's input and date command.
# History:
# 2015/07/16 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
# 1\. 让使用者输入文件名称,并取得 fileuser 这个变量;
echo -e "I will use 'touch' command to create 3 files." # 纯粹显示信息
read -p "Please input your filename: " fileuser # 提示使用者输入
# 2\. 为了避免使用者随意按 Enter ,利用[变量功能](../Text/index.html#variable_other_re)分析文件名是否有设置?
filename=${fileuser:-"filename"} # 开始判断有否配置文件名
# 3\. 开始利用 date 指令来取得所需要的文件名了;
date1=$(date --date='2 days ago' +%Y%m%d) # 前两天的日期
date2=$(date --date='1 days ago' +%Y%m%d) # 前一天的日期
date3=$(date +%Y%m%d) # 今天的日期
file1=${filename}${date1} # 下面三行在配置文件名
file2=${filename}${date2}
file3=${filename}${date3}
# 4\. 将文件名创建吧!
touch "${file1}" # 下面三行在创建文件
touch "${file2}"
touch "${file3}"

上面的范例鸟哥使用了很多在第十章介绍过的概念: 包括小指令“ $(command) ”的取得讯
息、变量的设置功能、变量的累加以及利用 touch 指令辅助! 如果你开始执行这个
create_3_filename.sh 之后,你可以进行两次执行:一次直接按 [Enter] 来查阅文件名是啥?
一次可以输入一些字符,

数值运算:简单的加减乘除

各位看官应该还记得,我们可以使用 declare 来定义变量的类型吧? 当变量定义成为整数后
才能够进行加减运算啊!此外,我们也可以利用“ $((计算式)) ”来进行数值运算的。 可
惜的是, bash shell 里头默认仅支持到整数的数据而已。OK!那我们来玩玩看,如果我们要
使用者输入两个变量, 然后将两个变量的内容相乘,最后输出相乘的结果,那可以怎么做?
[dmtsai@study bin]$ vim multiplying.sh
#!/bin/bash
# Program:
# User inputs 2 integer numbers; program will cross these two numbers.
# History:
# 2015/07/16 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "You SHOULD input 2 numbers, I will multiplying them! \n"
read -p "first number: " firstnu
read -p "second number: " secnu
total=$((${firstnu}*${secnu}))
echo -e "\nThe result of ${firstnu} x ${secnu} is ==> ${total}"

在数值的运算上,我们可以使用“ declare -i total=${firstnu}*${secnu} ” 也可以使用上面的方式
来进行!基本上,鸟哥比较建议使用这样的方式来进行运算:
var=$((运算内容))
不但容易记忆,而且也比较方便的多,因为两个小括号内可以加上空白字符喔! 未来你可以
使用这种方式来计算的呀!至于数值运算上的处理,则有:“ +, -, , /, % ”等等。 那个 % 是取
余数啦~举例来说, 13 对 3 取余数,结果是 13=43+1,所以余数是 1 啊!就是:
[dmtsai@study bin]$ echo $(( 13 % 3 ))
1
这样了解了吧?另外,如果你想要计算含有小数点的数据时,其实可以通过 bc 这个指令的协
助喔! 例如可以这样做:
[dmtsai@study bin]$ echo "123.123*55.9" |  bc
6882.575
了解了 bc 的妙用之后,来让我们测试一下如何计算 pi 这个东西呢?
数值运算:通过 bc 计算 pi
其实计算 pi 时,小数点以下位数可以无限制的延伸下去!而 bc 有提供一个运算 pi 的函数,
只是想要使用该函数必须要使用 bc -l 来调用才行。 也因为这个小数点以下位数可以无线延伸
运算的特性存在,所以我们可以通过下面这只小脚本来让使用者输入一个“小数点为数值”,
以让 pi 能够更准确!
[dmtsai@study bin]$ vim cal_pi.sh
#!/bin/bash
# Program:
# User input a scale number to calculate pi number.
# History:
# 2015/07/16 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "This program will calculate pi value. \n"
echo -e "You should input a float number to calculate pi value.\n"
read -p "The scale number (10~10000) ? " checking
num=${checking:-"10"} # 开始判断有否有输入数值
echo -e "Starting calcuate pi value. Be patient."
time echo "scale=${num}; 4*a(1)" | bc -lq

上述数据中,那个 4*a(1) 是 bc 主动提供的一个计算 pi 的函数,至于 scale 就是要 bc 计
算几个小数点下位数的意思。当 scale 的数值越大, 代表 pi 要被计算的越精确,当然用掉的
时间就会越多!因此,你可以尝试输入不同的数值看看!不过,最好是不要超过 5000 啦!因
为会算很久! 如果你要让你的 CPU 随时保持在高负载,这个程序算下去你就会知道有多操
CPU ?! ^_^
Tips 鸟哥的实验室中,为了要确认虚拟机的效率问题,所以很多时候需要保持虚拟机在忙碌
的状态~鸟哥的学生就是丢这只程序进去系统跑! 但是将 scale 调高一些,那计算就得要花
比较多时间~用以达到我们需要 CPU 忙碌的状态喔!

这样可以判断你的脚本是否设计正确喔!

12.2.2 script 的執行方式差異 (source, sh script, ./script)

不同的 script 執行方式會造成不一樣的結果喔!尤其影響 bash 的環境很大呢!腳本的執行方式除了前面小節談到的方式之外,還可以利用 source 或小數點 (.) 來執行喔!那麼這種執行方式有何不同呢?當然是不同的啦!讓我們來說說!

  • 利用直接執行的方式來執行 script

當使用前一小節提到的直接指令下達 (不論是絕對路徑/相對路徑還是 ${PATH} 內),或者是利用 bash (或 sh) 來下達腳本時, 該 script 都會使用一個新的 bash 環境來執行腳本內的指令!也就是說,使用這種執行方式時, 其實 script 是在子程序的 bash 內執行的!我們在第十章 BASH 內談到 export 的功能時,曾經就父程序/子程序談過一些概念性的問題, 重點在於:『當子程序完成後,在子程序內的各項變數或動作將會結束而不會傳回到父程序中』! 這是什麼意思呢?

我們舉剛剛提到過的 showname.sh 這個腳本來說明好了,這個腳本可以讓使用者自行設定兩個變數,分別是 firstname 與 lastname,想一想,如果你直接執行該指令時,該指令幫你設定的 firstname 會不會生效?看一下底下的執行結果:

[dmtsai@study bin]$ echo ${firstname} ${lastname}
<==確認了,這兩個變數並不存在喔!
[dmtsai@study bin]$ sh showname.sh
Please input your first name: VBird <==這個名字是鳥哥自己輸入的
Please input your last name: Tsai Your full name is: VBird Tsai <==看吧!在 script 運作中,這兩個變數有生效
[dmtsai@study bin]$ echo ${firstname} ${lastname}
<==事實上,這兩個變數在父程序的 bash 中還是不存在的!

上面的結果你應該會覺得很奇怪,怎麼我已經利用 showname.sh 設定好的變數竟然在 bash 環境底下無效!怎麼回事呢? 如果將程序相關性繪製成圖的話,我們以下圖來說明。當你使用直接執行的方法來處理時,系統會給予一支新的 bash 讓我們來執行 showname.sh 裡面的指令,因此你的 firstname, lastname 等變數其實是在下圖中的子程序 bash 內執行的。 當 showname.sh 執行完畢後,子程序 bash 內的所有資料便被移除,因此上表的練習中,在父程序底下 echo ${firstname} 時, 就看不到任何東西了!這樣可以理解嗎?

圖12.2.1、showname.sh 在子程序當中運作的示意圖
  • 利用 source 來執行腳本:在父程序中執行

如果你使用 source 來執行指令那就不一樣了!同樣的腳本我們來執行看看:

[dmtsai@study bin]$ source showname.sh
Please input your first name: VBird
Please input your last name: Tsai Your full name is: VBird Tsai
[dmtsai@study bin]$ echo ${firstname} ${lastname}
VBird Tsai <==嘿嘿!有資料產生喔!

竟然生效了!沒錯啊!因為 source 對 script 的執行方式可以使用底下的圖示來說明! showname.sh 會在父程序中執行的,因此各項動作都會在原本的 bash 內生效!這也是為啥你不登出系統而要讓某些寫入 ~/.bashrc 的設定生效時,需要使用『 source ~/.bashrc 』而不能使用『 bash ~/.bashrc 』是一樣的啊!

圖12.2.2、showname.sh 在父程序當中運作的示意圖

鸟哥的 Linux 私房菜Shell Scripts篇(二)的更多相关文章

  1. 鸟哥的 Linux 私房菜Shell Scripts篇(一)

    参考: http://linux.vbird.org/linux_basic/0340bashshell-scripts.php#script_be http://www.runoob.com/lin ...

  2. 鸟哥的 Linux 私房菜Shell Scripts篇(四)

    12.4 条件判断式 只要讲到『程式』的话,那么条件判断式,亦即是『 if then 』这种判别式肯定一定要学习的!因为很多时候,我们都必须要依据某些资料来判断程式该如何进行.举例来说,我们在上头的a ...

  3. 鸟哥的 Linux 私房菜Shell Scripts篇(三)

    参考: http://linux.vbird.org/linux_basic/0340bashshell-scripts.php#script_be http://www.runoob.com/lin ...

  4. 拒绝从入门到放弃_《鸟哥的 Linux 私房菜 — 基础学习篇(第三版)》必读目录

    目录 目录 前言 关于这本书 必看知识点 最后 前言 相信部分刚进入这个行业的新同学会对一个问题感到疑惑,为什么从培训学校出来的学员不被欢迎? 这里记录下一些我个人的看法(博主也曾有面试新员工的经历) ...

  5. 每周一书-《鸟哥的Linux私房菜基础学习篇(第四版)》台湾原版,你想要吗?

     首先说明,本周活动有效时间为2016年10月19日到2016年10月31日.   目在介绍这本书之前,首先要感谢QQ号为:1084830483(路在远方),来自哈尔滨工程大学的同学赠送给玄魂工作室的 ...

  6. 【Linux】鸟哥的Linux私房菜基础学习篇整理(一)

    最近,一直在写PPC的模拟器和汇编器,也在做设计.所以重新看了看<鸟哥的Linux私房菜>,还是有好多命令不太熟悉.就打算写几篇blog记下来. 1. nl [-bnw] filename ...

  7. 《鸟哥的Linux私房菜-基础学习篇(第三版)》(三)

    第2章 Linxu怎样学习         1. Linux当前的应用角色 当前的Linux常见的应用可略分为企业应用和个人应用双方面. 首先谈了企业环境的利用. 1)网络server. 2)关键任务 ...

  8. 鸟哥的Linux私房菜 基础学习篇读书笔记(9):Linux磁盘与文件系统管理(2)

    上一篇文章主要从理论上分析了Linux的Ext2文件系统.这一篇主要解说怎样查看Linux的文件系统的容量以及解说Linux文件系统中的连接文件. 能够通过df和du命令来查看磁盘与文件夹的容量.df ...

  9. 《鸟哥的Linux私房菜-基础学习篇(第三版)》(四)

    第3章 主机规划与磁盘分区        1. Linux与硬件的搭配        首先谈了认识计算机的硬件配置. 然后谈了选择与Linux搭配的主机配置. 在Linuxserver中,内存的重要性 ...

随机推荐

  1. 如何将页面上的数据导入excel中

    网上关于页面数据导入excel的文章很多,但是大部分都是关于 ActiveXObject 对象,可是ActiveXObject 对象是只支持IE的,可我连IE11也测试了,还是无法识别,又查到消息,好 ...

  2. java对文件的检索

    先说下思路吧. 1.先把xls等文件转换为静态html文件:可以用很多插件,类似我的博客地址: http://www.cnblogs.com/Alandre/p/3221006.html 2.再对转的 ...

  3. Qt5——从零开始的学生管理系统

    Qt教程——从零开始的学生管理系统(文件) 一.项目设计 1.需求分析 记录并处理学生成绩信息. 1)添加新的学生数据: 2)根据学号对已有的学生数据进行修改: 3)根据学号删除已存在的学生信息: 4 ...

  4. vi常用命令总结

    1. 打开文件 > vi 文件 //该模式是命令模式 2. 尾行模式操作 > :q //该模式是“尾行模式” > :w //保存已经修改的文档 > :wq //保存并退出 &g ...

  5. Python vtk学习(1)

    Vtk,(visualization toolkit)是一个开源的免费软件系统,主要用于三维计算机图形学.图像处理和可视化.Vtk是在面向对象原理的基础上设计和实现的,它的内核是用C++构建的,包含有 ...

  6. IdentityServer4 中文文档 -7- (简介)贡献

    IdentityServer4 中文文档 -7- (简介)贡献 原文:http://docs.identityserver.io/en/release/intro/contributing.html ...

  7. 跨站请求伪造CSRF(Cross-site request forgery)

    CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站 ...

  8. 【WebSocket No.2】WebSocket和Socket实现聊天群发

    介绍: 前面写过一篇简单的websocke实现服务端.这一篇就不在说什么基础的东西主要是来用实例说话,主要是讲一下实现单聊和群组聊天和所有群发的思路设计. 直接不懂的可以看一下上一篇简单版本再来看也行 ...

  9. tomcat启动时卡住

    tomcat启动时卡住 进入jdk/jre/lib/security/java.security文件 找到securerandom.source将这一行隐藏 并在下面一行加入securerandom. ...

  10. Linux常用基本命令:三剑客命令之-awk格式化动作

    我们之前说过,awk是一个超强的文本格式化工具,而本文的printf动作就是经常用来做格式化文本的.使用方式跟c语言的printf差不多. 1,printf默认不会回车换行 ghostwu@dev:~ ...