2

I am trying to use read, to read from a file descriptor, like so:

read -u fd

as in in this link.

Here is the code I am using in a bash script:

MESSAGE=$(read -u $NODE_CHANNEL_FD)
echo " parent message => $MESSAGE"  >&2

The exact error message:

read: Illegal option -u

Anyone know what this could possibly be about?

cuonglm
  • 153,898
  • the file descriptor is definitely defined by NODE_CHANNEL_FD, so that shouldn't be part of the problem – Alexander Mills Dec 09 '16 at 03:19
  • if I run the bash script with the bash executable, instead of the sh executable, the error goes away. But what confuses me, is that at the top of the of the shell script, is the hashbang - #!/usr/bin/env bash, which I thought meant to tell sh to run the file with bash.... – Alexander Mills Dec 09 '16 at 03:21
  • Among modern Bourne-like shells, only bash. ksh and zsh support read -u <fd_num>. – cuonglm Dec 09 '16 at 03:22
  • thanks, yeah, so any idea why /usr/bin/env might not be defined on my system? that's why this is not working AFAICT. The shebang won't work, because /usr/bin/env is not even a directory...I am on Ubuntu 16.04 – Alexander Mills Dec 09 '16 at 03:24
  • Not sure why /usr/bin/env is relevant here. Ubuntu /bin/sh is linked to /bin/dash, so you may want to use /bin/bash instead. – cuonglm Dec 09 '16 at 03:25
  • it's relevant because I thought /usr/bin/env was universal, and that's what was at the top of my file as a shebang, I bet if I try #! /bin/bash it will work..thanks – Alexander Mills Dec 09 '16 at 03:27
  • LOL, my bad, I thought that /usr/bin/env was a directory, but of course env is program/executable, now I really don't why it doesn't work, but some progress is being made – Alexander Mills Dec 09 '16 at 03:38
  • If you are explicitly running the script with sh (e.g. sh myscript) then that will override the shebang line. Just make the file executable and run it by its path + name ./myscript. See What is the difference between running “bash script.sh” and “./script.sh”? – steeldriver Dec 09 '16 at 03:38
  • yeah I am explicitly running it with sh...I thought sh was responsible for finding the right interpreter, but I guess not, a lower level facility must do that... – Alexander Mills Dec 09 '16 at 03:40
  • I guess my question is - if I fork a process to run a shell script...how can I know whether to fork an sh or bash process? Do I manually have to read the shebang of the file or go by the extension name of the file? – Alexander Mills Dec 09 '16 at 03:43
  • ./script should do it – Jeff Schaller Dec 09 '16 at 16:20
  • Right but I am running this script as a child process from Node.js...I simply don't know how to start a child process in Node.js to run a script that doesnt invoke either sh or bash directly. – Alexander Mills Dec 09 '16 at 19:05

1 Answers1

8

The error message suggests that you are in fact not executing the script using bash.

Either make the script executable and add a proper #!-line on the first line of the script, e.g.

#!/bin/bash

Or, execute the script with bash explicitly:

$ bash script.sh

You should treat sh and bash as implementing separate languages, and use the correct interpreter for the script you're writing. In this case, you're using read with the -u option. This is originally a ksh extension to the standard read specification, and it's also implemented in bash and zsh. Hence, you need to run the script with bash, zsh or ksh.

How to know when to use sh and when to use bash or some other shell? It's simple, you learn the way sh works and what other features other shells add.

Kusalananda
  • 333,661
  • 1
    -u was initially a ksh extension. Also supported by zsh and bash. One can always use read <&"$fd" in standard sh to get the same effect. – Stéphane Chazelas Sep 04 '17 at 11:27
  • @StéphaneChazelas You're better at shell history than what I am... – Kusalananda Sep 04 '17 at 12:02
  • 1
    There are very few features that are native to bash. Most for come from ksh and csh, a few from zsh and mksh. If in doubt, you can always check the ksh86 or ksh88 (here ksh88i, but there has been little evolution in ksh88 feature-wise since 1988) man pages. If it's not in ksh88, it may come from ksh93, but then, you'd need to check if it was added in bash or ksh93 first. – Stéphane Chazelas Sep 04 '17 at 12:59
  • @StéphaneChazelas Thanks! I appreciate the pointers. – Kusalananda Sep 04 '17 at 13:04