Sourcing files in shell script vs sourcing on command line - linux

I have the problem that my shell script is not acting exactly the same as my manual typing into a console. I am attempting to find and source some setup files in a shell script as follows:
#!/bin/bash
TURTLE_SHELL=bash
# source setup.sh from same directory as this file
_TURTLE_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)
. "$_TURTLE_SETUP_DIR/turtle_setup.sh"
This bash file calls a .sh file:
#!/bin/env sh
_TURTLE_ROS_SETUP_DIR=$_TURTLE_SETUP_DIR/../devel
if [ -z "$TURTLE_SHELL" ]; then
TURTLE_SHELL=sh
fi
if [ -d "$PX4_FIRMWARE_DIR/integrationtests" ]; then
if [ -f "$PX4_FIRMWARE_DIR/integrationtests/setup_gazebo_ros.bash" ]; then
. "$PX4_FIRMWARE_DIR/integrationtests/setup_gazebo_ros.bash" "$PX4_FIRMWARE_DIR"
fi
fi
if [ "$TURTLE_SHELL" = "bash" ]; then
if [ -f "$_TURTLE_ROS_SETUP_DIR/setup.bash" ]; then
source $_TURTLE_ROS_SETUP_DIR/setup.bash
fi
else
if [ "$TURTLE_SHELL" = "sh" ]; then
if [ -f "$_TURTLE_ROS_SETUP_DIR/setup.sh" ]; then
source $_TURTLE_ROS_SETUP_DIR/setup.sh
fi
fi
fi
The line in question is:
. "$PX4_FIRMWARE_DIR/integrationtests/setup_gazebo_ros.bash" "$PX4_FIRMWARE_DIR"
I have made sure that this code is actually running and that my environment variables are correct. If I run this command on the command line everything works well. However, the same is not true when the file is sourced via shell script. Why is this? Is there something different about the environment of a shell script that is different from a command line. Also, how can I fix this problem?
Edit:
I am sourcing either the .bash or the .sh scale, depending upon which shell I am using.
Edit 2:
I am sourcing this script. Thus, everything is run in my default bash terminal, and it is all run within the same terminal and not a terminal spawned from a child process. Why is the script not sourcing setup_gazebo_ros.bash within the current shell?

It's the same reason why you source the env script and not run it. When you run the script it runs in a new shell and the variables are not transferred back to the parent shell.
To illustrate
$ cat << ! > foo.sh
> export foo='FOO'
> !
$ chmod +x foo.sh
$ ./foo.sh
$ echo $foo
$ source ./foo.sh
$ echo $foo
FOO

Related

Bash: Creating a shell variable in a bash script that I can access from command line

I have very little experience working with bash. With that being said I need to create a bash script that takes your current directory path and saves it to a shell variable. I then need to be able to type "echo $shellvariable" and have that output the directory that I saved to that variable in the bash script. This is what I have so far.
#!/bin/bash
mypath=$(pwd)
cd $1
echo $mypath
exec bash
now when I go to command line and type "echo $mypath" it outputs nothing.
You can just run source <file_with_your_vars>, this will load your variables in yours script or command line session.
> cat source_vars.sh
my_var="value_of_my_var"
> echo $my_var
> source source_vars.sh
> echo $my_var
value_of_my_var
You have to export the variable for it to exist in the newly-execed shell:
#!/bin/bash
export mypath=$(pwd)
cd $1
echo $mypath
exec bash
Hello
'env -i' gives control what vars a shell/programm get...
#!/bin/bash
mypath=$(pwd)
cd $1
echo $mypath
env -i mypath=${mypath} exec bash
...i.e. with minimal environment.

Create a script that adds lines of code to .bashrc then reloads the terminal

