|
Using the SAS System with other Programming Languages in the UNIX Environment OUTLINE
1. Abstract
Several features exist in the SAS System that facilitate the
development of powerful and flexible applications in the UNIX
environment. These features allow you to run standalone programs
from the SAS System and invoke the SAS System from standalone
programs. Passing data to and from the SAS System in both scenarios
is explained with detailed examples.
2. Introduction
Customers often call Technical Support and want to access a
standalone program they have written in a language other than SAS.
This paper discusses several options for accessing other programs
from the SAS System in the UNIX environment. Methods for passing
data to and from these programs is explained. Customers may also
want to invoke a SAS application from their standalone program (for
example, a C program). This paper discusses options for accessing
the SAS System from C programs and shell scripts. Methods for
passing data to and from the SAS System are explained.
3. Calling Standalone Programs from the SAS System
If you have a standalone program that you want to execute from
within the SAS System, you have several options. The method you
choose depends on what you want to accomplish. Five methods will be
discussed:
- X statement
- X command
- %SYSEXEC macro
- SYSTEM function in the DATA step or in SCL
- PIPE device type on the FILENAME statement
An explanation will be given later. Before these methods are
discussed, an explanation of return codes is necessary.
3.1 Return Codes
When you execute a UNIX program from within the SAS System, the
return code of the UNIX command is available to the SAS session
unless the command is executed using the PIPE device type. The SAS
System accesses the return code with the wait system call.
The return code is returned in two bytes. The first byte (low order
8 bits) contains information about any UNIX signal that was
received while the command was executing. This byte is usually 0.
The second byte contains the actual return code. For example, if
you executed a command from within the SAS System that exited with
a return code of 1, SAS would receive this information in two
bytes:
00000001 00000000
| | | |
-------- --------
| |
| | first byte contains signal information
|
| second byte contains actual return code
The return code that is available to SAS in this case is 256, not
1, because the return code is shifted to the left 8 bits. If the
command you are executing is not terminated with a signal, the
return code is always n*256 where n is the actual return code (or
exit status) of the program. The following table illustrates return
code values.
exit return
status code two bytes
-------+--------+------------------
0 | 0 | 00000000 00000000
1 | 256 | 00000001 00000000
2 | 512 | 00000010 00000000
3 | 768 | 00000011 00000000
4 | 1024 | 00000010 00000000
.
.
.
You should always divide the return code by 256 to get the actual
exit status of your programs unless your program was terminated
with a signal.
A program is terminated with a signal if its return code is greater
than 0 and less than 256. The return code is equivalent to the
signal that was sent to the program. For example, the following SAS
statements submit the sleep command for 35 seconds, then print the
return code to the SAS log:
x 'sleep 35';
%put &SYSRC;
From another window, ascertain the process id of the sleep command
and specify it in the following UNIX command:
kill -SIGINT <process id>
The return code will be the integer equivalent to the interrupt
signal (SIGINT).
Signals and their corresponding integer values are defined in the
following header file:
/usr/include/sys/signal.h
3.2 The X Statement
The X statement is a convenient way to unconditionally execute a
UNIX command from within a SAS program or SCL program. For example,
if you wanted to remove the directory and all files in the
directory /tmp/sasjob, you could put the following statement at the
beginning of your SAS program:
x 'rm -r /tmp/sasjob';
%put "The return code is &SYSRC";
The X statement is not itself a conditional statement. In the
following example, the X statement will always execute.
data _null_;
sasvar=0;
if sasvar=1 then do;
x 'echo "this statement will always execute"';
end;
run;
You can make the X statement "conditional" by embedding your SAS
program in a macro. For example,
/*
* macro definition
*/
%macro cond(makedir);
%if &makedir = true %then %do;
x 'rm -r /tmp/sasjob';
%let rc = %eval(&SYSRC/256);
%if &rc = 0 %then %do;
%put rm -r /tmp/sasjob successful;
%end;
%else %do;
%put rm -r /tmp/sasjob failed with rc=&rc;
%end;
%end;
%mend;
/*
* macro invocation
*/
%cond(true);
The advantage to this method is that you don't need to have the
statement embedded within the step boundary of a DATA step. If the
only task you want to accomplish is to clean up the directory
/tmp/sasjob, you can avoid the overhead of loading the DATA step.
As you can see from the example, the return code is available in
the &SYSRC macro variable.
Before the SAS System starts the shell to execute any UNIX command,
it checks to see whether the command is cd, pwd, or setenv. These
three commands are built into the SAS System because they relate to
the environment of the SAS session. Refer to "SAS Companion for
UNIX Environments: Language, Version 6 First Edition" for
information on how the SAS System processes these commands.
3.3 The X Command
You can also use the X command to execute UNIX commands in Display
Manager. The X command is equivalent to the X statement with two
exceptions. First, the X command is issued from the command line.
Second, the X command does not put the return code in &SYSRC.
3.4 The %SYSEXEC Macro
The %SYSEXEC macro provides the same functionality as the X
statement. The %SYSEXEC macro can be used in open code. The return
code is available in the &SYSRC macro variable, as in the following
example:
%SYSEXEC /bin/sh -c "exit 1";
%put "The return code is &SYSRC";
Note in the above example, the value of &SYSRC will be 256, not 1. 3.5 The SYSTEM Call routine
Sometimes, you may want to conditionally execute a system command
within the DATA step or your SCL program. This can be accomplished
using the SYSTEM call routine. The syntax is:
rc=system('unix_command');
rc=rc/256
The numeric variable rc is assigned the return code of
unix_command. Remember that you need to divide the return code by
256. Your program can conditionally execute other code based on
the return code you get from unix_command.
For example, the following program will print the message "Elvis is
alive" if elvis is a userid in the /etc/passwd file:
data _null_;
rc=system('grep "^elvis:" /etc/passwd > /dev/null');
if rc = 0 then
put 'elvis is alive';
run;
This program will also run in an SCL program:
INIT:
rc=system('grep "^elvis:" /etc/passwd > /dev/null');
if rc = 0 then
put 'elvis is alive';
RETURN;
The advantage of the system call is that it is a conditional
statement within a DATA step or SCL program. The statement can be
executed based on one or more conditions. The X statement and
%SYSEXEC macro cannot be conditionally executed without macro
statements.
The disadvantage of the SYSTEM call is that it must be run in
either a DATA step or SCL program; and you may have the overhead of
loading the DATA step or AF application.
3.6 The PIPE Device Type
If you want to read data generated from a standalone program, an
effective and efficient facility to do this is the PIPE device
type. The syntax for associating a fileref with a UNIX command
using the PIPE device type is:
FILENAME fileref PIPE 'unix_command';
When the fileref is accessed in the DATA step, unix_command is
executed. Data written to standard output (stdout) by unix_command
is buffered and available to subsequent input statements in the
DATA step. For example, the following program creates a dataset
with one variable called UID. The dataset contains an observation
for everyone who uses the korn shell (/bin/ksh).
filename korn pipe 'grep "ksh$" /etc/passwd | sed "s/:.*$//"';
data kshusers;
infile korn lrecl=20 pad;
input uid $20.;
run;
Here's the same program written in SCL:
pipe:
/*
* create the dataset work.kshusers with the uid variable
*/
dsid=open('kshusers', 'n');
rc=newvar(dsid, 'uid', 'c', 20);
rc=close(dsid);
/*
* open the dataset in update mode so we can use the append function
*/
dsid=open('kshusers', 'u');
call set(dsid);
/*
* assign our UNIX command to a fileref
*/
command='grep "ksh$" /etc/passwd | sed "s/:.*$//"';
rc=filename('comfref', command, 'PIPE');
fid=fopen('comfref', 'S');
/*
* read the output from the pipe
*/
do while(fread(fid) ^= -1);
rc=fget(fid,uid);
rc=append(dsid);
end;
/*
* clean up
*/
rc=close(dsid);
rc=fclose(fid);
rc=filename('comfref', ' ');
return;
Information written to the pipe by your program is blocked until
the SAS System reads from the pipe. You don't have to worry about
running out of virtual memory due to large amounts of data passed
through the pipe since the data is transferred in pieces (or
blocks). You can however run out of memory if the actual command
you are executing consumes all available memory on your machine.
One limitation of the PIPE device type is the inability to read
binary data in variable length records using RECFM=N. For example,
to have a program that generates floating point numbers and pipe
the numbers directly into SAS, you need to use the RECFM=F argument
on the INFILE statement. The RECFM=F option indicates to the SAS
System that the records are fixed. Another way around this
limitation is to redirect the output of the program to a temporary
file, and then read the disk file.
When the SAS System opens a binary file using the RECFM=N option,
no buffering is performed. The SAS System must therefore be able to
seek backwards in the file. The ability to seek backwards does not
exist in a pipe since the data is gone once it is read. Therefore,
the RECFM=F option allows you to read binary data since i/o is
buffered.
You can also write to filerefs assigned with the PIPE device type.
For example, you can associate a fileref with your print command
and have your output directed to the printer:
filename printer pipe 'pstext | lp -dchpljr24';
data _null_;
file printer;
put 'This text has been sent through pstext';
put 'before being printed using the network';
put 'line printer (lp) utility';
run;
In the above example, text written to the PRINTER fileref is first
piped through the pstext utility. The pstext utility is shareware
that converts plain text to PostScript. The output from pstext is
sent to the lp command.
It is important to realize that 'unix_command' can be any valid
UNIX command or commands. UNIX has a rich set of filter programs
for reading, massaging, and writing data. These utilities can be
used with SAS to give you flexibity in designing an application.
4. Calling SAS from C
You may want to invoke the SAS System from a C program. You may
also want to pass data between your C program and the SAS process.
This can be accomplished with the fork and exec system calls. Data
can be passed back and forth using pipes. First, I will discuss a
simple example that runs a SAS program from a C program. Then I
will discuss pipes and how to pass data back and forth between a
parent and a child "SAS" process.
4.1 Discussion of fork and exec
An in-depth discussion of the fork and exec system calls is beyond
the scope of this paper. A brief overview is provided here. For
more information, you can refer to the UNIX man pages on fork and
exec.
In UNIX, programs are started with the exec system calls (there are
six different exec calls). A UNIX program is a file that contains
instructions and data that are used to initialize the instruction
and user-data segments of a process. A process is an instance of a
running program that contains instruction, user-data, and system-
data segments.
The exec system calls initialize a process from a specified
program; exec is the only way programs can be started under UNIX.
The fork system call creates a new (child) process that is a clone
of an existing process; fork is the only way new processes can be
created.
The six exec system calls are execl, execv, execle, execve, execlp,
and execvp. Refer to the UNIX man page on exec for a discussion of
exec system calls.
The system calls fork and exec are usually used together; exec by
itself is of little use; fork by itself is of no practical use.
Here is a C program that uses fork and exec to run a SAS program:
#include <stdio.h>
main()
{
int childpid, /* child process id */
rc; /* return code */
if ((childpid = fork()) == -1
{
fprintf(stderr, "Can't fork0);
exit(1);
}
else if (childpid == 0)
{
/*
* this is the child process; execute the SAS program
*/
execlp("sas", "sas", "program.sas", NULL);
}
else
{
/*
* this is the parent process
*/
printf("waiting for sas process %d to complete0, childpid);
wait(&rc);
rc=rc/256;
printf("sas process completed with rc=%d0, rc);
}
}
One important thing to note about fork and exec is that a copy of
the process is made in virtual memory when the fork statement is
executed. This is especially important when you use the SYSTEM
function, the X statement, or the %SYSEXEC macro because these
statements are implemented using fork and exec. For example, if
you have an interactive SAS program with the following SCL
statement, a copy of the process is made in memory to execute the
mkdir program:
rc=system('mkdir /tmp/foo');
This is particularly important if your application takes up a lot
of memory. For example, if your SAS process is 32MB, another 32MB
of virtual memory will be needed to execute the mkdir command
without regard for the memsize setting. If you have memsize set to
32MB, and your SAS process is already 32MB, SAS will attempt to
fork and exec the command specified by the system function. So, you
essentially need n MB of virtual memory free before executing the
command, where n is the current size of your SAS process. This is a
lot of overhead for executing trivial UNIX commands like mkdir in
your SAS application.
When designing your SAS application, you should execute as many
UNIX commands as possible early before your application gets large.
Different UNIX platforms implement fork differently. Some systems
also support the vfork system call. vfork forks a process but the
instruction and data segments are shared. This not only requires
less memory, but also speeds the cloning process. The SAS System
uses vfork for the PIPE device type on the filename statement. It
is more efficient in terms of memory overhead and speed to execute
your UNIX commands using the PIPE device type instead of using the
X statement, X command, system function, or %SYSEXEC macro. The
following DATA step illustrates this:
filename unixcmd PIPE 'mkdir /tmp/foodir';
data _null_;
infile unixcmd;
run;
Note that you do not actually have to use the input statement to
read the data.
The fork system call is used on systems that do not support vfork.
The vfork system call is provided on HP-UX systems. On systems that
do not support vfork, fork may be implemented similar to the vfork
system call. Refer to the UNIX man page on fork and vfork for more
information on how your system implements forking.
You can also use the PIPE device type in SCL. Here is an SCL method
that can be called from SCL programs:
UNIXCMD:
method command $;
rc=filename('comfref', command, 'PIPE');
fid=fopen('comfref', 'S');
fid=fclose(fid);
rc=filename('comfref',' ');
endmethod;
RETURN:
The method can be called from an SCL program with the following
syntax:
call method('methods.scl', 'unixcmd', 'mkdir /tmp/foodir');
Note that methods.scl is the catalog entry that contains the SCL
source for the method. Refer to documentation on methods in SAS
Technical Report P-216, SAS/AF Software, SAS/FSP Software, and SAS
Screen Control Language: Changes and Enhancements, Release 6.07.
There are two disadvantages to using the PIPE device type in the
DATA step. First, the DATA step must be loaded into memory. Second,
you have no automatic way of checking the return code of a UNIX
program executed using the PIPE device type.
There are other ways to get the return code using the PIPE device
type. You can save the return code to a flat file, then read the
return code from the file. You can also echo the return code to
stdout, then read the return code in using an input statement. The
following DATA step illustrates this:
filename unixcmd PIPE 'mkdir /tmp/foodir >/dev/null 2>&1; echo $?';
data _null_;
infile unixcmd;
input rc;
put rc=;
run;
Notes from the above example:
>/dev/null - direct stdout of mkdir command to /dev/null
2>&1 - direct stderr of mkdir command to /dev/null
echo $1 - echo the return code to stdout (available in the
bourne shell and korn shell using the special
shell veriable $?) - the C-shell variable is $status
Note in the above example that you do not need to divide the return
code by 256. This is because the return code is being accessed from
the shell (special variable $?).
4.2 Pipes In the UNIX environment, pipes are a means for processes to communicate with each other. Pipes are created with the pipe system call int file_desc[2]; ... pipe(file_desc); ...
Pipes are unidirectional. The pipe system call returns two file
descriptors:
file_desc[0] - used for reading
file_desc[1] - used for writing
Pipes are typically used when a parent process wants to write data
to a child process:
1. the process creates a pipe
2. the process closes the read end of the pipe (file_desc[0])
3. the process uses the fork system call (or vfork) to make a
copy of itself
4. the child process closes the write end of the pipe
(file_desc[1])
This provides a one-way flow of data between the two processes as
shown in the following diagram:
<diagram of pipes - (diagram PIPES)> 4.3 Using Pipes with the SAS System
Before using fork, exec, and pipe to develop an application that
communicates with a SAS process, you must first be familiar with
the following:
- the -stdio option in the SAS System
- Pre-defined File Descriptors in the SAS System
- the C function fcntl
4.4 The -stdio Option in the SAS System
UNIX processes have three file descriptors that are opened
automatically:
- stdin (file descriptor 0) is used for reading
- stdout (file descriptor 1) is used for writing
- stderr (file descriptor 2) is used for writing errors or
warnings.
File descriptors are described in more detail in "SAS Companion for
UNIX Environments: Language, Version 6 First Edition". Three SAS
filerefs are automatically assigned to these three file descriptors
in interactive SAS programs:
- STDIN - standard input
- STDOUT - standard output
- STDERR - standard error
These three filerefs are not assigned if the -stdio option is used.
The -stdio option instructs the SAS System to receive input from
stdin, to write the log to stderr, and to write output to stdout.
The -stdio option is designed to run the SAS System in
noninteractive mode, from a C program, or from a shell script.
For example, in the following SAS command, file sas_source is used
as the source program, sas_output is used for procedure output, and
sas_log is used for the SAS log.
/bin/sh
/bin/ksh sas -stdio < sas_source > sas_output 2> sas_log
/bin/csh (sas -stdio < sas_source > sas_output) >& sas_log
4.5 Pre-defined File Descriptors
The SAS System assigns filerefs of the following form to files
having a file descriptor larger than 2 and less than 10:
FILDESnumber
where number is a two-digit representation of the file descriptor.
For example, if you invoke the SAS System using the following
command, UNIX opens the file stats and assigns it to file
descriptor number 5:
sas run_stats 5< stats
The SAS System assigns the fileref FILDES05 to the file and
executes the program run_stats. When you read from FILDES05, you
read the file 'stats'. Not only does this allow you to communicate
with SAS using pipes, you can also use the same program to process
data from different files without changing the program to refer to
each file. You simply specify the input file when you invoke the
SAS System.
4.6 The fcntl System Call
The following discussion of the fcntl system call is necessary
before showing the next example. The fcntl system call changes
properties of an open file descriptor. The F_DUPFD command
duplicates the file descriptor. Here is an example of fcntl as it
would appear in your program, with a description of the arguments.
#include <fcntl.h>
...
int ret_fd;
...
ret_fd=fcntl(fd, F_DUPFD, arg);
...
where ret_fd - the new descriptor (int)
fd - existing file descriptor (int)
F_DUPFD - command that requests a duplicate of the
existing file descritor fd (int)
arg - the lowest number that the new file descriptor is
to assume (int)
Refer to the UNIX man pages or other UNIX documentation for a more
detailed discussion of fcntl.
4.7 Sample C Program Using Pipes With The SAS System
#include <stdio.h>
#include <fcntl.h>
/*
* The following array (i.e. SAS program) could be generated dynamically
*/
char sasprogram[] = { "
libname output '.';
data output.file;
infile fildes05;
input var1 var2;
run;
proc print data=output.file;
run;"
};
int src[2], /* file descriptors for the SAS source code */
data[2]; /* file descriptors for the SAS data */
int saspid; /* Process ID of the child (SAS process) */
void CloseSAS();
main(argc,argv)
int argc;
char **argv;
{
char buf[512]; /* Generic data buffer */
int counter; /* for loop counter */
/*
* Invoke the SAS System, and give it the SAS program to run
*/
if (OpenSAS(sasprogram) == -1)
{
fprintf(stderr, "Can't execute The SAS System!!0);
exit(1);
}
/*
* Generate two columns of integers for SAS input data.
*/
for(counter=0;counter<5;counter++)
{
sprintf(buf,"%d %d0,counter, counter);
DataToSAS( buf, strlen(buf) );
}
/*
* Terminate the SAS Process, then exit
*/
CloseSAS();
return(0);
}
int OpenSAS(sasprogram)
char *sasprogram;
{
int fd; /* file descriptor returned from fcntl */
pipe(src); /* The pipe for the SAS source statements. */
pipe(data); /* The pipe for the input data stream. */
if (!(saspid = fork()))
{
/*
* We're in the child. Reroute the pipes
*/
close(0); /* close stdin of the SAS process */
fcntl(src[0], F_DUPFD, 0); /* associate stdin with read end */
/* of the source pipe (src[0]) */
close(src[0]); /* close both ends of source pipe */
close(src[1]);
close(5); /* close just in case it is open */
fd=fcntl(data[0], F_DUPFD, 5); /* associate read end of the */
printf("fd from fcntl=%d0,fd);/* data pipe with file */
/* descriptor 5 */
close(data[0]); /* close both ends of the data */
close(data[1]); /* pipe */
/*
* run the SAS program
*/
execlp("sas", "sas", "-stdio", "-nodms", NULL);
}
/*
* we are in the parent process
*/
/*
* close the unwanted ends of the pipes; we are closing the read
* end of the pipe since both source and data will be "written to"
* the SAS process
*/
close(src[0]);
close(data[0]);
/*
* If invoking the SAS System failed
*/
if (saspid == -1)
{
close( src[1] ); /* close write end of both pipes */
close( data[1] );
return(-1); /* return with -1 */
}
/*
* Send the SAS System the SAS source to run and close the
* source pipe
*/
write(src[1], sasprogram, strlen(sasprogram));
close(src[1]);
/*
* Now any data written to the pipe "data[1]" will be sent
* to filedescriptor #5 of the SAS process.
*/
return(saspid);
}
/*
* Send data to the running SAS process
*/
int DataToSAS(buf, len)
char *buf;
int len;
{
if (write(data[1], buf, len) != len)
return(-1);
else
return(0);
}
/*
* Terminate the SAS process, wait for it, and print exit status
*/
void CloseSAS()
{
int rc;
close(data[1]);
while (wait(&rc) != saspid);
printf("the SAS process ended with rc= %d0, rc / 256);
}
5. Named Pipes
A named pipe, sometimes called a FIFO file, is a combination of a
file and a pipe. Like a file, a named pipe can be opened, written
to, and read from. When it is opened, a named pipe behaves more
like a pipe than a file. Written data is read in first-in-first-out
order. Once data has been read, it cannot be read again.
The following diagram illustrates how a named pipe works:
<named pipe diagram (diagram NAMED_PIPE)>
The UNIX command mknod is used with the p option to create a named
pipe. For example, to create a named pipe called named_pipe, issue
the following UNIX command:
mknod named_pipe p
You can use named pipes if you want a SAS program to wait for input
before running. For example, the following SAS program will wait
until data is written to named_pipe before completing.
data pipe;
infile 'named_pipe';
input dream1 dream2;
run;
When SAS executes the infile statement, the SAS process is blocked
(or put in a wait state) until data is written to the file
named_pipe. SAS will continue to read from the FIFO until the end-
of-file is encountered.
If the above SAS statements are in a file called npipe.sas and
submitted using the following UNIX command, the program waits for
data to be written to named_pipe:
sas npipe.sas &
Once data is written to named_pipe, the SAS System continues
processing until the process that was writing to the named pipe
closes the file (that is, until an EOF is encountered). To get the
SAS process to finish reading from named_pipe, we could use the
following UNIX command to write data to 'named_pipe':
echo "1 2" > named_pipe
The dataset pipe that is created would only have one observation.
You can write as many records to named_pipe as you want.
6. Calling SAS from a shell script
Sometimes it is useful to invoke the SAS System from a shell
script. There is nothing you can do in a shell script that can't be
done in a C program but shell scripts are usually more convenient
and easier to maintain. You can invoke the SAS System in
interactive or batch mode. Invoking the SAS System from a shell
script allows you to complete some tasks before the SAS System is
invoked. Such tasks include:
- AFS authentication: useful if you have data stored under AFS
where authentication is required before data is accessed
- invocation options: you may want to add invocation options
that your script parses before invoking the SAS System.
- move and copy files: you may want to make copies of data or
create unique libraries for the SAS process
- privileges: you may want to verify that a user has appropriate
priviledges, such as write access to a directory, before
invoking an application
- logging: you may want to log information such as: the host
that SAS is being run on or time it takes the process to run.
- control options: you may want to control certain options that
are used, for example, MEMSIZE, AUTOEXEC, and SYSPARM
- control SAS processes: you may want to limit the number of SAS
processes that are running concurrently by checking the number
of active SAS processes before submitting.
- set environment variables - the SAS System can access these
variables using the %SYSGET function
The following shell script runs npipe.sas in the background. After
running npipe.sas, the script sends data to named_pipe.
#!/bin/sh
#
# make the named pipe
#
mknod named_pipe p
#
# run the sas program in the background; this program will be
# blocked (that is, wait), until all data is written to the
# named_pipe (that is, until an EOF is received)
#
sas npipe.sas &
#
# use a "here text" with the cat command to send data to the
# named pipe
#
cat - > named_pipe << ----EOT----
1 2
3 4
5 6
7 8
----EOT----
#
# remove the named pipe
#
rm named_pipe
#
# end of script
#
After your SAS program completes, you can check the SAS return code
or scan the log for certain messages. Here are the return codes
generated by Release 6.09 of the SAS System and what they indicate:
Condition Return Code
all steps terminated normally 0
SAS System issued warning(s) 1
SAS System issued error(s) 2
User issued ABORT statement 3
User issued ABORT RETURN statement 4
User issued ABORT ABEND statement 5
User issued ABORT RETURN n statement n
User issued ABORT ABEND n statement n
6.1 Other Ways To Interpret Results
You can also use other UNIX tools to scan the SAS log for certain
text. For example, grep could be used to search for specific ERRORS
or WARNINGS in the SAS log.
7. Miscellaneous Features The following features can also be useful in SAS applications: SYSJOBID, %SYSGET, SYSGET, and the -SYSPARM option 7.1 SYSJOBID SYSJOBID is an automatic macro variable that contains the process id of the SAS process that is running. 7.2 %SYSGET and SYSGET The %SYSGET macro function returns the character string that is the value of the environment variable passed as the argument. A warning message is printed if the environment variable does not exist. The form of the %SYSGET function is: %SYSGET(environment_variable);
For example, to print the value of the HOME environment variable in
the SAS log, you could use the following SAS statements:
%LET HOMEVAR=%SYSGET(HOME);
%PUT &HOMEVAR;
The SYSGET function must be run in a DATA step or an SCL program. The
form of the SYSGET function is:
SYSGET('environment_variable');
For example, to print the value of the HOME environment variable in
the SAS log, you could use the following DATA step:
DATA _NULL_;
HOMEVAR=SYSGET('HOME');
PUT HOMEVAR;
RUN;
7.3 The -SYSPARM Option
The -SYSPARM option allows you to pass information to a SAS process
from the command line. The information is available to the SAS
System in the automatic macro variable &SYSPARM. For example, the
following SAS invocation passes an input file name to the SAS
System:
sas -sysparm "/my/input/file";
Then, you can use the following infile statement in your SAS
programs:
INFILE "&SYSPARM";
You must enclose the SYSPARM argument in quotes if your argument
has embedded blanks.
8. SAS/TOOLKIT
SAS/TOOLKIT software, an integrated component of the SAS System,
enables you to write your own customized SAS procedures (including
graphics procedures), informats, formats, functions (including IML
and DATA step functions), CALL routines, and database engines in
several languages, including C and Fortran.
There are several advantages that SAS/TOOLKIT has over integrating
standalone programs with the SAS System. Among the advantages are:
- extensibility: you can directly extend the capabilities of the
SAS System to meet the specialized needs of your users
- convenience: a component (for example, a SAS procedure)
incorporated into the SAS System allows you to put all your
programming tools in one place
- integration: the data used by user written procedures are
stored as SAS datasets and can thus be easily sorted, printed,
and analyzed using other SAS procedures during a single job
- efficiency: the components you develop run in the same address
space as your SAS process. Therefore, you do not have the
cloning overhead associated with fork and exec.
SAS/TOOLKIT is a powerful extension to the SAS System. Once you
compile and link the component(s) you are working on, you no longer
need SAS/TOOLKIT because you don't need SAS/TOOLKIT to use the
components you develop.
9. Conclusion
Your SAS applications can be integrated and used with other
programs and applications. The capabilities discussed in this paper
provide you with the flexibility and power to design applications
to meet your needs.
|