Best Practices and How-to for Administration of SLC Servers on Linux - Part 5 of 5
Appendix A: Example Autoexec.sas Program
/* autoexec.sas - SAS Automatic Startup Configuration
Author: Altair Americas Support team
Date: August 2025
Purpose: Configure SLC/SAS environment and autocall macro libraries
NOTE: Sets up environment - does NOT run any macros
NOTE: Is dependent on the AUTOCALL Macro Library is defined*/
/* Configure basic system options */
options
linesize=120
pagesize=60
date
number
source
mautosource;
/ Set up autocall macro library */
options sasautos=("/opt/slc_autocall" sasautos);
/* Set up global macro variables */
%global PROJECT_ROOT LOG_DIR CONFIG_DIR;
%let PROJECT_ROOT = /home/%sysget(USER)/projects;
%let LOG_DIR = /var/log/slc;
%let CONFIG_DIR = /etc/slc/authd;
/* Define utility macro */
%macro show_sasautos;
%put NOTE:- - - - - - - - - - - - - - - - - - - - - - -;
%put NOTE: SASAUTOS Search Path:;
%put NOTE: &sasautos;
%put NOTE:- - - - - - - - - - - - - - - - - - - - - - - ;
%mend show_sasautos;
/* Consolidated startup message */
%put;
%put;
%put NOTE:
================================================================;
%put NOTE: SLC Custom Configuration Loaded Successfully;
%put NOTE:
================================================================;
%put NOTE: User: %sysget(USER);
%put NOTE: Date: %sysfunc(today(), date9.);
%put NOTE: Time: %sysfunc(time(), time8.);
%put NOTE: Session: %sysfunc(datetime(), datetime20.);
%put NOTE: Current Directory: %sysget(PWD);
%put NOTE:- - - - - - - - - - - - - - - - - - - - - - - - - - - ;
%put NOTE: Environment Configuration:;
%put NOTE:PROJECT_ROOT = &PROJECT_ROOT;
%put NOTE:LOG_DIR = &LOG_DIR;
%put NOTE:CONFIG_DIR = &CONFIG_DIR;
%put NOTE:- - - - - - - - - - - - - - - - - - - - - - - - - - - ;
%put NOTE: Autocall Library: /opt/slc_autocall;
%if %sysfunc(fileexist(/opt/slc_autocall)) %then %do;
%if
%sysfunc(fileexist(/opt/slc_autocall/slc_connect_to_bq_libname.sas))
%then %do;
%put NOTE:✓ BigQuery connection macro available;
%end;
%if %sysfunc(fileexist(/opt/slc_autocall/hello.sas)) %then %do;
%put NOTE:✓ Hello welcome macro available;
%end;
%end;
%else %do;
%put WARNING: Autocall directory /opt/slc_autocall not found;
%end;
%put NOTE:
===================================================================;
%put;
%put;
options source source2;
/* Run welcome message from autocall library */
%hello;
Appendix B: hello.sas Macro
/*
*HELLO.SAS-Welcome message macro for SLC autocall library
*Usage: %hello;
*Displays welcome message and BigQueryconnectionexamples
*/
%macro hello;
%put;
%put;
%put NOTE:
================================================================;
%put NOTE: Welcome to SLC, %sysget(USER)!;
%put NOTE: Current directory: %sysget(PWD);
%put NOTE: Available custom macros in /opt/slc_autocall;
%put NOTE:
=================================================================;
%put NOTE: BigQuery Connection Examples:;
%put NOTE:- - - - - - - - - - - - - - - - - - - - - - - - - -;
%put NOTE: Positional parameter:;
%put NOTE:
%str(%%)slc_connect_to_bq_libname(/home/trb/.gcp/bigquery-service- account.json);
%put NOTE: Named parameter:;
%put NOTE: %str(%%)slc_connect_to_bq_libname(credpath=/home/trb/.gcp/bigquery- service-account.json);
%put NOTE: Environment variable (set BIGQUERY_OAUTH_TOKEN first):;
%put NOTE:%str(%%)slc_connect_to_bq_libname();
%put NOTE:
================================================================;
%put;
%put;
%mend hello;
Appendix C: SLC_CONNECT_TO_BQ_LIBNAME.sas
/*
*SLC_CONNECT_TO_BQ_LIBNAME.SAS
*SimpleBigQueryconnectionmacro
*Usage: %slc_connect_to_bq_libname(/path/to/key.json);
* %slc_connect_to_bq_libname(credpath=/path/to/key.json);
* %slc_connect_to_bq_libname();-usesBIGQUERY_OAUTH_TOKEN env var
*/
%macro slc_connect_to_bq_libname(credpath);
%localkey_file;
%put NOTE: [SLC_BQ] Starting BigQuery connection;
/*Set credential path*/
%if %length(&credpath)>0 %then %do;
%letkey_file=&credpath;
%end;
%else %do;
%let key_file=%sysget(BIGQUERY_OAUTH_TOKEN);
%end;
/*Validate credential path*/
%if %length(&key_file)=0 %then %do;
%put ERROR: [SLC_BQ] No credential path specified;
%put ERROR: [SLC_BQ] Set BIGQUERY_OAUTH_TOKEN or pass credpath parameter;
%return;
%end;
/*Check file exists*/
%if not %sysfunc(fileexist(&key_file)) %then %do;
%put ERROR: [SLC_BQ] Service account file not found: &key_file;
%return;
%end;
/*Check file permissions */
%sysexec ls -l "&key_file" | awk '{print$1}' > /tmp/bq_perm.txt;
data_null_;
infile '/tmp/bq_perm.txt';
input perms $10.;
if substr(perms,2,9) ne 'rw-------' then do;
put "WARNING: [SLC_BQ] Insecure file permissions: " perms;
put "WARNING: [SLC_BQ] File: &key_file";
put "WARNING: [SLC_BQ] Recommend: chmod 600 &key_file";
end;
run;
%sysexec rm -f /tmp/bq_perm.txt;
/* Establish BigQuery connection */
LIBNAME bq BIGQUERY
dsn="bq"
account="bigquery-464517"
database="bigquery-464517"
schema="ESA_CREDIT_RISK_USER_VIEWS"
private_key_path="&key_file"
scanstringcolumns=yes
dbmax_text=1024;
/* Validate connection */
%if %sysfunc(libref(bq)) = 0 %then %do;
%put NOTE: [SLC_BQ] Connection successful using: &key_file;
%end;
%else %do;
%put ERROR: [SLC_BQ] Connection failed - check credentials;
%end;
%mend slc_connect_to_bq_libname;
/* Call the macro */
%slc_connect_to_bq_libname;
Apendix D: TEST_CONNECT_TO_BQ_LIBNAME.sas
%include"/opt/slc_autocall/slc_connect_to_bq_libname.sas";
%slc_connect_to_bq_libname(/home/trb/.gcp/bigquery-service- account.json);
%if %sysfunc(libref(bq)) ne 0 %then %do;
%put ERROR: Big Query connection failed;
%abort;
%end;
/*Create test data*/
data bq_info;
process_datetime=datetime();
process_id = "&sysjobid";
test_message='BigQuery Connection Test';
sas_user = "%sysget(USER)";
formatted_datetime=put(datetime(),datetime20.);
output;
run;
data_null_;
setbq_info;
put "NOTE: [SLC_BQ_TEST]===========================";
put "NOTE: [SLC_BQ_TEST] BigQuery Connection Test";
put "NOTE: [SLC_BQ_TEST]===========================";
put "NOTE: [SLC_BQ_TEST]Process DateTime: "formatted_datetime;
put "NOTE: [SLC_BQ_TEST] Process ID: " process_id;
put "NOTE: [SLC_BQ_TEST] Test Message: "test_message;
put "NOTE: [SLC_BQ_TEST] SAS User: " sas_user;
put "NOTE: [SLC_BQ_TEST] Connection: SUCCESS";
put "NOTE: [SLC_BQ_TEST]===========================";
run;
proc datasets library =work nolist;
delete bq_info;
quit;
Appendix E: SLC_GET_ENVIRONMENT_VARS.sas
/*
*SLC_GET_ENVIRONMENT_VARS.SAS - Read all SLC environment variables
*Usage: %slc_get_environment_vars();
*Returns all environment variables currently defined in the SLC process
*/
%macro slc_get_environment_vars();
%local temp_file;
%let temp_file = /tmp/slc_env_output_&sysjobid..txt;
/* Capture environment variables to temporary file */
%sysexec env | sort > &temp_file;
options nosource nosource2 ls=200;
%put;
%put;
%put NOTE:
================================================================;
%put NOTE: â•‘ â•‘;
%put NOTE: â•‘SLC Environment Variables Currently Defined â•‘;
%put NOTE: â•‘ â•‘;
%put NOTE:
================================================================;
%put NOTE: All environment variables from current SLC process;
%put NOTE:- - - - - - - - - - - - - - - - - - - - - - - - - - - ;
/* Read and display environment variables with no DATA step messages */
data null;
retain var_count 0;
infile "&temp_file" truncover end=eof;
input env_line $2000.;
/* Parse variable name and value */
if index(env_line, '=') > 0 then do;
var_name = scan(env_line, 1, '=');
var_value = substr(env_line, index(env_line, '=') + 1);
/* Format with fixed alignment */
name_with_colon = strip(var_name) || ":";
put "NOTE " name_with_colon $35. var_value;
var_count + 1;
end;
if eof then call symputx('line_count', var_count);
run;
%put NOTE: - - - - - - - - - - - - - - - - - - - - - - -- - - - - ;
%put NOTE: Total environment variables found: &line_count;
%put NOTE:========================================================;
%put;
%put;
options source source2;
/* Clean up temporary file */
%sysexec rm -f &temp_file;
%mend slc_get_environment_vars;
/* Call the macro */
%slc_get_environment_vars;
Appendix F: Example altairslcenv.sh file
#! /bin/bash
#Updated SLC BigQuery Environment Setup (based on Altair support config)
#Clean up existing LD_LIBRARY_PATH to prevent duplicates export LD_LIBRARY_PATH=""
#Core SLC paths (lib and lib64 don't exist, libraries are in bin) export LD_LIBRARY_PATH="/opt/altair/slc/2026/bin"
#Add system library paths
#export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/lib/x86_64-linux- gnu:/usr/lib64:/usr/local/lib"
#Add Simba BigQuery driver path
#export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/opt/simba/googlebigqueryodbc/lib"
#Add Microsoft SQL Server ODBC driver path
#export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/opt/microsoft/msodbcsql17/lib64"
#ODBC Configuration - Use SLC's etc directory
#export ODBCINI=/opt/altair/slc/2026/etc/odbc.ini
#export ODBCSYSINI=/opt/altair/slc/2026/etc
#export ODBCINSTINI=/opt/altair/slc/2026/etc/odbcinst.ini
#Simba-specific configuration (use proper variable name)
#exportSIMBAGOOGLEBIGQUERYODBCINI=/opt/altair/slc/2026/etc/simba.googlebigqueryodbc.ini
#Google Cloud credential
#sexport GOOGLE_APPLICATION_CREDENTIALS=/home/trb/.gcp/bigquery-service- account.json
#SSL certificates
#export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
#export SSL_CERT_DIR=/etc/ssl/certs
#export CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
#export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
#PATH
#export PATH="/opt/altair/slc/2026/bin:$PATH"