I am trying to create a shell script that once run, adds a line of code to the end of .bashrc then reloads the terminal. This is the code i have written in my install.sh
function addbashaliases() {
echo 'if [ -f ~/aliases/.bash_aliases ]; then
. ~/aliases/.bash_aliases
fi' >> ~/.bashrc;
source ~/.bashrc
}
Nothing is happening. How should I write the code so that it runs and adds the text to the .bashrc file?
For the sake of clarity I prefer to append the information on the .bashrc file using the cat command instead of the echo. However, this should work also using your echo command.
This said you should make sure that:
The script calls the addbashaliases function
The ~/aliases/.bash_aliases file exists (I would expect to have something more similar to ~/.aliases/.bash_aliases)
You can check that the script has correctly run by checking the content of the ~/.bashrc file and printing some environment variable set on the .bash_aliases file after the source command.
#!/bin/bash
function addbashaliases() {
# Add source bash_aliases on .bashrc
cat >> ~/.bashrc << EOT
if [ -f ~/aliases/.bash_aliases ]; then
. ~/aliases/.bash_aliases
fi
EOT
# Reload current environment
source ~/.bashrc
}
# Execute the function
addbashaliases
I am just correcting your script. As per your logic it should be like below.
function addbashaliases() {
if [ -f ~/aliases/.bash_aliases ]; then
output=$(. ~/aliases/.bash_aliases)
echo $output >> ~/.bashrc
fi
source ~/.bashrc
}

Newbie: Script to change directories

The following is a snippet of a larger script I'm attempting. I just want this part to recognize the argument is a directory and then cd to that directory: i.e ./larj /etc.
#!/bin/ksh
# Filename: larj.sh
if [ $# -gt 1 ]; then
echo "0 or 1 arguments allowed."
exit
fi
if [ -f "$1" ]; then
echo "directory only."
exit
else
if [ -d "$1" ]; then
cd $1
fi
fi
When I run the script with /etc as the argument, it appears nothing happens; it stays in the same directory with no error.
Anyone have any suggestions how to get it to change directories?
Thanks
The cd is taking place within the script's shell.
When the script ends, it's shell exits, and you return to the directory before running the script. In order to change the directory you can
mkdir testdir
. ./your_script.sh testdir
At the end of the script you will be moved at directory testdir.
The problem why you cd can't work is that cd executes in the sub-shell when you execute the script as ./larj /etc. So when you execute the script, it changes the working directory of the subshell and has no impact on the current shell.
So you can execute it as . ./larj /etc.
Refer to Why doesn't “cd” work in a bash shell script?.

How to execute a command on the remote at login with ssh, after .bashrc sourcing?

I am working on different machines where my home is NFS-mounted. I want to switch easily to another machine if the one I am working on is too much loaded.
I often modify my environment in the shell I am working, and I would like to find the same modified (with respect to the bashrc) environment when I switch to another machine. I tried the following script, but it does not work because the .bashrc is sourced after source $HOME/.env-dump.txt.
Is there a clean way to execute some commands when logging to a machine with ssh as if you type them at the prompt after logged?
#!/usr/bin/env sh
if [[ $# != 1 ]];
echo 'sssh USAGE:'
echo ' sssh remotename'
exit 1
fi
printenv | sed -e '/_=.*/ d;s/\([^=]\+\)=\(.*\)/export \1="\2"/' > $HOME/.env-dump.txt
ssh $1 -t 'source $HOME/.env-dump.txt; bash -l'
Add the following lines to your ~/.bash_profile
[ -f "$HOME/.bashrc" ] && . $HOME/bashrc
[ -f "$HOME/.env-dump.txt" ] && source $HOME/.env-dump.txt
And create a ~/.bash_logout file with the line
[ -f "$HOME/.env-dump.txt" ] && rm $HOME/.env-dump.txt
Now you can simply call ssh $1 -t 'bash -l' in the last line of your script.
WARNING
The output of printenv contains some variables which are machine dependent like GNOME_KEYRING_CONTROL, SESSION_MANAGER, DBUS_SESSION_BUS_ADDRESS ... (These variables are form a Ubuntu 12.04). These variables should be removed from the ~/.env-dump.txt file.

Bash file shows "ln: command not found"

I'm trying to create a bash script to setup my development environment. The script is running as root but I get the error line 11: ln: command not found
#!/bin/bash
#Require script to run as root - doesn't work - syntax error in conditional expression: unexpected token `;'
#if [[ $(/usr/bin/id -u) -ne 0]]; then
# echo "Script must be run as root";
# exit;
#fi
#PHPMyAdmin
PATH="/etc/apache2/sites-available/phpmyadmin.local";
if [ ! -a PATH ]; then
ln -s /home/user/Ubuntu\ One/htdocs/vhosts/phpmyadmin.local PATH;
a2ensite phpmyadmin.local;
fi
PATH=...
Congratulations, you've clobbered how the shell finds commands. Don't do that.
PATH tells the shell where to look for commands. In your case, it looks for ln somewhere in /etc and predictably doesn't find it there.
You should use a different name.

Resources