XWait and XSync not behaving correctly - sas

I am running SAS 9 on Windows Vista. I am using system Commands to execute some Python code in some nested macros that are passing different parameters to Python each time. Im using the XSYNC and XWAIT options in SAS.
My understanding of this is that these two options should make SAS pause until the Python script has completed running. With this option the Python Command Prompt window closes when the code completes execution and I am then prompted to type EXIT, which is what you would expect.
However, when I use NOXWAIT XSYNC the SAS code passes each Python invocation, kicks it off and keeps running. After a few minutes I have hundreds of Command Prompt windows open all trying to run at the same time.
What am I doing wrong? As a work around I have tried using x 'EXIT' and call system ('EXIT') to close the windows administrator command prompt window down but this does not seem to be being passed to the window, even though the exit command is in a separate data null step to the one that calls the Python code.
Any ideas?
Here is code I'm using:
data _null_;
x 'cd C:\Python33';
x 'start test.py';
run;
data _null_;
call system ('exit');
run;
What happens is two Command Prompt windows open. The second one is the Python script running. This closes itself and I am left with the administrator window. I have tried putting an x command of 'Exit'; in the first data null step, but this has not worked.

XSYNC tells SAS to execute an external command synchronously, meaning SAS pauses until the command completes. You would use NOXSYNC only in very specific applications.
XWAIT tells SAS to wait for you to explicitly exit the window running the command. In most cases, you would want to use NOXWAIT.
The problem you describe suggests to me that your Python commands are not properly terminated. Sorry, nut I don't know Python. But consider putting your Python statements in a script file, which closes itself with an exit command, or adding an exit command to the SAS call, something like:
data _null_;
call system('python-command;exit');
run;
If this does not help, revise your question and show the complete SAS data step code you are using. Note, using a second X command to push an "exit" statement will not work; it must be part of the initial call.

Related

Start .exe file and automatically "press enter for "Save"" in SAS

I have a SAS program I would like to schedule, so we don't have to run it manually.
In the program we call an excecutable (reg.exe), like this:
X CALL "K:\reg.exe";
The executable opens a standard windows save-dialog and all we need to do is press save, which will save an xml-file. The save-dialog already opens in the correct directory.
What I would like is to somehow pass the instruction on, using code, to "press save", so the program can move on and work with the saved xml-file.
Is this possible somehow?
Thanks for your help!
Thomas:
There are numerous Windows utilities for scripted control of an interactive program. For example: AutoIt (my favorite), MouseRobot and AutoHotKey to name a few.
The statement
options xmin noxwait noxsync;
will cause the external program to run, not wait for the command session to exit, and not wait for the command to complete.
If your SAS programs needs to wait for the side effects of the scripting use of reg.exe to occur before occurring, use:
options xmin noxwait xsync;
These settings affect other operating system interfacing features, such as:
X command
CALL SYSTEM routine
%SYSEXEC statement
The use of your reg.exe might require your login to have admin rights.
The SYSTASK statement can also run external commands.
If you find that you are unable to run external commands, it is probably because the system setting NOXCMD is active. This setting is on by default in SAS server environments.

How to print SAS program log to console when running in batch mode

I am running my SAS program in batch mode through windows command prompt.
Start /WAIT "SAS_job" "C:\Program Files\SASHome\SASFoundation\9.4\sas.exe" -sysin D:\MySAS_Test.sas -nosplash -nologo -noicon
Can I display the SAS output or log on command prompt instead of writing to a file? Or print log as SAS program is running to track progress.
I think this is possible in Unix, but I'm not so sure about Windows.
You can write to STDOUT in Unix as mentioned in the documentation. But I don't see any such similar thing in Windows.
The most similar thing is unnamed pipes, which lets you interact with the console - but it's unclear if this is potentially helpful for you or not.
Unfortunately, I suspect SAS is generally not considering Windows a server type environment, and mostly supporting it to allow for desktop use; while it does support Windows servers certainly, most SAS server usage is Linux/Unix.
Your better bet is probably to go in the direction of another program that reads from the log file already produced and writes it out to the console, something analagous to tail in Unix. Or as mentioned in comments open the log in a text editor (you can even 'push' this from SAS if you have option xcmd enabled) and let it auto-refresh periodically.
One common use case in fact is to use, for example, UltraEdit to edit your SAS programs; it can even run them in batch directly, and then retrieve the log in that program.

SAS Error Handling in Windows Batch

