0

I have a function that takes input from the command line, and, optionally, from stdin. However, it will stop for input when no input stream is specified.

#!/bin/bash
somefunc() {
  # output strings on command line.
  while (($#)); do
    echo "$1"
    shift
  done

  # take input from stdin, if it exists.
  declare line
  while read -sr line; do 
    echo "$line"
  done
}

somefunc "$@"

This works:

$ somefunc "arg1" "arg2" "..." <"/some/file"

This does not:

$ somefunc "arg1" "arg2" "..." 

I can get around this problem by using a timeout on the read command (-t 0.0001 for instance), but this seems a bit kludgy and fragile.

Is there a better way of achieving this without using a timeout?

3
  • Duplicate
    – l0b0
    Oct 15, 2020 at 1:19
  • that's not the best solution in my view. can someone else think about this?
    – Gary Dean
    Oct 15, 2020 at 1:49
  • if fact, it's not a solution in any sense for this issue. can you can explain the relevancy?
    – Gary Dean
    Oct 15, 2020 at 2:12

3 Answers 3

1

The bash builtin test with -t should be able to do the job quite well. [ -t 0 ] There is a good example in this link:

How to detect if input is from argument, file or terminal

0

There are two solutions to this, and both are equally fast and not kludgy.

This is my preferred solution:

  # take input from stdin, if it exists.
  if read -t 0; then
    declare line
    while read -sr line; do 
      echo "$line"
    done
  fi

[ -t 0 ] also works:

  # take input from stdin, if it exists.
  if [ -t 0 ]; then
    declare line
    while read -sr line; do 
      echo "$line"
    done
  fi
1
0

Maybe if you add < /dev/null at the end of your command which is hanging.

This would feed the command dummy input so that it can move on and not try to mess with your stdin.

You must log in to answer this question.

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