您的位置:首页 > 运维架构 > Shell

Shell脚本攻略01-简介/终端打印

2016-12-01 02:31 661 查看

概述

 终端打印

 玩转变量与环境变量

 使用函数填加环境变量

 通过shell进行数学运算

 玩转文件描述符与重定向

 数组和关联数组

 使用别名

 获取终端信息

 获取、设置日期及延时

 调试脚本

 函数和参数

 将命令序列的输出读入变量

 以不按回车键的方式获取字符”n”

 运行命令直至执行成功

 字段分隔符和迭代器

 比较与测试

简介

本系列博客使用的是Bash(Bourne Again Shell),它是目前大多数GNU/Linux系统默认的shell环境。

查看默认的shell

[root@entel2 ~]#echo $SHELL
/bin/bash
[root@entel2 ~]#echo $0
-bash
[root@entel2 ~]#env |grep SHELL
SHELL=/bin/bash


$和#
提示符

打开终端后,就会出现一个提示符。其形式通常如下:

username@hostname$


或者

root@hostname #


要么就简单地以$或#表示, 格式其实是有 PS1(“prompt string one” 的简写)决定的, 这里我们要说的是
#
$


$表示普通用户, #表示管理员用户root

[root@entel2 ~]#


oracle@entel2:[/oracle]$


root是Linux系统中权限最高的用户。

注:

以root用户(管理员)的身份直接使用shell来执行任务可不是个好主意。因为如果shell具备较高的权限,命令中出现的输入错误有可能造成更严重的坏。