I have a scheduled SAS program in Windows, e.g.
sas.exe -nosplash -icon -sysin "myprogram.sas"
This process will hang if there's an "Out of Resources" error (e.g. no disk space), prompting for user input (Retry, Cancel, etc.). As it's a batch job, there is no user to give that input.
Is there a SAS system option which prevents the prompt for user input so it can be dealt with in the code itself?
How about -noterminal?
Extract from documentation:
If NOTERMINAL is specified, dialog boxes are not displayed.
Trying using the option
-batch
Since you are running in batch mode, also consider using the option
-errorabend
The best option is
-get_more_resources ;)
If the program is the cause to the resource error you have another question to ask!

Terminate whole process flow instead of single program

Is there a way to stop the process if certain criteria in any of the programs in this process is met?
I have a process consist of 5 SAS programs. This process is scheduled to run at 8am every morning. However, sometimes the database is not refreshed and this process will send out weird figures.
I need to have "exception control".. In 2nd program I check the database with some criteria. If no error, then keep running the rest of the code. Otherwise, send out an notification email and STOP running the 2nd program and all the subsequent programs.
I try %abort cancel but it only terminate the current program. The subsequent programs are not affected.. I can do checking in every single program but that make the code redundant...
I also try google "terminate SAS process" but most of them refer to abort statements which doesn't help...
If you're using Enterprise Guide, this is built into the program via logic gates.
First, in the program that determines whether the database file passed/failed ("gate program"), assign a macro variable a value based on that test. Presumably this program will do only things you're happy for it to do even if it fails.
On the process flow page, you right click on the program that determines if the database file passed/failed, and select 'Condition -> Add'.
Then add a condition based on a Macro Variable, and use 'equals' and the value you're looking for (or 'greater than' or whatever makes sense). Then select the next task after "Then run this task"; and put the other option after Else run this task.
Then, whichever of the two is forward-moving, should then have links to the rest of the programs you want run; the one that's not should end the process.
SAS gives an example of how to do that in KB Sample 39995 including a sample project you can download.
Second, you can set OBS=0 if you reach the error condition. This will let SAS continue working, but it in most cases won't be able to do anything (since OBS=0, then it can only affect 0 records of any dataset). I'm not sure that's a guarantee that it won't do anything, but in everything I've done that's been sufficient. I also have used OPTIONS ERRORABEND which works fine if you do all of your processing with external libnames which won't automatically reconnect when SAS is reconnected.
My understanding is that this is a batch process. You don't specify Operating System you are running your process on. Let's suppose you are running it on UNIX/Linux (I am hoping it is similar on Windows). Let's assume that your 5-programm process is run by the following shell script:
sas /program1.sas
sas /program2.sas
sas /program3.sas
sas /program4.sas
sas /program5.sas
If you want to stop your remaining process after program2.sas completes with ERRORs or WARNINGs you can modify your script to be
sas /program1.sas
sas /program2.sas
if [ $? -ne 0 ]
then
exit
fi
sas /program3.sas
sas /program4.sas
sas /program5.sas
In this script code a special shell script variable $? status code is passed from the previous command from SAS (0 means successful completion). If it is not 0 then the whole script stops due to the exit command.
For more information and code examples see How to conditionally terminate a SAS batch flow process in UNIX/Linux SAS blog post.

Auto Scheduled SAS Queries

I run some SAS queries monthly and they all take a fairly long time to run. I was wondering if there was any way I can schedule these to run on a certain date each month in a certain order?
Thanks for your help!
On unix you could set the programs up to run in batch mode with a cron job.
One trick you could use would be to set up a master SAS program to run everything.
Make one program that just contains any global variables that need to be changed each month and then call your monthly programs with includes.
something like:
%let globalvar1 = ThisMonth;
%let globalvar2 = LastMonth;
%include '/path/to/sas/program1';
%include '/path/to/sas/program2';
Then you run only this one program in batch...it will run them in the correct order and automatically wait for them to finish executing before moving to the next program (setting up separate cron jobs would require you to overestimate how long each one takes so they wouldn't conflict).
This will dump everything into one log file...which may be good or bad.
Another option would be to use X to call the program from the OS at each run.
I am not 100% on the syntax but this should work if you use the right syntax for your OS (this could work on unix or windows so you would only have to schedule one program).
At the end of each program just add:
X "Path/to/sas.exe" -batch -noterminal nextProgram.sas
This will let you chain the programs together so that they start the next one running after they finish. Then you just use task scheduler/cron to start "sas.exe -batch -noterminal firstProgram.sas"
Depending on what system you are working with, methods may be different.
The main idea is that you may store all queries to a SAS processing file then use system's scheduler (For example, task scheduler for Windows), to run monthly.
A quick help (for Windows):
http://analytics.ncsu.edu/sesug/2006/CC04_06.PDF