2019-07-05 23:31:06 -0500, Eric Blake: [...] > Sorry, but this patch violates POSIX. > > https://pubs.opengroup.org/onlinepubs/9699919799/toc.htm > > "If a file is '-', the cat utility shall read from the standard input at > that point in the sequence." [...]
But coreutils could do that when not under $POSIXLY_CORRECT, as that's admitedly a design flaw, and is quite annoying to have to do case $file in (-) file=./-;; esac cat -- "$file" to work around it. /dev/stdin could be seen as a fix to that misdesign, but not on Linux or Cygwin (where for instance cat /dev/stdin /dev/stdin does not work the same as cat - - unless stdin is a pipe for instance). It's unlikely people would use "cat -- -" and expect that "-" to mean stdin, so it would be unlikely to break existing scripts. (there's still the case of echo test | cat -- *.txt - or cat -- "$file" - though) But then, the same would have to be done for all GNU utilities for consistency. But then there are utilities like paste, join, comm where that would not be desirable, so probably not a good idea in the end (see also how paste - - doesn't work the same as paste /dev/stdin /dev/stdin even on systems other than Linux/Cygwin).. Note that gawk already does it in gawk -E file.awk "$file" Where using -E (as opposed to -f) fixes that problem and the one about "var=value.txt" being treated as a variable assignment and that other options are still processed by awk. [...] > If you wish to cat a file named '-' in the current directory, spell it > './-' or use an absolute path to that file. That's true of all command > line utilities that treat '-' as stdin (not just cat). [...] Or in a shell, use: cat < "$file" Or cat - < "$file" (but not cat -- - < "$file" ;-) To concatenate arbitrary files, ironically you can do: cat /dev/stdin /dev/fd/3 < "$file1" 3< "$file2" Which also has the benefit (or not) of not outputting anything if any of the files can't be opened. 2019-07-05 23:48:17 -0500, Eric Blake: [...] > For more fun, go figure out why: > > grep - - -- > grep [---] > > behave the same, regardless of whether you have a file named '-' in your > current working directory (unless you use shopt -s failglob). And the > rule on using ./- for a file in the current directory also applies to > touch, except there '-' means stdout instead of stdin. Only with GNU grep or compatible and when $POSIXLY_CORRECT is not in the environment. That's another misfeature IMO, but this time introduced by GNU and not *allowed* by POSIX. in "grep - - --", while for grep POSIX leaves it undefined whether "-" is treated as stdin or not, that "--" is required to be a file argument since it comes after a non-option argument. So that would likely report an error about a missing "--" file. That means that while: grep - *.txt is fine for POSIX compliant grep implementations, in GNU grep, you need: grep -- - *.txt or grep -e - -- *.txt About: grep [---] With bash, beside failglob, nullglob would also change the behaviour. Also, the behaviour of ranges is unspecified in POSIX outside of the POSIX locale. It could match (for both glob and grep RE) collating elements that are /equivalent/ to - for instance. That behaviour of GNU touch wrt touch - is not POSIX compliant AFAICT (though that's another case where /dev/stdout wouldn't work unless "touch" itself treated a "/dev/stdout" argument specially). -- Stephane
