Bash: Succinct way to loop over lines from stdin or command line arguments

bash

I've got a bash script I'd like to loop over the lines in stdin, or loop over each argument passed in.

Is there a clean way to write this so I don't have to have 2 loops?

#!/bin/bash

# if we have command line args... 
if [ -t 0 ]
then
  # loop over arguments
  for arg in "$@" 
  do
    # process each argument
  done
else
  # loop over lines from stdin
  while IFS= read -r line; do
    # process each line
  done
fi

EDIT: I'm looking for a generic solution that just uses a single loop, as I find I want to do this quite often, but have always wrote out 2 loops and then called a function instead. So maybe something that turns stdin into an array, so I could use a single loop instead?

Best Answer

We can also use redirection of standard input:

#!/usr/bin/env bash
test -t 0 && exec < <(printf '%s\n' "$@")
while IFS= read -r line; do
    echo "$line"
done

test with :

test.sh Hello World
test.sh < /etc/passwd
Related Question