Using putty -m option gives 'command not found' - linux

If I open a shell into a machine with: putty -load session_name and then execute a command to add a job to a Grid queue on a linux system (qsub -cwd -b hostname), everything works fine.
But if I add the command to a text file, and then do putty -load session_name -m file.txt, I get qsub: command not found
If I back out and simplify the text file to be only the command hostname and use the -m option, it also works fine.
If I use the Connection->SSH->Remote command, and do something similar as the -m command, I get the same results as from the command line.
I'm very much a novice at linux systems, and this seems like it should be a simple fix to tell something that 'qsub' exists somewhere. Either that or there are some restrictions on these remote access things...
Edit:
Ok, so the initial question was how to run it--and I figured that out (add an absolute path), but there are other environment variable issues as well. It appears that qsub requires the SGE_ROOT variable to be set, but that isn't set for the remote commands window either.
So, a better question is, how do I get the putty remote commands shell (using -m) to open with the same properties and setup as a manual command line shell?

qsub is on your path when you log in interactively, but in the non-interactive shell it is not. Give the full path in the script, or set PATH in the script, and you ought to fix your problem.
It seems you need to run your command in the context of an interactive session, but the sshd protocol doesn't directly do that. So try invoking the command indirectly through /bin/sh.
/bin/sh -i -c "qsub -cwd -b hostname"
The -i makes the shell initialize itself like an interactive one, so it will load all the environment variables in your .profile or .bashrc that are loaded in a real interactive shell. The -c provides a command to run within that interactive shell.
You shouldn't have to explicitly set any paths this way since it works in an interactive session.

Related

What is the difference between interactive and non-interactive SSH commands? [duplicate]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I have a command that runs fine if I ssh to a machine and run it, but fails when I try to run it using a remote ssh command like :
ssh user#IP <command>
Comparing the output of "env" using both methods resutls in different environments. When I manually login to the machine and run env, I get much more environment variables then when I run :
ssh user#IP "env"
Any idea why ?
There are different types of shells. The SSH command execution shell is a non-interactive shell, whereas your normal shell is either a login shell or an interactive shell. Description follows, from man bash:
A login shell is one whose first character of argument
zero is a -, or one started with the --login option.
An interactive shell is one started without non-option
arguments and without the -c option whose standard input
and error are both connected to terminals (as determined
by isatty(3)), or one started with the -i option. PS1 is
set and $- includes i if bash is interactive, allowing a
shell script or a startup file to test this state.
The following paragraphs describe how bash executes its
startup files. If any of the files exist but cannot be
read, bash reports an error. Tildes are expanded in file
names as described below under Tilde Expansion in the
EXPANSION section.
When bash is invoked as an interactive login shell, or as
a non-interactive shell with the --login option, it first
reads and executes commands from the file /etc/profile, if
that file exists. After reading that file, it looks for
~/.bash_profile, ~/.bash_login, and ~/.profile, in that
order, and reads and executes commands from the first one
that exists and is readable. The --noprofile option may
be used when the shell is started to inhibit this behav­
ior.
When a login shell exits, bash reads and executes commands
from the file ~/.bash_logout, if it exists.
When an interactive shell that is not a login shell is
started, bash reads and executes commands from ~/.bashrc,
if that file exists. This may be inhibited by using the
--norc option. The --rcfile file option will force bash
to read and execute commands from file instead of
~/.bashrc.
When bash is started non-interactively, to run a shell
script, for example, it looks for the variable BASH_ENV in
the environment, expands its value if it appears there,
and uses the expanded value as the name of a file to read
and execute. Bash behaves as if the following command
were executed:
if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
but the value of the PATH variable is not used to search
for the file name.
How about sourcing the profile before running the command?
ssh user#host "source /etc/profile; /path/script.sh"
You might find it best to change that to ~/.bash_profile, ~/.bashrc, or whatever.
(As here (linuxquestions.org))
Shell environment does not load when running remote ssh command. You can edit ssh environment file:
vi ~/.ssh/environment
Its format is:
VAR1=VALUE1
VAR2=VALUE2
Also, check sshd configuration for PermitUserEnvironment=yes option.
I had similar issue, but in the end I found out that ~/.bashrc was all I needed.
However, in Ubuntu, I had to comment the line that stops processing ~/.bashrc :
#If not running interactively, don't do anything
[ -z "$PS1" ] && return
I found an easy resolution for this issue was to add
source /etc/profile
to the top of the script.sh file I was trying to run on the target system.
On the systems here, this caused the environmental variables which were needed by script.sh to be configured as if running from a login shell.
In one of the prior responses it was suggested that ~/.bashr_profile etc... be used.
I didn't spend much time on this but, the problem with this is if you ssh to a different user on the target system than the shell on the source system from which you log in it appeared to me that this causes the source system user name to be used for the ~.
Just export the environment variables you want above the check for a non-interactive shell in ~/.bashrc.

