views:

327

answers:

3

I'm trying to write a helper function to use in a bash script to take a variable prompt string and return the value the user inputs. What I have sits and waits for a user to input the value without displaying the prompt first, which is puzzling. It also stores the echo in the return value ($foo), and doesn't keep the value read in with the pid variable.

!#/bin/bash
pid=0
promptValue() {
  msg="$1"
  echo -e "$msg"
  read val
  pid=$val
}

foo=$(promptValue "type something")

EDIT: For anyone who might want to use this in the future for their own use, this is the full (functional) script, which is designed to send an email (in this case to my cellphone) to let me know when a long running process completes. I'm sure there has to be a better way to do this, but meh. :-) (I wrote them like this to be used in a bash function library elsewhere.)

#!/bin/bash

promptValue() {
 read -p "$1"": " val
 echo $val
}

alertme() {
 if [ -z "$email" ]; then
   email=$(promptValue "Enter email")
 fi

 if [ -z "$email" ]; then 
   echo "ERROR: No email set!"
   exit 1
 fi

 if [ -z "$pid" ]; then
   pid=$(promptValue "Enter pid")
 fi

 if [ -z "$pid" ]; then 
   echo "ERROR: No pid set!"
   exit 1
 fi

 ps -ef | grep $pid | grep -v grep > /dev/null 2>&1
 while [ $? eq 0 ]; do
  sleep 10
  ps -ef | grep $pid | grep -v grep > /dev/null 2>&1
 done

 echo "Process Complete" | mailx -s "Process Complete" $email
}

alertme

Thanks again everyone!

A: 

obviously this will work if you execute directly instead assigning it to foo. If you are trying to capture the value of val then why noit just do:

promptValue "type something"
foo=$pid
ennuikiller
+1  A: 

The normal way to do it would seem to be something like:

#!/bin/bash
pid=0
promptValue() {
  read -p "$1"": " val
  pid=$val
}

promptValue "type something"
echo 'pid:'$pid'!'

$(...), "command substitution", takes the "command"'s standard output as the result (so it doesn't show the echo on your terminal, etc).

Alex Martelli
The extra quotes aren't necessary: `read -p "$1: " val` and `echo "pid:$pid!"` (although at the prompt, the superfluous exclamation point, when in double quotes, will cause a history "event not found error". In a script, this won't be a problem.
Dennis Williamson
+1  A: 

Functions' exit values are the same as that of the last command executed within the function or the value supplied by a return n statement where n is in the range 0-255. If you want the function to return a string or numeric value, you use echo. If you want to capture the output of a function in a variable and still be able to send output to the user without having that captured, use stderr which is what read -p does.

$ demo() {
    local num
    echo "capture this"
    echo "Message to user" >&2
    read -p $1 num
    echo $(( num * 2 ))
    return 42
}
$ result=$(demo "Enter a number: ")
Message to user
Enter a number: 12
$ echo $?
42
$ echo "$result"
capture this
24
$ echo "$num"
[null][newline]
Dennis Williamson
I ended up using a combination of this answer and Alex's answer above. Thanks gang!
Almo