[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Functions in shell scripts

Posted on 2006-05-02
8
Medium Priority
?
296 Views
Last Modified: 2012-05-05
I'm writing a script which is becoming a little on the lengthy side for easy management (>100 lines).  Instead of having half-a dozen nested IFs, I've chosen to use a sequence of single-level IFs and a few control variables that are set during the IFs.

However, I don't want to have to trawl through all these IFs to be able to edit the main body of the program.  I can use a function, but this still has to be defined before it's used.

Is there any way I can push this stuff down to the bottom of the script somewhere and leave me with all the nice stuff at the top to edit?

Thanks,
Steve :)
0
Comment
Question by:sda100
8 Comments
 
LVL 34

Expert Comment

by:PsiCop
ID: 16592129
Put the function in a different file, e.g. function.sh

Then in your script, include that file:

. function.sh

or

source function.sh
0
 
LVL 23

Expert Comment

by:Mysidia
ID: 16592206
You can define the function later than it appears in the file by using a 2-iteration loop.

The important thing to keep in mind, is that in shell script language, defining a function
is a runtime action;  the order in the file doesn't matter, just as long as the function definition
is run before the call is run, in the script.

I.E.


for PASS in  1 2 ;
do
  if [ $PASS -eq 2 ]  ; then        
         myfunction
  fi

  if [ $PASS -eq 1 ]  ; then        
      myfnuction() {
         statement1
         statement2
      }
  fi
done
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 16594393

. $0
if [ "$got_functions" -eq 1 ]; then
  # main code
fi
exit

got_functions=1
function f {
 # ..
}


you also could avoid the if condition by using $SHELL or alike, but that depends on the used shell and the shell's flavoiur on your platform, inshort: no general solution possible
0
Transaction-level recovery for Oracle database

Veeam Explore for Oracle delivers low RTOs and RPOs with agentless transaction log backup and transaction-level recovery of Oracle databases. You can restore the database to a precise point in time, even to a specific transaction.

 
LVL 35

Expert Comment

by:Duncan Roe
ID: 16594520
Define all your functions at the start of the script. Have a main() function first, which calls all the others in turn. The last line of your script (the only line that isn't part of a function definition) should be:
  main "$@"
You think >100 lines is long? With scripts arranged as above, you'll soon think scripts < 1000 lines are short :)
0
 
LVL 9

Author Comment

by:sda100
ID: 16594715
Thanks duncan_roe

I think I'm with you... can you give me a short example please?

Steve :)
0
 
LVL 35

Expert Comment

by:Duncan Roe
ID: 16600950
Hi sda100 - I don't use that pardadigm myself usually but I'm working on converting one of my scripts for you as an example.
Is taking too long just now (8AM) but will complete and post tonight
0
 
LVL 35

Accepted Solution

by:
Duncan Roe earned 2000 total points
ID: 16604042
Ok, here is my sfl script as posted in answer to previous qns, but factored into functions. Hope you find it helpful:

#!/bin/sh
#set -x

# Runs the show
main()
{
  try_gnu_args
  set_personality || exit 1

# Had to inline the next bit, coz it uses shift & args are local to functions
if [ -z "$1" ];then
  echo "Usage: $j <string> [<grep option>,...]" >&2
  exit 1
else
  k="$1"
  shift
fi

do_the_grep "$@"
}

# Sets fiddly gnu arg iff we have gnu grep
try_gnu_args()
{
  grep --version >/dev/null 2>&1
  [ $? -eq 0 ] && n=-noleaf || n=
}

# Check for good invocation.
# sfl is designed to be symlinked to - which synlink is used determines behaviour.
# list of symlinks:
# lrwxrwxrwx  1 dunc users    3 2004-09-30 22:12 afl -> sfl
# lrwxrwxrwx  1 dunc users    3 2004-09-30 22:12 aflc -> sfl
# lrwxrwxrwx  1 dunc users    3 2004-09-30 22:12 afll -> sfl
# lrwxrwxrwx  1 dunc users    3 2004-09-30 22:12 afllc -> sfl
# -rwxr-xr-x  1 dunc users 1183 2006-05-04 07:59 sfl
# lrwxrwxrwx  1 root root     3 2004-09-30 22:12 sflc -> sfl
# lrwxrwxrwx  1 root root     3 2004-09-30 22:12 sfll -> sfl
# lrwxrwxrwx  1 root root     3 2004-09-30 22:12 sfllc -> sfl
# lrwxrwxrwx  1 root root     3 2004-09-30 22:12 ufl -> sfl
# lrwxrwxrwx  1 root root     3 2004-09-30 22:12 uflc -> sfl
# lrwxrwxrwx  1 root root     3 2004-09-30 22:12 ufll -> sfl
# lrwxrwxrwx  1 root root     3 2004-09-30 22:12 ufllc -> sfl
set_personality()
{
  j=`basename $0`
  case $j in
  u*)
    f='.. -maxdepth 2 -mindepth 2'
    w=w
    ;;
  s*)
    f=.
    w=w
    ;;
  a*)
    f=.
    w=""
    ;;
  *)
    echo bad symlink of sfl to $j
    return 1
    ;;
  esac
  case $j in
  ?fl)
    i=''
    ;;
  ?fll)
    i=''
    f="$f -follow"
    ;;
  ?flc)
    i=i
    ;;
  ?fllc)
    i=i
    f="$f -follow"
    ;;
  *)
    echo bad symlink of sfl to $j
    return 1
    ;;
  esac
  return 0
}

# Actually do the gep
do_the_grep()
{
  find $f $n -depth -type f \( \
    -name "*.c" \
    -o -name "*.cpp" \
    -o -name "*.cxx" \
    -o -name "*.cc" \
    -o -name "*.f" \
    -o -name "*.for" \
    -o -name "*.S" \
    -o -name "*.h" \
    -o -name "*.java" \
    -o -name "*.exp" \
    -o -name "*.tcl" \
    -o -name "*.expect" \
    -o -name "*.pl" \
    -o -iname "makefile" \
    -o -name "make-file" \
    -o -name "*.i" \
    -o -name "*.l" \
    -o -name "*.lex" \
    -o -name "*.y" \
    -o -name "*.yacc" \
    -o -name "*.sh" \
    \) -print|xargs -n 32 -r -e grep -${i}s${w}n "$@" -- "$k" /dev/null
}
main "$@"
0
 
LVL 9

Author Comment

by:sda100
ID: 16610395
Thank you very much.  Long example, but I like it... and now I know what you mean by the main "$@" at the end.

Steve :)
0

Featured Post

Get free NFR key for Veeam Availability Suite 9.5

Veeam is happy to provide a free NFR license (1 year, 2 sockets) to all certified IT Pros. The license allows for the non-production use of Veeam Availability Suite v9.5 in your home lab, without any feature limitations. It works for both VMware and Hyper-V environments

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

How many times have you wanted to quickly do the same thing to a list but found yourself typing it again and again? I first figured out a small time saver with the up arrow to recall the last command but that can only get you so far if you have a bi…
If you have a server on collocation with the super-fast CPU, that doesn't mean that you get it running at full power. Here is a preamble. When doing inventory of Linux servers, that I'm administering, I've found that some of them are running on l…
Learn how to find files with the shell using the find and locate commands. Use locate to find a needle in a haystack.: With locate, check if the file still exists.: Use find to get the actual location of the file.:
Connecting to an Amazon Linux EC2 Instance from Windows Using PuTTY.
Suggested Courses
Course of the Month18 days, 18 hours left to enroll

834 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question