Linux, and Unix in general, and in fact
operating systems in general, all provide this facility ... through the notion of "scripting languages."
In the Unix environments, you typically have several such languages at your disposal: Bash-scripts; Perl; Python; Java; even PHP can be pressed into service. If you begin a file with
#!language_processor_name, this tells the shell what language-processor to invoke to "run" the file when, having made the file "executable," you type-in its name. So, you can write it in any language you please, and It Just Works.™
Microsoft Windows finally came on-board with a halfway decent shell ..
.. which they call PowerShell, and which of course is totally different. (Microsoft is like that...)
All of these facilities have the ability to "exec" another process as a child of itself, and to wait for that process to complete, collecting a return-code that is provided by the program when it exits. Just like MVS did. It's just a whole heck-of-a-lot more powerful and flexible than JCL ever was.
You could, for example, write a command which contains a list of SAS programs that are to be executed, and it cycles through that list, invoking
sas program_name and waiting for that run to complete. If the return-code is zero, indicating success, it continues running through the list. If nonzero, your program would print an error-message of some kind and stop.