Właśnie naprawiłem prawie dokładnie tę samą sytuację. Mam nadzieję, że nadal ci to pomoże, jeśli nie, być może inni. Zacząłem od su, nie sudo, ale ponieważ sudo ma na celu zawinięcie jednej innej komendy, to naprawdę powinno przekazywać kod wyjścia su. Jeśli nie, możesz zastosować poniższą poprawkę również na poziomie sudo.
Jak zauważyłeś, głównym problemem jest to, że su z powodzeniem wykonuje swoje polecenie. Domyślnym działaniem jest następnie zgłoszenie, że zakończyło się ono bez żadnych problemów, a więc zwraca kod wyjścia 0. Nie „wie”, że kod wyjścia inny niż 0 z polecenia był nieoczekiwany lub że powinien coś z tym zrobić. Zatem rozwiązaniem jest po prostu zmusić su do zwrócenia kodu wyjścia z ostatniego polecenia. Zrobiło to dla mnie
su <user_x> -c '<bunch_of_commands>; exit $?'
W przypadku, gdy sudo nie gra dobrze, całe polecenie powinno być mniej więcej tak (sprawdziłbym to dla ciebie, ale nie mam zainstalowanego sudo)
sudo 'su <user_x> -c \'<bunch_of_commands>; exit $?\'; exit$?'
Uważaj na zagnieżdżanie cytatów i upewnij się, że $? nie zostanie rozwinięty, więc nie ma podwójnych cudzysłowów.