How to run ssh-agent and ssh-add through an SH script? - linux

I have two following commands which I manually run when I connect on my VPS:
eval ssh-agent $SHELL
ssh-add /home/duvdevan/.ssh/id_rsa
I tried adding them into a ssh.sh and run it within that directory using:
./ssh.sh
But nothing happends.
I'm not that bash-savvy so any help is appreciated.

Instead of running, you need to source the script:
. ./ssh.sh
Otherwise, the environment variables set by the eval command will not be visible in your current shell, and so it cannot know where to find the running ssh agent.
To give a bit more background, here's how this works:
the ssh-agent command starts an ssh agent, and prints to stdout the environment variables you need to set to connect to the agent. The output is formatted as commands to execute. For a test, you can just run this command and see what it prints
the eval command executes the commands printed by ssh-agent. As mentioned earlier, these are commands to set environment variables. After these are executed, the ssh commands you will run in this shell will know where to find the agent
the ssh-add command is able to find the agent, thanks to the environment variables set earlier
these variables are set until the script exits. When you run ./ssh.sh, the variables are set inside the process of that script, and longer available after the script is finished
by sourcing the ssh.sh script using ., the commands inside will be executed in the current shell, and therefore the environment variables are still set, and so your ssh related command can find the agent

Related

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.

use environment variables of remote server in ssh command

I have two servers X(host) and Y(remote). A script abc.sh is saved on Y server. I am running abc.sh from server X using ssh command.
Script is running successfully but the commands which contain the environment variables(kept in /.bash_profile) of server Y are giving blank output.
When I am running abc.sh from server Y itself, all commands running successfully.
My question is how to include the environment variables of remote server(Y) so that full script will execute successfully.
NOTE : I don't have write access to etc directory so I can't change anything in it.
Thanks in advance!
You can include your environment variables like following:
ssh user#host_y 'source ~/.bash_profile; /path/to/your/script/abc.sh'
Since direct command run is not an interactive shell, your variable will not work there. source will run script in your current shell and make visible environment variables in that file to your script.
I run some cron jobs using ssh connect a remote machine. The code can't load all the environment variables. It works if I run the code in that machine.
I tried several ways that doesn't work for me.
Finally, I comment below lines in the ~/.bashrc file. It works for me.
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
The ssh connect open an no-interactive shell. So it will load the environment variables for an non-interactive shell if you comment or delete this block codes.
Alternatively, you can just put all of your required environment lines code above that line.

Setting console env using a shell script

I have a shell script setmyenv.sh as below
#!/bin/sh
export PATH=./abc/tools:$PATH
env | grep PATH
When I run it sh setmyenv.sh, I could see that the PATH env is set accordingly.
PATH=./abc/tools:<whatever my existing PATH setting>
However, after my command finish, if I manually type env | grep PATH on the console, I got
PATH=<whatever my existing PATH setting>
I lost the setting that I set using setmyenv.sh
It looks like the environement is only set in the lifetime of my script run.
How could I have the environment set sticky even after the script ended. i.e. the purpose of the script is to set the environment.?
P/S: I don't want to set it in my .bash_profile nor etc\profile, given I only want to set it when needed, by calling setmyenv.sh, but not every time I open my console. i.e. not per the answer of Using .sh script to set an environment variable or How to set global environment variables using shell script .sh
When you run
sh setmyenv.sh
it runs in a separate sh process and the changes to PATH are lost when the process finishes.
You need to source your script:
source setmyenv.sh
or
. setmyenv.sh
so that it runs in your current shell and all variable assignments are preserved. Remember not to have any exit in setmyenv.sh script. If you do, sourcing the script will terminate your shell.
See also:
Difference between sourcing a script vs executing it
What's a subshell

Shell script running from php code is using /sbin/nologin how to set this to /bin/bash

I am running a shell script by which we are scheduling a task using at command. But it schedules the at task but its not running the same beacuse its using shell /sbin/nologin when we are calling it from php code. It works fine if we run it from terminal.
You should check the "$PATH" env variable. When you are logged in from terminal the shell has initialized it's search path via .bashrc etc. "cron" or "at" jobs don't do that.
So try to log the environment variables to a file in your 'at' jobs and check if it is set up right.

In Linux shell do all commands that work in a shell script also work at the command prompt?

I'm trying to interactively test code before I put it into a script and was wondering if there are any things that behave differently in a script?
When you execute a script it has its own environment variables which are inherited from the parent process (the shell from which you executed the command). Only exported variables will be visible to the child script.
More information:
http://en.wikipedia.org/wiki/Environment_variable
http://www.kingcomputerservices.com/unix_101/understanding_unix_shells_and_environment_variables.htm
By the way, if you want your script to run in the same environment as the shell it is executed in, you can do it with the point command:
. script.sh
This will avoid creating a new process for you shell script.
A script runs in exactly the same way as if you typed the content in at a shell prompt. Even loops and if statements can be typed in at the shell prompt. The shell will keep asking for more until it has a complete statement to execute.
As David rightly pointed out, watch out for environment variables.
Depending on how you intend to launch your script, variables set in .profile and .bashrc may not be available. This is subject to whether the script is launched in interactive mode and whether it was a login shell. See Quick Startup File Reference.
A common problem I see is scripts that work when run from the shell but fail when run from another application (cron, nagios, buildbot, etc.) because $PATH was not set.
To test if a command/script would work in a clean session, you can login using:
ssh -t localhost "/bin/bash --noprofile --norc"
This ensures that we don't inherit any exported variables from the parent shell, and nothing from .profile or .rc.
If it works in a clean session and none of you're commands expect to be in interactive mode, then you're good to go!

Resources