linux "enable -n xxx" command works in terminal but not when put into a script

I've found a very strange issue, when in linux terminal I type "enable -n trap", it would disable the trap linux builtin command. But if I put it into a script like
#!/bin/bash
enable -n trap
and then run the script, there's no error but the command is also not disabled. Really appreciate if someone could share what is happening and how to run it in some file instead of directly in the terminal. Thank you!
The enable command only affects the current shell. When you run a script, that script is executed in a new process, so:
A new shell starts
The enable command runs and disables the trap command in that shell
The shell exits
If you want to affect the current shell, your only option is to source the script using the . (or source) command. If the script is named disable-trap.sh and is in your $PATH, you can run:
. disable-trap.sh
You can also provide a full path to the script:
. /path/to/disable-trap.sh
Sourcing a script like this is largely equivalent to typing the same commands in at the command line: it executes the instructions in the script in the current shell, rather than spawning a new process.

How to Change my default shell on server?

I was assigned an account for log in to a remote server, and I want to change my default shell.
I tried chsh command but it says: chsh: "/public/home/{my_id}/bin/zsh" is not listed in /etc/shells.
If you don't have permission to install zsh system wide, a quick fix is to append exec ~/bin/zsh -l to ~/.bash_profile (if bash is the current shell), or an equivalent rc file for the current login shell.
zsh -l starts zsh as a login shell.
exec COMMAND replaces the current process with COMMAND, so you'll only have to type exit (or press ctrl+d) once.
~/.bash_profile is executed when bash starts as a login shell, you can still run command bash normally.
Depending what is in ~/.bash_profile (or equivalent), you may wish to avoid executing its other contents, by putting exec ~/bin/zsh -l at the start of the file (not the end), and copy/port anything important over to the zsh equivalent, $ZDOTDIR/.zprofile.
I might also do export SHELL="$HOME/bin/zsh", although I'm unsure of the full effects of setting SHELL differently to that specified for your user in /etc/passwd, to a shell not in /etc/shells, and to a shell binary in your home path.
First check all the shells available on your linux system
cat /etc/shells
Use chsh command line utility for changing a login shell with the -s or –shell option like this.
# chsh --shell /bin/sh tecmint

Can make shell run interactively along with --command option

I'm using GNU bash that is installed as git bash. On startup I need to change directory, so I'm doing it like this:
"C:\Program Files\Git\bin\sh.exe" --rcfile "./cd.sh"
Where cd.sh just contains cd /d/ command. Everything works fine here. Now I'm trying to get rid of cd.sh file and pass command to the shell as a parameter yet I want it to remain interactive, so I'm doing like this:
"C:\Program Files\Git\bin\sh.exe" -ic "cd /d"
It executes the command (tested with echo command) but then exits. Why doesn't it stay interactive?
From man bash:
An interactive shell is one started without non-option arguments and without the -c option ...
From man dash:
If no args are present and if the standard input of the shell is connected to a terminal (or if the -i flag is set), and the -c option is not present, the shell is considered an interactive shell.

How can I debug the bash prompt?

I've been editing .bashrc files and other init files, and it seems that I've left behind a few code snippets or two that are causing a few errors at the prompt (e.g. file missing), but I can't find them.
How do I debug the prompt to find out what init scripts I've carelessly hacked?
Most of the shells have debug flags that show the commands being executed. Bash may even have one that shows a command before expansion of variables and after. Have you tried checking (I believe) -c -x or -X flags and see if they show the information you are looking for.
You can set them as first thing in the rc files (most global one) or just pass it down into bash command by invoking it from another shell.
In fact, if you invoke bash from another shell, you can also use script command to record everything you see and do into the file, which makes postmortem analysis so much easier.
Try invoking bash with the -x flag, then sourcing your .bashrc or .bash_profile or whatever you're using. That ought to be prolix enough to find your problem
ie:
bash -x
source .bashrc
The easiest way to get a clean initial state is to SSH into your current host, but instead of letting SSH launch your shell with default settings, you provide an explicit command which prevents .bashrc from being read.
ssh -tt localhost /bin/bash --norc
The -tt forces SSH to allocate a TTY, which is what would normally happen when you open a shell connection, but is not default when running an explicit command.
The --norc prevents bash from reading your settings file (since we want to do that ourselves).
You should now be at a bash prompt, in a clean environment. This is useful for examining what variable are set to before your .bashrc runs etc. Enable tracing and source your .bashrc:
set -x # Enable tracing
source .bashrc
Try to see where you've defined prompt - probably it in some dot file in your home directory:
grep PS1 ~/.*
You can see current value of prompt by just printing it:
echo $PS1
HTH
Check the .bash_history file in your home directory to find out what commands you have been running. If you used commands like vi filename to open the init scripts, it will find them in the command history.

Resources