Having aliases active in a terminal session without using bashrc or bash_profile or bash_aliases? - bash

This question is an offshoot of my question on whether there's anything wrong with having aliases on a production server.
So I tried creating a shell script with some aliases
#!/bin/sh
echo "creating aliases..."
alias f='clear;cd ..;ls;pwd'
alias ff='clear;cd ../..;ls;pwd'
Did a chmod +x al.sh, and ran the script ./al.sh, but although the "creating aliases..." statement got printed, none of the aliases worked, because they were obviously active only until the script ran.
So is there a way I can run a script containing the aliases I want, which will remain active as long as the terminal session is active? The basic idea being, not to cause problems for colleagues who use the same server.

For cases when you want to store functions and aliases just for your session, I find it quite useful to have a file with them and sourcing it when I login the server.
So just place it somewhere like:
~/nav_alias_file.sh
And then just after sshing the server type:
source ~/nav_alias_file.sh
Note by the way that, as Sundeep expressed in comments, you do not need the shebang in that file.

Related

How to properly write a bash executable file

I am having some issue in writing a simple executable .sh file via bash.
The order of operation as soon as I open a terminal (ctrl+alt+T) are:
pc:~$ roscd
pc:~/catkin_docking_ws/devel$ cd ..
pc:~/catkin_docking_ws$ cd devel/lib/tuginterface/
pc:~/catkin_docking_ws/devel/lib/tuginterface$ ./tuginterface
I have been investigating this small issue and came across this source which advises to change and rename the project as an alias and that is exactly what I tried to do:
alias proj="roscd"
alias proj2="cd .."
alias proj3="cd devel/lib/tuginterface/"
alias exec="./tuginterface"
My current executable file after many trials is:
#!/bin/bash
alias proj="roscd"
alias proj2="cd .."
alias proj3="cd devel/lib/tuginterface/"
alias exec="./tuginterface"
But it still does not work.
The same post advises to create a script and after that an alias in the startup file.
Please advise on how to solve this problem and sorry if it is a simple question but I don't seem to catch the mistake I am making.
The script doesn't need to define aliases. Aliases are commands that you can type yourself. The script can just execute the commands directly.
#!/bin/bash
cd ~/catkin_docking_ws/devel/lib/tuginterface
./tuginterface
I've combined the three cd commands into one that jumps straight to the correct directory.
"But I thought cd doesn't work in shell scripts?"
It depends what you're looking for. When a script changes directory it affects later commands in the script, so in that respect it does work. The change of directory is only inside the script, though. The person calling the script won't see the directory change. Their current directory is unaffected.

Unix bash alias not working after start screen

Hi I am having a problem with setting alias in mac after I start the screen command, I have alias for working with git, like
commit=git commit
they work as I expect when I start my terminal (iTerm2), but then sometimes I use screen to have simultaneous instances in remotes servers and virtual machines I work with. After this the alias disappear(command not found).
Does anyone know why or how solve it?
To make the alias work, you must use the alias command. For example, to create an alias in Bash you do:
$ alias commit="git commit"
This works temporarily ie.: in your current shell. In order to make it "stick", you must put it in your ~/.bashrc. That will make it be sourced to all instances of Bash you'll invoke during your terminal session.
When you start screen, it starts a separate Bash too, so you'll be covered.
You write something about VMs. If you need this alias to work there, you must make ~/.bashrc on these VMs to have the same aliases. But that's the other story. You should already know how to achieve what you want.
You need to make sure your aliases are defined in ~/.bashrc to ensure they get included in all logins. You can test this out: edit your ~/.bashrc to include this line:
echo "bashrc"
And then edit your ~/.bash_profile to include this line:
echo "bash_profile"
You'll see when you start screen that only "bashrc" is displayed.
See this question for much more detail on the subject.

SSH heredoc to run Perl script on another server can't find right paths

