Perl's system() returns the code shifted left 8 bits (1 becomes 256): use exit($? >> 8).
In a pipe (script | tee log) the shell returns the last command's status: use set -o pipefail.
A script that ends with echo or another command returns that command's status: exit with the real code explicitly.
Test outside AutoSys: run the wrapper, then echo $?.
✦ Definition~90s read
What is AutoSys Shows SUCCESS but the Script Failed?
AutoSys decides SUCCESS or FAILURE from one number: the exit status of the command it started (0 means success, unless you change it with max_exit_success). When AutoSys 'gets it wrong', a wrapper, a pipe, or an out-of-range exit value changed that number before AutoSys saw it.
★
AutoSys only reads the final score, never the match report.
Plain-English First
AutoSys only reads the final score, never the match report. If the wrapper copies the score down wrong, AutoSys believes it. The fix is always in the wrapper.
The log is full of ORA- errors, but AutoSys says SUCCESS and the downstream reports ran on empty tables. It looks like AutoSys is lying. It isn't: it reported exactly the number the process returned. This guide shows the three common ways that number gets changed, and how to stop each one.
What AutoSys Actually Reads
AutoSys starts your command and waits for it to exit. The exit status, a number from 0 to 255, decides the result: 0 is SUCCESS and anything else is FAILURE, unless max_exit_success says otherwise. It doesn't read the job's output or log. If the number is wrong, the status is wrong.
test_wrapper.shBASH
1
2
/apps/fin/bin/run_load.pl
echo "exit status: $?"
Output
ORA-01653: unable to extend table FIN.TXN
exit status: 0
🎯 Key Takeaway
AutoSys trusts the exit status, and only that.
Exit 256 Wraps to 0
An exit status keeps only its low 8 bits. 256 in binary is 1 followed by eight zeros, so its low 8 bits are all zero: exit 256 is seen as 0. Perl's system() returns the child's status shifted left by 8, so a child that exits 1 gives 256, and exit(system(...)) turns a failure into success.
run_load.plPERL
1
2
3
4
5
# Wrong: a failure (256) becomes exit 0
# exit(system('/apps/fin/load.sh'));
system('/apps/fin/load.sh');
exit($? >> 8); # 1, the real exit code
⚠ Any multiple of 256 is 0
512, 768 and so on also wrap to 0. Never exit with a value above 255.
🎯 Key Takeaway
Shift the status back: exit($? >> 8).
Pipes Hide Failures
In a pipeline like load.sh | tee load.log, the shell returns the status of the last command, tee, which almost always succeeds. Your load can fail and the job still shows SUCCESS. set -o pipefail makes the pipeline return the first non-zero status instead.
wrapper.shBASH
1
2
3
4
#!/bin/bash
set -o pipefail
/apps/fin/load.sh 2>&1 | tee /apps/fin/logs/load.log
exit $?
🎯 Key Takeaway
Pipelines return the last command's status unless pipefail is set.
The Last Command Wins
A script without an explicit exit returns the status of its last command. A failed load followed by echo "done" or a cleanup rm exits 0. Save the real status straight after the work, and exit with it.
Some tools return small non-zero codes for warnings. If that's genuinely OK, say so in the job with max_exit_success rather than hiding codes in a wrapper, so the rule is visible to everyone.
job.jilTEXT
1
2
update_job: FIN_COPY
max_exit_success: 1 /* 0 and 1 both count as success */
🎯 Key Takeaway
Widen success in the JIL, not in a wrapper.
● Production incidentPOST-MORTEMseverity: high
SUCCESS With an Empty Table
Symptom
FIN_LOAD showed SU with exit code 0, but load.log ended with ORA-01653 and the table was empty. Reports ran on no data.
Assumption
The team assumed AutoSys was misreporting and raised a vendor ticket.
Root cause
A Perl wrapper ran exit(system('/apps/fin/load.sh')). load.sh exited 1, system() returned 256 (1 shifted left 8 bits), and exit(256) wrapped to 0 because exit statuses keep only 8 bits.
Fix
Changed the wrapper to exit($? >> 8), added set -o pipefail to shell wrappers that pipe into tee, and added a test that runs each wrapper with a forced failure and checks echo $?.
Key lesson
AutoSys reports what the process returned.
Exit 256 is exit 0.
Test wrappers with a forced failure.
Production debug guideFind where the number changed5 entries
Symptom · 01
Script failed, AutoSys shows SUCCESS
→
Fix
Run the job's exact command outside AutoSys, then echo $?. If it prints 0, the wrapper is the problem.
Symptom · 02
Perl or Python wrapper
→
Fix
Check how it returns the child's status. Perl: exit($? >> 8). Python: sys.exit(subprocess.run(...).returncode).
Symptom · 03
Command contains a pipe
→
Fix
Without pipefail the last command's status wins. Add set -o pipefail.
Symptom · 04
Script ends with echo, rm or logging
→
Fix
That last command's status is returned. Save rc=$? after the real work and exit $rc.
Symptom · 05
Success expected on a non-zero code
→
Fix
Some tools return 1 for warnings. Use max_exit_success deliberately, not as a workaround.
⚙ Quick Reference
5 commands from this guide
File
Command / Code
Purpose
test_wrapper.sh
/apps/fin/bin/run_load.pl
What AutoSys Actually Reads
run_load.pl
system('/apps/fin/load.sh');
Exit 256 Wraps to 0
wrapper.sh
set -o pipefail
Pipes Hide Failures
load.sh
sqlplus -s user/@FINDB @load.sql
The Last Command Wins
job.jil
update_job: FIN_COPY
When Non-Zero Should Count as Success
Key takeaways
1
AutoSys reports the process exit status, nothing else.
2
Exit statuses keep 8 bits
256 becomes 0.
3
In Perl, return $? >> 8.
4
Pipelines need set -o pipefail.
5
Test every wrapper with a forced failure and echo $?.
Common mistakes to avoid
3 patterns
×
Blaming AutoSys
Symptom
Vendor ticket, no fix.
Fix
Run the command and echo $?: AutoSys shows that number.
×
exit(system(...)) in Perl
Symptom
Failures show as SUCCESS.
Fix
exit($? >> 8).
×
Piping into tee without pipefail
Symptom
Failed loads succeed.
Fix
set -o pipefail.
INTERVIEW PREP · PRACTICE MODE
Interview Questions on This Topic
Q01SENIOR
A script logs an error but AutoSys shows SUCCESS. Where do you look?
Q02SENIOR
Why does exit 256 count as success?
Q01 of 02SENIOR
A script logs an error but AutoSys shows SUCCESS. Where do you look?
ANSWER
At the exit status the wrapper returns: run it and echo $?. Common causes are pipes without pipefail, a final command that succeeds, or an exit value above 255.
Q02 of 02SENIOR
Why does exit 256 count as success?
ANSWER
Exit statuses keep only the low 8 bits; 256's low 8 bits are 0.
01
A script logs an error but AutoSys shows SUCCESS. Where do you look?
SENIOR
02
Why does exit 256 count as success?
SENIOR
FAQ · 3 QUESTIONS
Frequently Asked Questions
01
Why does AutoSys show success when my script failed?
The process returned 0. Usually a wrapper, a pipe or the script's last command changed the exit status.
Was this helpful?
02
Why does exit code 256 show as 0?
Exit statuses are 8 bits, so values wrap: 256 is 0, 257 is 1.
Was this helpful?
03
What is max_exit_success in AutoSys?
The highest exit code AutoSys treats as success. The default is 0.