11

This is a copy of my post from stackoverflow; I realize I should have asked it here...

I want to run a script that changes the hostname and have my bash prompt (PS1 variable) update immediately with the proper hostname. How do I make this happen?

I run this

#!/bin/bash
# Usage: ./changehost <newhostname>

#Do two sed's to edit the files for persistent hostname change
sed -i s/$(hostname)/$1/g "/etc/hosts"
sed -i s/$(hostname)/$1/g "/etc/sysconfig/network"

#run the hostname command with new hostname to update it
hostname $1

In a terminal like so and get this

[user@host dir]# ./changehost newhostname
[user@host dir]# 

But what I want is this

[user@host dir]# ./changehost newhostname
[user@newhostname dir]# 

The terminal is updated properly only when I open up a new shell.

I have also tried to do

export PS1='somestring'; export PS1='[\u@\h \W]\$' 

outside of the script in the terminal and it does switch to 'somestring' and back, but the hostname is unchanged. :\

Is it possible that the \h is stored in memory when the process begins and can't be changed after startup?

  • This isn't about programming, so should be on one of the other stackexchange sites, not here. However, you should be able to solve it by simply changing PS1 to some other string and then back again, which will cause bash to re-read the hostname. – Jonathan Wakely Oct 2 '15 at 22:39
  • 1
    Were you going to share your current $PS1 with us? – Ignacio Vazquez-Abrams Oct 2 '15 at 22:45
  • 1
    Exactly: what are the contents of PS1? echo "$PS1" s.b. "[\u@\h \w]\$ " – Bruce Oct 2 '15 at 23:01
  • Yes, my $PS1 has the \h in it, and happens to be "[\u@\h \w]\$" exactly. – Joseph Glover Oct 3 '15 at 20:05
  • Copy from my comment below... Unfortunately this (. ~/.bashrc) doesn't do anything. I have also tried to do export PS1='somestring'; export PS1='[\u@\h \W]\$' outside of the script in the terminal and it does switch to 'somestring' and back, but the hostname is unchanged. :\ Is it possible that the \h is stored in memory when the process begins and can't be changed after startup? – Joseph Glover Oct 5 '15 at 17:10
7

If your PS1 is similar to:

export PS1='[\u@\h \W]\$'

The value of \h is only set on bash startup. Therefore, if you change the hostname, you need to start a new bash instance:

exec bash

Will replace bash by a new instance (with the value of \h updated). Sadly, it will exit a running script. Some other magic is needed to make the change for a shell script that follow executing code after the hostname change. I believe that it is not possible to keep the same script running with an updated hostname and \h. But I also believe that that is not what you are asking for.

  • 1
    So this is probably the closest I can get to my functionality without exiting the terminal. Unfortunately it still leaves the other instance of bash one level up, so when the user exits it returns to the old instance and therefore old hostname. But thanks for confirmation that it is only set on startup! That's what I was thinking, but I wasn't sure. Do you have a source that you could point me to to confirm this? Thanks! – Joseph Glover Oct 6 '15 at 14:59
6

two problems

PS1 is set once, you have to re-set once hostname is changed.

You may edit the script with

export PS1='[\u@'$(hostname)' \W]\$' 

at the end, but the script should be run as

. ./changehost newhostname

note the leading dot.

If you don't use leading dot, PS1 will be set in a new temporary shell and be lost.


It is not clear if bash update hostname (username) value (stored in /h, /u) once it is running as those value are unlikely to change.

However bash take care of PATH.

  • I don't understand export PS1='[\u@'$(hostname)'\h \W]\$' What is the point of $(hostname)? \h should be the shortname of the hostname, correct? – Joseph Glover Oct 5 '15 at 17:33
  • Also, I guess I wasn't clear before, but even doing export outside of the script, in the terminal that I ran the script, I still don't get an updated PS1. Note, I can change the PS1 just fine to anything, but simply the \h value is not updated! – Joseph Glover Oct 5 '15 at 17:37
1

1) you did not change the hostname. If you really like to change the hostname, you need to call:

uname -S newname

or

hostname newname

depending on the OS you are using.

2) It is unclear whether bash rereads the hostname with \h. If you like to always see the current hostname, call:

PS1="`hostname`'
  • So I actually do change the hostname, using hostname newname, and it is persistent in the calling terminal, even when running the script without sourcing it. Running export PS1='`hostname`' does properly change the PS1 to the new hostname, but if I can't get the \h variable to update, I will just get the user to exit the shell. – Joseph Glover Oct 5 '15 at 19:11
0

It looks like bash is not reading the current hostname on each prompt display, so you would need to tell bash to re-read it. You can try with:

PS1=$PS1

or

. ~/.bashrc
  • Unfortunately this doesn't do anything. I have also tried to do export PS1='somestring'; export PS1='[\u@\h \W]\$' outside of the script in the terminal and it does switch to 'somestring' and back, but the hostname is unchanged. :\ Is it possible that the \h is stored in memory when the process begins and can't be changed after startup? – Joseph Glover Oct 5 '15 at 16:37
  • @JosephGlover Yes, maybe it is read at launch and stored, so you will need to launch another shell to have it updated. – Álvaro Gutiérrez Oct 5 '15 at 20:43
0

It is possible to set a system's hostname directly with the hostname utility on many operating systems, However if you choose to edit the files by hand here is an augmented version of your script. I added a test for the existence of user arguments, backups for the original files and sourced the user's .bashrc at the end of the script.

#!/bin/bash 

# Error if anything goes wrong and report all commands
set -xe

# Test that the user supplied an argument
if [[ "$#" != 1 ]]
then printf "Usage: $0 <newhostname>\n"
     exit 1
fi

# Back up the files first (but don't clobber old backups).
cp -n /etc/hosts /etc/hosts.bak
cp -n /etc/sysconfig/network /etc/sysconfig/network.bak


# Do two seds to edit the files for persistent hostname change:
sed -i "s/$(hostname)/$1/g" /etc/hosts
sed -i "s/$(hostname)/$1/g" /etc/sysconfig/network

# Source the user's .bashrc file
. /home/$USER/.bashrc
  • I've tried like so, but sourcing doesn't seem to do anything. – Joseph Glover Oct 5 '15 at 16:36
  • Is the change refleced when you start a new interactive shell? bash -i – none Oct 5 '15 at 18:24
  • Yes, the changed is reflected. – Joseph Glover Oct 5 '15 at 19:03
  • Try .bash_profile and if that does not work then essentially you deserve an explanation: Most systems will begin by sourcing /etc/profile at early run time and then from there source any number of other configuration files. generally ending with the shell rc and/or profile to finalize the setup of the user's /home – none Oct 5 '15 at 19:08
  • I have sourced my .bash_profile file and it does not work. And I am also familiar already with how the rc and profile files work, but thank you for the explanation. – Joseph Glover Oct 5 '15 at 19:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.