Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
making a bash script accept input from a pipe
Alternatively, you can get the stream directly from 'stdin':

cat /dev/stdin

Some special files and directories are different for each running process, so '/dev/stdin' is always the pipe-input of the process looking it up.

In this example I use 'cat', but you can use any other means to read from '/dev/stdin', so this is a solution that should work for all programming languages that support reading from a file.
My website - My git repos

"Things are only impossible until they’re not." - Captain Jean-Luc Picard
(07-17-2019, 10:09 PM)aetesaki Wrote: It has the same problems as with the other methods I found when googling: You can't check if the stream is empty without potentially deleting characters from the stream.

You can do it like a lot of other applications do it: Only accept data from stdin if you use the '-' option.

(07-17-2019, 10:09 PM)aetesaki Wrote: But the biggest problem is that your code will just halt the script forever, unless you hit ctrl+d, ctrl+c or ctrl+z.

Try piping something into it. You will find that it works perfectly fine. Why? Simple: When cat reads from stdin without piping anything into it, the shell opens the pipe and only closes it when an end-of-data character is send or the program is terminated. However if you pipe something into it, the pipe will usually be closed by the sending program once it has send all it wants to send.

In other words, the script will simply have common behaviour regarding pipes.
My website - My git repos

"Things are only impossible until they’re not." - Captain Jean-Luc Picard
(07-18-2019, 08:30 AM)aetesaki Wrote: As I said, I have tested it, and it doesn't work

It works exactly as I described it. Here is a screenshot:

.png   a-screenshot.png (Size: 36.03 KB / Downloads: 9)
My website - My git repos

"Things are only impossible until they’re not." - Captain Jean-Luc Picard
(07-18-2019, 12:06 PM)aetesaki Wrote: Tell me, did you even read my script,


Did you read the my explanation why my version also works?

(07-18-2019, 12:06 PM)aetesaki Wrote: or did you just read my name and go "I'm going to bash (no pun intended) this moron's head in verbally"?
There's a word for that kind of behavior, bullying.

Do you honestly think that just because we had an arguement here some time ago I actively seek out your posts to "bully" you? I can assure you that I have no grudge with anyone, including you, over some mean words in an online discussion. I was simply providing an alternative to your solution, without indicating whether it is better or worse.

(07-18-2019, 12:06 PM)aetesaki Wrote: Read my lips: IT DOES NOT WORK, unless you're a bully and just wants to bully someone smarter than you, without actually taking the time to check what your victim provides. A screenshot of a script specifically design to bully the OP, does not negate the victims correct claim, that your bully script DOES NOT WORK in a real life situation as opposed to the script provided by the victim, which actually DOES WORK IN A REAL LIFE SITUATION.

But apparently you have a grudge with me. Which is a shame, because otherwise this could have been a constructive discussion about scripts and pipes.

Despite, I explained how and why my solution works.

(07-18-2019, 12:06 PM)aetesaki Wrote: someone smarter than you,

Is this really what you want? An online discussion about who is smarter? Where both sides will just end up bragging about their skills and achievements?

Sorry, but I refuse to take part in that.

If you want to think that I am stupid, go ahead.
My website - My git repos

"Things are only impossible until they’re not." - Captain Jean-Luc Picard
(07-18-2019, 06:52 PM)aetesaki Wrote: Then get lost! and stay lost forever!

I just want to point out that you are accusing me of bullying while you are the only unfriendly one in this thread.

(07-18-2019, 06:52 PM)aetesaki Wrote: You are obviously lying when you say you read my script, cause if you had, you would've seen from the start that your bully script was equivalent to
echo foo | cat
which in turn is equivalent to
echo foo
which is why your bully script can never work as my script, because running
bully foo
WILL break it in the exact way described in my first reply, computer halting until you hit ctrl+d, ctrl+c, or ctrl+z.

You obviously misunderstood me. I never said that what I provided was a full drop-in replacement of your solution. I just provided the alternative of directly reading from 'stdin'. I explained how it works and why it works, which you did not read, because otherwise you would not have assumed that the code snippet I provided was supposed to be a completely implemented solution. I also mentioned that one could follow UNIX tradition by only letting the script read from stdin when a '-' is provided as an arguement.

You want to see that implemented? Here:


case "$1" in
    "-") INPUT="$(cat /dev/stdin)" ;;
    *)   INPUT="$*" ;;

echo "$INPUT"

Here is what is does:

$ ./ foo

$ echo foo | ./ -

$ echo foo | ./ bar

Just as I explained it.

The important part here is not 'cat' but '/dev/stdin', because you can also use other mechanism (in other programming languages) to read from there and get the same result.

(07-18-2019, 06:52 PM)aetesaki Wrote: So get lost, and stay lost, your bullying is not welcome

I am not bullying you. Is that really so hard to understand? I did not even remotely say anything against you or your solution. I am not plotting against you. I am not bullying you. I did not came here to attack you, nor to argue with you. I simply wanted to add my thoughts and my solution to a problem.

So please tell me how I am supposedly bullying you by simply providing an alternative and explaining it.
My website - My git repos

"Things are only impossible until they’re not." - Captain Jean-Luc Picard
(07-18-2019, 08:00 PM)aetesaki Wrote: Well, if you will add the ability to read from keyboard…
# pipe - This script will echo whatever it is given, whether it's from a previous command, or an argument

# If stdin is open, dump its content to $pipe
[ ! -t 0 ] && pipe=$(cat)

# Check for arguments
# If there are no arguments
if [ "$#" == "0" ]; then
   # check if $pipe is empty
   if [ -z "$pipe" ]; then
       # if $pipe is empty display error message and exit
       echo "Received neither arguments nor piped output from a previous command"
       exit 1

# if the first argument is -
if [ "$1" == "-" ]; then
  # throw it away
  # warn the user
  echo "Type in your response, hit enter and ctrl+d on an empty line when you are finished"
  # and save the stream

# combine all arguments
args="$@ $pipe $kbdin"
# and dump them back into the argument list
set -- "$args"

# echo the arguments
echo $@

This is a reasonable solution.

I also edited my initial response to make it a bit clearer what I was trying to say.
My website - My git repos

"Things are only impossible until they’re not." - Captain Jean-Luc Picard

Forum Jump:

Users browsing this thread: 1 Guest(s)