LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-13-2010, 04:18 AM   #1
Jerry Mcguire
Member
 
Registered: Jul 2009
Location: Hong Kong SAR
Distribution: RedHat, Fedora
Posts: 201

Rep: Reputation: 31
global bash shell functions


Hi, I wonder if there is anyway to make a user-defined bash shell function global, meaning the function can be use in any bash shell scripts, interactively or not.

This is what I attempted:

Code:
$ tail -n 3 /etc/bashrc
echotm () {
  echo "[`date`] $@"
}

$ echotm hello world
[Mon Sep 13 17:15:28 HKT 2010] hello world

$ cat a.sh
#!/bin/sh
echotm hello world

$ sh a.sh
a.sh: line 2: echotm: command not found
Any idea?
 
Old 09-13-2010, 04:28 AM   #2
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
you can source it. man source for more
 
Old 09-13-2010, 04:34 AM   #3
Jerry Mcguire
Member
 
Registered: Jul 2009
Location: Hong Kong SAR
Distribution: RedHat, Fedora
Posts: 201

Original Poster
Rep: Reputation: 31
That works! Thanks.
 
Old 09-13-2010, 05:24 AM   #4
Jerry Mcguire
Member
 
Registered: Jul 2009
Location: Hong Kong SAR
Distribution: RedHat, Fedora
Posts: 201

Original Poster
Rep: Reputation: 31
wait wait...
There is an undesired side-effect of sourcing the file.

As you can see, the command 'echotm' displays timestamp when echo'ing. It is widely used in writing logs in my systems. However, as a habit whether good or bad, I have an 'exit' statement in all the scripts. The exit statement down in some sub-script (script called by another) terminates the entire script in the first level, rendering the whole thing broken.

Code:
$ cat lv1.sh
#!/bin/sh
echo lv 1 in
sh lv2.sh
echo lv 1 out
exit 0

$ cat lv2.sh
#!/bin/sh
echo lv 2 in
echo lv 2 out
exit 0

$ sh lv1.sh
lv 1 in
lv 2 in
lv 2 out
lv 1 out

$ source lv1.sh
lv 1 in
lv 2 in
lv 2 out
Of course, replacing 'echo' with 'echotm' won't work in the first case. But then, rear part of lv1.sh is never executed in the second case.

My last resort is to make 'echotm' a executable shell script file in /usr/local/bin.
 
Old 09-13-2010, 06:11 AM   #5
vikas027
Senior Member
 
Registered: May 2007
Location: Sydney
Distribution: RHEL, CentOS, Ubuntu, Debian, OS X
Posts: 1,305

Rep: Reputation: 107Reputation: 107
You can also use alias for this purpose

Code:
alias echotm='echo hello world';export echotm
To make this permanent include it in your /etc/bashrc or $HOME/.bashrc
 
Old 09-13-2010, 06:11 AM   #6
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
Hi,

Sourcing is done in the current shell, executing is done in a new child shell.

Sourcing a script that you would normally execute can have side effects (exit being one of those).

If you put your function in, for example .bashrc or .bash_profile it will be accessible in all the (bash) shells and its sub-shells.

I have, for example, this function in my .bashrc:
Code:
ALL2LOWER () 
{ 
    /bin/ls * | awk '{ print "mv "$0" "tolower($0) }' | bash
}
It is accessible from the shell and from within scripts.

You can also make a dedicated file that you can source that holds all the functions you need, there shouldn't be a hash-bang or exit in that file. You can decide to source this file by hand when you need it or source this file from for example .bashrc so that all the functions are accessible in all shells.

Hope this helps.
 
Old 09-13-2010, 10:08 AM   #7
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
Quote:
Originally Posted by Jerry Mcguire View Post
Code:
$ cat lv1.sh
#!/bin/sh
echo lv 1 in
sh lv2.sh
echo lv 1 out
exit 0

$ cat lv2.sh
#!/bin/sh
echo lv 2 in
echo lv 2 out
exit 0

$ sh lv1.sh
lv 1 in
lv 2 in
lv 2 out
lv 1 out

$ source lv1.sh
lv 1 in
lv 2 in
lv 2 out
The output's quite odd. Before you called 'source lv1.sh', did you also replaced 'sh lv2.sh' in lv1.sh with 'source lv2.sh' ?

Anyway, the solution I think would be to just call the subscript inside a subshell:

a.sh
Code:
#!/bin/sh

echofunc() {
    echo "echofunc: $1"
}

echofunc "a 0"
( . ./b.sh; )
echofunc "a 1"

exit 0
b.sh
Code:
#!/bin/sh

