If you'll forgive me a bit of answer recycling, I think you may find this useful.
_fn() { set -- "$@" $(cat)
while ${1+:} false ; do
echo "$1" && [ "$1" = "arg2" ] && echo "$1"
$YOUR_CHK
shift
done
}
echo "arg2" | _fn "arg1"
OUTPUT
arg1
arg2
arg2
That handles both cmd-line args and stdin. It only runs the while loop to check them while you still have at least one argument saved in your parameter array. It does discard every argument it checks, so part of $YOUR_CHK should be saving information you think valuable in one way or another.
_fn would behave the same if its contents were the body of a script, or as is in the form of a shell function.
_fn handles stdin - in this case "arg2" echoed over the |pipe - in the first line by setting its positional parameter shell $@array to everything passed on the command-line - or "$@" - AND everything cat spits out via $(comand substitution).
while _fn's $1 first parameter is ${set+} we substitute the shell's built-in :true to satisfy the while loop conditional. As soon as $1 is unset that substitution fails to happen, the conditional evaluates to false and the while loop breaks.
For every iteration of the while loop the _fn() echoes its $1 first parameter && if successful (echo is always successful) [ tests ] to see if $1 equals the string "arg2" && if the [ test ] is successful _fn() echoes $1 again.
$YOUR_CHK is a null-op - it is an unset variable that evaluates to nothing before ever the shell executes any code.
For every iteration of the while loop we shift away the $1 first parameter. So on iteration 1 "$@" looks like:
arg1 arg2
But after we shift the first time it looks like:
arg2
And after we shift the last time it looks like:
So this brings us back around again to ${1+:} false - because $1 is now unset the shell will not substitute :true and instead only false is evaluated, which breaks the while loop and ends the _fn().