I've been working for a customer that has about 450 hundred servers running all kind of different Web Applications / Mail services / FTP / Web Statistics etc.. I have a single user / password access to all of the servers (using LDAP authentication) – just like many of my colleagues and by default most of servers shell set is Korn Shell (/bin/ksh) is automatically run on ssh login time ( as it is set as the default shell ). I have nothing personally against Korn Shell but as mainly script in Bash Shell last 10+ years and I'm used to Bash's terminal behavior so much, each time I login to the servers I had to run manually run :
/bin/bash
This becomes really annoying, because I have to login to so many servers daily and do various stuff, so I got pissed off at the end and I wanted to change default shell set (only for my current) user to BASH, since there are other users that work on servers and its not a good idea to change globally servers global shell to bash, because such action could hurt some poor colleague love for KSH 🙂
A note to make here is the servers are primary running SuSE SLES / CentOS and Debian and RHEL Linux, but this bash one liner would be working on any other Linux release which has a bash >=2.0, I've tested it exactly on bash 3.2.25.
I have dump of all server hostnames / IPs in a plain text (.txt) file called all_servers_list.txt and since the servers are not accessible between each other but only through a special HOP station running Windows I couldn't install and use sshpass for mass deploy of new $SHELL variable configuration into home directory's $HOME/.profile ( ~/.profile ) . Thus I was forced to use a standard SSH client and a MobaXTERM inistallation which comes with integrated CygWin bash (for windows) and thus I can run normal Linux bash code inside the MobaXTerm Terminal on the Windows 2012R2 (jump host) .. 🙂
while read line; do ssh my-user@$line 'echo "export SHELL=/bin/bash ; exec /bin/bash" >> /home/my-user/.profile' < /dev/null; done < all_servers_list.txt
Since SSH client doesn't have a non-interactive way to pass on password from command line (for security reasons), to make above bash one liner loop to deploy bash as a default shell (mass) on all servers I have to paste (my Sotred in Memory Copied password) the SSH remote login server password 450 times each time I',m prompted by SSH to input password manually (this takes about 20) minutes but it is a worthy time, since from then on /bin/bash runs automatically on server login time. One important note to make is the </dev/null here is necessery because otherwise ssh is having troubles with reading the host in the loop. If you try running above cmd without </dev/null you, the loop is about to end after first login attempt. Changing default shell to multiple servers is not done only to servers with default ksh, but for any servers with default csh shell or any other obscure shell to bash (if bash is installed) is achieved by above command.
As you can guess above while bash loop, can easily be modified to run any other command to a bunch of hundred or thousand servers of your choise, the only inconvenience you will have is you have to paste the password for each server part of loop to which ssh is creating connection.
This example works on Linux but should work fine on any other platform that have /bin/bash (or /usr/local/bin/bash) installed if on FreeBSD / NetBSD, it should work on HP-UX and SunOS / Solaris hosts which have bash installed too.
Once you've launched the loop and added /bin/bash to run on login to check on next login where you're really running bash shell there is the:
echo $SHELL
/bin/bash
If you want keep / grep output of shell variable $SHELL:
MYSHELL=`ps -hp $$|awk '{echo $5}'`
Anyhow on some Linux hosts this variable might show bash and still you might be running old shell ksh / csh, the better way to check your SHELL is with ps -p $$ command (nowdays not known by many admins)
ps -p $$
PID TTY TIME CMD
866 pts/0 00:00:00 bash
Now I can happily use bash on all the servers every time I login. Cheers and Thanks God ! 🙂