【问题标题】:Capture stdout and stderr from SAS in Windows?在 Windows 中从 SAS 捕获标准输出和标准错误?
【发布时间】:2011-11-22 22:47:16
【问题描述】:

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

通过 SAS 程序,我想做以下事情:

  • 将警告消息和错误消息重定向到标准错误,而不是将它们打印到日志文件中
  • 在 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;

调用 SAS 的 Python:

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()

我在控制台上的结果是:

('', '')

【问题讨论】:

标签: python sas


【解决方案1】:

据我所知,这是不可能直接实现的。您可以通过使用 -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;

希望这会有所帮助。

【讨论】:

  • 只是一个想法 - 使用套接字你可以让 SAS 模拟发送到 STDOUT。旧的 SAS/Intranet 模块也可以用于此目的....
  • 谢谢罗伯。我之前使用过 sysparm 和日志文件参数进行批处理,所以我想我会采用这种方法。日志文件被锁定太糟糕了。我希望对输入数据有足够的控制,以避免我必须解析的许多错误,所以也许我可以检测到尽可能多的错误(例如,与预期不同的观察数量)并输出到我自己的模拟 STDERR。另外,我会研究一下套接字。
【解决方案2】:

我手边没有 Windows 版本的 SAS,但在 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;

【讨论】:

  • 有趣。这在 Windows 上不起作用。我猜SAS只是没有标准输出/标准错误句柄:(
【解决方案3】:

Google 为您将日志重定向到 STDERR:

   proc printto log=STDERR;
   run;

   data _null_;
      1=x;
   run;

【讨论】:

  • 谢谢,我试过了。它不会将日志重定向到标准错误。它会创建一个名为“stderr.log”的日志文件。
猜你喜欢
  • 2013-05-11
  • 1970-01-01
  • 2018-11-25
  • 1970-01-01
  • 2018-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-28
相关资源
最近更新 更多