Question

im trying to get a bash to pass argument to another bash, I manged to do this by sourcing one of the and calling it from the other so they would be parent and child under the same shell. the problem is that the child is a loop becuase im traying to catch events (it might be reading a fifo(pipefile)) and this blocked the bash... right, so i tought hmmm let's try running the bash on the back ground and the problem i get here i guess is that the variables dont come int becuase i guess it is not under the same shell i tried sourcing and backgounding that but no possitive results...

also at some point with testing my shell starts going crazy when i send to fifo(pipe file) even if nothing (that i know is reading) it acts as if something had read that fifo, and some of my other bash screens start doing crazy stuff... :O

anyway was wondering if anyone can help me. Dont know if what im trying to do is even possible... Thanks.

DOnt know where i read (haven been able to find the page again, yet) that moveing script to the background makes it accesible to parent and child, subprocess and its the papas mamas, but that's not my experience up to now.

bash1

   #!/bin/bash

    while true
    do

    . ./bash2.sh &

    if [[ $VARIABLE = 1 ]]; then
    echo "message recevied"
    fi

bash2

  #!/bin/bash

    while true
    do

    if [[ $(cat ./fifo1) = 0 ]]; then
    VARIABLE=1
    fi
    done

Thanks

Was it helpful?

Solution

Because & always starts a new process, there is little difference between

. ./bash2.sh &

and

# Assuming bash2.sh is executable
./bash2.sh &

Any variables defined by bash2.sh are confined to the process that executes it; they are not available to bash1.sh. Your choices are

  1. Run . ./bash2.sh in the foreground, and wait for it to complete
  2. Have ./bash2.sh write to something (a file, named pipe, etc) which bash1.sh can read from.

OTHER TIPS

Well you are close, but you have a few errors in the provided examples. Firstly you don't need the While loop in either script as it does not serve a purpose in the code examples you provided so I omitted them from my examples.

Example 1

#!/bin/bash

external_function(){
   echo "This is printed from the sourced script"; 
   [ -e ./fifo1 ] && return $TRUE || return $FALSE
}

Example 2

#!/bin/bash

source ./test.sh
external_function && echo "the file exists" || echo "The file doesn't exist" 
exit

What you are doing is using the . (source or dot operator) which will read and execute commands from the filename argument in the current shell context.

Syntax

  . filename [arguments]

  source filename [arguments]

When a script is run using source it runs within the existing shell, any variables created or modified by the script will remain available after the script completes. In contrast if the script is run just as filename, then a separate subshell (with a completely separate set of variables) would be spawned to run the script.

This means you do NOT want to use the & to fork the second script to a new process as it will never return to the main script.

Also I typically will put the code I wish to run in the second (sourced) script in a function. I think it makes it easier to read and you can use this to check return codes from the function which makes debugging much easier.

And lastly if [[ $(cat ./fifo1) = 0 ]] is merely checking for existence as you are checking the exit status of the cat command. You can simply this with the line below:

[ -e / ] && return $TRUE || return $FALSE

-e is a bash File Test Operator that checks for a FILE's existence.

&& is a bash Operator that will run the following command if the last command returned a successfully exit code (not zero)

|| is a bash Operator in that will run the following command if the last command returned an failed exit code (zero)

Further Reading:

I use this reference for bash alot and I think it is worth mentioning

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top