I am managing to execute a shell script on a remote server using JSch exec using the helpful examples provided here. I can see the echoes being returned from the script and the exit status at the end is 0 - so all looks good at first glance.
However, the problem is that the script itself calls out to other scripts, and these appear to be completely ignored, just skipped over.
The script calls other scripts directly. i.e. the first line of the script is something like:
JSch jsch = new JSch();
Session session = jsch.getSession(username, hostIPAddress, port);
//create the execution channel over the session
ChannelExec channelExec = (ChannelExec)session.openChannel("exec");
I assume the script looks like:
I.e. the script relies on the
. (the current path) being in the
PATH environment variable, what is not a default.
So for the script to ever work, the
. has to be added to the
PATH in some startup script. It's quite probable that an addition occurs (probably unintentionally incorrectly) only for interactive sessions. Probably because the addition is done in a startup script that is executed (sourced) for the interactive sessions only.
The "exec" channel in the JSch (rightfully) does not allocate a pseudo terminal (PTY) for the session. As a consequence a different set of startup scripts is (might be) sourced than, when you login with an SSH client. And/or different branches in the scripts are taken, based on absence/presence of the
TERM environment variable. So the environment might differ from the interactive session you use with your SSH client.
Solutions are (in preferred order):
Correct the script not to rely on non-default settings of having the
PATH. Call the sub-scripts with an explicit path:
Correct the startup scripts to add the
. to the
PATH unconditionally (even for non-interactive sessions).
(not recommended) Force the pseudo terminal allocation for the "exec" channel using the
Channel channel=session.openChannel("exec"); ((ChannelExec)channel).setPty(true);
Using the pseudo terminal to automate a command execution can bring you nasty side effects. See for example Is there a simple way to get rid of junk values that come when you SSH using Python's Paramiko library and fetch output from CLI of a remote machine?
See also a related question Shell ping command with source option is failing when executed using JSch setCommand.