I have a Perl program on server_B which uses Perl DBI and 5.010 and runs fine from the server_B terminal. I run it from a shell script which first prepares some arguments and then passes them to the Perl program, all works fine.
I need to run a shell script on server_A that will execute that script on server_B. This is because the Perl program creates several files that I want to SFTP back over to server_A. This is the script I'm running on server_A:
ssh server_B <<- EOF
perl/update.sh
EOF
There is some strange behavior which I'm trying to understand:
The script (update.sh) on server_B runs mysql, which is not installed on server_A (which is why I have to do this whole thing.) If I try to run it on server_B as-is, I can call mysql just like that. But when I run the above script (on server_A) to ssh into server_B and run that script, it doesn't recognize mysql unless I change the file (on server_B) to call the full path /opt/mysql/client/bin/mysql (even though that file is already on server_B with mysql installed) Does this mean server_B is picking up on the PATH variable from server_A instead of using my PATH variable from server_B? Is it trying to run my programs from server_A on the files on server_B? How and why??
If I make the change above it executes the script, but when it hits Perl it says
Perl v5.10.0- required - this is only v5.8.8
Again, 5.10 works fine on server_B but the version of Perl on server_A is 5.8.8.
So I got rid of use 5.010; because it actually wasn't necessary, but then I have a similar problem with my modules (DBI and DBD::mysql). I get:
Can't locate DBI.pm in #INC (#INC contains.. [my Perl PATH from server_A])
at perlfile.pl line 4
I was expecting the ssh heredoc call to update.sh (from server_A) to run exactly as update.sh does if I call it on server_B, but instead it seems like it's trying to use my programs from server_A on server_B, which I find weird. Can anyone help me understand why it's happening? I feel like I'm misunderstanding something fundamental about how ssh works.
server_A is AIX with ksh
server_B is AIX with bash
Edit - since some of you voted to the effect that I haven't done my research, here's what else I've tried. I didn't mention because I don't understand them fully, these are just guesses based on other SO posts & hunches. It'd be disingenuous if I gave the impression I knew what I was talking about.
If this is a duplicate, which question should I be looking at? If this is a "just read the manual situation", which one? What should I look for?
Read man ssh looking for clues related to environment variables, didn't find anything I understood
Tried running with -t
Tried running with -t -t
Did log in remotely with ssh and manually running it - this DOES work
Sourced my .bash_profile in the update script
Tried to re-assign PATH as the remote server's PATH when ssh
Tried using a different delimiter for the heredoc
Tried < instead of <<
Tried without the "-"
Edit 2 with Saigo's help below I determined that when in interactive ssh, if I echo $PATH I do get the target server's $PATH, but in a shell script I don't. That led me to this:
https://serverfault.com/questions/643333/different-bash-path-variables-when-using-ssh-script-vs-interactive-ssh
where I found out that scripted ssh doesn't call .bashrc, but interactive ssh does. So it looks like I was on the right track trying to source .bash_profile inside the scripted SSH heredoc, just need .bashrc not .bash_profile - however I don't have a .bashrc on the target server. I do have .profile but when I source that, I get an error stating it's for interactive bash sessions only. So now I'm just trying to find whatever file would contain my $PATH variable because it's apparently not .bashrc as there isn't one in there.
Edit 3 - tried hard-coding the PATH variable into a file and sourcing that and even then when I echo $PATH I get the origin server's PATH variable. It is reading the file in correctly, I also assigned another test variable and echoed that as part of the script. I tried sourcing /etc/profile and no luck.
I found a solution that works perfectly. I wasn't able to get it to work with ~/.bashrc, ~/.bash_profile, or ~/.ssh/rc but still not sure why it's not picking up my environment variables even with sourcing these.
Since it works when I manually ssh in and then run the commands one-by-one, I used these arguments to run ssh in a forced interactive login.
ssh server_B bash --login -i "~/perl/update.sh"
See these for more:
https://superuser.com/questions/564926/profile-is-not-loaded-when-using-ssh-ubuntu
https://unix.stackexchange.com/questions/46143/why-bash-unable-to-find-command-even-if-path-is-specified-properly
Hope this is useful for someone in the future. Thank you for your assistance Saigo.

Running a script automatically when logging in via ssh

I would like to know if there is a (simple) solution to the following issue:
When I log in with ssh to a specific host, I would like to automatically execute a (bash)script on that host. This way I could -for example- load my aliases on that host.
Definitively the bashrc script is not executed; The ssh configuration files do not seem to help in this issue either.
Any suggestions?
Thanks in advance!
BTW: The host is running on Gentoo
If .bashrc isn't being run, try .profile, which has a similar function. Different shells use different startup scripts at different times, so knowing when to run things is useful.
On many systems where you have a choice of which shell to use, you are put through ~/.profile only. This way there is no need to find out (and no probably wrong guessing) which shell you're running in and which profile to actually load (.bashrc, .cshrc, .kshrc etc.) and which ones to avoid loading.
The easiest solution in your case would be to create a link (a symbolic one if you prefer visibility) to your favourite shell's startup script as in ln -s ~/.bashrc ~/.profile. If you don't intend to ever using anything other than bash, you're set.

if .bash_profile usually source .bashrc any way, why not just use .bashrc?

it seems that we will put
source ~/.bashrc
in our .bash_profile anyway. So why not just use one file, say .bashrc ?
Because there may be things you only want to do once per login (so in .bash_profile) rather than every time an xterm or the like opens (as per .bashrc), for example asking the user for a passphrase to decrypt and load SSH keys into an ssh agent, etc etc.
You can put some things in .bash_profile that are not appropriate for a shell instance that is not a terminal. For example, if you ran an external command from your editor through the shell - the shell instance would source .bashrc but not .bash_profile. For example, I might put alias ls=ls -F in my profile, but you wouldn't want that alias applied for just any instance of the shell, just ones you would interact with.

Resources