Calling Bash Functions in the BG


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Calling Bash Functions in the BG
# 1  
Old 07-08-2016
Calling Bash Functions in the BG

I'm trying to call some functions in the background so that I can multitask in this script. Not working so hot. The functions I call don't ever seem to get called. I'm doing it the exact same way in another script and it's working like a champ so I'm very confused. Here's a pretty simple repro:

Code:
#!/bin/bash
 AT1="machine1"
AT2="machine2"
CM2=""
CM="machine4"
 check_background()
{
  # loop to check that background jobs finish
  WAIT_COUNT=0
  JOBS_COUNT="$(jobs -pr)"
  while [ "${JOBS_COUNT}" ]
  do
    let "WAIT_COUNT=${WAIT_COUNT}+1"
    if [ ${WAIT_COUNT} -gt 60 ]
    then
        echo "Waited 5 minutes for jobs to complete killing old jobs"
        kill $(jobs -pr)
        echo "Waiting 30 seconds to ensure validation is sucessful"
        sleep 30
    fi
    sleep 5
    JOBS_COUNT="$(jobs -pr)"
    NUMBER_JOBS=$(echo ${JOBS_COUNT} | wc -w | tr -d '[:space:]')
    echo -e "${NUMBER_JOBS} background jobs running, waiting 5 minutes (300 seconds) for them to complete"
    echo -e "Time Elapsed: $(( ${WAIT_COUNT} * 5 )) seconds\n"
  done
}
 app_background_stop ()
{
  SERVER=$1
  NUM_CK=$2
  echo "Server: ${SERVER} Num: ${NUM_CK}"
  sleep 30
}
app_stop ()
{
  #Stop all the at1 servers
  for at1_server in ${AT1}
  do
     app_background_stop ${AT1} 1 > /dev/null 2>&1 &
  done
  
  #Stop all the at2 servers
  for at2_server in ${AT2}
  do
      app_background_stop ${AT2} 2 > /dev/null 2>&1 &
  done
  
  #Stop all the backup cm servers
  for cm2_server in ${CM2}
  do
      app_background_stop ${CM2} 3 > /dev/null 2>&1 &
  done
  
  #Sleep a bit so the jobs have time to get started
  sleep 5
  
  check_background
  
  #Stop the primary CM
  app_background_stop ${CM} 4 > /dev/null 2>&1 &
}
 #Main routine
app_stop

And the results when I run it in debug:

Code:
$ bash -x ./test.sh
+ AT1=machine1
+ AT2=machine2
+ CM2=
+ CM=machine4
+ app_stop
+ for at1_server in '${AT1}'
+ for at2_server in '${AT2}'
+ app_background_stop machine1 1
+ sleep 5
+ app_background_stop machine2 2
+ check_background
+ WAIT_COUNT=0
++ jobs -pr
+ JOBS_COUNT='25429
25430'
+ '[' '25429
25430' ']'
+ let WAIT_COUNT=0+1
+ '[' 1 -gt 60 ']'
+ sleep 5
++ jobs -pr
+ JOBS_COUNT='25429
25430'
++ echo 25429 25430
++ wc -w
++ tr -d '[:space:]'
+ NUMBER_JOBS=2
+ echo -e '2 background jobs running, waiting 5 minutes (300 seconds) for them to complete'
2 background jobs running, waiting 5 minutes (300 seconds) for them to complete
+ echo -e 'Time Elapsed: 5 seconds\n'
Time Elapsed: 5 seconds
 + '[' '25429
25430' ']'
+ let WAIT_COUNT=1+1
+ '[' 2 -gt 60 ']'
+ sleep 5
++ jobs -pr
+ JOBS_COUNT='25429
25430'
++ echo 25429 25430
++ wc -w
++ tr -d '[:space:]'
+ NUMBER_JOBS=2
+ echo -e '2 background jobs running, waiting 5 minutes (300 seconds) for them to complete'
2 background jobs running, waiting 5 minutes (300 seconds) for them to complete
+ echo -e 'Time Elapsed: 10 seconds\n'
Time Elapsed: 10 seconds
 + '[' '25429
25430' ']'
+ let WAIT_COUNT=2+1
+ '[' 3 -gt 60 ']'
+ sleep 5
++ jobs -pr
+ JOBS_COUNT='25429
25430'
++ echo 25429 25430
++ wc -w
++ tr -d '[:space:]'
+ NUMBER_JOBS=2
+ echo -e '2 background jobs running, waiting 5 minutes (300 seconds) for them to complete'
2 background jobs running, waiting 5 minutes (300 seconds) for them to complete
+ echo -e 'Time Elapsed: 15 seconds\n'
Time Elapsed: 15 seconds
 + '[' '25429
