Bash script unable to disable expected output

I'm trying to understand why a script behaves different when run through a pipe.

My OS:

Linux  myip 3.13.0-92-generic #139-Ubuntu SMP Tue Jun 28 20:42:26 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

This script (myscript.sh):


#!/bin/bash

echo whoami:
whoami
echo who:
who
echo who am i:
who am i
echo logname:
logname

Gives the expected output of:

whoami
ubuntu
who
ubuntu   pts/1        2018-05-03 14:15 (8.21.68.241)
who am i
ubuntu   pts/1        2018-05-03 14:15 (8.21.68.241)
logname
ubuntu

But when run like through a pipe, the "who am i" command does not show the same output. doesnt show anything at all.

ubuntu@myIp:~$ cat ~/myscript.sh | bash
whoami:
ubuntu
who:
ubuntu   pts/1        2018-05-03 14:15 (8.21.68.241)
who am i:
logname:
ubuntu

What could be the problem? How can i get the piped way of running the script behave exactly as how the script would behave if run the regular way?

Without a terminal you don't get the usual terminal control niceties. It does work, you just don't see it. Try redirecting the result into a file.

2 Likes

Expanding a little on what Corona688 has already said, the who utility uses its standard input file descriptor to determine the terminal being used as your controlling terminal. If your script is not the first process in a pipeline or if standard input is redirected from a non-terminal device file, it might not know how to determine who you are.

On a macOS or BSD system, these conditions would lead to output similar to:

dwc      tty??    May  3 09:59

instead of the normal output:

dwc      ttys007  Apr 28 08:53

that I get when standard input is connected to my terminal. I'm surprised that Linux (at least Ubuntu Linux) doesn't give you any output at all.

1 Like