16

Why does file xxx.src lead to cannot open `xxx.src' (No such file or directory) but has an exit status of 0 (success)?

$ file xxx.src ; echo $?
xxx.src: cannot open `xxx.src' (No such file or directory)
0

Note: to compare with ls:

$ ls xxx.src ; echo $?
ls: cannot access 'xxx.src': No such file or directory
2

3 Answers 3

26

The superficial answer is that it's always been that way, and so everybody does it. POSIX states that

If the file named by the file operand does not exist, cannot be read, or the type of the file named by the file operand cannot be determined, this shall not be considered an error that affects the exit status.

Unfortunately, no rationale is given, so the only obvious reason for why POSIX states that is historical practice.

The file utility first appeared in Unix Research version 4 in 1973. At the time, standard utilities didn't check for errors (even though processes had had a return status since at least version 3 if not version 2). For example, cat started returning a nonzero status if a file did not exist only in version 8: version 7 just printed an error message and kept going. But even by version 10, file only exited with a nonzero status if it could not read the magic file, not if it could not read a data file.

A possible reason for file not to fail is that it isn't just interested in file contents, but also in files types, and it considers “does not exist” to be a special kind of file alongside directory, symbolic link, broken symbolic link, etc. This is a weak justification since an unreadable file is really not a special kind of file, it's a file whose nature cannot be determined, which is an error by any sensible measure. Also, it could apply to ls, which still did not return an error if given a nonexistent file name as of version 10, but for which this eventually became universal practice.

So it seems that the return status of file is a mistake that time forgot. Now that there are probably scripts out there that rely on file not returning an error status if the file does not exist, it's too late to change.

25

This behavior is documented on Linux, and required by the POSIX standard. From the file manual on an Ubuntu system:

EXIT STATUS
     file will exit with 0 if the operation was successful or >0 if an error was encoun‐
     tered.  The following errors cause diagnostic messages, but don't affect the pro‐
     gram exit code (as POSIX requires), unless -E is specified:
           •   A file cannot be found
           •   There is no permission to read a file
           •   The file type cannot be determined

With -E (as noted above):

$ file -E saonteuh; echo $?
saonteuh: ERROR: cannot stat `saonteuh' (No such file or directory)
1

The non-standard -E option on Linux is documented as

On filesystem errors (file not found etc), instead of handling the error as regular output as POSIX mandates and keep going, issue an error message and exit.

The POSIX specification for the file utility says (my emphasis):

If the file named by the file operand does not exist, cannot be read, or the type of the file named by the file operand cannot be determined, this shall not be considered an error that affects the exit status.

5
  • 2
    Someone's using Dvorak. I knew I recognized that file name.
    – Andreas
    Commented Apr 3, 2021 at 0:37
  • @Andreas I use dvorak and I don't recognize that file name Commented Apr 3, 2021 at 8:41
  • @AndreasGrapentin they're typical keys pressed when you mash your keyboard in dvorak mode (vs ';aslkdfj' in qwerty)
    – Eric Reed
    Commented Apr 3, 2021 at 15:20
  • Is there a know rationale for POSIX' file spec? Other similar utilities like grep, cat, wc report an error when a file argument could not be found. Commented Apr 3, 2021 at 17:37
  • @Peter-ReinstateMonica The Rationale section for the file utility does not mention anything to do with the exit-status or how errors like "file not found" should be handled, or why the utility should behave as it described.
    – Kusalananda
    Commented Apr 3, 2021 at 21:13
1

The file man page clearly says " If the file does not exist, cannot be read or its file status could not be determined then, it is not considered as an error that affects the exit status. The output indicates that the file was processed but the type could not be determined."

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .