Summary:ASTERISK-08438: [patch] Shell Dialplan Function, returns output
Reporter:Brandon Kruse (bkruse)Labels:
Date Opened:2006-12-26 14:48:49.000-0600Date Closed:2007-01-07 08:41:29.000-0600
Versions:Frequency of
Environment:Attachments:( 0) 20061228__cut_with_newlines.diff.txt
( 1) func_shell.c
( 2) func_shell.c.new
( 3) func_shell.corydon.c
Description:  -= Info about function 'SHELL' =-


Executes a command as if you were at a shell.

Returns the value from a system command
Example:  Set(foo=${SHELL(echo "bar")})
Example:  Noop(${foo})  will yield "bar"


Thanks to russell and jason for all the help in the world!

If there is anything I can fix, or clean up, please let me know!
Comments:By: Russell Bryant (russell) 2006-12-26 15:12:05.000-0600

1) You need to run pclose() after you are finished reading the output from the program.

2) I would say just delete the .write version all together.  Asterisk will produce its own error messages in the case when a function can't be found.

By: Russell Bryant (russell) 2006-12-26 15:12:28.000-0600

Oh, also, in one place in the help text, you have "Shell()" instead of "SHELL()"

By: Brandon Kruse (bkruse) 2006-12-26 15:23:45.000-0600

thanks russell.....please delete the version up there now.....and I will reload it

i had pclose, i do not know where it went :P

By: Brandon Kruse (bkruse) 2006-12-26 15:33:53.000-0600

func_shell.c.new has your suggested changes russell, thanks again


By: Tilghman Lesher (tilghman) 2006-12-27 18:05:39.000-0600

A couple thoughts:

1) You should remove the tabs from within your log message.
2) Your description contains two lines starting with "Example", although it is clear from the description that there is, in fact, only one example.  I would replace the second with simply spaces.
3) I'm somewhat troubled by the fact that all of your output has a newline appended.  This will make comparing values difficult, as there is no way currently to encode a newline into a dialplan variable.
4) I would additionally like a way to split a multiple line output into its separate component lines.  Perhaps that could be attained with a modification to CUT().
5) Shell commands are sometimes generic, though not always.  It might be advisable to at least acknowledge subtle differences between syntax, depending upon the platform.  See the recent consternation of the developers about the differences between bash linked to sh and dash linked to sh for an example of this.
6) A common error when using shell commands in a multithreaded environment is not making filenames unique enough.  For example, using $$ for the pid does not work well when multiple threads use the same pid.  Some recognition of this in the description might save someone hours of frustration.

By: Brandon Kruse (bkruse) 2006-12-27 19:22:19.000-0600


Thank you so much for the information. I will make these changes to the best
of my ability and upload a new file.

Thanks Again!

By: Tilghman Lesher (tilghman) 2006-12-28 16:02:34.000-0600

One more thought:

If you remove the trailing newline from the last line in the buffer, then the simple case of a single line of output needs no further processing, as you can compare that value very simply.

See CURL() for an example of another dialplan function which does this, for the same reason.

By: Brandon Kruse (bkruse) 2006-12-28 16:26:09.000-0600

thanks corydon, ill get a chance to hack at it tonight, and update you guys with a new one!


By: hristo (hristo) 2007-01-05 05:43:55.000-0600

If I try to run some script (php) in the background SHELL will still wait for it to finish and dialplan execution continues only after the script is done. Is there a way to run some application in the background with SHELL? I don't really care about the output. I'm trying to use it as replacement for "external notify" in VM and it is being called in the 'h' extension.

By: Tilghman Lesher (tilghman) 2007-01-05 07:45:54.000-0600

hristo:  in that case, why not just use the System command with a concluding '&', to place the process in the background?

By: Brandon Kruse (bkruse) 2007-01-05 13:44:34.000-0600

Corydon, thanks for getting to it for me.

If I wanted to do that, I could have not put in the fgets line all together, and just wrote the system command and not read the output. However, this is the normal use of ${SHELL()}

I would just run the system command with & ( I have used this before )

exten => 1,1,Answer()
exten => 1,n,System(php -q yay.php arg1 arg2 &)
exten => 1,n,Noop(sweet, it didnt hang on me.)

${SHELL()} was written with direct intent of being able to read the output.

Hope this helps, thanks corydon.

By: hristo (hristo) 2007-01-05 18:38:17.000-0600

I just wanted to give SHELL() a try and wasn't really aware that it was intentionally designed that way. Thanks!

By: Brandon Kruse (bkruse) 2007-01-05 22:48:18.000-0600

no problem, its designed not exit until it reads EOF.

just use system() instead, you could just take out the while statement with fgets and it would work the way you want :]

By: Tilghman Lesher (tilghman) 2007-01-07 08:41:29.000-0600

Committed, revision 49785.