I have a bash script where I use find
to get a bunch of files in a directory, from which I then use xargs
to execute said files in a chroot environment 1 script at a time. My understanding has been that xargs quits and stop processing once it sees a non-zero exit code, however, for some reason this does not seem to be the case.
The script I have:
#!/usr/bin/env bash
set -euo pipefail
script_dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )
rootfs="$1"
exec_script() {
script="$1"
relative_script_path="$(realpath --relative-to="$script_dir" "$script")"
echo -e "\e[1;94m=> executing script $script ($relative_script_path)\e[0m"
sleep 5
if ! "$rootfs/enter-chroot" sh -c "/$relative_script_path"; then
echo -e "\e[1;31m=> script $script failed\e[0m"
exit 1
fi
echo -e "\e[1;32m=> script $script ran successfully\e[0m"
}
export -f exec_script
export rootfs
export script_dir
find "$script_dir/build/scripts" -name '*.sh' -print0 | sort -z | xargs -r -0 -I% -n1 bash -c 'exec_script "$@"' _ %
And when I run it, I get the following output:
./build/run.sh /tmp/test
=> executing script /tmp/builder/build/scripts/000-upgrade.sh (build/scripts/000-upgrade.sh)
environment: line 4: /tmp/test/enter-chroot: Not a directory
=> script /tmp/builder/build/scripts/000-upgrade.sh failed
=> executing script /tmp/builder/build/scripts/001-firmware.sh (build/scripts/001-firmware.sh)
environment: line 4: /tmp/test/enter-chroot: Not a directory
=> script /tmp/builder/build/scripts/001-firmware.sh failed
Where am I going wrong? How can I ensure that xargs stops processing and exits with a non-zero exit code?
xargs
quit at all. I've learned something new today too, thank you. – Chris Davies Feb 10 '20 at 21:50.. | xargs -0 sh -c 'exec_script "$@" || exit 255' sh
(adjust for the other options you're passing to xargs and your script). – Feb 10 '20 at 23:08find ... \( -exec script {} \; -o -quit \)
instead. – Feb 10 '20 at 23:11-d
wasn't available forread
, later I refactored it so it runs through the host's bash and only executes the scripts in the chroot, but I guess I didn't think to go back to looping. In addition, using the loop doesn't require exporting the variables and/or functions. And yes, it's a simple way of creating script execution order as there's some dependencies and for some reason find does not sort them correctly though I've prefixed them with numbers. – Hosh Sadiq Feb 11 '20 at 08:08xargs ... bash
. And POSIX doesn't yet support NULL-terminated lines either. – Chris Davies Feb 11 '20 at 08:19