11#! /bin/sh
2+ #
3+ # Strict, portable POSIX-sh entrypoint that runs an arbitrary
4+ # command, captures its output, exit-code and coarse resource
5+ # usage, then prints a single-line JSON blob to stdout.
26
3- # This script is written in the strictest, most portable POSIX sh.
4- # It makes zero assumptions about the shell's features.
5-
6- # Use a simple, POSIX-compliant method for escaping JSON strings.
7+ # Very small, POSIX-compliant JSON string escaper
78json_escape () {
8- sed -e ' :a;N;$!ba' -e ' s/\\/\\\\/g' -e ' s/"/\\"/g' -e ' s/\n/\\n/g' -e ' s/\t/\\t/g' -e ' s/\r/\\r/g'
9+ sed -e ' :a;N;$!ba' \
10+ -e ' s/\\/\\\\/g' \
11+ -e ' s/"/\\"/g' \
12+ -e ' s/\n/\\n/g' \
13+ -e ' s/\t/\\t/g' \
14+ -e ' s/\r/\\r/g'
915}
1016
11- # Exit immediately if no command is provided.
17+ # ---------- argument check --------------------------------------------------
18+
1219if [ " $# " -eq 0 ]; then
13- printf ' {"exit_code": 127, "resource_usage": null, "stdout": "", "stderr": "Entrypoint Error: No command provided."}'
20+ printf ' {"exit_code":127,"resource_usage":null,"stdout":"","stderr":"Entrypoint Error: No command provided."}'
1421 exit 0
1522fi
1623
17- # Create temporary files for stdout and stderr. Exit if mktemp fails.
24+ # ---------- temp files & timing --------------------------------------------
25+
1826set -e
19- OUT=$( mktemp)
20- ERR=$( mktemp)
27+ OUT=" $( mktemp -t out.XXXXXX ) " || exit 1
28+ ERR=" $( mktemp -t err.XXXXXX ) " || exit 1
2129trap ' rm -f "$OUT" "$ERR"' EXIT
2230set +e
2331
24- # Record start time using nanosecond precision (%s for seconds, %N for nanoseconds).
25- START_TIME=$( date +%s.%N)
32+ START_TIME=" $( date +%s.%N) "
33+
34+ # ---------- run user command in the background -----------------------------
2635
27- # This subshell construct is the key. It isolates the user command.
28- # A failure inside this subshell will not crash our main script.
2936( " $@ " > " $OUT " 2> " $ERR " ) &
3037PID=$!
3138
39+ CLK_TCK=" $( getconf CLK_TCK 2> /dev/null || printf ' 100' ) "
3240PEAK_KB=0
3341JIFS=0
3442
35- # Loop while the process directory exists. This is the most reliable check.
36- while [ -d " /proc/$PID " ]; do
37- # Silence all errors from grep/cat to prevent log contamination from race conditions.
43+ # ---------- lightweight sampling loop --------------------------------------
44+
45+ # `kill -0` succeeds while the process is alive but does not send a signal.
46+ while kill -0 " $PID " 2> /dev/null; do
47+ # peak-RSS (VmHWM)
3848 CUR_KB=$( grep VmHWM " /proc/$PID /status" 2> /dev/null | awk ' {print $2}' )
3949 if [ -n " $CUR_KB " ] && [ " $CUR_KB " -gt " $PEAK_KB " ]; then
4050 PEAK_KB=$CUR_KB
4151 fi
4252
43- # Use awk for arithmetic; it handles empty/malformed input without crashing the shell.
44- CPU_JIFFIES=$( awk ' {print $14 + $15}' " /proc/$PID /stat" 2> /dev/null)
53+ # user + sys CPU time (jiffies)
54+ CPU_JIFFIES=$( awk ' {print $14+ $15}' " /proc/$PID /stat" 2> /dev/null)
4555 if [ -n " $CPU_JIFFIES " ]; then
4656 JIFS=$CPU_JIFFIES
4757 fi
48- sleep 0.05
58+
59+ # 5 ms sampling interval
60+ sleep 0.005
4961done
5062
51- # This will now work correctly because the parent script is not PID 1.
63+ # ---------- reap child & compute metrics -----------------------------------
64+
5265wait " $PID "
5366EXIT_CODE=$?
5467
55- END_TIME=$( date +%s.%N)
56- # Calculate elapsed time using floating-point math via awk, formatted to 6 decimal places.
57- # The result is stored in ELAPSED_S, which the original JSON block uses.
58- ELAPSED_S=$( printf ' %s\n' " $END_TIME $START_TIME " | awk ' {printf "%.6f", $1 - $2}' )
68+ END_TIME=" $( date +%s.%N) "
69+ ELAPSED_S=$( printf ' %s\n' " $END_TIME $START_TIME " | awk ' {printf "%.6f",$1-$2}' )
5970
60- # Defensively get clock ticks per second.
61- CLK_TCK=$( getconf CLK_TCK 2> /dev/null || printf " 100" )
71+ # ---------- emit single-line JSON ------------------------------------------
6272
63- OUT_JSON=$( cat " $OUT " | json_escape)
64- ERR_JSON=$( cat " $ERR " | json_escape)
65-
66- # Use the most robust printf format possible, passing all variables as arguments.
67- # The final output has NO trailing newline. This is critical.
68- json=$( cat << EOF
73+ printf ' %s' " $( cat << EOF
6974{
7075 "exit_code": ${EXIT_CODE:- 1} ,
7176 "resource_usage": {
@@ -78,7 +83,4 @@ json=$(cat <<EOF
7883 "stderr": "$( cat " $ERR " | json_escape) "
7984}
8085EOF
81- )
82-
83- # final output – no trailing newline!
84- printf ' %s' " $json "
86+ ) "
0 commit comments