用户是通过终端会话同shell环境打交道的。如果你使用的是基于图形用户界面的系统,这指的就是终端窗口。如果没有图形用户界面(生产服务器或SSH会话),那么登录后你看到的就是shell提示符。
在终端中显示文本是大多数脚本和实用工具经常需要执行的任务。shell可以使用多种方法和格式显示文本。
Shell 在终端中显示输出 预备知识
命令都是在终端会话中输入并执行的。打开终端时会出现一个提示符。有很多方法可以配置提示符,不过其形式通常如下:
username@hostname$
或者也可以配置成root@hostname #
,或者简单地显示为$
或#
。
$
表示普通用户,#
表示管理员用户root。root是Linux系统中权限最高的用户。
以root用户(管理员)的身份直接使用shell来执行任务可不是个好主意。因为如果shell具备较高的权限,命令中出现的输入错误有可能造成更严重的破坏,所以推荐使用普通用户(shell会在提示符中以
$
来表明这种身份)登录系统,然后借助sudo
这类工具来运行特权命令。使用sudo <command> <arguments>
执行命令的效果和root一样。
shell脚本通常以shebang1起始:
1shebang这个词其实是两个字符名称(sharp-bang)的简写。在Unix的行话里,用sharp或hash(有时候是mesh)来称呼字符“#
”,用bang来称呼惊叹号“!
”,因而shebang合起来就代表了这两个字符。
#!/bin/bash
shebang是一个文本行,其中#!
位于解释器路径之前。/bin/bash是Bash的解释器命令路径。bash将以#
符号开头的行视为注释。脚本中只有第一行可以使用shebang来定义解释该脚本所使用的解释器。
脚本的执行方式有两种。
(1) 将脚本名作为命令行参数:
bash myScript.sh
(2) 授予脚本执行权限,将其变为可执行文件:
chmod 755 myScript.sh
./myScript.sh.
如果将脚本作为bash
的命令行参数来运行,那么就用不着使用shebang了。可以利用shebang来实现脚本的独立运行。可执行脚本使用shebang之后的解释器路径来解释脚本。
使用chmod
命令赋予脚本可执行权限:
$ chmod a+x sample.sh
该命令使得所有用户可以按照下列方式执行该脚本:
$ ./sample.sh #./表示当前目录
或者
$ /home/path/sample.sh #使用脚本的完整路径
内核会读取脚本的首行并注意到shebang为#!/bin/bash
。它会识别出/bin/bash
并执行该脚本:
$ /bin/bash sample.sh
当启动一个交互式shell时,它会执行一组命令来初始化提示文本、颜色等设置。这组命令来自用户主目录中的脚本文件~/.bashrc(对于登录shell则是~/.bash_profile)。Bash shell还维护了一个历史记录文件~/.bash_history,用于保存用户运行过的命令。
~表示主目录,它通常是
/home/user
,其中user
是用户名,如果是root用户,则为/root
。登录shell是登录主机后创建的那个shell。但登录图形化环境(比如GNOME、KDE等)后所创建的终端会话并不是登录shell。使用GNOME或KDE这类显示管理器登录后并不会读取.profile或.bash_profile(绝大部分情况下不会),而使用ssh登录远程系统时则会读取.profile。shell使用分号或换行符来分隔单个命令或命令序列。比如:$ cmd1 ; cmd2
这等同于:
$ cmd1 $ cmd2
注释部分以#
为起始,一直延续到行尾。注释行通常用于描述代码或是在调试期间禁止执行某行代码2:
2shell不执行脚本中的任何注释部分。
# sample.sh - echoes "hello world"
echo "hello world"
现在让我们继续讨论基本特性。
Shell 在终端中显示输出 实战演练
echo
是用于终端打印的最基本命令。
默认情况下,echo
在每次调用后会添加一个换行符:
$ echo "Welcome to Bash"
Welcome to Bash
只需要将文本放入双引号中,echo
命令就可以将其中的文本在终端中打印出来。类似地,不使用双引号也可以得到同样的输出结果:
$ echo Welcome to Bash
Welcome to Bash
实现相同效果的另一种方式是使用单引号:
$ echo 'text in quotes'
这些方法看起来相似,但各有特定的用途及副作用。双引号允许shell解释字符串中出现的特殊字符。单引号不会对其做任何解释。
思考下面这行命令:
$ echo "cannot include exclamation - ! within double quotes"
命令输出如下:
bash: !: event not found error
如果需要打印像!
这样的特殊字符,那就不要将其放入双引号中,而是使用单引号,或是在特殊字符之前加上一个反斜线(\):
$ echo Hello world !
或者
$ echo 'Hello world !'
或者
$ echo "Hello world \!" #将转义字符放在前面
如果不使用引号,我们无法在echo
中使用分号,因为分号在Bash shell中用作命令间的分隔符:
echo hello; hello
对于上面的命令,Bash将echo hello
作为一个命令,将hello
作为另外一个命令。
在下一条攻略中将讨论到的变量替换不会在单引号中执行。
另一个可用于终端打印的命令是printf
。该命令使用的参数和C语言中的printf
函数一样。例如:
$ printf "Hello world"
printf
命令接受引用文本或由空格分隔的参数。我们可以在printf
中使用格式化字符串来指定字符串的宽度、左右对齐方式等。默认情况下,printf
并不会自动添加换行符,我们必须在需要的时候手动指定,比如在下面的脚本中:
#!/bin/bash
#文件名: printf.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
可以得到如下格式化的输出:
No Name Mark
1 Sarath 80.35
2 James 91.00
3 Jeff 77.56
Shell 在终端中显示输出 工作原理
%s
、%c
、%d
和%f
都是格式替换符(format substitution character),它们定义了该如何打印后续参数。%-5s
指明了一个格式为左对齐且宽度为5的字符串替换(-
表示左对齐)。如果不指明-
,字符串就采用右对齐形式。宽度指定了保留给某个字符串的字符数量。对Name
而言,其保留宽度是10。因此,任何Name
字段的内容都会被显示在10字符宽的保留区域内,如果内容不足10个字符,余下的则以空格填充。
对于浮点数,可以使用其他参数对小数部分进行舍入(round off)。
对于Mark
字段,我们将其格式化为%-4.2f
,其中.2
指定保留两位小数。注意,在每行的格式字符串后都有一个换行符(\n
)。
Shell 在终端中显示输出 补充内容
使用echo
和printf
的命令选项时,要确保选项出现在命令中的所有字符串之前,否则Bash会将其视为另外一个字符串。
1.在echo
中转义换行符
默认情况下,echo
会在输出文本的尾部追加一个换行符。可以使用选项-n
来禁止这种行为。echo
同样接受双包含转义序列的双引号字符串作为参数。在使用转义序列时,需要使用echo -e "**包含转义序列的字符串**"
这种形式。例如:
echo -e "1\t2\t3"
1 2 3
2.打印彩色输出
脚本可以使用转义序列在终端中生成彩色文本。
文本颜色是由对应的色彩码来描述的。其中包括:重置=0,黑色=30,红色=31,绿色=32,黄色=33,蓝色=34,洋红=35,青色=36,白色=37。
要打印彩色文本,可输入如下命令:
echo -e "\e[1;42m Green Background \e[0m"
这些例子中包含了一些转义序列。可以使用man console_codes
来查看相关文档。