为什么shell脚本中的最后一行命令行(uptime
如下)能够在文件末尾没有换行符的情况下成功执行?
例如:
root@jcdb:/tmp#
root@jcdb:/tmp#
root@jcdb:/tmp# cat dp
date
pwd
uptimeroot@jcdb:/tmp#
root@jcdb:/tmp#
root@jcdb:/tmp#
root@jcdb:/tmp# ./dp
Wed Jun 6 16:27:26 EAT 2018
/tmp
4:27pm up 1 day, 17:25, 2 users, load average: 0.39, 0.40, 0.41
root@jcdb:/tmp#
root@jcdb:/tmp#
答案1
当 shell 读取 shell 脚本时,即使没有终止换行符,它的扫描代码也会接受脚本末尾的最后一个单词。
这是效果POSIX 标准中关于 shell 应如何识别其输入中的标记的第一条规则:
如果识别到输入结束,则应分隔当前标记(如果有)。
事实上,它说当前标记在此处被定界,这意味着脚本中的最后一个单词以及该非终止行的其余部分将被接受为解释器的输入,而不是导致错误或将 shell 放入未定义的状态。
在评论中,引用了编辑vi
。标准vi
编辑器可以编辑最后一行不以换行符终止的文件。但是,在将缓冲区写入文件时,它将用换行符终止缓冲区的最后一行(保存空文件时除外,在这种情况下明确不允许添加换行符)。对于标准编辑器也是如此ex
:
输入文件
输入文件应是文本文件或将是文本文件的文件,除了不完整的最后一行,其长度不超过
{LINE_MAX}-1
字节且不包含任何NUL
字符。默认情况下,任何不完整的最后一行都应被视为尾随<newline>
.实现可以选择允许编辑其他形式的文件ex
。
编辑vim
器有一个设置 ,eol
它确定是否应保留未终止的最后一行。默认行为是终止最后一行。见于.:help eol
vim
标准编辑器的输入ed
应该是一个文本文件,这意味着如果正在编辑一个最后一行未正确终止的文件(这使得它不是一个文本文件),那么在技术上是未指定的。在 OpenBSD 上,ed
打开非终止文本文件时,编辑器会显示“已附加换行符”。
输入文件
输入文件应为文本文件。