How to Check Whether a Subsystem Is Active in IBM i Using CL
If you’ve spent any time automating operations on IBM i, you’ve probably bumped into this classic requirement: “Before I run this job, I need to know whether a subsystem is active.”
It sounds simple, but depending on your tooling and IBM i version, there are several ways to approach it. Some are modern and elegant. Others are… let’s say “heritage techniques.” In this post, we’ll walk through the three most common methods so you can choose the one that fits your environment.
Option 1: The Modern Way — Query SUBSYSTEM_INFO with SQL
If your system is reasonably up to date, IBM has gifted us a clean solution: the QSYS2.SUBSYSTEM_INFO view. It tells you exactly what you want to know, including whether a subsystem is ACTIVE, INACTIVE, ENDING, or RESTRICTED.
You can call it directly from CL using RUNSQL.
“But RUNSQL does not output to an outfile!” I can hear you exclaim!
Don’t worry, we will simply do a little SQL CREATE TABLE trick like this:
/* Code sample from https://www.nicklitten.com/ibm-i-control-language-check-subsystem-status/ */
PGM
DCLF FILE(QTEMP/CHKSBSTMP) ALWVARLEN(*YES)
DLTF FILE(QTEMP/CHKSBSTMP)
MONMSG MSGID(CPF0000)
RUNSQL SQL('CREATE TABLE QTEMP/CHKSBSTMP AS (SELECT +
STATUS FROM QSYS2/SUBSYSTEM_INFO WHERE +
SUBSYSTEM_DESCRIPTION = ''QINTER'' AND +
SUBSYSTEM_DESCRIPTION_LIBRARY = ''QSYS'') +
WITH DATA') COMMIT(*NONE) NAMING(*SYS)
RCVF RCDFMT(*FILE)
MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(FAIL))
SNDPGMMSG MSG('Subsystem QINTER is' *BCAT %SST(&STATUS 3 10))
RETURN
FAIL: SNDPGMMSG MSG('* Unable to retrieve subsystem status!')
ENDPGM
Why this method rocks
- No APIs to wrangle
- No parsing of spool files
- Works beautifully with modern tooling like ACS and VS Code
- Gives you precise subsystem state, not just “running or not”
If you’re on a current TR, this is the method to use.
Option 2: The Classic Way — Use the QWDRSBSD API
Before SQL views existed, the standard way to check subsystem status was the QWDRSBSD API. It’s still fully supported and works on every IBM i release you’re likely to encounter.
PGM
DCL VAR(&SBSNAME) TYPE(*CHAR) LEN(10) VALUE(QINTER)
DCL VAR(&SBSLIB) TYPE(*CHAR) LEN(10) VALUE(QSYS)
DCL VAR(&QUALNAME) TYPE(*CHAR) LEN(20)
DCL VAR(&RCVVAR) TYPE(*CHAR) LEN(512)
DCL VAR(&RCVLEN) TYPE(*INT) LEN(4) VALUE(512)
DCL VAR(&FORMAT) TYPE(*CHAR) LEN(8) +
VALUE('SBSI0100')
DCL VAR(&ERRCODE) TYPE(*CHAR) LEN(16) +
VALUE(X'00000000')
DCL VAR(&STATUS) TYPE(*CHAR) LEN(10)
CHGVAR VAR(&QUALNAME) VALUE(&SBSNAME *CAT &SBSLIB)
CALL PGM(QWDRSBSD) PARM((&RCVVAR) (&RCVLEN) +
(&FORMAT) (&QUALNAME) (&ERRCODE))
MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(FAIL))
/* Extract subsystem status (positions 29-38 in SBSI0100) */
CHGVAR VAR(&STATUS) VALUE(%SST(&RCVVAR 29 10))
SNDPGMMSG MSG('Subsystem QINTER is' *BCAT &STATUS)
RETURN
FAIL: SNDPGMMSG MSG('* Unable to retrieve subsystem status!')
ENDPGM
Why you might choose this method
- Works everywhere
- No SQL required
- Reliable and battle tested
If you’re maintaining older systems or writing code that must run across mixed environments, this is a safe choice.
Option 3: The Quick and Dirty Way — WRKSBS + MONMSG
Sometimes you just need a fast check and you don’t care about elegance. In that case, you can rely on the fact that WRKSBS fails if the subsystem isn’t active.
PGM
QSYS/WRKSBSJOB SBS(QINTER) OUTPUT(*PRINT)
MONMSG MSGID(CPF0000) EXEC(DO)
SNDPGMMSG MSG('Subsystem QINTER is NOT active')
RETURN
ENDDO
SNDPGMMSG MSG('Subsystem QINTER is active')
ENDPGM
Pros and cons
- ✔ Very simple
- ✔ Works on any release
- ✘ Not precise
- ✘ Depends on command failure, which is never ideal
Use this only when you need a quick‑and‑dirty solution.
So, Which Method Should You Use?
If your system supports it, SQL SUBSYSTEM_INFO is the clear winner. It’s clean, modern, and gives you the exact subsystem state without any fuss.
If you’re working on older systems or writing code that must run everywhere, the QWDRSBSD API is your dependable workhorse.
And if you’re in a hurry, well… the WRKSBS trick will get the job done.
Do you want to see a reusable CL command (CHKSBSACT), complete with return variables and message handling? Then jump over to my CL Programming Course lesson here
What is IBM CL?
IBM i Control Language (CL) is a powerful scripting language for the IBM AS/400, IBM iSeries and IBM i Systems. It’s got roots in the older IBM Job Control Language, and it works as a simple way to script commands, instructions and other functions into an easy-to-understand programs.
