B4J Question jShell, using same shell multiple times

JLock

Member
Licensed User
I wish to use the same shell multiple times as I have a piece of code that relies on exporting environmental variables to linux. I achieve this through running a .sh file. I then run a function that is dependent on these exported variables but it does not work, as it cannot find said variables. I presume this is because every time you refresh a shell in linux it loses all exported variables.

I am using the same shl variable between the two Initialize and runs as I thought this would maintain the shell and the exported variables but this does not seem to be the case. Is there such a way to maintain the exported variables throughout the entirety of my bacRead method? Thanks in advance. All code is shown below.

EDIT: I'm also perplexed as to how jShell interacts with the bash -c command. I've been trying to run "bash -c "export foo=bar; echo \$foo" through the terminal but am not receiving my echo of bar as expected.



B4X:
Sub bacRead(bacDevice As Int, bacType As Int, bacInstance As Int, bacProperty As Int) As String
    Dim shl As Shell
    ' Casting all the input paramters into String as that is how .Initialize requires them
    Dim deviceString As String = bacDevice
    Dim deviceType As String = bacType
    Dim deviceInstance As String = bacInstance
    Dim deviceProperty As String = bacProperty
 
    shl.Initialize("connect", "./bvlc.sh", Array As String("192.168.1.25"))
    shl.WorkingDirectory = "/home/pi/bacnet-stack-0.8.5/bin"
    shl.Run(10000)
    StartMessageLoop
 
    ' Initializing the name as read, command as bacrp and passing the parameters. Parameters can be dynamic.
    shl.Initialize("read", "./bin/bacrp", Array As String(deviceString, deviceType, deviceInstance, deviceProperty))
    ' Setting the working directory. On Linux it must be the bacnet-stack-0.8.x containing bin/bacrp.
    shl.WorkingDirectory = "/home/pi/bacnet-stack-0.8.5"
    ' 10 second timeout
    shl.Run(10000)
    StartMessageLoop
    ' Goes to read_ProcessCompleted on this line before going onwards.
    Dim presentState As String = shl.GetTempOut
    Return(presentState)
    End Sub

' This is automatically called when the process above finishes.
' The bit before the _ (in this case "read") MUST MATCH the first parameter given to the .Initialize function.
Sub read_ProcessCompleted(Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
    ' Stops the thread from tampering with message queue and returns to bacRead()
    If Not(Success And ExitCode = 0) Then
        Log("Error: " & StdErr)
    End If
    StopMessageLoop
    Return
End Sub

Sub connect_ProcessCompleted(Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
    If Not(Success And ExitCode = 0) Then
        Log("Error: " & StdErr)
    End If
    Log("Out: " & StdOut)
    StopMessageLoop
    Return
End Sub
 
Last edited:

OliverA

Expert
Licensed User
Longtime User
1) You'll need to write a third script that wraps the other two scripts. Then you call that script via jShell and pass all (the first and the second script's) parameters to it.
2) Try putting a space between the first period and the first / for your script files, i.e.
B4X:
shl.Initialize("connect", ". /bvlc.sh", Array As String("192.168.1.25"))
shl.Initialize("read", ". /bin/bacrp", Array As String(deviceString, deviceType, deviceInstance, deviceProperty))
instead of
B4X:
shl.Initialize("connect", "./bvlc.sh", Array As String("192.168.1.25"))
shl.Initialize("read", "./bin/bacrp", Array As String(deviceString, deviceType, deviceInstance, deviceProperty))
Source: https://stackoverflow.com/a/28489593
 
Upvote 0

JLock

Member
Licensed User
I ended up creating a Shell file yesterday that effectively ran the commands that both scripts were doing and it seemed to work fine but I haven't tried calling it through jShell yet. It just consists of variable declaration followed by calling both commands via their paths in sequence. Is that what you refer to when you say a third script wrapping the other two?

If/when that inevitably fails I'll use the space after the dot because it seems to be what I require anyway. Thank you for the help.

EDIT: Seems like just writing the two functions into a custom .sh script and then running that via bash achieved what I wanted. If there is something bad about this, please let me know but otherwise it seems fine for the time being.
 
Last edited:
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Upvote 0
Top