25430' ']'
+ let WAIT_COUNT=3+1
+ '[' 4 -gt 60 ']'
+ sleep 5
++ jobs -pr
+ JOBS_COUNT='25429
25430'
++ echo 25429 25430
++ wc -w
++ tr -d '[:space:]'
+ NUMBER_JOBS=2
+ echo -e '2 background jobs running, waiting 5 minutes (300 seconds) for them to complete'
2 background jobs running, waiting 5 minutes (300 seconds) for them to complete
+ echo -e 'Time Elapsed: 20 seconds\n'
Time Elapsed: 20 seconds
 + '[' '25429
25430' ']'
+ let WAIT_COUNT=4+1
+ '[' 5 -gt 60 ']'
+ sleep 5
++ jobs -pr
+ JOBS_COUNT=
++ echo
++ wc -w
++ tr -d '[:space:]'
+ NUMBER_JOBS=0
+ echo -e '0 background jobs running, waiting 5 minutes (300 seconds) for them to complete'
0 background jobs running, waiting 5 minutes (300 seconds) for them to complete
+ echo -e 'Time Elapsed: 25 seconds\n'
Time Elapsed: 25 seconds
 + '[' '' ']'
+ app_background_stop machine4 4

Any ideas?

Thanks,
Eric
# 2  
Old 07-08-2016
How about replacing this...

Code:
     app_background_stop ${AT1} 1 > /dev/null 2>&1 &

...with this for debugging:

Code:
      app_background_stop ${AT1} 1 > /tmp/${AT1} 2>&1 &

...and checking /tmp/${AT1} ?

And you can omit the file descriptors 0 and 1 - they are default. 0 for input redirection and 1 for output redirection.
# 3  
Old 07-08-2016
I changed the code to:

Code:
#!/bin/bash
 AT1="machine1"
AT2="machine2"
CM2=""
CM="machine4"
 check_background()
{
  # loop to check that background jobs finish
  WAIT_COUNT=0
  JOBS_COUNT="$(jobs -pr)"
  while [ "${JOBS_COUNT}" ]
  do
    let "WAIT_COUNT=${WAIT_COUNT}+1"
    if [ ${WAIT_COUNT} -gt 60 ]
    then
        echo "Waited 5 minutes for jobs to complete killing old jobs"
        kill $(jobs -pr)
        echo "Waiting 30 seconds to ensure validation is sucessful"
        sleep 30
    fi
    sleep 5
    JOBS_COUNT="$(jobs -pr)"
    NUMBER_JOBS=$(echo ${JOBS_COUNT} | wc -w | tr -d '[:space:]')
    echo -e "${NUMBER_JOBS} background jobs running, waiting 5 minutes (300 seconds) for them to complete"
    echo -e "Time Elapsed: $(( ${WAIT_COUNT} * 5 )) seconds\n"
  done
}
 app_background_stop ()
{
  SERVER=$1
  NUM_CK=$2
  echo "Server: ${SERVER} Num: ${NUM_CK}"
  sleep 30
}
app_stop ()
{
  #Stop all the at1 servers
  for at1_server in ${AT1}
  do
     app_background_stop ${AT1} 1 > /tmp/test.out 2>&1 &
  done
  
  #Stop all the at2 servers
  for at2_server in ${AT2}
  do
      app_background_stop ${AT2} 2 > /tmp/test2.out 2>&1 &
  done
  
  #Stop all the backup cm servers
  for cm2_server in ${CM2}
  do
      app_background_stop ${CM2} 3 > /tmp/test3.out 2>&1 &
  done
  
  #Sleep a bit so the jobs have time to get started
  sleep 5
  
  check_background
  
  #Stop the primary CM
  app_background_stop ${CM} 4 > /tmp/test4.out 2>&1 &
}
 #Main routine
app_stop

The 3 files that got created had in them:

Quote:
$ cat test.out
Server: machine1 Num: 1
$ cat test2.out
Server: machine2 Num: 2
$ cat test4.out
Server: machine4 Num: 4
So it did go in there. Just didn't do what I expected it to do in the non-repro version of this script. Gotcha, thanks!

By "omit file descriptors 0 and 1", do you mean:

app_background_stop ${AT1} 1 > /tmp/${AT1} 2> &

Or just:

app_background_stop ${AT1} 1 2> &

(e.g. > is file descriptor 0 and &1 is file descriptor 1)?

