How to check for Input Redirection in my script?

All,

I have a requirement to write a script where I check for Input redirection when the script was executed, based on which I handle my logic. Below is the example:

my.script

#! /bin/ksh
# Not sure how to frame the if condition below
if [ input_redir = "Y" ]; then
  echo "Input Redirected from a file"
  Do Processing.....
else
  echo "No Input Redirection"
  Do Processing....
fi

So once the script is written, the script could be executed in following 2 ways which i should handle:

Run 1
Executed as:

./my.script

Result:

No Input Redirection

Run 2
Executed as:

./my.script < test.file

Result:

Input Redirected from a file

Hope I made myself clear. Let me know for any questions.

Bharath

Do you really need ? What is the real problem ?
You need input, you need input from stdin or from file like most of commands has done ?
If argument, it's the input file, if not then use stdin:

file=$1
cat $file | while read line
do
    some...
done

Thanks kshji,

I did try that, below is the example where I tried to use the No. of arguments to find the redirection, but that does NOT work for me. And only so I did not post it in my first post.

my.script

#! /bin/ksh
numargs=$#
case $numargs in
0)
  echo "No. of Args : $numargs"
  echo "Parameter 0 = $0"
;;
*)
  echo "No. of Args : $numargs"
  i=1;
  for d in $@
  do
    echo "Parameter $i = `echo $d`"
    i=`expr $i + 1`
  done
;;
esac

Below are the different runs:
Run 1: Running with NO redirection

$ ./my.script
No. of Args : 0
Parameter 0 = ./my.script

Run 2: Running with redirection

$ ./my.script < test.file
No. of Args : 0
Parameter 0 = ./my.script

Run 3: Running with arguments

$ ./my.script Hi this is a test text
No. of Args : 6
Parameter 1 = Hi
Parameter 2 = this
Parameter 3 = is
Parameter 4 = a
Parameter 5 = test
Parameter 6 = text

Hope this helps! Let me know if you need any more information.

Thanks
Bharath

What you have found out is common knowledge: input (or output) redirection is not part of any parameters because it is an OS service: every process has several I/O-channels and per default 3 of them are in use: <stdin>, <stdout> and <stderr>. It is only common default, but in no way necessary, that <stdin> is pointing to the keyboard and <stdout> and <stderr> are both pointing to the terminal screen.

A program is not (and should not be) aware which device or file its input or output points to. This indifference makes UNIX programs so versatile.

Again, would you please tell us what your original problem is, which you are trying to solve with this distinction between different sources of input. Maybe (i dare say probably) your design is flawed from the beginning and we can find a better one together?

I hope this helps.

bakunin

Thanks bakunin for the detailed explanation. Below ismy requirement.

I currently have my script written only to accept user inputs (which obviously has many echoes and is constantly relying on the terminal input by user). Now i am trying to add the Input from file functionality also to it (where I would want the script to run with no echoes and terminal inputs, more like a script silently running on the background taking the inputs from the file). Which is why I need to find the rediection flag so that I can handle both of the scenarios differently.

The one way I could think of now, is using the filename as an argument and checking for argument count. Based ona rg count, I handle each case seperately.

Let me know if there is a better approach.

Sincerely appreciate your comments.

thanks again,
Bharath

You could accept a specific option like "-f /path/to/inputfile" and act according to this option being set or not. Below is a sketch of the logic for better understanding. Use "getopts" instead of my construction for a production-grade script:

#! /bin/ksh

typeset inFile=""

while [ -n "$1" ] ; do
     case $1 in
          -f)
               shift
               inFile="$1"
               shift
               ;;

          -x)
               # some other option
               shift
               ;;

          *)
               print - "Error: unknown option"
               exit 1
               ;;

     esac
done

# if $inFile is empty the user has not specified any input file
if [ -n "$inFile" ] ; then
     # interactive operation goes here
else
     # batch operation goes here
fi

exit 0

Now "script -f /some/file" would lead to batch operation whereas "script" would lead to interactive operation.

I hope this helps.

bakunin

I guess you are looking for something like this??

test.sh

exec 6<&0
while read line
do
echo $line
done<&6

exec 6<&-

And now, you can call like below..

sh test.sh < file

One way which works whether the data is presented on a pipeline, an inward redirect, or interactive.

#!/bin/ksh
#
# If nothing is using channel zero we are interactive
if [ -t 0 ]
then
        while true
        do
                echo "Enter data line: "; read line
                if [ "${line}""X" = "X" ]
                then
                        exit
                fi
                echo "${line}"
        done
fi
#
# Data is piped to this script
(
while read line
do
        echo "${line}"
done
) <&0