《shell编程实战》第2章shell脚本入门(中)

一、写第一个shell脚本
写脚本以前的准备工做:
因为vim比vi强大,一般选用vim编辑器取代vi。具体操做方法为:
[root@thzzc1994 ~]# echo "alias vi=vim" >> /etc/profile
[root@thzzc1994 ~]# tail -1 /etc/profile
alias vi=vim
[root@thzzc1994 ~]# source /etc/profile
二、第一行写脚本编辑器
咱们如今写的脚本,第一行通常都是#!/bin/bash。不一样的脚本的解释器是不同的,好比:
#!/usr/bin/expect #<==expect解决交互式的语言开头解释器
#!/usr/bin/perl #<==perl语言解释器
#!/usr/bin/env python #<==python语言解释器
若是这些脚本的第一行不指定解释器,那么就要用对应的解释器来执行脚本,这样才能确保脚本正确执行。例如:
若是是Shell脚本,就用bash test.sh执行test.sh。
若是是Python脚本,就用python test.py执行test.py。
若是是expect脚本,就用expect test.exp执行test.exp。
三、查看bash版本
cat /etc/redhat-release
bash --version
四、检测bash漏洞
检测方法:
[root@thzzc1994 ~]# env x='() { :;};echo be careful' bash -c "echo this is a test"
be careful
this is a test
若是输出be careful,表示说明须要尽快升级了
[root@thzzc1994 ~]# rpm -qa bash
bash-4.1.2-14.el6.x86_64
而书中老男孩无漏洞版本为4.1.2-40
看来我须要尽快升级bash了
为了展现破壳漏洞,咱们不如破解bash看看。下面是网上找的一篇我认为写得比较全的。
破解方法:(我没看懂,但要相信咱们之后必定能看懂!)
http://www.javashuo.com/article/p-kxbnclal-gg.html
升级方法:
[root@thzzc1994 ~]# yum update bash -y >/dev/null && echo install ok
There are unfinished transactions remaining. You might consider running yum-complete-transaction first to finish them.
install ok
[root@thzzc1994 ~]# env x='() { :;};echo be careful' bash -c "echo this is a test"
this is a test
若是没有输出be careful,则bash没有漏洞。说明升级成功了。
[root@thzzc1994 ~]# rpm -qa bash
bash-4.1.2-40.el6.x86_64
检验一下,果真跟老男孩的版本同样了。
五、重视注释
开发脚本时,若是没有注释,那么团队里的其余人就会很难理解脚本对应内容的用途,并且若是时间过长,本身也会忘记。所以,咱们要尽可能养成为shell脚本书写关键注释的习惯,书写注释不光是为了方便别人,更是为了方便本身,避免影响团队的协做效率,以及给后来接手的人带来维护困难。
其实,不止脚本,包括/etc/rc.local、/etc/exports、/var/spool/cron/root等系统文件都尽可能加上注释。这不是必须的,但能反映一个优秀运维的习惯和规范。
特别提示:脚本中尽可能不要使用中文,防止本机或切换系统环境后中文乱码的困扰。若是非要加中文,清根据自身状况对字符集进行调整,如:export LANG="zh_CN.UTF-8",而且在脚本中从新定义字符集设置,和系统保持一致。
另外,linux中全部字母、符号(包括单引号、双引号和反引号)都应该是英文状态下的符号,这点须要特别注意。
六、shell脚本启动流程
(1)脚本运行时,会先调用系统环境配置文件,配好环境变量。其顺序为:
/etc/profile==>~/.bash_profile==>~/.bashrc==>/etc/bashrc
(2)父脚本生成==>请求新进程==>子脚本生成==>子脚本结束==>父脚本结束
提示:设置linux的crond任务时,最好在脚本中从新定义环境变量,不然,部分系统环境变量不会被加载。
七、执行脚本的四种方法
(1)bash xx.sh或sh xx.sh,适用于脚本没有可执行权限x或脚本没有解释器的时候。(老男孩推荐)
(2)path/xx.sh或./xx.sh,该方法须要可执行权限x
(3)source xx.sh或. xx.sh。区别于其余方法,该方法会在当前父shell中加载并执行相关脚本,而其余方法都会启动新的进程执行子脚本。好处是,使用source或.能够将xx.sh自身脚本中的变量值或函数等返回值传递到当前父shell脚本中使用。
(4)sh<xx.sh或cat xx.sh|sh,老男孩将它用于将字符串拼接成命令再经由管道交给bash操做。python

附录:
一、如何判断环境文件加载的前后顺序?
参考网上export加变量方法,不能解释所有文件,不行;又参考touch&&man --full-time,四个时间戳如出一辙。网上两种方法都不行,因而本身想到一种方法,以下:
执行以下命令(试过了,这四行的前后顺序不影响),而后重启。
[root@thzzc1994 ~]# echo "rm etcprofile">>/etc/profile
[root@thzzc1994 ~]# echo "rm etcbashrc">>/etc/bashrc
[root@thzzc1994 ~]# echo "rm homebashrc">>~/.bashrc
[root@thzzc1994 ~]# echo "rm homebashprofile">>~/.bash_profile
[root@thzzc1994 ~]# reboot
登陆进去之后,会看到以下提示:
rm: 没法删除"etcprofile": 没有那个文件或目录
rm: 没法删除"etcbashrc": 没有那个文件或目录
rm: 没法删除"homebashrc": 没有那个文件或目录
rm: 没法删除"homebashprofile": 没有那个文件或目录
总结:不难看出,调用顺序为/etc/profile==>/etc/bashrc==>~/.bashrc==>~/.bash_profile。
----大体看这种方法,好像没有问题。但是这四个文件存在着相互调用关系,还能这样搞么?在~/.bash_profile中,发现就调用过~/.bashrc。
不难在~/.bash_profile中找到
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
一样,在~/.bashrc中找到
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
受到启发,修改四句echo,把echo放到文件的最开头去,修改完保存,从新登录,提示变成:
rm: cannot remove `etcprofile': No such file or directory
rm: 没法删除"homebashprofile": 没有那个文件或目录
rm: 没法删除"homebashrc": 没有那个文件或目录
rm: 没法删除"etcbashrc": 没有那个文件或目录
这才终于应了那个顺序:/etc/profile==>~/.bash_profile==>~/.bashrc==>/etc/bashrclinux

相关文章
相关标签/搜索