Bash 和 Dash 的问题
Debian和Ubuntu中,/bin/sh默认已经指向dash,它主要是为了执行脚本而出现,而不是交互,原因是dash更快、更高效,但功能相比bash要少很多,语法严格遵守POSIX标准。
从Ubuntu 6.10开始,默认使用dash(theDebian Almquist Shell)而不是bash(the GNUBourne-Again Shell),但Login Shell还是bash。Ubuntu在启动的时候会运行很多shell脚本,使用dash可以加快启动速度。
bash和dash兼容性问题:在需要bash的脚本的第一行写上”#!/bin/bash” 。在Makefile中可以设置SHELL = /bin/bash。
默认sh切换(dash切换bash为例)
- sudo dpkg-reconfigure dash (bash选择NO)
- sudo ln -fs /bin/bash /bin/sh
login 与 non-login shell
1. login shell
在某用户由/bin/login登陆进系统后启动的shell,跟这个用户绑定。这个shell是用户登陆后启动的第一个进程。login进程在启动shell时传递第0个参数指明shell的名字,该参数第一个字符为”-“,指明这是一个login shell。比方对bash而言,启动参数为”-bash”。
当bash以login shell启动时,它会运行/etc/profile中的命令,然后/etc/profile调用/etc/profile.d文件夹下的全部脚本。然后运行~/.bash_profile。~/.bash_profile调用~/.bashrc,最后~/.bashrc又调用/etc/bashrc。
2. non-login shell
不需login而由某些程序启动的shell。
传递给shell的参数,是没有“-”前缀的。还以Bash为例。当以非login方式启动时,它会调用~/.bashrc,随后~/.bashrc中调用/etc/bashrc,最后/etc/bashrc调用全部/etc/profile.d文件夹下的脚本。
3. 识别shell是否为login shell
在该shell下运行echo $0。假设输出为该shell名字,加上一个“-”前缀,则说明该shell为login shell,比如-bash,-su等。
SecureCRT中SSH登陆:login shell。
mrhjlong@hjl-virtual-machine:~$ echo $0
-bash
- Ubuntu系统下打开Terminal:non-login shell。
mrhjlong@hjl-virtual-machine:~$ echo $0
bash
一. 简介
shell脚本通常是一个以shebang起始的文本文件,如下所示: #!/bin/bash。
/bin/bash是Bash的解释器命令路径。
1. 两种运行脚本的方式
- 将脚本作为bash的命令行参数,就用不着脚本中的shebang了。
$ bash script.sh #假设脚本位于当前目录下
- 利用shebang来实现脚本的独立运行。对此必须设置脚本的可执行权限,这样它就可以使用位于#!之后的解释器路径来运行了。内核会读取脚本的首行并注意到shebang为#!/bin/bash,它识别出/bin/bash并在内部像这样执行该脚本:$ /bin/bash script.sh。
$ chmod a+x script.sh
$ ./script.sh
$ /bin/bash script.sh
2. shell相关文件
当启动shell时,开始会执行一组命令来定义诸如提示文本、颜色等各类设置,这组命令来自位于用户主目录中的脚本文件~/.bashrc(对于登录shell则是~/.bash_profile)。
Bash还维护了一个历史记录文件~/.bash_history,用于保存用户运行过的命令。
注:~表示主目录,它通常是/home/user,其中user是用户名,如果是root用户,则为/root。
3. 命令分隔
每个命令或是命令序列是通过使用分号或换行符来分隔的。
$ cmd1; cmd2
#等同于
$ cmd1
$ cmd2
二. 终端打印
1. echo命令
终端打印的基本命令。
引号之间的区别
- 单引号:所见即所得,即将单引号内的内容原样输出,剥夺其中的所有字符的特殊含义。
- 双引号:双引号会解释特殊字符的含义,这些特殊字符有: 美元符$,反斜杠\,反引号`,感叹号!。
- 反引号:两个反引号包围起来的字符串,将作为命令来运行。
命令替换是指shell能够将一个命令的标准输出插在一个命令行中任何位置。shell中有两种方法作命令替换:把shell命令用反引号或者$(…)结构括起来。根据POSIX规范,要求系统工程师采用的是$(…)的形式。 - 不带引号:没法显示命令界定符,如分号(;),多个空格。
不会将含有空格的字符串视为一个整体输,,如果内容中有命令、变量等,会先把变量、命令解析出结果,然后在输出最终内容来,如果字符串中带有空格等特殊字符,则不能完整的输出。
mrhjlong@hjl-virtual-machine:bashTest$ cat symbol.sh
#!/bin/bash
a="1 2 3 4"
echo $a
echo "$a"
mrhjlong@hjl-virtual-machine:bashTest$ ./symbol.sh
1 2 3 4
1 2 3 4
mrhjlong@hjl-virtual-machine:~$ echo '$HOME'
$HOME
mrhjlong@hjl-virtual-machine:~$ echo "$HOME"
/home/mrhjlong
mrhjlong@hjl-virtual-machine:~$ echo -e "\$HOME"
$HOME
mrhjlong@hjl-virtual-machine:bashTest$ echo `date`
2018年 03月 19日 星期一 00:36:45 CST
mrhjlong@hjl-virtual-machine:bashTest$ echo "$(date)"
2018年 03月 19日 星期一 00:36:59 CST
echo中转义字符
- 在默认情况下,echo在每次调用后会添加一个换行符,可以使用选项-n来忽略结尾的换行符。
- echo同样接受双引号字符串内的转义序列作为参数:echo –e “包含转义序列的字符串”。
mrhjlong@hjl-virtual-machine:bashTest$ echo -e "1\t2\t3"
1 2 3
打印彩色输出
每种颜色都有对应的颜色码。
- 字体颜色:重置=0,黑色=30,红色=31,绿色=32,黄色=33,蓝色=34,洋红=35,青色=36,白色=37。
mrhjlong@hjl-virtual-machine:bashTest$ echo -e "\e[1;31m This is red text \e[0m"
This is red text
- 背景颜色:重置=0,黑色=40,红色=41,绿色=42,黄色=43,蓝色=44,洋红=45,青色=46,白色=47。
mrhjlong@hjl-virtual-machine:bashTest$ echo -e "\e[1;42m Green Background \e[0m"
Green Background
2. printf命令
printf使用的参数和C语言中的printf函数一样。
在默认情况下,printf并不像echo命令一样会自动添加换行符,我们必须在需要的时候手动添加\n。
printf使用引用文本或由空格分隔的参数。我们可以在printf中使用格式化字符串,还可以指定字符串的宽度、左右对齐方式等。
mrhjlong@hjl-virtual-machine:bashTest$ cat printf.sh
#!/bin/bash
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
mrhjlong@hjl-virtual-machine:bashTest$ ./printf.sh
No Name Mark
1 Sarath 80.35
2 James 91.00
3 Jeff 77.56
3. 注意
使用echo和printf的命令选项时,要确保选项应该出现在命令行内所有字符串之前,否则Bash会将其视为另外一个字符串。