4
votes

How do I look for user input from the keyboard in the bash shell? I was thinking this would just work,

int b;

scanf("%d", &b);

but it says

-bash: /Users/[name]/.bash_profile: line 17: syntax error near unexpected token `"%d",'

-bash: /Users/[name]/.bash_profile: line 17: `scanf("%d", &b);'

EDIT

backdoor() {
   printf "\nAccess backdoor Mr. Fletcher?\n\n"
   read -r b
   if (( b == 1 )) ; then
     printf "\nAccessing backdoor...\n\n"
   fi   
}
3
I'm curious -- what documentation or other context lead to trying to use a C library function in a shell script? - Charles Duffy
I am a noob programmer, I started by learning LUA, left it for like a year, then started to learn C, and then just today started to try to learn the bash stuff. - Nightlock32
You don't need to declare your variables, either -- the int b can just be left out, as can the semicolons at endlines. I'd suggest starting from scratch with something like mywiki.wooledge.org/BashGuide rather than assuming that syntax from completely different languages will work for bash. - Charles Duffy
@CharlesDuffy re "What context lead to trying to use a C library function in a shell script?": Well, there is a printf builtin! - Peter - Reinstate Monica
@CharlesDuffy Yes of course. I was just outlining a possible train of thought which might lead to the asumption that there is a scanf in bash. In fact, I came to this very page because I googled "bash scanf"; I am trying to parse a string with a minimal set of sub-processes. There sure is a host of even bash-built-in string manipulation functions which can be used instead of a scanf. It's also not quite clear how one would realize the by-reference semantics of scanf target variables. But still: A printf without a scanf is an obvious asymmetry :-). - Peter - Reinstate Monica

3 Answers

7
votes

Just use the read builtin:

read -r b

No need to specify type (as per %d), as variables aren't typed in shell scripts unless you jump through (needless) hoops to make them so; if you want to use a value as a decimal, that's a question of the context in which it's evaluated, not the manner in which it's read or stored.

For instance:

(( b == 1 ))

...treats $b as a decimal, whereas

[[ $b = 1 ]]

...does a string comparison between b and "1".

2
votes

While you can declare variables as integers in Bash, the results won't do what you expect. A non-integer value will be converted to zero, which is probably not what you want. Here is a more bullet-proof way to ensure you gather an integer:

while read -p "Enter integer: " integer; do
    [[ "$integer" =~ [[:digit:]]+ ]] && break
    echo "Not an integer: $integer" >&2
done

This is particularly useful when you want to inform the user why a value is rejected, rather than just re-prompting.

0
votes

You're trying to mix C-like syntax with Bash syntax.

backdoor() {

    printf '\n%s\n\n' 'Access backdoor Mr. Fletcher?'

    read -r b

    if ((b == 1))
    then
        printf '\n%s\n\n' 'Accessing backdoor...'
    fi
}