Asterisk 13.22.0 - SHELL() function - does not pass multiple Asterisk variables

1.5k views Asked by At

I've given up trying to use system() to call BASH scripts with parameters from Asterisk 13.

Turned out under Asterisk 13.22.0 System() DOES work, but only if you do NOT attempt to pass any parameters to the called script.

This works, and reliably calls the script:

same=>n,System(/bin/bash /usr/src/bash/setData.sh)

However, the moment you do this:

same=>n,System(/bin/bash /usr/src/bash/setData.sh ${CHANNEL(accountcode)})

you get

WARNING[30982][C-00000238] app_system.c: Unable to execute '/usr/src`/bash/setData.sh'`

I therefore tried to use SHELL() to do what I was trying to do with SYSTEM().

This also does not work, as SHELL() apparently can only ever parse ONE asterisk parameter in the string sent to it. All the rest are sent as blank.

If I do this:

same=>n,Set(nothing=${SHELL(/usr/src/verdi/bash/verdiLogIncomingCall.sh NA 201807270838t49hgzs SIP/centra-out-00006d9a IN SIP/3027-00006db1 SIP/3027-00006db1 ApiLogIncomingCall.java 1)})

The script sees, on dialplan execution:

[root@acasterisk bash]# cat passed_param.txt
http://127.0.0.1/api/logIncomingCall?account_reference=NA&call_reference=201807270838t49hgzs&originating_channel_id=SIP/centra-out-00006d9a&direction=IN&requested_endpoint=SIP/3027-00006db1&caller_id=SIP/3027-00006db1&sourced_from=ApiLogIncomingCall.java&successfully_sent_to_server=1
[root@acasterisk bash]#

E. g. all params present - because no variable references need to be parsed.

If I use this:

[macro-verdianswer]
exten=>s,1,NoOp(Entering Verdi answer macro - picked up by ${CHANNEL}) 
same=>n,NoOp(Source Channel: ${sourceChannel}) 
same=>n,NoOp(Answering Channel: ${CHANNEL}) 
same=>n,NoOp(Lodging CDR accountcode: ${curIncAccCode} as an incoming call from ${numbersource} with VerDi and answered by ${CHANNEL}...)
same=>n,Set(CHANNEL(accountcode)=${curIncAccCode})
same=>n,Set(nothing=${SHELL(/usr/src/verdi/bash/verdiLogIncomingCall.sh NA ${curIncAccCode} ${sourceChannel} IN ${CHANNEL} ${numbersource} ApiLogIncomingCall.java 1)})
same=>n,MacroExit()

giving this on exection:

-- SIP/3002-000070c2 answered SIP/centra-out-000070bf
    -- Executing [s@macro-verdianswer:1] NoOp("SIP/3002-000070c2", "Entering Verdi answer macro - picked up by SIP/3002-000070c2") in new stack
    -- Executing [s@macro-verdianswer:2] NoOp("SIP/3002-000070c2", "Source Channel: SIP/centra-out-000070bf") in new stack
    -- Executing [s@macro-verdianswer:3] NoOp("SIP/3002-000070c2", "Answering Channel: SIP/3002-000070c2") in new stack
    -- Executing [s@macro-verdianswer:4] NoOp("SIP/3002-000070c2", "Lodging CDR accountcode: 2018072709061hrriyu
    --  as an incoming call from xxxxxxxxxx with VerDi and answered by SIP/3002-000070c2...") in new stack
    -- Executing [s@macro-verdianswer:7] Set("SIP/3002-000070c2", "nothing=Incoming call NOT stored. Contact software support.
    -- ") in new stack

e. g. my variables ARE populated, and if I NoOp them, they have values.

In this situation, the script called via SHELL() sees:

[root@acasterisk bash]# cat passed_param.txt http://127.0.0.1/api/logIncomingCall?account_reference=NA&call_reference=2018072709061hrriyu&originating_channel_id=&direction=&requested_endpoint=&caller_id=&sourced_from=&successfully_sent_to_server=

E. g. SHELL() apparently only ever parses the FIRST Asterisk variable passed into it as a string, and never parses subsequent variable references.

Can anybody confirm or suggest a solution?

I desperately need to be able to execute external BASH scripts and pass multiple parameters to them, somehow. Nothing that worked in 1.8 for this works in 13...

Thanks!

Stefan

1

There are 1 answers

0
Stefan On

Here is a related question of mine which has the exact same cause and was solved in the exact same way

Ok, this is solved.

Turns out the problem was that one of the variables I was passing to the Asterisk 13.22.0 SHELL() dialplan function contained a linefeed (\n or hex 0x0a) character.

This also happened to be the FIRST variable I was passing in to the call to SHELL().

So it appeared that SHELL was only parsing one parameter - it was - but the REASON it was not parsing the following parameters and evaluating them for Asterisk channel data, was the presence of this trailing \n in the first Asterisk 13.22.0 channel variable I was passing to SHELL().

Solving the problem was straightforward, I just removed the trailing \n from the first Asterisk channel variable passed to SHELL() in Asterisk 13.22.0, and SHELL() started working as expected.

So a germane difference between Asterisk 1.8 and Asterisk 10 / 11 / 12 / 13 for the SYSTEM() and SHELL() applications is apparently that if any parameter references are evaluated in a parameter string passed into SYSTEM() and SHELL(), parsing and evaluation of said SYSTEM() or SHELL() parameter strings stops at the point where a linefeed character is encountered.

So all I had to do was, in my script generating the UUID I was passing in as first parameter - which was breaking SYSTEM() and SHELL() - was to omit the trailing \n.

My script sent the data like this from BASH:

echo $uuid

All I had to do was change this line to

echo -n $uuid

in the UUID generator BASH script.

Once that was done the Asterisk 13.22.0 SYSTEM() and SHELL() dialplan app and dialplan function started behaving and working as they did in Asterisk 1.8.32.3 where the code was originally developed.

So, when working with Asterisk 13 and later, be aware of any linefeeds - especially in parsed and evaluated channel variable references - implied in a parameter string sent to SYSTEM() or SHELL() - apparently they stop parsing and evaluating variables the moment they encounter a \n or linefeed character.

This is NOT true of 1.8.32.3 and below versions of Asterisk, as far as I can determine.

Hope this helps someone.