The short answer
No single CALL SYSTEM syntax guarantees identical behavior on IBM i, Unix, and Linux, because the port of CALL SYSTEM itself differs: on IBM i it routes through the system command interface and (in some REXX implementations there) quoted commands can return captured output, while on Unix/Linux it typically forks a shell and only the numeric exit status comes back. What you can guarantee everywhere is the return code — so the reliable design is: treat the exit status as the only cross-platform signal, push all output capture into shell redirection, and verify restored data with checksums computed outside the backup tool's own success message.
What is confirmed vs. assumed
Confirmed by general shell behavior: a command invoked through a system-call wrapper returns the child process's exit status, and a well-behaved utility (tar, rsync, db2) exits non-zero on failure. That part is portable.
Likely, but verify on your exact interpreter: the IBM i output-capture-into-a-variable feature for quoted commands is an implementation extension, not part of portable REXX. Classic Regina and ooRexx on Unix/Linux do not capture stdout this way; output goes to the terminal unless you redirect it. Because REXX variants differ, treat any capture-on-IBM-i behavior as platform-specific and confirm it against your interpreter's documentation before depending on it — this is the piece most likely to silently change meaning when the script is ported.
A portable pattern
Standardize on this shape on every platform:
cmd = 'tar -xf backup.tar -C /restore/dir 2>/tmp/restore.err'
rc = 0
CALL SYSTEM cmd
rc = RESULT /* or RC, depending on interpreter */
if rc <> 0 then do
say 'Restore failed, rc='rc
exit rc
end
Key points:
- Redirect output in the command string itself (
>log 2>&1 on Unix/Linux; on IBM i, spool or file redirection appropriate to the shell you invoke). Never rely on the REXX variable-capture extension if the script must run on Unix/Linux. - Check the status explicitly after every CALL SYSTEM. Do not assume the interpreter raises an error condition on non-zero exit — in many REXX ports it does not; the code just lands in RC/RESULT and execution continues, which is exactly how silent corruption happens.
- Keep utility flags per-platform. tar option syntax (especially around compression and numeric-owner flags) and db2 restore syntax differ. Isolate them in a small platform-detection block rather than assuming one syntax.
Verifying the restored data
Exit status alone does not prove integrity — a restore can "succeed" while producing truncated or stale files. Add a verification layer that is identical on all platforms:
- At backup time, generate a manifest of SHA-256 checksums for the archived files and store it with (or alongside) the backup.
- After restore, recompute checksums and compare against the manifest. On Unix/Linux use
sha256sum -c manifest.txt; on IBM i use the equivalent available hash tool or a small script. Invoke this via a second CALL SYSTEM and check its status too. - Treat a checksum mismatch as a hard failure, even if the restore command returned zero.
Be cautious with compression and encryption options: enable them only after confirming the same algorithm and version exist on every target platform, and confirm decryption keys are present before starting — a missing key typically aborts mid-restore, leaving a partial tree. Also test overwrite behavior in staging first: unconditional overwrite can silently replace newer files.
One detail that would change this advice
Which REXX interpreter (and version) is running on each platform matters — the exact name of the status variable, whether CALL SYSTEM raises an error condition, and whether IBM i output capture is available all depend on it. If you can share that, the status-check idiom above can be made exact instead of defensive.