1
votes

I've used the following script (found on this site) and have trouble getting it to work.

askit () {
while true ;
do
        read -r -n 1 -p "continue? [y/n] :" rep
        case $rep in
                [yY] ) return 0 ;;
                [nN] ) return 1 ;;
                * ) printf "no no, only y or n" 
        esac
done
}


if $(askit)
then
        printf "\nWe go on, %s say.\n" $you
else
        printf "\nThat's it, %s want to quit!\n" $you
        break
fi

It works for "y" or "n" entries. Other entries loop back without terminal output. After the next "y" or "n" the result is always false.

The newlines in the printf statements are a legacy from not being able to put printf statements within the case statement. I've tried echo as well with the same result.

The return statement seems to be outputting to the if conditional. I'm pretty sure my syntax is ok. I've looked into fflush and stdbuf...

Question: Why does printf output to the if statement and not to the terminal?

1
Can you provide the x-ref to where you got this from so the original can be improved? - Jonathan Leffler
Welcome to Stack Overflow. Please note that the preferred way of saying 'thanks' around here is by up-voting good questions and helpful answers (once you have enough reputation to do so), and by accepting the most helpful answer to any question you ask (which also gives you a small boost to your reputation). Please see the About page and also How do I ask questions here? and What do I do when someone answers my question? - Jonathan Leffler

1 Answers

1
votes

There are a couple of issues with this :

Firstly, the askit function will not return till you exit the while loop or you return a value.

If I understand correctly you wish to print We go on, you say stuff every time the user need to enter a value.

Assuming that you have a variable you declared inside the function fun you may do it like below :

#!/bin/bash
askit()
{
name="User"
while true
do
   printf "\n%s, go to to say " $name
   read -r -n 1 -p "continue?[y/n] :" rep
   case $rep in
          [yY]) return 0;;
          [nN]) return 1;;
          * ) printf "\nEnter either y or n\n" ;;
   esac
done
}

if askit
then
printf "\nSuccess\n"
else
printf "\nFailure\n"
fi

Secondly, you cannot use $(askit) as this will populate the rest of the if statement from the whatever you print inside the askit function. This is clearly not what you wish to have. You just need a confirmation if the function returned successfully or not.

Question: Why does printf output to the if statement and not to the terminal?

$() is command substitution which is usually used to pass result one command to another. When you pass a function with printfs things however becomes ugly.