docs.intersystems.com
Home  /  Application Development: Language Bindings and Gateways  /  Using the Callout Gateway  /  Issuing Operating System Commands


Using the Callout Gateway
Issuing Operating System Commands
[Back]  [Next] 
InterSystems: The power behind what matters   
Search:  


The $ZF(-1) and $ZF(-2) functions allow you to issue operating systems commands from InterSystems IRIS™. These are the only InterSystems Callout functions that can be used without a special Callout shared library (see Creating an InterSystems Callout Library). The following topics are discussed in this section:
Issuing System Commands with $ZF(-1)
$ZF(-1) permits a command of the host operating system to be invoked. The specified command is executed as a spawned child process from the current console. $ZF(-1) waits for the process to end, and will not allow the parent InterSystems IRIS process to exit while the child process is executing.
After the child process exits, $ZF(-1) returns the exit status code issued by the operating system shell. Possible values are 0 if the function call is successful, 1 if an error occurs, or -1 if a child process could not be spawned.
Windows
On Windows, the following ObjectScript code creates a directory named test folder under the current directory (the extra quotes around the directory name are required in Windows because the name contains a space):
   SET status = $ZF(-1,"mkdir ""test folder""")
UNIX® and related operating systems
The following example executes a pwd command:
   SET status = $ZF(-1,"pwd") 
The shell window displays output similar to the following:
   /usr/cachesys
Note:
In most cases, $ZF(-1) should be used only with commands that have their effect in the background. If a command requires user input (as in the following example, which requires the user to close Notepad), the child process may hang.
The commands in the following example use the default application for .txt files to open the specified file:
Opening a text file with $ZF(-1)
   SET fname="""C:\My Test.txt"""
   WRITE fname,!
   SET status=$ZF(-1,fname)
   WRITE status

///      NOTE: THIS EXAMPLE STARTS A PROCESS THAT WILL NOT RETURN UNTIL YOU
///      CLOSE THE PROGRAM (USUALLY NOTEPAD) THAT OPENS THE TEXT FILE.
Note:
Using $ZF(-1) in the Terminal
$ZF(-1) can also be used load an interactive operating system shell in the Terminal (see Operating System Shells in Using the Terminal). It works just like the ! terminal command except that $ZF(-1) executes in a separate window, while ! works entirely within the Terminal window.
Spawning Concurrent Child Processes with $ZF(-2)
$ZF(-2) executes the specified program as a spawned child process from the current console. It returns immediately after spawning the child process and does not wait for the process to terminate. Input and output devices default to the null device.
Note:
Commands initiated via $ZF(-2) should not perform I/O on the principal device. Typically, InterSystems IRIS equates the principal device to the null device.
$ZF(-2) does not return the child process exit status. Instead, it returns zero if the child process was created successfully, or -1 if a child process could not be forked. $ZF(-2) permits a program invoked from InterSystems IRIS to continue execution even if InterSystems IRIS is terminated.
$ZF(-2) closes the parent process principal device (specified in special variable $PRINCIPAL) before executing the command. This is done because the child process executes concurrently with the parent. If $ZF(-2) did not close $PRINCIPAL, output from the parent and the child would become intermingled. When using $ZF(-2) you should redirect I/O in the command if you wish to recover output from the child process. For example:
   SET x=$ZF(-2,"ls -l > mydir.txt")
If the pathname supplied in progname contains a space character, pathname handling is platform-dependent. UNIX® permits space characters in pathnames, but a pathname containing spaces must be enclosed in double quote (") characters. Windows requires that you either strip out blank spaces, or supply an additional set of quotes around a pathname that contains spaces, as shown in the following examples. With no spaces "C:/MyDocuments"; with spaces ""C:/My Documents"". You can use the NormalizeFilenameWithSpaces() method of the %Library.File class to handle spaces in pathnames as appropriate for the host platform.
Adding the %System_Callout:USE Privilege
If your InterSystems security setting is higher than minimal, both $ZF(-1) and $ZF(-2) require the %System_Callout:USE privilege.
The %System_CallOut resource is already assigned to the %Developer Role, which you will have if you selected the Developer setup during InterSystems IRIS installation. The following sections describe how to assign this resource if you do not already have it:
Assigning a Role to a User
Use the following procedure to assign the %Developer role:
  1. Open the Management Portal, go to [System Administration] > [Security Management] > [Users] and click Edit on the user description you want to use, then select the [Roles] tab.
  2. Move the %Developer role from the Available column to the Selected column and click Assign. The role will appear in the list of roles assigned to this user. (If the %Developer role does not appear in the Available column, check the list of roles to see if you already have this role).
  3. Click the Profile button. The %Developer role should be listed on the Roles: line.
Creating a New Role
In some cases, it may be desirable to have a role that allows use of $ZF(-1) and $ZF(-2) but does not grant any other privileges. Use the following procedure to create a new role that grants only the %System_CallOut:USE privilege:
  1. Open the Management Portal and go to [System Administration] > [Security Management] > [Roles].
  2. Click the Create New Role button to bring up the Edit Roles page.
  3. Fill in the name and description:
    When you click Save, an Add button appears on the form.
  4. Click the Add button to pop up a scrolling list of resources, select %System_CallOut from the list, and click Save. Click Close on the Edit Role form.
  5. On the Roles page, the new UseCallout role is now in the list of role definitions.