Захватить stdout и stderr из SAS в Windows? - PullRequest
5 голосов
/ 23 ноября 2011

Я хочу вызвать программу SAS из другой программы в Windows. У меня есть некоторый опыт вызова SAS из командной строки в пакетном режиме, но нет реального опыта получения сообщений от него и обработки этих сообщений. Я погуглил и нашел довольно много информации о чтении из stdin из SAS-программы, но я не могу понять, как заставить мою SAS-программу записывать в stdout или stderr. Могу ли я даже сделать это в Windows?

Из программы 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()

Мои результаты на консоли из этого:

('', '')

Ответы [ 3 ]

2 голосов
/ 23 ноября 2011

Насколько я знаю, это невозможно достичь напрямую. Вы можете эмулировать это, передавая уникальное имя файла в sas с помощью параметра командной строки -sysparm и сохраняя в нем свой вывод STDOUT. Затем можно использовать параметр командной строки -log, чтобы отправить журнал sas в другой файл. После завершения программы SAS вы сможете использовать выбранную вами программу для анализа каждого из созданных файлов. К сожалению, файл журнала блокируется до тех пор, пока программа sas не завершит его, поэтому, если вы хотите использовать SAS для обработки файла журнала, вам потребуется запустить вторичную последующую программу для этого. (т.е. вы не можете прочитать файл журнала из программы SAS, которая его создает).

Как только вы прочитаете журнал, вы можете найти строки, начинающиеся с ОШИБКА: или ПРЕДУПРЕЖДЕНИЕ: и предпринять соответствующие действия (в моем случае он отправляет мне электронное письмо). Вы можете добавить логику, которая соответствует вашему стилю кодирования. Например, некоторые вещи, которые SAS рассматривает как ЗАМЕЧАНИЯ, я считаю ОШИБКАМИ. Кроме того, некоторые вещи, которые 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;

Надеюсь, это поможет.

2 голосов
/ 23 ноября 2011

У меня нет удобной версии 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 голосов
/ 23 ноября 2011

Googled перенаправляя журнал в STDERR для вас:

   proc printto log=STDERR;
   run;

   data _null_;
      1=x;
   run;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...