2

Why can the last command line in the shell script (uptime below) be executed successfully without the newline at the end of the file?

For example:

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#
3

When the shell reads the shell script, its scanning code will accept the last word at the end of the script even if there is no terminating newline.

This is the effect of the first rule in the POSIX standard regarding how the shell should recognize tokens in its input:

If the end of input is recognized, the current token (if any) shall be delimited.

The fact that it say that the current token is delimited here means that the last word in the script, along with the rest of that non-terminated line, will be accepted as input to the interpreter rather than causing an error or putting the shell into an undefined state.


In comments, a reference is made to the vi editor. A standard vi editor is allowed to edit a file whose last line is not terminated by a newline. It will, however, terminate the last line of the buffer with a newline when writing it to file (except for when saving an empty file, in which case adding a newline is explicitly not allowed). This is also true for a standard ex editor:

INPUT FILES

Input files shall be text files or files that would be text files except for an incomplete last line that is not longer than {LINE_MAX}-1 bytes in length and contains no NUL characters. By default, any incomplete last line shall be treated as if it had a trailing <newline>. The editing of other forms of files may optionally be allowed by ex implementations.

The vim editor has a setting, eol, which determines whether it should preserve the non-terminated last line or not. The default behaviour is to terminate the last line. See :help eol in vim.

The input to the standard ed editor is supposed to be a text file, which means that what happens if one is editing a file whose last line in not properly terminated (which makes it not a text file) is technically unspecified. On OpenBSD, the ed editor will say "newline appended" when opening a non-terminated text file.

INPUT FILES

The input files shall be text files.

  • Thanks! 1) Do all the types of shell, such as ksh/sh/csh/bash, conform to the POSIX standard rule ? 2) But indeed the last command line is still regarded as a incomplete line while the script is opened with vi ! – lylklb Jun 7 '18 at 2:10
  • @lylklb All of those shells, with the exception of csh, are POSIX shells and should behave the same way with regards to this. csh is not a POSIX shell, so you would have to test that individually. I don't think I understand your second question. Normally a "line" needs to be terminated by a newline, but since the POSIX parsing rules for shell scripts have this special rule, the last line of a shell script may remain unterminated. – Kusalananda Jun 7 '18 at 6:03
  • 1) I have tested it in the csh environment, and it also work fine w/o last newline! 2) It is just a message at the bottom of vi editor that prompts "Incomplete last line". I think that this symptom is mainly due to the non-POSIX compliant systems/editors! – lylklb Jun 7 '18 at 14:30
  • @lylklb 1) Good. 2) No it is not. The lines of a text file should all be delimited by a newline character. The parsing rules for shell script allows the last line to be unterminated. This allows the shell to execute scripts which are read from a command substitution, like sh -c "$(cat script)". The last line of script will not be terminated by a newline when given to the sh interpreter, since the command substitution removes it. Also, in printf 'echo hello' | sh the script (echo hello) does not have a newline at the end. – Kusalananda Jun 7 '18 at 14:49
  • Could you please tell me where can be found with more detail/documents about this parsing rule for the last line in shell scripts ? – lylklb Jun 8 '18 at 2:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.