News for hackers. Stuff that matters.
Re:Sockets in Your Shell by izabera on Thursday December 03, 2020 @09:09AM (#25288925)

  if [ exec 1>/dev/null 2>/dev/null 3>/dev/tcp/localhost/4000 ] ; then
This code runs `[ exec ]` (which tests if "exec" is a non-empty string, thus it returns true) and redirects its output and error to /dev/null, and fd 3 to /dev/tcp/whatever. If the socket opening fails, `[ exec ]` is not even executed, and the overall command returns nonzero. Completely equivalent to `: 3>/dev/tcp/localhost/4000`, which also returns nonzero if the socket can't be opened.

It happens to work for the intended purpose, but not for the reasons the author intended.

Re:Sockets in Your Shell by kzrdude on Thursday December 03, 2020 @09:44AM (#25289283)
A testament to the brokenness of making `[` a command
Re:Sockets in Your Shell by dundarious on Thursday December 03, 2020 @06:48PM (#25297107)
I prefer to always use the `test` command instead (it’s the exact equivalent of `[`), and never use `[[` bashisms (well, almost never).
Re:Sockets in Your Shell by xyzzy_plugh on Thursday December 03, 2020 @07:33PM (#25297517)
And here I thought I was the only one!
Re:Sockets in Your Shell by kzrdude on Friday December 04, 2020 @05:42AM (#25300946)
I also do this.
Re:Sockets in Your Shell by yrro on Thursday December 03, 2020 @01:30PM (#25292565)
shellcheck has this to say:

    In exec.sh line 1:
    if [ exec 1>/dev/null 2>/dev/null 3>/dev/tcp/localhost/4000 ] ; then
    ^-- SC1009: The mentioned syntax error was in this if expression.
       ^-- SC1073: Couldn't parse this test expression. Fix to allow more checks.
         ^-- SC1014: Use 'if cmd; then ..' to check exit code, or 'if [[ $(cmd) == .. ]]' to check output.
              ^-- SC1072: Expected test to end here (don't wrap commands in []/[[]]). Fix any mentioned problems and try again.
    
    For more information:
      https://www.shellcheck.net/wiki/SC1014 -- Use 'if cmd; then ..' to check ex...
      https://www.shellcheck.net/wiki/SC1072 -- Expected test to end here (don't ...
      https://www.shellcheck.net/wiki/SC1073 -- Couldn't parse this test expressi...
Re:Sockets in Your Shell by who23 on Saturday December 05, 2020 @02:36AM (#25312638)
Hey I'm the author - I did not know about this! I suppose I should have guessed somebody made a shell script linter at some point though. Very useful!
Re:Sockets in Your Shell by gricardo99 on Thursday December 03, 2020 @01:35PM (#25292631)
I'm not sure if the code example changed on the linked page after your comment, but I see this code:

  #!/bin/bash
  if exec 3>/dev/tcp/localhost/4000 ; then
 echo "server up!"
  else
 echo "server down."
  fi
Which also confused me for similar reasons to your comment. I'm not familiar with exec, but generally non-zero return means a fail, and zero means success. So why is the "server up" for non-zero result?
Re:Sockets in Your Shell by gricardo99 on Thursday December 03, 2020 @01:42PM (#25292742)
Sure enough, I tested this, and the server up/down is reversed from what it should be:

   > exec 3>/dev/tcp/localhost/4000
     bash: connect: Connection refused
     bash: /dev/tcp/localhost/4000: Connection refused
   > echo $?
    1
But if a localhost port is listening (in another terminal window: > nc -l localhost 4000):

   > exec 3>/dev/tcp/localhost/4000
   > echo $?
     0
Re:Sockets in Your Shell by dllthomas on Thursday December 03, 2020 @03:25PM (#25294272)
In the quoted code, "server up" is for a zero result - `if` is reversed from what you think it is:

    > if true; then echo yup; fi
    yup
    > true
    > echo $?
    0
Re:Sockets in Your Shell by gricardo99 on Thursday December 03, 2020 @05:01PM (#25295792)
indeed you are right. Thanks for the reply. I'm too accustomed to seeing code like:

  if [ $? -eq 0 ]; then echo "pass";else echo "fail";fi
But without the expression '[ ... ]' shell/bash does indeed treat zero return code (success) as boolean true. For whatever reason I have not seen much (if any) bash code that simply uses:

  if COMMAND; then ...
Re:Sockets in Your Shell by fl0wenol on Thursday December 03, 2020 @05:19PM (#25296026)
You really really should use if COMMAND logic, in the event that all you care about is zero or non-zero result. I find it easier to follow for shell control flow.

It also works for shell functions.

Re:Sockets in Your Shell by dllthomas on Thursday December 03, 2020 @06:44PM (#25297063)
From one perspective,

    if [ $? -eq 0 ]; then ...
is actually an instance of

    if COMMAND; then ...
because [ is itself a command.
Re:Sockets in Your Shell by gricardo99 on Thursday December 03, 2020 @11:35PM (#25299004)
yep, I think that's the key point I need to drill into my head. The unix/linux idiom where 0 is true/success and non-zero is a failure can be counter-intuitive when combined with "if" (at least for me, hence my mistake reading the code). In most/other computing contexts "if 0" is never taken. I think this might explain why I've seen a lot more bash code that is explicitly written in the form more familiar to "if" usage in other languages (pseudo-code): "if res == 0". But "if COMMAND" is taking care of the interpretation of the return code, so doing the explicit compare is redundant.
Re:Sockets in Your Shell by who23 on Saturday December 05, 2020 @02:23AM (#25312579)
Hey I'm the author. Bash treats 0 exit codes as a success, so the "server up" echo runs if the connection is made.
Re:Sockets in Your Shell by who23 on Saturday December 05, 2020 @02:21AM (#25312570)
Hi I'm the author! Yes, I wrote this code quite quickly and when I originally posted this on reddit someone pointed out my mistake. The more you know, I suppose.