Is it possible to prompt for input if not given on command line?

I have a script built that takes the standard inputs $1 $2 $3 after the name and parses some data.

 
hexsite=`echo "obase=16;$1"|bc`
hexfix=$(printf "%.3X" 0x$hexsite)
if [ "$2" == "1x" ] || [ "$2" == "1X" ];then
type=33
elif [ "$2" == "ev" ] || [ "$2" == "EV" ];then
type=59
elif [ "$2" == "both" ];then
type=99
else type=00
fi
cat /directory/*.2012$3*|

I am looking for a way to prompt for the input if someone does not include it in the command line. I can get the input via 'read' statements:

 
echo "Input site number: "
read decsite
hexsite=`echo "obase=16;$decsite"|bc`
hexfix=$(printf "%.3X" 0x$hexsite)
echo "Input type: "
read rawtype
if [ "$rawtype" == "1x" ] || [ "$rawtype" == "1X" ];then
type=33
elif [ "$rawtype" == "ev" ] || [ "$rawtype" == "EV" ];then
type=59
elif [ "$rawtype" == "both" ];then
type=99
else type=00
fi
echo "Input date: "
read daterange
cat /directory/*.2012$daterange*|

But I would like to work both ways instead of one or the other depending on what the user does.

Test $# (number of args) and prompt/assign from args as required:

if [ $# -eq 2 ]
then
    decsite=$1
    rawtype=$2
else
    echo "Input site number: "
    read decsite
    echo "Input type: "
    read rawtype
fi

---------- Post updated at 08:30 AM ---------- Previous update was at 08:27 AM ----------

Think about using case for your rawtype test:

case $rawtype in
    1x|1X) type=33 ;;
    [eE][Vv]) type=59 ;;
    both|Both|BOTH) type=99 ;;
    *) type=100 ;;
esac
1 Like

How about:

while [ -z "${decsite:=$1}" ]; do
  printf "Input site number: "
  read decsite
done

while [ -z "${rawtype:=$2}" ]; do
  printf "Input type: "
  read rawtype
done

while [ -z "${daterange:=$3}" ]; do
  printf "Input date: "
  read daterange
done
2 Likes

Awesome response, case is working great so far but the test fails. I forgot to mention I am using bash, sorry about that.

I give it command line entries and it still prompts and overwrites the variables at the moment. I am back to digging with this guidance though, so it is good. :slight_smile:

I will look up the while option too, since it never hurts to know more than one way to skin a <insert animal or vegetable of choice here>!

Reason the test failed is that I missed that you have 3 params (not 2).

Scrutinizer's solution is pretty nice as it also traps blank values being entered when prompting.

1 Like

Oh, I added my third variable when trying it. Is it that $# won't trap all three? I take it using - eq 2 checks for existence?

 
if [ $# -eq 2 ]
then
decsite=$1
rawtype=$2
daterange=$3
else
echo "Input site number: "
read decsite
echo "Input type: "
read rawtype
echo "Input date: "
read daterange
fi

---------- Post updated at 04:14 PM ---------- Previous update was at 04:06 PM ----------

Scrutinizer's answer worked beautifully! I have NO idea how and will spend the next hours/days figuring it out, but it works. :slight_smile:

Chubler_XL, case is much more elegant in the script as well, so thanks for that!

No $# is the number of params passed so you would want to check that 3 were passed with -eq 3 like this:

if [ $# -eq 3 ]
then
   decsite=$1
   rawtype=$2
   daterange=$3
else
   echo "Input site number: "
   read decsite
   echo "Input type: "
   read rawtype
   echo "Input date: "
   read daterange
fi

Schrutinizer's solution will prompt for daterange if you only pass 2 and rawtype+daterange if you only pass 1. This gives you a mix of passed and prompted values.

1 Like

Cool, that makes sense then. TMYK and all that. :slight_smile: Oh, I noticed indentation on the code snippets provided. Is that a tab or just spaces? I figure it is for readability since my local guru tends to code all on one line. Saves space I imagine, but not my favorite thing to parse out. :slight_smile:

Yes, indentation is optional and can be tabs or spaces.

It's a good idea for readability, many solutions posted here are compressed onto one line with variable names like A,f or Z; but you will find things much easier a year down the track when something stops working, if you have good indentation and used ASSET, FAIL_COUNT and EXIT_STATUS!