echofunc "b 0"
( . ./c.sh; )
echofunc "b 1"

exit 0
c.sh
Code:
#!/bin/sh

echofunc "c 0"
echofunc "c 1"

exit 0
sh a.sh

---- EDIT ----

You might also want to try Shell Script Loader.

You can use the call() function for that.

Last edited by konsolebox; 09-13-2010 at 10:26 AM.
 
Old 09-13-2010, 10:49 AM   #8
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Functions can also be exported in the same way variables can (at least in bash). Just use the -f flag.

export -f functionname

This will make it available to any script run within that shell.

Overall though, I think it's best simply to incorporate everything directly into your script in some way. The more external dependencies you have, the more difficult it will be to keep track of it all in the long run.
 
1 members found this post helpful.
Old 09-13-2010, 09:37 PM   #9
Jerry Mcguire
Member
 
Registered: Jul 2009
Location: Hong Kong SAR
Distribution: RedHat, Fedora
Posts: 201

Original Poster
Rep: Reputation: 31
Quote:
Originally Posted by konsolebox View Post
The output's quite odd. Before you called 'source lv1.sh', did you also replaced 'sh lv2.sh' in lv1.sh with 'source lv2.sh' ?
Yes, you are right. Should be 'source lv2.sh' in lv1.sh.

--
Alias won't be a nice option because it has limitations such as, only the front part is converted. Alias can't do things like 'ls -l $@ | less'.

--
Also, I did put the function echotm in my .bashrc or /etc/bashrc, and export -f echotm. It works.

And then putting common functions in a separate file without hash-bang and exit seem to be working very well too.

Thank you all.

Last edited by Jerry Mcguire; 09-13-2010 at 09:40 PM.
 
Old 09-13-2010, 11:16 PM   #10
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
Quote:
Originally Posted by David the H. View Post
Functions can also be exported in the same way variables can (at least in bash). Just use the -f flag.

export -f functionname

This will make it available to any script run within that shell.
Only that he needed something that will resolve with the exit builtin. Also, the return builtin might have also been a better alternative (wrapped inside a function).
Quote:
Overall though, I think it's best simply to incorporate everything directly into your script in some way. The more external dependencies you have, the more difficult it will be to keep track of it all in the long run.
Well there may still be some coders that will instead prefer not to place all codes in one script.. especially when the size of the code is large. Dependencies may be made less of a problem if you leave them independent and stable. It may also be easy to track them if they are organized, and that the names and codes are written.. uniformly.

I somehow remember something similar with this conversation. It was quite an odd event of the past .
 
Old 09-13-2010, 11:27 PM   #11
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
Quote:
Originally Posted by Jerry Mcguire View Post
Yes, you are right. Should be 'source lv2.sh' in lv1.sh.
Huh? What I meant is if you did as the output implies that.. you did. So with your answer, does it mean that you didn't?

Quote:
Also, I did put the function echotm in my .bashrc or /etc/bashrc, and export -f echotm. It works.

And then putting common functions in a separate file without hash-bang and exit seem to be working very well too.

Thank you all.
I'm curious of the oddity but nevermind. Good thing your problem's already solved.
 
Old 09-14-2010, 02:36 AM   #12
Jerry Mcguire
Member
 
Registered: Jul 2009
Location: Hong Kong SAR
Distribution: RedHat, Fedora
Posts: 201

Original Poster
Rep: Reputation: 31
I did the lv1-lv2-test one machine, and then re-type the output in LQ on another machine, which is why.

----

why odd?

Method 1:

~/.bashrc:
Code:
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

# User specific aliases and functions
echo2 () {
        echo hello world
}
export -f echo2
a.sh:
Code:
#!/bin/sh
echo2
exit 0
execution:
Code:
$ sh a.sh
hello world
Method 2:

~/common_func:
Code:
echo3 () {
        echo good day
}
b.sh:
Code:
#!/bin/sh
source $HOME/common_func
echo3
exit 0
execution:
Code:
$ sh b.sh
good day
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Global Expressions using Vi and Shell Scripting metallica1973 Linux - General 4 08-02-2010 08:39 PM
[SOLVED] BASH: Global Variables carolflb Linux - Newbie 4 01-23-2010 07:55 AM
LXer: Terminal functions for shell scripting with Shell Curses LXer Syndicated Linux News 0 03-26-2008 11:50 PM
SHELL scripting/ shell functions mayaabboud Linux - Newbie 6 12-26-2007 08:18 AM
about shell scripts global variables nesta Programming 2 01-05-2007 12:32 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:23 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration