Bash script to modify /etc/hosts file - linux

When I´m running the next bash it work´s in the first time, but if I try to run again it dosent modify the file
oldHS=$HOSTNAME
echo -n "New hostname: "
read NHOST
sed -i "s/$oldHS/$NHOST/g" /etc/hosts
sudo hostnamectl set-hostname $NHOST
read -p "In the following file please validate the change. If it is correct, press control + x otherwise make the change and press control + o. Press enter to continue"
sudo nano /etc/hosts
hostnamectl
read -p "Presione enter para finalizar"
The hostnamectl set-hostname $NHOST always make the change but the script only the first time make the change in the /etc/hosts file

As Shawn said in the comments, the $HOSTNAME doesn`t reflect the chanague until I start a new shell. I made a change in the oldHS variable for this and it works
oldHS=$(hostname)

Related

Switch to root user within bash script

Im currently logged in as admin and I want to edit the /etc/hosts file which required root access.
I'm not able to make the changes. The script gets executed sucessfully but the changes arent made.
My Script - Runs Sucessfully when executed from terminal
sudo -s
echo "127.0.0.1" >> /etc/hosts
su admin
sudo -s - switches to root without password when executed from terminal
su admin - switches back to admin user when run on terminal
My /etc/hosts file remains empty after running the script
There is no need to actually switch your user within the script.
Also, you can't echo something as root like that because the redirect (>>) is executed by the shell.
A possible workaround is using tee:
echo "127.0.0.1" | sudo tee -a /etc/hosts
Further explanation:
tee basically takes the data from the standard input and writes it either to the standard output, or to a file. For more information see the commands manual ($ man tee)

calling SSH Sudo Commands in a bash script

I am trying to run the command while looping through
a series of sever addresses.
while read server
do
ssh -t $sever "sudo md5sum $fileName >> hashes"
done < serverNamesFile
within a script in bash but i keep getting this error
sudo: sorry, you must have a tty to run sudo
if I run the same line of commands in the command line though, it works perfectly fine.
Can someone tell me why this keeps happening?
you probably have
Defaults requiretty
in your /etc/sudoers file.
As the option's name suggests, that will cause sudo to require a tty
I solved my problem. apparently looping through a series of servers inside a script causes the "TTY" error for SSH.
a better practice is to create a script that takes in the address of the server you want to SSH in and then pass in the commands that way. you can still loop through a series of file or commands by calling SSH each time and use this command:
while read stuff
do
ssh -qtt $severName " command"
done < $fileStuff

How to copy output of command line from remote, to local clipboard via ssh

I am using HPC on campus and it is CentOS. I asked administrator to install xclip in HCP. But he said it would endanger to HPC. I am not root user. I am wondering whether there is a way to I can copy output of command line to clipboard directly without installing xclip. I do not want to use mouse to select and copy. Is there a way in terminal that it can redirect the output to clipboard?
This is sort of hackish:
Start a local xclip server:
#!/bin/bash
while true
do nc -l localhost 8888 | xclip
done
Connect with a reverse port redirection:
ssh <something something> -R 8888:localhost:8888
On the remote write what you want to copy to that port. Some options are:
echo "I WANT TO COPY THIS" | nc -C localhost 8888 #close on eof varies with version
Or
echo "I WANT TO COPY THIS" > /dev/tcp/localhost/8888
If both fail, you may still try with perl or python.

How to display current time on welcome message/MOTD?

echo "Current date and time: $(date)" >> /etc/motd
The above code displays the current time that was added to /etc/motd.
I want the user to see the actual current time and date after the login. Is there a way to do this?
Rather than a one-shot time how about if the user sees the current time at each command line prompt?
Try this first from the command line prompt:
PS1="\# \w$bk"
The prompt will look like: 11:41 AM ~
More information for the user might be to add the username and local machine name with the time. With the user "DrPete" on a local machine named "LittleSorrel" the prompt:
PS1="\u on \h \# \w$bk "
Looks like: DrPete on LittleSorrel 10:34 AM ~
To reset the prompt to default to "# ":
PS1="# "
To make the prompt permanently available, add the prompt construction of your choice, i.e.,
export PS1="\# \w$bk "
To ~/.profile.
From this guide
https://ownyourbits.com/2017/04/05/customize-your-motd-login-message-in-debian-and-ubuntu/
sudo mkdir -p /etc/update-motd.d
sudo cat > /etc/update-motd.d/10date <<'EOF'
#!/bin/sh
echo
echo echo "Current date and time: $(date)"
EOF
sudo chmod a+x /etc/update-motd.d/*
It will show up in the next login.
For Centos 7 I suggest using dynamic MOTD with my updated PAM package to have update-motd.d feature from Ubuntu.
Install with:
yum install https://github.com/gdubicki/centos-pam-with-update-motd/releases/download/1.1.8-1022.3/pam-1.1.8-1022.el7.x86_64.rpm
Use with:
Delete the default static /etc/motd.
Make SSHD not show the static MOTD with lines PrintMotd no, Banner none, UsePAM yes (and optionally PrintLastLog no) in your /etc/ssh/sshd_config & reload sshd service.
Add this line to your /etc/pam.d/sshd: session optional pam_motd.so motd=/run/motd.dynamic.
Add your script to /etc/update-motd.d:
#!/bin/bash
echo "Current date and time: $(date)"
...as /etc/update-motd.d/10time file for example, with permissions to be read and executed by root.
Please see https://github.com/gdubicki/centos-pam-with-update-motd for the most up to date info.

how to write a bash shell script to ssh to remote machine and change user and export a env variable and do other commands

I have a webservice that runs on multiple different remote redhat machines. Whenever I want to update the service I will sync down the new webservice source code written in perl from a version control depot(I use perforce) and restart the service using that new synced down perl code. I think it is too boring to log to remote machines one by one and do that series of commands to restart the service one by one manully. So I wrote a bash script update.sh like below in order to "do it one time one place, update all machines". I will run this shell script in my local machine. But it seems that it won't work. It only execute the first command "sudo -u webservice_username -i" as I can tell from the command line in my local machine. (The code below only shows how it will update one of the remote webservice. The "export P4USER=myname" is for usage of perforce client)
#!/bin/sh
ssh myname#remotehost1 'sudo -u webservice_username -i ; export P4USER=myname; cd dir ; p4 sync ; cd bin ; ./prog --domain=config_file restart ; tail -f ../logs/service.log'
Why I know the only first command is executed? Well because after I input the password for the ssh on my local machine, it shows:
Your environment has been modified. Please check /tmp/webservice.env.
And it just gets stuck there. I mean no return.
As suggested by a commentor, I added "-t" for ssh
#!/bin/sh
ssh -t myname#remotehost1 'sudo -u webservice_username -i ; export P4USER=myname; cd dir ; p4 sync ; cd bin ; ./prog --domain=config_file restart ; tail -f ../logs/service.log'
This would let the local commandline return. But it seems weird, it cannot cd to that "dir", it says "cd:dir: No such file or directory" it also says "p4: command not found". So it looks like the sudo -u command executes with no effect and the export command has either not executed or excuted with no effect.
A detailed local log file is like below:
Your environment has been modified. Please check /tmp/dir/.env.
bash: line 0: cd: dir: No such file or directory
bash: p4: command not found
bash: line 0: cd: bin: No such file or directory
bash: ./prog: No such file or directory
tail: cannot open `../logs/service.log' for reading: No such file or directory
tail: no files remaining
Instead of connecting via ssh and then immediately changing users, can you not use something like ssh -t webservice_username#remotehost1 to connect with the desired username to begin with? That would avoid needing to sudo altogether.
If that isn't a possibility, try wrapping up all of the commands that you want to run in a shell script and store it on the remote machine. If you can get your task working from a script, then your ssh call becomes much simpler and should encounter fewer problems:
ssh myname#remotehost1 '/path/to/script'
For easily updating this script, you can write a short script for your local machine that uploads the most recent version via scp and then uses ssh to invoke it.
Note that when you run:
#!/bin/sh
ssh myname#remotehost1 'sudo -u webservice_username -i ; export P4USER=myname; cd dir ; p4 sync ; cd bin ; ./prog --domain=config_file restart ; tail -f ../logs/service.log'
Your ssh session runs sudo -u webservice_username -i waits for it to exit and then runs the rest of the commands; it does not execute sudo and then run the commands following. This has to do with the context in which you're running the series of commands. All the commands get executed in the shell of myname#remotehost1 and all sudo -u webservice_username - i is starts a shell for webservice_username and doesn't actually run any commands.
Really the best solution here is like bta said; write a script and then rsync/scp it to the destination and then run that using sudo.
export command simply not working with ssh like this, what you want to do is remote modify ~/.bashrc and it will source itself each time u do ssh login.

Resources