所以推荐使用普通用户登录系统(使用$来表明这种身份,root登录时要使用#), 然后借助sudo这类工具来运行特权命令。

使用
sudo <command> <arguments>
这种形式执行命令的效果和root一样。

shell脚本通常是一个以shebang起始的文本文件

shebang这个词其实是两个字符名称的组合。

在Unix的行话里,用sharp或hash(有时候是mesh)来称呼字符“ #”,用bang来称呼惊叹号“ !”,因而shebang合起来就代表了这两个字符。

#!/bin/bash


shebang是一个文本行,其中#!位于解释器路径之前。 /bin/bash是Bash的解释器命令路径。

运行脚本的两种方式

将脚本作为bash的命令行参数

将脚本作为命令行参数时的运行方式如下(#号后面的文本是注释,不必输入到命令行中):

$ bash script.sh #假设脚本位于当前目录下


或者

$ bash /home/path/script.sh #使用script.sh的完整路径


如果将脚本作为bash的命令行参数来运行,那么就用不着脚本中的shebang了。

授予脚本执行权限,将其变为可执行文件

要是有需要的话,可以利用shebang来实现脚本的独立运行。对此必须设置脚本的可执行权限,这样它就可以使用位于#!之后的解释器路径来运行了。

就像这样:

$ chmod a+x script.sh


该命令赋予所有用户script.sh文件的可执行权限。这个脚本能以下列方式执行:

$ ./script.sh #./表示当前目录


或者

$ /home/path/script.sh #使用脚本的完整路径


内核会读取脚本的首行并注意到shebang为#!/bin/bash。它识别出/bin/bash并在内部像这样执行该脚本:

$ /bin/bash script.sh


当启动shell时,它一开始会执行一组命令来定义诸如提示文本、颜色等各类设置。这组命令来自位于用户主目录中的脚本文件~/.bashrc(对于登录shell则是~/.bash_profile)。

Bash还维护了一个历史记录文件~/.bash_history,用于保存用户运行过的命令。

~表示主目录,它通常是/home/user,其中user是用户名,如果是root用户则为/root。

在Bash中,每个命令或是命令序列是通过使用分号或换行符来分隔的。比如:

$ cmd1 ; cmd2


它等同于:

$ cmd1
$ cmd2


如果 是 cmd1&&cmd2 只有当cmd1执行成功才回执行cmd2,而 ; 则没有这个限制。

字符#指明注释的开始。

注释部分以#为起始,一直延续到行尾。注释行通常用于为代码提供注释信息,或者停止执行某行代码。(shell不执行脚本中的任何注释部分。)

终端打印

终端是交互式工具,用户可以通过它与shell环境进行交互。

在终端中打印文本是绝大多数shell脚本和工具日常需要执行的基本任务。在这则攻略中我们会看到, 可以使用各种方法,采用各种格式进行打印.

echo

之前整理了一篇 Shell echo-使用echo实现更复杂的输出格式控制

这里再此说明一下:

echo是用于终端打印的基本命令。

在默认情况下,echo在每次调用后会添加一个换行符。

[root@entel1 ~]# echo "welcome to the blog of Bash"
welcome to the blog of Bash


只需要使用带双引号的文本,结合echo命令就可以将该文本在终端中打印出来。

类似地,不带双引号的文本也可以得到同样的输出结果:

[root@entel1 ~]# echo welcome to the blog of Bash
welcome to the blog of Bash


当然了,使用单引号同样也可以达到相同的目的

[root@entel1 ~]# echo 'welcome to the blog of Bash'
welcome to the blog of Bash


这些方法看起来相似,但各有一些特殊用途和副作用,看如下命令。

[root@entel1 ~]# echo "hello world !"
-bash: !": event not found

[root@entel1 ~]# echo "!"
-bash: !: event not found


命令将会返回:

bash: !: event not found error

因此,如果需要打印!,那就不要将其放入双引号中,或者你可以在其之前加上个特殊的转义字符(\)将!转义,就像这样:

[root@entel1 ~]# echo hello world !
hello world !
[root@entel1 ~]# echo 'hello world!'
hello world!
[root@entel1 ~]# echo "hello world \!"   #将转义字符放在前面
hello world \!


每种方法的副作用:

 使用不带引号的echo时,没法在所要显示的文本中使用分号(;),因为分号在Bash shell 中被用作命令定界符。

如下:

[root@entel1 ~]# echo ;

[root@entel1 ~]# echo linux shell ;
linux shell


 以echo hello;hello为例, echo hello被视为一个命令,第二个hello则被视为另一 个命令。

[root@entel1 ~]# echo ls ; ls
ls
anaconda-ks.cfg  Desktop    Downloads    install.log.syslog          Music               Pictures  Templates


 变量替换在单引号中无效

使用单引号时,变量不会被扩展(expand),将依照原样显示。这意味着:

$ echo '$var' will print $var


但如果变量var已经定义过,那么
$ echo "$var"
会打印出该变量的值;

如果没有定义过,则什么都不打印。

[root@entel1 Templates]# cat test.sh
#!/bin/bash
var=xiaogongjiang
echo '$var' will print $var
echo '$var2' will print $var2
[root@entel1 Templates]# ./test.sh --观察var2的输出为空,因为未定义
$var will print xiaogongjiang
$var2 will print
[root@entel1 Templates]#


printf

之前整理了一篇 Shell printf 命令

这里再此说明一下:

printf使用的参数和C语言中的printf函数一样。

[root@entel1 ~]# printf "hello world"
hello world[root@entel1 ~]#


printf使用引用文本或由空格分隔的参数。

我们可以在printf中使用格式化字符串,还可以指定字符串的宽度、左右对齐方式等。

在默认情况下, printf并不像echo命令一样会自动添加换行符,我们必须在需要的时候手动添加,比如在下面的脚本中:

[root@entel1 ~]# cat print.sh
#!/bin/bash
#文件名:print.sh
printf "%-5s %-10s %-4s\n" No Name Mark
printf "%-5s %-10s %-4.2f\n" 1 Sarath 80.3456
printf "%-5s %-10s %-4.2f\n" 2 James 90.9989
printf "%-5s %-10s %-4.2f\n" 3 Jeff 77.564
[root@entel1 ~]# chmod +x print.sh
[root@entel1 ~]# ./print.sh
No    Name       Mark
1     Sarath     80.35
2     James      91.00
3     Jeff       77.56


注释:

%s、 %c、 %d和%f都是格式替换符(format substitution character),其所对应的参数可以置于带引号的格式字符串之后。

%-5s指明了一个格式为左对齐且宽度为5的字符串替换(-表示左对齐)。如果不用-指定对齐方式,字符串就采用右对齐形式。

宽度指定了保留给某个变量的字符数。对Name而言,保留宽度是10。因此,任何Name字段的内容都会被显示在10字符宽的保留区域内,如果内容不足10个字符,余下的则以空格符填充。

对于浮点数,可以使用其他参数对小数部分进行舍入。

对于Mark字段,将其格式化为%-4.2f,其中.2指定保留2个小数位。

注意,在每行格式字符串后都有一个换行符(\n)

其他注意事项

使用echo和printf的命令选项时,要确保选项应该出现在命令行内所有字符串之前,否则Bash会将其视为另外一个字符串。

在echo中转义换行符

在默认情况下, echo会将一个换行符追加到输出文本的尾部。可以使用选项-n来忽略结尾的换行符。

echo同样接受双引号字符串内的转义序列作为参数。如果需要使用转义序列,则采用echo –e “包含转义序列的字符串”这种形式。

例如:

注意比较

[root@entel1 ~]# echo -e  "1\t2\t3"
1   2   3
[root@entel1 ~]# echo -e  "a\tb\tc"
a   b   c
[root@entel1 ~]# echo "a\tb\t\c"
a\tb\t\c


打印彩色输出

在终端中生成彩色输出相当好玩,我们可以使用转义序列来实现。

每种颜色都有对应的颜色码。比如:重置=0,黑色=30,红色=31,绿色=32,黄色=33,蓝色=34,洋红=35,青色=36,白色=37。

要打印彩色文本,可输入如下命令:

echo -e "\e[1;31m This is red text \e[0m"


\e[1;31将颜色设为红色,\e[0m将颜色重新置回。

只需要将31替换成想要的颜色码就可以了。

要设置彩色背景,经常使用的颜色码是:重置=0,黑色=40,红色=41,绿色=42,黄色=43,蓝色=44,洋红=45,青色=46,白色=47。

要打印彩色文本,可输入如下命令:

echo -e "\e[1;42m Green Background \e[0m"


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: