2011-11-22 106 views
5

我想从Windows上的另一个程序调用SAS程序。我有一些在批处理模式下从命令行调用SAS的经验,但没有真正的经验从它接收消息并处理这些消息。我搜索了很多关于从SAS程序中读取stdin的信息,但似乎无法弄清楚如何让我的SAS程序写出stdout或stderr。我可以在Windows中做到这一点吗?在Windows中从SAS捕获stdout和stderr?

从SAS程序,我想做到以下几点:

  • 重定向警告信息和错误信息,而不是到stderr它们打印到日志文件
  • 内SAS程序,手动检测错误和/或其他问题并将它们输出到stderr或stdout。

这是我曾尝试:

SAS

data test; 
    attrib i length=8; 

    do i = 1 to 10; 
     put 'putting'; *how can i make this go to stdout?; 
     putlog 'putting to log'; *this can go to the log - that is okay; 
     if i = 5 then do; 
      *pretend this is an error I am manually detecting - how can i make this go to stderr?; 
      put 'we found 5'; 
     end; 
     output; 
    end; 
run; 

data _null_; 

    1 = y; *this is an error detected by SAS. How can I make this go to stderr?; 

run; 

的Python调用SAS:

import subprocess 
import os 


if __name__ == '__main__': 

    filename = os.path.normpath(r'C:\Users\oob\Desktop\sas_python_test.sas') 
    sas_executable = os.path.normpath(r'C:\Program Files\SAS\SASFoundation\9.2\sas.exe') 

    cmd = r'"' + sas_executable + r'"' + " " + r'"' + filename + r'"' 

    p = subprocess.Popen(cmd,shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE) 
    print p.communicate() 

我从这个控制台上的结果:

('', '') 
+1

我从来没有使用SAS,但它是一个控制台应用程序?它可能没有stdout/stderr的句柄。在这种情况下,尝试使用PyWin32的'win32com'模块[使用OLE自动化SAS](http://support.sas.com/documentation/cdl/en/hostwin/63285/HTML/default/viewer.htm#oleauto.htm)。 – eryksun

+0

以下是有关使用可能有所帮助的未命名管道的SAS文档的链接: http://support.sas.com/documentation/cdl/en/hostwin/63285/HTML/default/viewer.htm#unnamed.htm – RWill

回答

2

据我知道这是不可能直接实现。您可以通过使用-sysparm命令行参数将唯一文件名传入sas来模拟此操作,并将STDOUT输出保存到该文件中。然后可以使用-log命令行参数将sas日志发送到其他文件。一旦SAS程序完成,您将能够使用您选择的程序来解析每个生成的文件。不幸的是,日志文件被锁定,直到sas程序完成它,所以如果你想使用SAS来处理日志文件,你需要启动一个次要的后续程序来做到这一点。 (即,您无法从正在创建它的SAS程序中读取日志文件)。

一旦你阅读登录,你可以寻找以ERROR:或WARNING开头的行,并采取适当的行动(在我的情况下它会发送一封电子邮件给我)。你可能想要添加一些适合你编码风格的逻辑。例如,一些SAS认为是NOTES的东西我认为是ERRORS。此外,SAS将一些事情视为我不关心的错误。这是我使用的逻辑:

data problems log; 
    length line $1000; 

    infile "&logfile"; 
    input; 

    logfile = "&logfile"; 
    line_no = _n_; 
    line = _infile_; 
    problem = 0; 

    if 
    (
    line =: "ERROR:" 
    or line =: "WARNING:" 
    or line =: "NOTE: Numeric values have been converted to character values" 
    or line =: "NOTE: Character values have been converted to numeric values" 
    or line =: "NOTE: Missing values were generated as a result of performing an operation on missing values" 
    or line =: "NOTE: MERGE statement has more than one data set with repeats of BY values" 
    or line =: "NOTE: Invalid (or missing) arguments to the INTNX function have caused the function to return" 
    or line =: "INFO: Character variables have defaulted to a length of 200" 
    or line =: "NOTE: Invalid" 
) 
    and not 
    (
    line =: "WARNING: Your system is scheduled to expire" 
    or line =: "WARNING: The Base Product product with which Session Manager is associated" 
    or line =: "WARNING: will be expiring soon, and is currently in warning mode to indicate" 
    or line =: "WARNING: this upcoming expiration. Please run PROC SETINIT to obtain more" 
    or line =: "WARNING: information on your warning period." 
    or line =: "WARNING: This CREATE TABLE statement recursively references the target table. A consequence" 
    or line =: "WARNING: Unable to copy SASUSER registry to WORK registry. Because of this, you will not see registry customizations during this" 
    or line =: "WARNING: Estimates did not improve after a ridge was encountered in the objective function." 
    or line =: "WARNING: Estimates may not have converged." 
    or line =: "ERROR: A lock is not available for" 
    or line =: "ERROR: Errors printed on pages" 
) 
    then do; 
    problem = 1; 
    output problems; 
    end; 
    output log; 
run; 

希望这会有所帮助。

+0

只是一个思想 - 使用套接字,你可以让SAS模拟发送到STDOUT。旧的SAS/Intranet模块也可以用于这个目的.... –

+0

感谢罗布我已经使用sysparm和日志文件参数为批处理之前,所以我想我会采取这种方法。日志文件被锁定太糟糕了,我希望有足够的控制输入数据,以避免许多错误,我将不得不解析,所以也许我可以检测尽可能多的数据(例如,观察次数不同于预期的次数),并输出到我自己的模拟STDERR中。另外,我还会查看套接字。 – oob

2

我没有SAS方便的Windows版本,但是在UNIX上我重定向到STDOUT这样的:

data _null_; 
    file STDOUT; 
    do i=1 to 10; 
    put i=; 
    end; 
run; 

不知道如何重定向错误日志STDERR,但打印到STDERR应该是这样的:

ods listing file=STDERR; 

proc print data=sashelp.class; 
run; 
+0

有趣的。这在Windows上不起作用。我猜SAS没有stdout/stderr句柄: – oob

+0

'ods listing file = STDERR;'work on unix。Thanx –

-1

Google搜索重定向日志STDERR你:

proc printto log=STDERR; 
    run; 

    data _null_; 
     1=x; 
    run; 
+0

谢谢我已经试过了,它不会将日志重定向到stderr,它会创建一个名为log 'stderr.log'。 – oob

相关问题