For security reasons, /bin/su does not accept a password from the command line:
user@host$ echo pass | su -c id su: must be run from a terminal
When you can execute commands on a system but you don't have an interactive shell (these things happen), then you can't use su this way.
But using socat, you can simulate a tty for any program and provide the input from STDIN, a socket, a file, whatever...
Here is how you would run it:
user@host$ (sleep 1; echo SuperSecr3t) | socat - EXEC:'su -c id',pty,ctty,setsid Password: ### No input here, just wait 1sec uid=0(root) gid=0(root) groups=0(root)
Taking this further, now imagine that you have a non-interactive shell access as a standard user (user1). On this system, there is another user (user2) who can run commands as root using sudo, but user1 can't. You happen to know the password to the user2 account. What you want to do is switch to user2 via su, then run a command as root using sudo from the user2 account.
Here is how to proceed:
user1@host$ echo -e '#!/bin/sh\necho User2SuperPasswd | sudo -S id' > runasroot.sh user1@host$ chmod +x runasroot.sh user1@host$ (sleep 1; echo User2SuperPasswd) | socat - EXEC:'su user2 -c ./runasroot.sh',pty,ctty,setsid Password: ### No input here, just wait 1 sec [sudo] password for user2: uid=0(root) gid=0(root) groups=0(root)