Running function with read command in bash - bash

I need small help with shell function.
I created small function with read command inside, I need to call this function and the return value to outside variable
Check()
{
echo "type something : "
read anyword
echo $anyword
}
out=`Check`
echo $out
the problem is that echo line is not presenting anything until i press enter.
I want that this function will act like python.
Thanks,

The problem is the backticks. If you CTRL+C before the prompt ends, and try to echo $out, you notice that your prompt is saved into the $out variable. Move the prompt outside the function call. Maybe this will help:
Check()
{
read anyword
echo $anyword
}
echo "type something : "
out=`Check`
echo $out
If you're using bash specifically, consider read -p also.
Alternatively, if you want to keep the prompt inside the function:
Check()
{
echo "Type something: " >&2
read anyword
echo $anyword
}
That way, it will write to stderr instead of stdout, so it won't get eaten up.

Related

Clearing the echo history

I have a bash script that calls a function which returns a value. I have included the scripts below:
Script
source ./utilities/function1.sh
result=$(Function1)
echo "Result: $result"
Function1
function Function1 {
echo "Inside Function: Function1"
cat <<EOF
this is the result
EOF
}
I want to be able to echo to the console within the function and return only the value I want, not including the messages that were echoed to the console, but when I run the script the following is returned:
Result: Inside Function: Func1
this is the result
Is this the best way to return a value from a bash function or is there a way I can echo to the console and return a value without the content of the echo commands from the function?
Thanks in advance
There are a few ways to do what you want. two simple ones are:
Use STDERR to echo to the console and capture STDOUT in your script. By default, STDOUT is on File Descriptor 1 and STDERR is on File Descriptor 2:
function myFunction() {
echo "This goes to STDOUT" >&1 # '>&1' is the default, so can be left out.
echo "This goes to STDERR" >&2
}
result=$(myFunction)
echo ${result}
Use a variable to return a string to the caller:
function myFunction() {
echo "This goes to STDOUT"
result="This goes into the variable"
}
declare result="" # Has global scope. Can be modified from anywhere.
myFunction
echo ${result}
Global scope variables are not good programming practice, but are a necessary evil in bash scripting.

I got nothing while i expect echo something after enter 123 to below script

I want to print a sentence when enter 123 but nothing happened without error. What is going on. This script for testing with no extra script in it's file.
fun1() {
echo "plz entr ur name"
read $user
if [ "$user" = "123" ]
then
echo "su & zo"
exit
fi
}
fun1
read takes the name of a variable to populate.
read user
read $user is equivalent to read, when $user expands to the empty string. If this is bash, then read will populate the variable REPLY instead. if [ "$REPLY" = 123 ] would work in that case.
But you really just want to to call read with the correct argument.

Shell Funtion string variables result blank?

I have small script which have a function asking user input (name of user) and then I have echo function
which is running the function and asking for input,
After that I have echo the $User_name in last line (Users_name_is - )which is set in function but its result is black, I want to use $User_name in further script.
what i am doing wrong ?
#!/bin/sh
funtion_one()
{
read varname
if [ $varname == skull ]; then
echo "Nice to meet you $varname"
#User_name=$varname
else
echo "I dont know you $varname"
fi
User_name=$varname
}
echo Hello, who am I talking to?
while :
do
case $(funtion_one) in
"Nice to meet you skull") break
;;
"I dont know you") $(funtion_one)
;;
esac
done
echo "Users_name_is - $User_name"
I want result Users_name_is - skull
When you do $(funtion_one), you are executing the function inside a subshell, so any variables created cease to exist after the function finishes.
An alternative would be this:
function_one()
{
read varname
if [ "$varname" = skull ]; then
echo "Nice to meet you $varname" >&2
else
echo "I dont know you $varname" >&2
fi
echo "$varname"
}
user_name=$(function_one)
Now user_name exists in the parent shell. The messages are sent to standard error, and the name that has been read is sent to standard output so that it can be captured by the command substitution $().
Alternatively, you can simply execute the function in the parent shell:
# change
echo $(funtion_one)
# to
funtion_one
But then all the variables used inside the function will continue to exist after it has been run.
It seems the function is getting in the way of you achieving what you want. I would restructure your code to something much simpler like this:
while read name; do
if [ "$name" = skull ]; then
echo "Nice to meet you $name"
break
fi
echo "I don't know you $name"
done
There are a lot of ways to structure your code, and it seems like you're trying to do something like:
#!/bin/sh
get_user_name() {
local varname
printf 'Hello, who am I talking to? '
read varname
if test "$varname" = skull; then
echo "Nice to meet you $varname"
User_name=$varname
return 0
else
echo "I dont know you $varname" >&2
return 1
fi
}
unset User_name
while ! get_user_name
do
case "$User_name" in
skull) break
;;
esac
done
echo "Users_name_is - $User_name"
It's perfectly valid to use a function to get the input, but if you want that function to set a variable in the caller you cannot call it as a subshell, and it's easiest if the shell returns a value to indicate success or failure.

Echo output to terminal within function in BASH

I am writing a script in BASH. I have a function within the script that I want to provide progress feedback to the user. Only problem is that the echo command does not print to the terminal. Instead all echos are concatenated together and returned at the end.
Considering the following simplified code how do I get the first echo to print in the users terminal and have the second echo as the return value?
function test_function {
echo "Echo value to terminal"
echo "return value"
}
return_val=$(test_function)
Yet a solution other than sending to STDERR (it may be preferred if your STDERR has other uses, or possibly be redirected by the caller)
This solution direct prints to the terminal tty:
function test_function {
echo "Echo value to terminal" > /dev/tty
echo "return value"
}
-- update --
If your system support the tty command, you could obtain your tty device from the tty command, and thus you may:
echo "this prints to the terminal" > `tty`
send terminal output to stderr:
function test_function {
echo "Echo value to terminal" >&2
echo "return value"
}
Dont use command substitution to obtain the return value from the function
The return value is always available at the $? variable. You can use the variable rather than using command substitution
Test
$ function test_function {
> return_val=10;
> echo "Echo value to terminal $return_val";
> return $return_val;
> }
$ test_function
Echo value to terminal 10
$ return_value=$?
$ echo $return_value
10
If you don't know in which terminal/device you are:
function print_to_terminal(){
echo "Value" >$(tty)
}

is it possible to avoid the execution of a certain command?

I have to avoid the execution of a certain command in a bash script.
I thought to use a preexec trap to do so.
Let's say I want to avoid the command 'source' just for axample.
What I did is basically the following:
#!/bin/bash
function preexec ()
{
if test $( echo "$BASH_COMMAND" | cut -d " " -f1 ) == "source"
then
echo ">>> do not execute this"
else
echo ">>> execute this"
fi
}
trap 'preexec' DEBUG
echo "start"
source "source.sh"
echo "go on"
exit 0
the idea works fine, but at this point I don't know how to avoid the execution of said command.
Any idea how to solve this?
One workaround would be to define an alias for that command that does nothing and undefine it after the script has completed. The alias must be declared within the script itself for this to work:
alias source=:
## The actual script source here...
unalias source
Redefine the source command by using a function called source.
Functions can be exported.
source() { builtin source /dev/null; return 0; }
source() { read < /dev/null; return 0; }
source() { :; return 0; }
export -f source

Resources