2011-11-22 84 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

相關問題