Search code examples
shellasteriskquotessingle-quotes

How to echo variable input into a file


I need to invoke a shell call from Asterisk dialplan in order to log some data to a text file, so I tried this:

Set(log=[${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)}] [${UNIQUEID}] ${ARG1})
SYSTEM(echo "${log}" >> /var/log/asterisk/log.txt)

(No assumptions can be made about the contents of ARG1. It may contain single quotes, double quotes, ampersands, or any other characters.)

This seemed to work, but I recently found calls that had & in their caller ID were being dropped as soon as they entered the switch because the function crashed and the call dropped.

I tried replacing double quotes in the echo statement with single quotes, but if the caller ID name contains a single quote, the function will not crash but it does not echo anything at all.

Here is my dilemma:

  • I cannot escape anything (at least manually). ARG1 is variable per call, and could be literally anything. As such, this isn't a static string where I can simply escape quotes.
  • I cannot use a HEREDOC, which is what seems to be the recommended approach. I am invoking a shell call using SYSTEM() which gives me one shot to execute shell code. I can't have a bunch of separate lines for all that EOF stuff.
  • I don't see how I can pass this into a bash script to do that, either. I would need to get the entire $log variable into a script in order to do the HEREDOC stuff there, and I'll have the same problem as I'm having now - how to get the whole thing there intact, without causing an error.
  • Since this is a single shell call, whatever command or commands I run needs to be a bash one-liner.

The variable log itself does not contain any variables when expanded. Is there any way here to make the echoing work as desired?


Solution

  • Why do you think you "cannot escape anything?" Put the string in single quotes, and all you need to escape is single quotes. This could be done with the REPLACE function.

    Set(log=[${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)}] [${UNIQUEID}] ${REPLACE(${ARG1},','"'"')})
    SYSTEM(echo '${log}' >> /var/log/asterisk/log.txt)
    

    But I think the cleaner solution is to use the FILE function instead.

    FILE(/var/log/asterisk/log.txt,,,a)=${log}