2011-11-22 6 views
5

Chcę wywołać program SAS z innego programu w systemie Windows. Mam pewne doświadczenie w uruchamianiu SAS z wiersza poleceń w trybie wsadowym, ale nie ma prawdziwego doświadczenia otrzymywania z niego wiadomości i obsługi tych wiadomości. Przeszukałem go i znalazłem sporo informacji na temat czytania ze stdin z programu SAS, ale nie mogę się domyślić, jak sprawić, by mój program SAS zapisywał się na stdout lub stderr. Czy mogę to zrobić w systemie Windows?Przechwytywanie stdout i stderr z SAS w systemie Windows?

Z programu SAS, chciałbym wykonać następujące czynności:

  • Przekierowanie Wiadomości i komunikaty o błędach Ostrzeżenie na stderr zamiast drukować je w pliku dziennika
  • W ramach programu SAS, ręcznie wykryć błędy i/lub inne problemy i wyprowadzać je na stderr lub stdout.

Oto co próbowałem:

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; 

Pythona, który wywołuje 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() 

Moje wyniki na konsoli od tego są:

('', '') 
+1

Nigdy nie używałem SAS, ale czy jest to aplikacja konsolowa? Może nie mieć uchwytów dla stdout/stderr. W takim przypadku wypróbuj moduł 'win32com' PyWin32, aby zautomatyzować SAS używając OLE (http://support.sas.com/documentation/cdl/en/hostwin/63285/HTML/default/viewer.htm#oleauto.htm). – eryksun

+0

Oto link do dokumentacji SAS dotyczącej używania nienazwanych rur, które mogą być pomocne: http://support.sas.com/documentation/cdl/en/hostwin/63285/HTML/default/viewer.htm#unnamed.htm – RWill

Odpowiedz

2

o ile wiem, to nie jest możliwe, aby osiągnąć bezpośrednio. Możesz to naśladować, przekazując unikalną nazwę pliku do sas używając parametru -sysparm i zapisując do tego wyjście STDOUT. Następnie można użyć parametru wiersza polecenia -log, aby wysłać dziennik sas do innego pliku. Po zakończeniu programu SAS będziesz mógł użyć wybranego programu do przeanalizowania każdego z plików, które zostały wyprodukowane. Niestety plik logu jest zablokowany, dopóki program sas nie zakończy pracy, więc jeśli chcesz użyć SAS do przetworzenia pliku logu, musisz uruchomić drugi program kontrolny, aby to zrobić. (tzn. nie można odczytać pliku dziennika z programu SAS, który go tworzy).

Po przeczytaniu logu możesz poszukać linii zaczynających się od BŁĘDU: lub OSTRZEŻENIE: i podjąć odpowiednie działania (w moim przypadku wysyła mi e-mail). Możesz dodać trochę logiki, która pasuje do twojego stylu kodowania. Na przykład niektóre rzeczy, które SAS traktuje jako UWAGI Uważam, że BŁĘDY. Ponadto, niektóre rzeczy SAS traktuje jako BŁĘDY, o które nie dbam. Oto logika której używam:

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; 

Mam nadzieję, że to pomoże.

+0

Pomyślnie - używając gniazd, możesz uzyskać SAS, aby emulować wysyłanie do STDOUT, stary moduł SAS/Intranet również by działał w tym celu ... –

+0

Dzięki Rob. Użyłem sysparmu i dziennika argumenty pliku dla przetwarzania wsadowego przed, więc myślę, że pójdę do tego podejścia.Nie jest źle o pliku dziennika jest zablokowany.Mam nadzieję, że mają wystarczającą kontrolę nad danymi wejściowymi, aby uniknąć wielu błędów, które musiałbym analizować, więc może Potrafię wykryć jak najwięcej (np. Różną liczbę spostrzeżeń, niż się spodziewano) i wyprowadzić na mój własny, emulowany STDERR, a także zajrzeć do gniazd. – oob

2

nie mam wersję Windows SAS poręczny, ale w systemie UNIX przekierować do STDOUT tak:

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

Nie wiem, jak przekierować dziennik błędów na stderr, ale drukowanie na stderr wyglądałby następująco :

ods listing file=STDERR; 

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

interesujące . To nie działa w systemie Windows. Przypuszczam, że SAS po prostu nie ma uchwytów stdout/stderr :( – oob

+0

'ods listing file = STDERR;' działa na Uniksie Thanx –

-1

Googled przekierowanie dziennik na stderr dla Ciebie:

proc printto log=STDERR; 
    run; 

    data _null_; 
     1=x; 
    run; 
+0

Dzięki temu próbowałem tego.Nie przekierowuje logu na stderr.Oto tworzy plik dziennika o nazwie 'stderr.log'. – oob