Written by

Senior Software Engineer
MOD
Question Ashok Kumar Thangavel · Oct 16, 2024

File generation issues while using $ZF(-100 asynchronously

Hello Community,

We use $ZF(-1 synchronous call to generate the pdf files. Now I want to change to asynchronously. So, I use $ZF(-100 with "/ASYNC" function. I use "/ASYNC" directly write $ZF(-100,"/ASYNC","notepad.exe") in windows/linux it throws the <NOTOPEN> error, However If I use $ZF(-100,"/ASYNC /SHELL","notepad.exe") it opens the notepad without issues.

However, I execute the below in Linux system the file is not generated properly. But  $ZF(-2,"/ASYNC /SHELL", " /fop/fop -r -fo ""/grp1/tempXSL-FO.TT.12.xml"" -pdf ""/grp1/tempXSL-FO.TT.12.pdf"" 1>/dev/null 2>""/grp1/tempXSL-FO.TT.12.err"" ") this works

write $ZF(-100,"/ASYNC /SHELL", " /fop/fop -r -fo ""/grp1/tempXSL-FO.TT.12.xml"" -pdf ""/grp1/tempXSL-FO.TT.12.pdf"" 1>/dev/null 2>""/grp1/tempXSL-FO.TT.12.err"" ")

Thanks!

Product version: IRIS 2021.1
$ZV: IRIS for UNIX 2021.1.2

Comments

DC AI Bot · May 26 Bot

$ZF(-100) is intended to replace $ZF(-1) and $ZF(-2) and can run commands synchronously or asynchronously, with or without a shell. /ASYNC means the call returns immediately, and when /ASYNC is used the return code 0 only means the child process was launched; the actual program execution status is unknown. $ZF(-100) also sets $ZCHILD to the PID of the started program. [1][2]

Your <NOTOPEN> when using write $ZF(-100,"/ASYNC","notepad.exe") is consistent with the documented behavior that $ZF(-100) can raise <NOTOPEN> in some error conditions, and the general execution behavior differs depending on whether /SHELL is specified. In particular, on any system, when /SHELL is specified, a command line is created and passed; on Windows, even without /SHELL, a command line is created and passed. [1]

For shell commands, InterSystems shows that you should use /SHELL, and for asynchronous shell commands the documented pattern is like:

do $zf(-100,"/shell /async","mkdir","c:\temp\x")

So using /ASYNC /SHELL for shell-style execution is the documented usage pattern. [3][2]

For your Linux PDF-generation case, the most relevant documented point is that with /ASYNC, output is not displayed and you do not get the program’s completion status back from $ZF(-100). If you need to understand why the file is not being generated properly, the documentation recommends I/O redirection with /STDOUT and /STDERR, and also /LOGCMD to log the exact constructed command line. [2][3]

A documented way to troubleshoot this is to redirect standard output and standard error to files, for example by using /STDOUT=... and /STDERR=.... The docs state that these keywords create the files if they do not exist and truncate them if they do exist; += appends instead. To send both standard output and standard error to the same file, specify the same file for both keywords. [2]

Using shell redirection syntax such as 1>/dev/null 2>... inside the command string is shell-dependent, while $ZF(-100) already provides built-in redirection keywords /STDOUT and /STDERR. For an asynchronous command, the documented example for collecting errors is:

set status = $ZF(-100,"/ASYNC /STDERR+=""temp.txt""","cat","nosuch.file")

and then inspect the redirected file afterward. [2]

To see the exact command line InterSystems builds, use /LOGCMD; this sends the program command and arguments to the messages log. [2]

The docs also show that arguments should be passed as comma-delimited arguments or via an argument array, for example:

SET args=2
SET args(1)="-01"
SET args(2)="myfile.c"
SET status = $ZF(-100,"/ASYNC", "gcc",.args)

and the args parameter supports a local array with indirection .args. [1]

So for your case, the documented direction would be:

  1. Keep using $ZF(-100) instead of $ZF(-2) or $ZF(-1). [1]
  2. Use /ASYNC /SHELL if you are executing through the shell. [3][2]
  3. Pass arguments in the supported $ZF(-100) argument style rather than relying only on embedded shell redirection syntax. [1][2]
  4. Add /LOGCMD and use /STDOUT= and /STDERR= files so you can verify the actual generated command and capture any runtime errors from FOP. [3][2]

Note: The search results did not include a source that specifically explains why your exact FOP command works with $ZF(-2) but not with $ZF(-100), so the safe conclusion from the available material is that $ZF(-100) should be used with its documented argument passing and redirection features, and that /LOGCMD, /STDOUT, and /STDERR are the supported ways to diagnose the asynchronous failure. [3][2]


Sources:

Tell us more:
Don't like the style
Not factually correct
Didn't fully follow instructions
Refused when it shouldn't have
Being lazy
More...
Submit
0 0