bash FUNCNAME value expanding - bash

I have one lib-file. It has one wrapper-like substitution of ponOS function. I want to display in function ponOS name of function where it is called from.
$> cat ./parasha_lib.sh
#!/bin/bash
function ponOS {
echo "$1: hello from ponOS"
}
ponOS='ponOS ${FUNCNAME}'
But, what I see is that this solution did not work as well as I want.
$> cat ./test.sh
#!/bin/bash
source ./parasha_lib.sh
function main {
echo "message from ${FUNCNAME}"
ponOS
}
main
So, I've got
$> ./test.sh
message from main
: hello from ponOS
But I wanna get this:
$> ./test.sh
message from main
main: hello from ponOS
What should I do?
One of the important things here is that ./test.sh shouldn't be modified (ponOS ${FUNCNAME} it's not the solution).

To do that, you need to set ponOS as an alias so that ${FUNCNAME} is expanded when called within the main function and not when the script is sourced.
Modify ./parasha_lib.sh to:
#!/bin/bash
function ponOS {
echo "$1: hello from ponOS"
}
shopt -s expand_aliases # enable alias expansion
alias ponOS='ponOS ${FUNCNAME}' # create an alias to call ponOS
Note that shopt -s expand_aliases is required to enable alias expansion. From the bash manpage:
Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt
Now, without changing test.sh we get the desired output:
[me#home]$ ./test.sh
message from main
main: hello from ponOS

See FUNCNAME at http://www.gnu.org/software/bash/manual/bash.html#Bash-Variables
parasha_lib.sh
#!/bin/bash
function ponOS {
echo "${FUNCNAME[1]}: hello from ponOS"
}
test.sh
#!/bin/bash
source ./parasha_lib.sh
function main {
echo "message from ${FUNCNAME}"
ponOS
}
main
Result ./test.sh
message from main
main: hello from ponOS

Related

Pass function name as argument when running bash script

Assuming I have the following script:
#!/bin/bash
function hello (){
echo hello,
}
function world (){
echo world!
}
Is it possible to select the functions to run while I start the script?
For exmaple:
./test.sh hello world
output:
hello,world!
Just iterate over the arguments and run them.
for i in "$#"; do
"$i"
done
Do not use function name(), just name(). See https://wiki.bash-hackers.org/scripting/obsolete . Check your scripts with shellcheck .
You can use eval command to execute first argument.
#!/bin/bash
function hello (){
echo hello,
}
function world (){
echo world!
}
eval $1

access modifiers in bash

Say I have a bash script and I want some variables to appear when sourced and others to only be accessible from within the script (both functions and variables). What's the convention to achieve this?
Let's say test.sh is your bash script.
What you can do is extract all the common items and put them in common.sh which can be sourced by other scripts.
The BASH_SOURCE array helps you here:
Consider this script, source.sh
#!/bin/bash
if [[ ${BASH_SOURCE[0]} == "$0" ]]; then
# this code is run when the script is _executed_
foo=bar
privFunc() { echo "running as a script"; }
main() {
privFunc
publicFunc
}
fi
# this code is run when script is executed or sourced
answer=42
publicFunc() { echo "Hello, world!"; }
echo "$0 - ${BASH_SOURCE[0]}"
[[ ${BASH_SOURCE[0]} == "$0" ]] && main
Running it:
$ bash source.sh
source.sh - source.sh
running as a script
Hello, world!
Sourcing it:
$ source source.sh
bash - source.sh
$ declare -p answer
declare -- answer="42"
$ declare -p foo
bash: declare: foo: not found
$ publicFunc
Hello, world!
$ privFunc
bash: privFunc: command not found
$ main
bash: main: command not found

Exceuting function in Shell file from command

In my shellFile.sh I wrote this function:
#!/bin/bash
myFunction(){
echo 1
}
I tried to call the function from the command line this way:
shellFile.sh
shellFile.sh myFunction
After this two lines there is no output and no errors. I apologize if this question is asked before but I couldn't find it.
you can call your function inside your script like this
#!/bin/bash
myFunction(){
echo 1
}
myFunction
If you want to use the function interactively you can source the script, then call the function from the command line.
$ source shellFile.sh
$ myFunction
1
If you want the function to be available from the command line, you need to create the function in the current shell, using the dot . command, or in Bash its workalike source:
$ . shellFile.sh
$ myFunction
1
$
I suggest:
#!/bin/bash
myFunction(){
echo 1
}
$1
Usage: ./shellFile.sh myFunction
Output:
1
You need to call the function in the script:
#!/bin/bash
myFunction() {
echo 1
}
myFunction

How to call function dynamically in ksh

How to call a function along with script name at runtime in ksh.
For example: function test
function test { echo "shankar" }
Script: emptycheck.ksh
Run time:
./emptycheck.ksh test # <---- Here I want function name (test) here
It's not clear what you are after, but perhaps this is useful:
$ cat a.sh
#!/bin/bash
foo() { echo foo; }
bar() { echo bar; }
${1-foo}
$ ./a.sh foo
foo
$ ./a.sh
foo
$ ./a.sh bar
bar
When you do not want to use getopts and have all functions activated, read the functions in your current environment using a dot:
I copy the example of William Pursell with the other syntax:
$ cat a.sh
#!/bin/bash
foo() { echo Echoing foo; }
bar() { echo Echoing bar; }
$ . a.sh
$ foo
Echoing foo
$ bar
Echoing bar
you can name a function "test", but as mentioned, it's dangerous.
and don't bother with the "#! ..." when sourcing a file. if you ain't running bash when you source it, that won't change the picture.
if you insist on naming a function for an existing command or builtin (there are good reasons to), then to use the existing command or builtin, you use the "command" builtin, which says "avoid any alias or function of that name, and go for the default definition".
e.g. the former "test" is now accessed "command test ..."
therefore, the proper use of the "command" command is inside an overriding function, e.g.
function cd {
# clean up garbage in the current directory, so then:
command cd $* # executes the "real" cd, so you can:
# do whatever useful things you may what to do on arriving in the new one:
# e.g. i do a "dotlib", which sources any ".*rc" files in the current directory.
}
function comment { echo $* 2>/dev/null; }
comment good luck!

Bash - How to call a function declared in a parent shell?

I am writing a bash script that calls functions declared in the parent shell, but it doesn't work.
For example:
$ function myfunc() { echo "Here in myfunc" ; }
$ myfunc
Here in myfunc
$ cat test.sh
#! /bin/bash
echo "Here in the script"
myfunc
$ ./test.sh
Here in the script
./test.sh: line 4: myfunc: command not found
$ myfunc
Here in myfunc
As you can see the script ./test.sh is unable to call the function myfunc, is there some way to make that function visible to the script?
Try
$ export -f myfunc
in the parent shell, to export the function.
#OP, normally you would put your function that every script uses in a file, then you source it in your script. example, save
function myfunc() { echo "Here in myfunc" ; }
in a file called /path/library. Then in your script, source it like this:
#!/bin/bash
. /path/library
myfunc
This also works but I noticed ${0} takes parent's value:
Maybe more useful if you don't want to have a bunch of export calls in your scripts.
script1:
#!/bin/bash
func()
{
echo func "${1}"
}
func "1"
$(. ./script2)
script2:
#!/bin/bash
func "2"
Output:
[mymachine]# ./script1
func 1
func 2

Resources