Ran into this building a sandbox integration on @rivet-dev/agentos-core 0.2.15. python3 works on its own but vanishes as soon as it's inside a subshell.
import { AgentOs } from "@rivet-dev/agentos-core";
const vm = await AgentOs.create({});
for (const cmd of [
`python3 -c "print('hi')"`,
`python3 -c "print('hi')" | head -n 1`,
`sh -c "python3 -c 'print(1)'"`,
`echo hi | head -n 1`,
]) {
const r = await vm.exec(cmd);
console.log(`${cmd}\n exitCode=${r.exitCode} stdout=${JSON.stringify(r.stdout)} stderr=${JSON.stringify(r.stderr)}\n`);
}
await vm.dispose();
python3 -c "print('hi')"
exitCode=0 stdout="hi\n" stderr=""
python3 -c "print('hi')" | head -n 1
exitCode=0 stdout="" stderr="error: command not found: python3\n"
sh -c "python3 -c 'print(1)'"
exitCode=127 stdout="" stderr="error: command not found: python3\n"
echo hi | head -n 1
exitCode=0 stdout="hi\n" stderr=""
I think there are two things here.
The first is that python3 isn't resolvable inside a subshell. Since anything with a pipe gets wrapped in sh -c, pipelines hit the same wall. Plain coreutils are fine (echo hi | head works), so it looks specific to the kernel-stub commands — /bin/python3 is a 32-byte #!/bin/sh + # kernel command stub file, which I assume is meant to be intercepted by name before anything actually execs it, and the interception doesn't reach into the child shell.
The second one is what actually bit us: the pipeline returns exitCode: 0 even though the command wasn't found. The sh -c case gets it right and returns 127. We check exit codes to decide whether a command worked, so a 0 with empty stdout reads as "ran fine, no output" rather than "never ran".
Same shape with registry commands — rg from @agentos-software/ripgrep 0.3.3 works standalone but gives failed to execute command 'rg': Permission denied (os error 2) inside sh -c.
Possibly related to #1877 since that's in the same area, though python3 is a runtime rather than a published command package, so it might be separate.
Happy to test a patch if it's useful.
Ran into this building a sandbox integration on
@rivet-dev/agentos-core0.2.15.python3works on its own but vanishes as soon as it's inside a subshell.I think there are two things here.
The first is that
python3isn't resolvable inside a subshell. Since anything with a pipe gets wrapped insh -c, pipelines hit the same wall. Plain coreutils are fine (echo hi | headworks), so it looks specific to the kernel-stub commands —/bin/python3is a 32-byte#!/bin/sh+# kernel command stubfile, which I assume is meant to be intercepted by name before anything actually execs it, and the interception doesn't reach into the child shell.The second one is what actually bit us: the pipeline returns
exitCode: 0even though the command wasn't found. Thesh -ccase gets it right and returns 127. We check exit codes to decide whether a command worked, so a 0 with empty stdout reads as "ran fine, no output" rather than "never ran".Same shape with registry commands —
rgfrom@agentos-software/ripgrep0.3.3 works standalone but givesfailed to execute command 'rg': Permission denied (os error 2)insidesh -c.Possibly related to #1877 since that's in the same area, though python3 is a runtime rather than a published command package, so it might be separate.
Happy to test a patch if it's useful.