Bash-在脚本中更改主机名后,PS1没有使用正确的主机名更新


11

这是我从stackoverflow获得的帖子的副本;我意识到我应该在这里问这个...

我想运行一个更改主机名的脚本,并使用正确的主机名立即更新我的bash提示符(PS1变量)。我如何做到这一点?

我跑这个

#!/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

在这样的终端中得到这个

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

但是我想要的是

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

仅当我打开新外壳时,终端才能正确更新。

我也试过做

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

不在终端脚本中,并且确实切换为“ somestring”并返回,但主机名未更改。:\

进程开始时\ h是否可能存储在内存中,并且启动后无法更改?


这与编程无关,因此应该位于其他stackexchange网站之一上,而不是此处。但是,您应该能够通过简单地将PS1更改为其他字符串然后再次返回来解决它,这将导致bash重新读取主机名。
Jonathan Wakely

1
您要$PS1与我们分享您的最新消息吗?
伊格纳西奥·巴斯克斯

1
确实:PS1的内容是什么?echo“ $ PS1” sb“ [\ u @ \ h \ w] \ $”
Bruce

是的,我的$ PS1中有\ h,恰好是“ [\ u @ \ h \ w] \ $”。
2015年

从下面的评论中复制...不幸的是,此(。〜/ .bashrc)没有任何作用。我也尝试export PS1='somestring'; export PS1='[\u@\h \W]\$'在终端的脚本之外进行操作,并且确实切换为“ somestring”并返回,但主机名未更改。:\进程开始时\ h是否可能存储在内存中,并且启动后无法更改?
约瑟夫·格洛弗

Answers:


7

如果您的PS1类似于:

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

\ h的值仅在bash启动时设置。因此,如果更改主机名,则需要启动一个新的bash实例:

exec bash

将用新实例替换bash(更新了\ h的值)。可悲的是,它将退出正在运行的脚本。在更改主机名之后,还需要执行一些其他魔术来更改在执行代码之后执行的Shell脚本。我认为无法使用更新的主机名和来保持相同的脚本运行\h。但是我也相信这不是您要的。


1
因此,这可能是我在不退出终端的情况下最接近我的功能的地方。不幸的是,它仍然将bash的另一个实例保留为一个级别,因此,当用户退出时,它将返回到旧实例,因此返回到旧主机名。但是感谢您确认它仅在启动时设置!那就是我的想法,但是我不确定。您是否有消息来源可以指出来确认这一点?谢谢!
约瑟夫·格洛弗

6

两个问题

PS1设置一次,更改主机名后必须重新设置。

您可以使用

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

最后,但脚本应以

. ./changehost newhostname

注意前导点。

如果不使用前导点,则PS1将设置在新的临时外壳中并丢失。


目前尚不清楚bash更新主机名(用户名)值(存储在/ h,/ u中)一旦运行,因为这些值不太可能更改。

但是bash需要注意PATH。


我不明白export PS1='[\u@'$(hostname)'\h \W]\$' $(hostname)的意义是什么?\ h应该是主机名的简称,对吗?
约瑟夫·格洛弗

另外,我想我之前还不清楚,但是即使export在脚本之外进行操作,在运行脚本的终端中,我仍然没有获得更新的PS1。注意,我可以将PS1更改为任何值,但是\ h值不会更新!
约瑟夫·格洛弗

1

1)您没有更改主机名。如果您确实想更改主机名,则需要致电:

uname -S newname

要么

hostname newname

取决于您使用的操作系统。

2)不清楚bash是否使用重新读取主机名\h。如果您希望始终看到当前主机名,请致电:

PS1="`hostname`'

因此,实际上我确实使用来更改了主机名hostname newname,即使在运行脚本而无需采购脚本的情况下,主机名也可以在调用终端中保持不变。运行export PS1='`hostname`'确实可以将PS1正确地更改为新的主机名,但是如果我无法获取该\h变量的更新,我只会让用户退出外壳。
约瑟夫格洛弗2015年

0

看来bash在每个提示显示中都没有读取当前的主机名,因此您需要告诉bash重新读取它。您可以尝试:

PS1=$PS1

要么

. ~/.bashrc

不幸的是,这没有任何作用。我也尝试export PS1='somestring'; export PS1='[\u@\h \W]\$'在终端的脚本之外进行操作,并且确实切换为“ somestring”并返回,但主机名未更改。:\进程开始时\ h是否可能存储在内存中,并且启动后无法更改?
约瑟夫·格洛弗

@JosephGlover是的,也许它是在启动时读取并存储的,所以您将需要启动另一个shell来对其进行更新。

0

可以hostname在许多操作系统上使用实用程序直接设置系统的主机名,但是,如果您选择手动编辑文件,则这里是脚本的增强版本。我添加了一个关于用户参数存在性的测试,原始文件的备份,并在脚本结尾处获取了用户的.bashrc。

#!/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

我已经尝试过了,但是采购似乎无能为力。
约瑟夫格洛弗2015年

启动新的交互式外壳程序时,更改是否已取消?bash -i

是的,更改已反映出来。
约瑟夫·格洛弗

尝试.bash_profile,如果它不起作用,那么从本质上讲,您应该得到一个解释:多数系统将在运行时先从/ etc / profile采购,然后从那里获取许多其他配置文件。通常以外壳rc和/或配置文件结尾,以最终确定用户/ home的设置

我已经获取了我的.bash_profile文件,但是它不起作用。而且我也已经很熟悉rc和profile文件的工作方式,但是感谢您的解释。
约瑟夫·格洛弗
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.