0

I am sshed into another machine. Within that machine, I have a script called get_count.sh

#!/bin/sh

nzsql -u user -pw password -host hostname -port 1234 -db database -c "query"

run this script when I am sshed in and it works as expected. ./get_count.sh

I am using a python module paramiko. This allows me to ssh in a machine and pass commands with python to the ssh session.

I am getting the output:

./get_count.sh: line 3: nzsql: command not found

I am connected to the same ssh session but I am not sure why this is occurring. Essentially these two processes are doing the same thing but I am not sure why doing the same thing is working one way and not working the other way

I tried changing the contents of my script to be something simple because I thought it could be due to paramiko. So I replaced my nzsql query with echo 123 and it functioned properly.

My .bashrc:

# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

# User specific aliases and functions

my .bash_profile:

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

export PATH

I did an echo $PATH through paramiko and I get :

 /usr/local/java/current/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin

Through logging in the terminal:

/usr/local/java/current/bin:/usr/lib/oracle/11.2/client64/bin:/app/netezza/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/bli1/bin
Liondancer
  • 15,721
  • 51
  • 149
  • 255
  • 1
    Most likely there is something in your .bashrc (like a PATH setting) which is not being run. – cdarke Mar 06 '15 at 17:45
  • @cdarke Any idea how I can fix this? – Liondancer Mar 06 '15 at 17:49
  • If you cannot figure out how to get `paramiko` read your .bashrc (or do not want to spend the time), calling the program in the script via absolute path should work around it, i.e. `/app/netezza/bin/nzsql -u user ...` – Clemens Klein-Robbenhaar Mar 06 '15 at 19:42
  • @ClemensKlein-Robbenhaar After some reading around found out I could do this (very new to shells scripting) and I tried that but I am getting `/app/netezza/bin/nzsql: error while loading shared libraries: libssl.so.4: cannot open shared object file: No such file or directory ` – Liondancer Mar 06 '15 at 20:11
  • Ouch, that is no good news. It seems the shell is started without any sane environment. Maybe you can botch this up by setting `LD_LIBARAY_PATH=/usr/lib` but I guess that will just lead to the next problem ... so I am running out of good advice here. – Clemens Klein-Robbenhaar Mar 06 '15 at 20:18
  • It might just mean that ssl (Secure Sockets Layer) is not installed. – cdarke Mar 08 '15 at 08:05
  • If, at your shell, you `ssh host ./get_count` -- instead of first invoking `ssh host` and then running `./get_count` in the interactive session -- do you have the same problem? (If you're testing manually with an approach that creates an interactive shell, and then automating with an approach that creates a noninteractive shell, then you have different remote dotfiles run between the approaches). – Charles Duffy Jan 07 '17 at 18:17

1 Answers1

3

I'm assuming, here, that you're invoking the paramiko method exec_command() to run your command.

exec_command() is not like running the same command from an interactive session!

Instead, when you run client.exec_command('./get_count.sh'), you're getting behavior equivalent to ssh yourhost "./get_count.sh". This runs only a noninteractive shell, and doesn't run the same scripts that an interactive login shell (invoked by ssh yourhost) would call.


Preferred: Simulating Paramiko's exec_command Behavior At Your Shell

Your best bet here is first to reproduce from the command line; develop a fix there; and then to port that fix over to your code.

# do this to reproduce behavior from the command line:
ssh yourhost ./get_count.sh

...then, work through manual dotfile inclusion. The following is a rough example of one thing this may look like:

ssh yourhost '. .profile; . .bashrc; ./get_count.sh'

Once you have something working with your shell command passed on the SSH command line, then you can pass that to the exec_command() paramiko method.


Fallback: Getting Interactive-Session Behavior from Paramiko

Alternately, if you want paramiko to behave the same way an interactive session does, use the invoke_shell() Paramiko method. Note that you have to do a significant bit of extra work this way -- simulating keystrokes to execute your remote command, monitoring output to determine whether that command has exited, and determining exit status yourself. For this reason, I don't recommend it.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441