Reputation: 378
I'm working with a growing bash script and within this script I have a number of functions. One of these functions is supposed to return a variables value, but I am running into some issues with the syntax. Below is an example of the code.
ShowTags() {
local tag=0
read tag
echo "$tag"
}
selected_tag=$(ShowTags)
echo "$selected_tag"
pulled this code from a Linux Journal article, but the problem is it doesn't seem to work, or perhaps it does and im missing something. Essentially whenever the function is called the script hangs up and does not output anything, I need to CTRL+C to drop back to CLI.
The article in question is below.
http://www.linuxjournal.com/content/return-values-bash-functions
So my question is this the proper way to return a value? Is there a better or more dependable way of doing this? And if there is please give me an example so I can figure this out without using global variables.
EDIT:
The behavior of this is really getting to me now. I am using the following script.
ShowTags() {
echo "hi"
local tag=0
read tag
echo "$tag"
}
selected_tag=$(ShowTags)
echo "$selected_tag
Basically what happens is bash will act as if the read command is taking place before the echo tag at the top of the function. As soon as I pass something to read though it will run the top echo, and complete the rest of the script. I am not sure why this is happening. This is exactly what is happening in my main script.
Upvotes: 2
Views: 222
Reputation: 780723
Change echo "hi"
to echo "hi" >/dev/tty
.
The reason you're not seeing it immediately is that $(ShowTags)
captures all the standard output of the function, and that gets assigned to selected_tag
. So you don't see any of it until you echo that variable.
By redirecting the prompt to /dev/tty
, it's always displayed immediately on the terminal, not sent to the function's stdout
, so it doesn't get captured by the command substitution.
Upvotes: 2
Reputation: 125708
As @thatotherguy pointed out, your function declaration syntax is off; but I suspect that's a transcription error, as if it was wrong in the script you'd get different problems. I think what's going on is that the read tag
command in the function is trying to read a value from standard input (by default that's the terminal), and pausing until you type something in. I'm not sure what it's intended to do, but as written I'd expect it to pause indefinitely until something's typed in.
Solution: either type something in, or use something other than read
. You could also add a prompt (read -p "Enter a tag: " tag
) to make it more clear what's going on.
BTW, I have a couple of objections to the linux journal article you linked. These aren't relevant to your script, but things you should be aware of.
First, the function
keyword is a nonstandard bashism, and I recommend against using it. myfunc() ...
is sufficient to introduce a function definition.
Second, and more serious, the article recommends using eval
in an unsafe way. Actually, it's really hard to use eval
safely (see BashFAQ #48). You can improve it a great deal just by changing the quoting, and even more by not using eval
at all:
eval $__resultvar="'$myresult'" # BAD, can evaluate parts of $myresult as executable code
eval $__resultvar='"$myresult"' # better, is only vulnerable to executing $__resultvar
declare $__resultvar="$myresult" # better still
See BashFAQ #6 for more options and discussion.
Upvotes: 0
Reputation: 123410
You are trying to define a function with Name { ... ]
. You have to use name() { ... }
:
ShowTags() { # add ()
local tag=0
read tag
echo "$tag"
} # End with }
selected_tag=$(ShowTags)
echo "$selected_tag"
It now lets the user type in a string and have it written back:
$ bash myscript
hello world # <- my input
hello world # script's output
You can add a prompt with read -p "Enter tag: " tag
to make it more obvious when to write your input.
Upvotes: 0