Thanks for the help!
# 4  
Old 07-08-2016
That's what I meant:

Code:
 app_background_stop ${AT1} >/tmp/${AT1} 2>&1 &

Sorry. Redirect target &1 can not be abbreviated to &.

Or another example:

Code:
command 0<input.txt 1>output.txt 2>&1

...is the same as...

Code:
command <input.txt >output.txt 2>&1

# 5  
Old 07-08-2016
... which is equivalent to
Code:
command <input.txt &>output.txt

# 6  
Old 07-08-2016
The & isn't for redirect, it's to background the function call so that I can do multiple function calls without waiting for each other. So what I'm trying to accomplish is:

Code:
my_function ${arg1} ${arg2} &

So that the script keeps moving forward while my_function is being run. Is that not happening here? Sorry if I'm being slow...
# 7  
Old 07-08-2016
What you are doing is quite fine. As I've understood you got further with your problem. So the redirect thing is just additional information for a better basic understanding and not your main task.

These are different kind of things:
  • & run in background
  • >&2 redirect STDOUT to the same location as STDERR
  • &> redirect all open output file descriptors, to the target that's following

Last edited by stomp; 07-08-2016 at 03:29 PM..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Bash functions sequence ?

OK, I know function has to be defined first - in sequence - before it can be used. So the script has to be build "bottoms -up style, if you pardon my expression. I am running into a problem reusing function and breaking the sequence. It would be nice to be able to see the function... (10 Replies)
Discussion started by: annacreek
10 Replies

2. Shell Programming and Scripting

Bash calling a few functions syntax error

In the bash function below if the user selets "y" then the menu function is called and if they select "n" the move function is called. That all seems to work, my question is after the files are moved an echo, line in bold is displayed and another function called backup is called. I am getting a... (1 Reply)
Discussion started by: cmccabe
1 Replies

3. AIX

Calling functions from main program from dlopened library function

Hello All, I am trying to call a function from the calling main program from a dlopened library function, below is the entire code, when I execute it it crashes with sigill. Can you guys help me out I guess I am missing out on the linker flag or something here. besides I am new to AIX and... (1 Reply)
Discussion started by: syedtoah
1 Replies

4. Shell Programming and Scripting

functions and variables in bash

I have a bash script with some functions as below and am wondering if I can use the variables declared in setup in the other functions and in the rest of the bash script. setup(){ none=0; low=1; medium=2; high=3; debug=4 var1="red" var2="fred" } create_basemap() { ... (7 Replies)
Discussion started by: kristinu
7 Replies

5. Shell Programming and Scripting

Calling multiple functions in parallel

Hello, I have multiple functions within a shell script. eg. function_database_backup, unix_tar_creation, etc. I would like to run these functions in parallel, as each is independent of the other. If these were simple commands, I could have probably run each of the commands in background. ... (1 Reply)
Discussion started by: neil.k
1 Replies

6. Shell Programming and Scripting

Is it possible make the shell read functions 1 by 1 and calling an other function?

Greetings, I m wondering if it's possible do do the following : I have a simple function called "FindMoveDelete" which does the following : FindMoveDelete() { find . -iname "$FILENAME*.ext" -exec mv {} "$PATH/$VAR" \; && find . -maxdepth 1 -type d -iname "$FILENAME*" -exec rm -rf {}... (6 Replies)
Discussion started by: Sekullos
6 Replies

7. Shell Programming and Scripting

bash functions arguments

This script is called fuu; #!/bin/bash speak() { case $1 in 1)echo one ;; 2)echo two ;; 3)echo three ;; esac } speak exit 0 when i run fuu 2 i expect "two" like... (2 Replies)
Discussion started by: Tártaro
2 Replies

8. Shell Programming and Scripting

Mathematical functions in bash shell

Hi, How can i do the mathematical calculations in bash shell? Are the mathematical functions available in bash shell? Ex: pow ceil floor sqrt (5 Replies)
Discussion started by: cola
5 Replies

9. Shell Programming and Scripting

Calling Functions of Other K Shell Program

Hi, I have a K shell a.ksh function abc { // Some logic } In b.ksh i have included the a.ksh ./a.ksh I want to call the abc function from this b.ksh script. Thanks Vijay (2 Replies)
Discussion started by: vijaykrc
2 Replies

10. Shell Programming and Scripting

Calling functions in scripts directly

Hi, I have a menu driven script that does various tasks, I want to be able to call functions directly from within other unix scripts from my menu script. Is this possible? (12 Replies)
Discussion started by: LiquidChild
12 Replies
Login or Register to Ask a Question