logoalt Hacker News

refptoday at 7:33 AM3 repliesview on HN

They are NOT superflous, and all you need to prove it is `zsh` (but there are others that follow suit in similar fashions):

  zsh% echo "hello world" > data
  
  zsh% < data && echo "READABLE"   # <- will print the contents of data
  hello world
  READABLE
  
  zsh% : < data && echo "READABLE" # <- this will not
  READABLE
So, if you want something that "everyone can use" without going into details about the difference between commonly used shells.. you'd use the null-command.

---

and given that we use the null-command, it _WILL_ behave different with or without subshell.. and all you need is `bash --posix` to prove it:

    % cat subshell.sh
    #!/bin/bash --posix
    ( : < missing.json ); echo AFTER    # <- will echo AFTER
    
    % ./subshell.sh
    ./subshell.sh: line 2: missing.json: No such file or directory
    AFTER
    
    % cat no-subshell.sh
    #!/bin/bash --posix
    : < missing.json; echo AFTER        # <- this will not
    
    % ./no-subshell.sh
    ./no-subshell.sh: line 2: missing.json: No such file or directory

    % : ^- apparently.. there is a difference

The output above is not truncated, `no-subshell.sh` will stop executing due to the broken read.

---

One should never trust things just because they are written, but that also applies to comments on HN. Originally when I read your message I actually thought I made a mistake, I was very close to writing an apology comment and adding a note to the blog post, but not close enough - I had to test it again.

I'm thankful for the watchful eyes and scrutiny when reading things online, that's good - keep it up, but your message is factually wrong - on so many levels.


Replies

brabeltoday at 8:09 AM

It’s very common that the most upvoted comment on a post is a mistaken correction. People seem to love comments seemingly proving that the post is wrong without actually checking anything. And once it has enough upvotes a big discussion may follow up with personal attacks on the author or other questionable comments, while the people trying to point out that the post actually is accurate get either buried under the critic storm or downvoted to oblivion because people just don’t like the truth. This happens in every controversial topic.

One of the reasons I stopped writing.

show 1 reply
kazinatortoday at 3:20 PM

  zsh% < data > /dev/null && echo READABLE   # <- fixes it, sorta
Maybe zsh still reads the entire file and copies it to /dev/null, which would be a severe performance problem for large files.

The colon by itself, without the subprocess, also prevents the dumping to stdout:

  zsh% : < data && echo READABLE
However, with the subprocess parentheses, we can redirect the nonexistence diagnostic to /dev/null, which I don't see mentioned or exemplified in the article:

  zsh% : < nonexistent 2> /dev/null && echo READABLE
  zsh: no such file or directory: nonexistent
  zsh% (: < nonexistent) 2> /dev/null && echo READABLE
The normal way of testing whether something exists and is readable that you would actually use in production script looks more like this:

  $ test -r file && echo YES
  $ [ -r file ] && echo YES
so we are talking about obfuscated coding.

I would say that "if you want something everyone can use", the -r test would be the first candidate.

BTW, why not bring up the strawman of tcsh?

  tcsh% < nonexistent && echo READABLE
  Invalid null command.
  tcsh% : < nonexistent && echo READABLE
  nonexistent: No such file or directory.
Yes, if we want an obfuscated readability test which works literally in any shell that is currently still in deployment in systems that permit new scripts to be installed and run, it looks like do need that colon.

However, fish doesn't like &&:

  fish> < nonexistent && echo yes
  fish: Expected a command, but instead found a redirection
  fish> : < nonexistent && echo yes
  fish: Unsupported use of '&&'. In fish, please use 'COMMAND; and COMMAND'.
  : < nonexistent && echo yes
                  ^
Does it support test -r?

  fish> test -r nonexistent
  fish> test -r nonexistent; and echo yes
  fish> test -r /etc/hosts; and echo yes
  yes
Not parentheses though:

  fish> ( test -r /etc/hosts ); and echo yes
  fish: Illegal command name “( test -r /etc/hosts )”
We clearly have to restrict the idea of what "everyone can use" to POSIX-like shells; there is no getting around shell differences absolutely, other than for perhaps trivial command invocations.
show 1 reply