Accessing an exit code outside of a su -m $USER -c "<cmd>"

348

Solution 1

I just fixed almost exactly the same situation. Hope it still helps you, if not then perhaps others. I started from su, not sudo, but since sudo is intended to wrap a single other command, it really ought to relay su's exit code. If not, you can apply the fix below on the sudo level also.

Like you noted the main problem is that su succesfully executes it's command. The default action is then to report that it completed without any problems and so it returns exit code 0. It doesn't "know" that a non 0 exit code from a command was unexpected, or that it should do something with it. Thus the solution is quite simply to make su return the exit code of it's last command. This did it for me

su <user_x> -c '<bunch_of_commands>; exit $?'

In case sudo doesn't play nice, the whole command should be something like this (I would check this for you but I don't have sudo installed)

sudo 'su <user_x> -c \'<bunch_of_commands>; exit $?\'; exit$?'

Watch for the nesting of quotes and make sure $? doesn't get expanded, so no double quotes.

Solution 2

Echo the return value inside the command and access it outside by assigning the whole command to a variable (using a subshell.)

RETVAL=$(sudo su -m $USER -c "./shutdown.sh &> /dev/null; echo \$?")
echo $RETVAL
Share:
348
Todorov96
Author by

Todorov96

Updated on September 18, 2022

Comments

  • Todorov96
    Todorov96 over 1 year


    I am using .NET CF and my task is to print fiscal and non-fiscal receipt. So I need to connect to the FML 10 KL via bluetooth. I am using SerialPort to do this, but after sending commands nothing happens.
    I tried sending the commands like this :

        byte[] buf = new byte[218];
        using (StreamWriter writer = new StreamWriter(inPort.BaseStream))
        {
           writer.Write(buf);
           //inPort.NewLine = "\n";
           //var msg = inPort.ReadLine();
        }
    

    I populate "buf" with my command.
    After that I try to read the responce but everytime I get timeout.Also I tried to "write" with text and not byte array, but I get the same result. If anyone can give me some advice that would be great.

    • Baddack
      Baddack over 6 years
      I would recommend using the Write with text from your SerialPort class as you suggested you tried. But you need to make sure your SerialPort is setup correctly. Check the following settings: the BaudRate, DataBits, Parity, PortName, and StopBits.
  • Nick
    Nick over 11 years
    This is actually not correct. This will always return zero because the "su -m $USER -c <cmd>" will always succeed even if the actual command within it doesn't.
  • Nick
    Nick over 11 years
    Yeah, this is what I am doing right now, but I was hoping not to rely on a tmp file.
  • zero2cx
    zero2cx over 11 years
    @Nick -- It works here. What's your output? Try sudo su -m zero2cx -c "/bin/false &> /dev/null" but with your system username. $? should be '1'.
  • Nick
    Nick over 11 years
    Yup, with my own username it returns "1" as expected. But I'm trying to use this to run an app via its own user and not root or any other user.
  • zero2cx
    zero2cx over 11 years
    @Nick -- It should work with $ USER=appusername set as you wish. Don't user a real username, insread use your intended appusername. It should work, it does for me.