SM02
SM02
SM02
Paper SM02
ABSTRACT
A batch file is a file that contains a sequence, or batch, of commands. Batch files are useful for storing sets of
commands that are always executed together because you can simply enter the name of the batch file, or double
click on it, instead of entering each command individually. For example entering a copy or rename command.
For example, the Windows Batch Script language can be used with the interpreter cmd.exe, which is the default
interpreter on Windows® platforms: NT, XP, Vista, 7 and later.
Taking the example of a repetitive task, such as the run of several SAS programs at once, we would like to introduce
the basic of Windows Batch Scripting language. The example will show the following:
- Select a set of programs by dragging the selected programs into the icon representing the batch program
- Get automatically the name of the files “passed” to the script and generate a loop
- Within the loop:
Batch submit each selected SAS program
Prompt the user with the execution status
Promptly inform the user if the program generated some errors or warning by analyzing the SAS
log
- Prompt the user when the batch is terminated with some metrics e.g. elapsed time
Other examples include creating automatic backups of your study task folders, running P21® in batch, creating a
SAS® program standard layout (e.g. with standard header with automatically filled).
INTRODUCTION
There once was a programmer, Simone Margaritelli, a researcher at Zimperium, who hacked his coffee machine to
brew coffee using the command line:
Another “lazy” programmer wrote some scripts to get his jobs done: Nihad Abbasov, contributing as “Narkoz” on
GitHub ; he created some scripts with funny names, including one which sent automatic emails with message like
“not feeling well/working from home” if no “interactive sessions on the company server at 8:45am” with his login,
even selecting random reasons from a pre-defined list.
While we may not have the audacity of the latter programmer, we hope to show how the use of batch commands can
make everyday tasks one keystroke away.
In other words, a batch file is a text file that “batches” (bundles or packages) into a single file, a set of commands
that would otherwise have to be presented to the system interactively from a keyboard one at a time, so that multiple
actions can be automated on your computer via a simple mouse-click.
1
PhUSE EU Connect 2018
Users have to manually (groan) open the log, and manually (double groan) search for errors, warnings or other
suspicious notes like uninitialized or not referenced. Plus, and this may be more subjective, the log is stored in the
same folder as the program which may not follow your company’s standard practice – requiring yet another “manual”
action to move the log?
Running in batch SAS programs could also avoid dependency from one’s user profile, which would have been
loaded during an interactive SAS session – typically templates inappropriately stored in a sasuser library ; to execute
in batch the SAS programs becomes then particularly relevant for a production run.
This is one scenario where Batch scripting can come to the rescue by running one SAS program or a selection of
SAS programs, storing the logs in the correct folder, searching the logs for keywords and giving the user a summary
of what it found in the logs.
But before we get to that, you may want to back up what is in your folder – in case things go unexpectedly wrong!
Why not use batch to manage this as well? Let’s start by a quick introduction to some of the basic script commands.
Script Action
Echo display as text anything written after echo
@echo off removes all the paths where the actions are being performed – makes
execution/messages easier to read
Pause batch “pauses” after execution so user can see what happens (unlike the
SAS batch run, for example..)
echo. may be used to display a blank line, between user messages for more
elegant presentation, for example
:top Example of a loop
(script actions…)
goto top
set creates a variable, e.g. set name=Laura, and to resolve what the name is
surround it with % %, e.g. echo %name% would display Laura
/a to get mathematical interpretation
== or EQU is equals, e.g. if %you%==1 echo %v1% - if the variable you equals 1 then
the variable v1 will display
NEQ is not equals
rem use to ignore everything on the line following the rem, including quotes,
redirection symbols, and other commands
%~d1%~p1 active folder
2
PhUSE EU Connect 2018
And in so doing, by running our script, we have backed up our files and are now covered in case of accidental file
overwrite or removal.
@ECHO off
ECHO.
ECHO.To clean content of the sub-folders Lst/Log/Output/Data
ECHO.
ECHO =============== Execution Start ===============
ECHO.
SET /P AREYOUSURE=Are you sure (y/[n])?
IF /I "%AREYOUSURE%" NEQ "y" GOTO END
ECHO - Removing lst files stored within the 'Lst' folder
del "%~dp0\..\Lst\*.lst" /f /q
ECHO - Removing log files stored within the 'Log' folder
del "%~dp0\..\Log\*.log" /f /q
ECHO - Removing rtf files stored within the 'Output' folder
del "%~dp0\..\Output\*.rtf" /f /q
ECHO - Removing sas7bdat files stored within the 'data' folder
del "%~dp0\..\Data\*.sas7bdat" /f /q
ECHO.
:END
ECHO =============== Execution completed ===========
ECHO.
PAUSE
First we SET or create the variable AREYOUSURE, because we’ve had feedback in the past that people were not so
sure they wanted to delete all their work, understandably. The /P is a sort of switch which allows the developer to set
3
PhUSE EU Connect 2018
the value of a variable to a line of input entered by the user, i.e. the user needs to answer the question “Are you sure
(y/n)?” with a y or n before any files are removed. The /I may be used to ignore case sensitivity here. If they answer
“n”, the script will go to the end (GOTO END) and not perform any action. Otherwise, it moves to the folders of interest
and deletes the file types we have specified in those folders, e.g. logs in the Log folder, lsts in the Lsts and so on.
The “%~dp0” variable when referenced within a Windows batch file will expand to the drive letter and path of that
batch file, so when the script is run from a specific folder, in our case we run from a Pgm sub-folder, del
"%~dp0\..\Lst\*.lst" /f /q moves up and then down a level to the Lst sub-folder and removes all lst files it finds
there, ignoring any read-only setting (/f) and without prompting (/q for “quiet mode”).
Stepping the pace up a bit, to run a program or set of programs in batch, saving the log and lst in their appropriate
folders, we could use the following:
@ECHO off
ECHO ============================== batch BEGIN ===========================================
ECHO.
ECHO Batch execution started at %Time%
ECHO Detection of the active folder = %~d1%~p1
set /A NbProgsRan=0
set /A NbProgsRan+=1
ECHO.
)
ECHO.
ECHO ================================= batch END ================================================
PAUSE
First the log and lst folders need to be set: if they are subfolders in the folder from where the program is run,
%~d1%~p1\log or in another subfolder at the same level as the program %~d1%~p1..\log , or neither, in which case
they are stored with the program.
Every program dropped into the batch script, FOR %%A IN (%*) DO ( is then run
"D:\SAS94\SASHome\SASFoundation\9.4\sas.exe" -sysin "%~d1%~p1%%~nA%%~xA".
with their corresponding log/lst saved in the LogFolder/Lstfolder
-log "%LogFolder%\%%~nA.log" -print "%LstFolder%\%%~nA.lst"
4
PhUSE EU Connect 2018
We’d also however like the script to now tell us what happened in the logs. We can do this by adding a log scan for
messages of interest,
set /A TotalNbOfLogERROR=0
set /A TotalNbOfLogWARNING=0
….
ECHO --- Log scanning - messages are displayed by decreasing order of criticality:
findstr /A:4F /n "ERROR fatal" "%LogFolder%\%%~nA.log"
findstr /A:2F /n "WARNING uninitialized unequal" "%LogFolder%\%%~nA.log"
findstr /A:1F /n /c:"MERGE statement has more than" "%LogFolder%\%%~nA.log"
ECHO.
)
and summarize the number found using,
rem --- to compute the cumulative number of ERROR or WARNING message(s) in the log files
if exist "%LogFolder%\%%~nA.log" (
for /f "tokens=*" %%j in ('findstr "ERROR" "%LogFolder%\%%~nA.log"') do @SET /A
TotalNbOfLogERROR += 1
for /f "tokens=*" %%j in ('findstr "WARNING" "%LogFolder%\%%~nA.log"') do @SET /A
TotalNbOfLogWARNING += 1
)
By adjusting color we can highlight for users any important messages found, we liked red for errors or warnings
found, and green if there were none, following the color codes:
For example:
if "!TotalNbOfLogERROR!" gtr "0" (
rem Call :Color 4F "FAILED:"
rem ECHO. Total number of ERROR messages in the log files: !TotalNbOfLogERROR!
powershell.exe "(Write-Host -NoNewLine -BackgroundColor """DarkRed""" -ForegroundColor
"""White""" Total number of ERROR messages in the log files: !TotalNbOfLogERROR!. )"
echo.
)
5
PhUSE EU Connect 2018
OTHER EXAMPLES
PROGRAM CREATION WITH STANDARD HEADER
Because we like to follow Good Programming Practice, “A standard header should be used for every program”, we
again use batch script to do the work (see the appendix for the full script).
users are prompted to enter a program name. To avoid unintentional overwriting of an existing program, one could
add a check if the file already exists, or will receive a warning if the program already exists:
Details to include in the program header and body can be sent to the sas program (defined in SASfile) via all
commands starting with @echo and ending with >> "%SASfile%.sas”. The directory in which the program is created
can be added using %CD% if desired.
Similarly, comments can be included in the body of the program using a leading % symbol, i.e.
@echo %%*--- at output level: save lst file if generated;>> "%SASfile%.sas"
6
PhUSE EU Connect 2018
To ensure the FileAlreadyExists message is not displayed even when a new program is being created, a goto
may be deployed to skip it goto :DONE… (:FileAlreadyExists….) :Done.
This example is managed by a VBS code which is having 2 arguments, i.e. the 2 files selected that the user wants to
compare. The script is opening in hidden mode the first file with MS Word, and is making use of the track changes
facility to open the second file and proceed to the comparison between the 2 files.
The differences are highlighted and saved in a new doc file as displayed above; the MS Word session opened
temporarily is then closed so the user would only see on the screen one window at the completion of the execution,
as following:
The comparison could be done on any file that MS Word is able to open, that is including txt files: so this script can
also be used advantageously to compare the 2 versions of one SAS program.
CALLING SCRIPTS
One of the selling-point of scripts like these is that they can be called or launched in a variety of ways, at least one of
which should satisfy the most fastidious of users. These principles could apply to any script.
7
PhUSE EU Connect 2018
Taking the run program script mentioned earlier, this is called simply by dragging-and-dropping the
arguments (=a selection of files!) over the .bat script, directly from the window explorer interface:
Another option is via the windows explorer ‘send to’ menu. Take the compare script we covered, it is copied
to the users local profile e.g. [drive]:\Users\[username]\AppData\Roaming\Microsoft\Windows\SendTo. Back
at the server, the 2 outputs to compare are selected, right-clicked and the user scrolls to the script action, in
this case “Compare the 2 word files selected”.
8
PhUSE EU Connect 2018
Windows Script Host (.vbs, .js and .wsf) - released by Microsoft in 1998, and consisting of cscript.exe and
wscript.exe, runs scripts written in VBScript or JScript. It can run them in windowed mode (with the
9
PhUSE EU Connect 2018
wscript.exe host) or in console-based mode (with the cscript.exe host). They have been a part of Windows
since Windows 98.
PowerShell (.ps1) — released in 2006 by Microsoft and can operate with Windows XP (SP2/SP3) and later
versions. PowerShell can operate both interactively (from a command-line interface) and also via saved
scripts, and has a strong resemblance to Unix® shells.
Unix-style shell scripting languages can be used if a Unix compatibility tool, such as Cygwin, is installed.
Cross-platform scripting tools including Perl®, Python®, Ruby®, Rexx® Node.js and PHP® are available for
Windows.
Since 2016, active release and support of Windows Subsystem for Linux (WSL) upon which several Linux
distros now run; WSL aims for native Linux compatibility.
CONCLUSION
Following the thought process involved as described in this paper, you can use scripts as stepping stones to build a
bigger process. Whatever could be the scripting language of your choice, start with considering a script as a unit of
task:
o Split the process, identify routine tasks
e.g. Back-up / Clean-up / Program Run / Log check / Summary
o Select most appropriate programming language, ideally, trying to do abstraction:
from other languages
from specialized software (code resources will be more limited)
o Build each process like a wall: modules can be added brick by brick to build a complete ‘solution’,
o Take care of the user experience
in requesting minimal action from his side (e.g. by counting the number of mouse clicks
requested to perform one operation) ,
and in prompting his input appropriately: for instance confirmation before a critical action
is performed.
o Interface your program with other software (text editors, call from SAS with the x command, etc.), so
their integration is optimal
o Be minimal in the writing of a program. for maintenance and ease of updates
An organized library of scripts can result in an entire solution, e.g. automating all the sequence of a production run:
10
PhUSE EU Connect 2018
REFERENCES
Narkov scripts: https://fossbytes.com/this-lazy-programmer-wrote-some-scripts-to-secretly-automate-a-lot-of-his-job/
Windows batch scripting: https://en.wikipedia.org/wiki/Batch_file
Guide to Windows Batch Scripting: http://steve-jansen.github.io/guides/windows-batch-scripting/
DosTips - The DOS Batch Guide: https://www.dostips.com/
Running Windows or MS-DOS Commands from within SAS:
http://support.sas.com/documentation/cdl/en/hostwin/63285/HTML/default/viewer.htm#exittemp.htm
SAS Batch processing under Windows:
https://communities.sas.com/t5/SAS-Communities-Library/Batch-processing-under-Windows/ta-p/475977
ACKNOWLEDGMENTS
We would like to also thank Remi Gerin for his “laziness” and “fussiness” leading to several script developments that
has made the lives of our programming teams easier.
CONTACT INFORMATION
Your comments and questions are valued and encouraged. Contact the author at:
Nicolas Rouillé
Cytel Inc.
Route de Pré-Bois 20
1215 Geneva – Switzerland
Email: [email protected]
Laura Phelan
Cytel France Sarl
63, Avenue des Champs Elysées
75008 Paris, France
Email: [email protected]
Web: www.cytel.com
11
PhUSE EU Connect 2018
APPENDIX
FULL SCRIPT: DRAG AND DROP PROGRAM(S) RUN BATCH SCRIPT
12
PhUSE EU Connect 2018
13