勾引顺序
首先我们要说下bash脚本的启动,Linux中系统初始化都是按照一定顺序加载各个文件初始化脚本(Shell脚本)。脚本所在文件启动顺序很主要,下面这个图显示了Linux系统个初始化脚本和环境变量的加载顺序,包括了bash、sh和zsh等常见的shell。
bash的加载遵照上图,从上到下顺序实行加载,尤其要把稳non-login、非交互(上面蓝色线)实行,它不会加载很多脚本,比如/etc/profile(总profile),/etc/bash.bashrc(总basrc),和个人的.profile, .bash_profie,.bash_login和.bashrc等。以是如果你脚本处于这样环境下(比如cron脚本),你就要在脚本中自我设置一些环境变量。这样就可以避免由于环境变量导致的一些莫名其妙的的问题,比如写的好脚本为什么上岸就可以实行,放到cron里面自动实行就弗成。
我们知道Linux下统统皆文件,包括硬件设备,个中三个分外的文件句斌,标准输入(stdin)、标准输出(stdout)和标准缺点(stderr),其句柄号为三个整数0,1和2。

< :用于重定向改变标准输入(stdin)。
0< :0< 和<一样 ,<符号之前须要制订一个FD,默认为0。
<< :输入一段文本,直到读到<<后指定的内容,这便是常说的heredoc。
> :用于重定向改变标准输出(stdout)。
1> :1> 和>一样 ,> 默认的FD为1。
2> :改变标准缺点(stderr)。
>> :重定向输出到文件,追加到文件末端。
set -o noclobber :设置 > 不能覆盖已经存在的文件。
set +o noclobber :这支 > 可以覆盖已经存在的文件。
>| :设置set -o noclobber后,利用 >| 可以临时覆盖已经存在的文件。
/dev/null 和 /dev/zero这两个文件是两个比较分外设备。/dev/null,或称空设备,它会丢弃统统写入它的数据,但是读取它则会抛出错误。在shell中常用它来表示放弃实行的结果(或者缺点),这样只关注于程序实行,比如在cron中的任务,输出和缺点都没故意义。
command > /dev/null
可以将stdout、stderr都重定向输出到/dev/null:
command > /dev/null 2>&1 或者
command &> /dev/null
command >& /dev/null
/dev/zero 设备用于供应无限制的空null内供读取。当读取该设备(文件)时候,它会供应无限的空字符 null。我们可以从/dev/zero 读取任意数量的 null 字符。和 /dev/null 不同,/dev/zero紧张用于作为null数据源供读取,当然/dev/zero也支持写入,可以用做数据黑洞,。
/dev/zero紧张用场是供应字符流来初始化数据存储,也便是利用空字符覆盖目标数据。还可以用来一个特定大小的空缺文件。
比如用空缺文件覆盖分区,删除分区的数据可以用(慎用!
):
dd if=/dev/zero of=/dev/<destination partition>
创建一个一个1M的文件,可以利用
dd if=/dev/zero of=cc count=1024 bs=1024
``和$()反引号(Tab键上面的键)和$(),两者基本上类似,在shell中都表示实行命令。
echo`ls`
echo $(ls)
最常用的用法是将一些命令结果输出通报个其他命令作为参数。比如要查询当前目录和子目录下所有PHP中的包含\"大众eval\"大众函数(似疑木马),可以用下面命令:
grep eval `find -type f -name \"大众.php\公众`
两者紧张的差异在于嵌套更大略。
对``来说要实现嵌套就要增加很多反斜杠来转义,比如:
echo `echo \`echo \\\`echo hello,Chongchong\!\\\`\``
而用$()就简介的多了:
echo $(echo $(echo $(echo hello,Chongchong\!)))
<()这是个很故意义的操作符,他有点类似于$(),而对括弧中命令的输出重用。但是在<高下文中其输出结果被会视为文件,可以用于以文件名为参数的命令中。
比如我们要实行下面一些例子
grep keys file1> /tmp/a
grep keys file2> /tmp/b
diff /tmp/a /tmp/b
用<()以上可以用oneline单行来代替:
diff <(grep keys file1)<(grep keys file2)
引用bash引用比较繁芜,我们先从大略的开始。
首先,引号中的变量:
A='123'
echo \公众$A\公众
echo '$A'
这个结果很大略,双引号会阐明变量,输出为其值123,而单引号不会阐明,输出为$A。
下面三个echo 都会打印啥呢?
mkdir -p tmp
cd tmp
touch a
echo
echo \公众\"大众
echo ''
Bash中还有很多引用办法的快捷操作符,个中一些可以极大的提高我们的事情效率
!$
表示重复末了一个命令的末了一个参数。如果你正在处理一个文件,通过该操作符可以在命令后重新引入参数,从而节省大量重复输入。
grep xxx /long/path/to/some/file/or/other.txt
vim !$
!:1-$
该操作符,更故意思,它获取上一个命令的所有参数并将它们引入。以是:
grep isthere /long/path/to/some/file/or/other.txt
egrep !:1-$
fgrep !:1-$
!表示'查看上一个命令',:是一个分隔符,1表示'取第一个单词', -表示范围'直到',$表示'末了一个单词'。
我们可以用!实现同样的目的。但是基于上面规则,我们就可以随意定制参数的范围了。比如如利用!:2-3。
:h
如果把该操作符放在一个文件名后面,它会删除文件夹以外的文件名称。比如:
grep XXX /long/path/to/some/file/or/other.txt
cd !$:h
通配符和正则表达式通配符合正则表达式中都会用,看起来很相似,但它们差异很大
请阐明下面这个命令:
rename -n 's/(.)/HEAD$1/'
上面两个星号表达意思完备不同:
第一个由于用单引号括住,shell不会对其阐明,作为参数都提交给rename命令。rename会对其阐明 ,而s/(.)/HEAD$1/是一个正则更换。在正则表达式中 表示对前面字符的0个或者多个模式。.表示一个字符,以是.表示匹配所有内容;()表示对括住内容进行引用,在更换后面部分用\1或者$1表示它。
第二个会被shell阐明,在shell中表示通配符,表示当前事情文件夹中所有文件的列表更换。
以是全体命令表示将文件下所有文件名都增加上HEAD 前缀。请考试测验下面两个命令:
ls
ls .
第二个看起来更像是一个正则表达式,但是实际是什么样的呢?请你考试测验对输出阐明下。
条件语句,[和[[请考试测验实行一下语句会输出什么?
if grep XXX /dev/null
then
echo Chongchong
else
echo lo
fi
grep的返回代码使得像这样的代码更直不雅观地作为其作为退出状态阐明时候带来的副浸染。
下面两个语句的输出呢?
if [ $(grep XXX /dev/null) = '' ]
then
echo -n Chongchong
else
echo -n lo
fi
if [[ $(grep XXX /dev/null) = '' ]]
then
echo -n Chongchong
else
echo -n lo
fi
[是测试的原始形式,然后[[引入了更灵巧和直不雅观的办法。在上面的第一个if块中,if语句由于$(grep XXX /dev/null)被评估为空,导致这种比较:[=''],这会抛出错误,针对这种情形就须要利用[[]]来避免这种非常,还有一个常用的技巧是利用:
if [x$(grep XXX /dev/null)='x']
以是,如果命令没有返回任何内容,它仍旧可以正常运行,而不会抛出非常,中断实行。
退出状态码我们知道每次shell实行,推出是都会给shell一个状态码。
如果命令实行正常,则会返回给shell状态码0。如果不堪利,则会得到一个非零代码,用来表详细缺点的种类,个中 1表示\公众一样平常缺点\"大众,还有其他更多信息,可以在程序中详细定义。状态码,可以通过$?查看。但有些命令会设置有分外设置比如grep,请考试测验下面的命令:
grep XXX /dev/null
echo $?
grep中利用退出代码来指示它是否匹配。
set 语句Bash中也供应了可配置的选项,可以即时设置环境变量等。
set -e
如果任何命令返回非零退出状态,则从脚本退出。
set -X
会输出在运行时运行的命令。
以是脚本可能会利用这样的开头:
#!/bin/bash
set -e
set -x
grep XXX /dev/null
echo $?
getopts如果要写一个较大的程序,涉及的输入比较繁芜,则须要利用getopts来简化你的事情,用他来帮你做输入和参数处理的事情,比如下面一个例子:
getopts后面跟的是参数列表字符串,每个字母表示一个选项,带:选项表示选项还会有值,比如上面例子中对应的-j /home/soft/java 和-m /home/soft/maven 。而getopts字符串中没有跟随:的字母便是开关型选项,不须要指定值,等同于true/false,只要带上了这个参数便是true。
getopts是shell内部命令,可以在shell脚本中直策应用,同时shell也支持一个外部命令getopt有很多发行版本也都自带。详细可以搜索参考详细文档,本文不在赘述。
总结:抛砖引玉,本文中列出了shell中一些常见的技巧和随意马虎稠浊的知识点,希望能对大家有所帮助,如果大家有更好的想法技巧也可以一起分享出来,一起参考学习。