0

say i have a function of this nature in my .bash_profile

sayword(){
   echo $1
}

now the command will be run like sayword hello now i want the function to be able to take input from other command using unix pipe. something like cat words.txt | sayword and it outputs each of the word in words.txt. How do i do that ?. I read a question here that talks about redirecting to dev/null but that doesn't seem to work .

2 Answers2

1

You can write it this way

function sayword() {
  if [ $# -eq 0 ]
  then
    while read input; do
      echo $input
    done
  else
    echo $1
  fi
}

and then you can call it like this

date | sayword
petrubear
  • 616
  • 5
  • 6
  • while this is helpful , it looks like i can call it this way ``` sayword hello``` anymore , i need such flexibility . i appreciate your answer anyways , thanks alot – shammah zealsham May 28 '20 at 13:05
  • 1
    I edited my answer to fit your needs, check if it helps – petrubear May 28 '20 at 13:08
  • If you call this as `sayword 1 2 3` it only repeats `1`. If you want all inputs on one line, use `echo "$@"`. If you want them output on separate lines, use `printf "%s\n" "$@"`. – Paul Hodges May 28 '20 at 14:12
0

This is where you want the -t condition: that can test if stdin is a pipe/redirection or the terminal (i.e. interactive):

sayword() {
  {
    echo "$(date) - saying words"
    if [ -t 0 ]; then
      # stdin is the terminal: take input from the cmdline parameters:
      echo "$*"
    else
      # stdin is a pipe or redirection
      cat
    fi
  } >> "$HOME/words.txt"
}

Then, these both append to the file:

$ sayword hello
$ cat ~/words.txt
Thu May 28 09:22:27 EDT 2020 - saying words
hello
$ echo foo bar | sayword
$ cat ~/words.txt
Thu May 28 09:22:27 EDT 2020 - saying words
hello
Thu May 28 09:22:37 EDT 2020 - saying words
foo bar
glenn jackman
  • 238,783
  • 38
  • 220
  • 352