echo命令在bash和dash上的区别

今天自己在新服务器上编译的时候突然发现无法生成备份包了,同样的源代码在之前用的服务器上编译就很正常的可以生成备份包,于是觉得很好奇,为什么会这样呢?

根据错误信息提示发现,由于生成的一个ini配置文件每一行的前面出现了无法识别的-e,打开配置文件一看还真的是每行前面都多出来了一个-e,还以为是之前新服务器没有配置好造成的,把编译生成的ini文件删除之后,重新编译一遍发现新生成的ini文件一样还是每行前面都有一个-e,我就很纳闷了,然后我就看了一下MakeFile中生成这个配置文件的这一段代码,基本都是这样的:

1
2
3
4
output_config_file: BUILD_CFG:=${SAVE_FOLDER}/cfg_build.ini
output_config_file:
@echo -e "[CFG_BUILD]" > ${BUILD_CFG}
@echo -e "BOARD = $(BOARD_ID)" >> ${BUILD_CFG}

上面这段代码的内容很简单啊,无非就是在生成的cfg_build.ini中输出一些需要的内容,为什么会在cfg_build.ini的每行前面多处一个-e,实在搞不明白之后就找负责服务器的同事问了一下,他说也不太清楚要问一下这个Makefile脚本的作者,于是又找到了Makefile脚本的作者,他告诉了我一句bash和dash的区别,自己也不太清楚,就Google了一下,慢慢地就搞清楚了,惊叹原来是这样的

这个是因为Ubuntu在从6.10开始,就将先前默认的bash shell更换成了dash shell,据说是因为bash更小巧,运行更快,还与POSIX标准相兼容,也就是将/bin/sh链接到了/bin/dash而不是/bin/bash。我们可以验证一下是不是这样的,首先在打开一个Ubuntu的Terminal,我们输入如下命令:

1
ls -l /bin/sh`

我们可以看到输出是这样的

1
/bin/sh -> dash

这就证实了Ubuntu确是将dash作为默认的/bin/sh,这样一来什么都搞清楚了,因为dash shell中标准的echo不支持转义参数-e,也就是说-e是bash shellecho带的一个可选参数,既然这样,那么解决办法就是将Ubuntu默认的/bin/sh改为bash shell只需要下面这样一条命令就可以了:

1
sudo dpkg-reconfigure dash

然后在弹出的选项中选择否(No),就搞定了,此时再次执行ls -l /bin/sh命令就发现已经指向/bin/bash了,重新编译代码,发现此时生成的build_cfg.ini文件中每行前面已经没有-e了,问题顺利解决了

补充一:@echo是关闭命令在屏幕上回显的意思

我们知道shell脚本会依次执行脚本中的的每条命令,并且会在显示器上显示,如果你不想让它们显示,可以加一个“echo off”,当然,“echo off”也是命令,它本身也会显示,如果连这条也不显示,就在前面加个“@”。

补充二:echo 命令基本的功能是输出,通过选项和参数组合,是能够产生很多功能的

这里举两个例子,例子1:

1
echo -e "\n Project1: \n\n\tplan \n\twrite \n\ttest\n" > project1

输出格式化内容到project1中
例子2:

1
echo -e The gif files are *.gif

输出当前目录下所有名字以.gif后缀的图片文件

补充三 附上dash和bash的简单介绍

bash shell是几乎所有Linux发行版的默认shell。作为标准Unix shell——Bourne shell(沿用创建者的名字)的替代,bash shell由GNU工程开发。bash shell的名称就是针对这个Bourne shell的文字游戏,全称为“Bourne again shell”。 bash有很灵活和强大的编程接口,同时又有很友好的用户界面。功能包括命令补齐、通配符、命令历史记录、别名等

dash shell是作为Debian Linux发行版的一部分开发的,主要出现在Ubuntu Linux发行版中。它是Bourne shell的精简版,支持的功能不像bash shell支持的那样多,这可能会给脚本编程带来一些问题

dash shell的历史很有趣,它是ash shell的直系后代,而ash shell是Unix系统上原来的Bourne shell的简化版本。令人不解的是,实际上dash shell在许多基于Debian的Linux发行版中并不是默认的shell。由于bash shell在Linux中的流行,大多数基于Debian的Linux发行版将bash shell用作普通登录shell,只将dash shell用作安装脚本的快速启动shell来安装发行版文件。而流行的Ubuntu发行版是一个例外。Ubuntu Linux发行版将bash shell用作默认的交互shell,但将dash shell用作默认的/bin/sh shell。这通常会让shell脚本程序员很困惑,并给在Linux环境中运行shell脚本带来了很多问题