8

As you might have guessed from the title, I would like to know if it is possible to change a RasPis hostname from the config.txt file on the SD card.

I'm making a lot of SDs from a custom image, and obviously the hostnames collide when booting (they are used from other apps in the network).

5
  • 3
    What's wrong with just setting /etc/hostname?
    – goldilocks
    Mar 30, 2016 at 13:24
  • 2
    Depending on the number of machines you are managing, it may be time to look at a configuration management solution (i.e. puppet, ansible, chef). Mar 30, 2016 at 13:42
  • @goldilocks that I must boot the Pi ^^ and some of the SDs are being sent overseas... I'll check those out! thanks Steve!
    – Jo Colina
    Mar 30, 2016 at 14:08
  • For folks just trying to change your Pi's hostname (but don't need a custom image) you can run sudo raspi-config and select Advanced Options -> Hostname to update your Pi's name.
    – dimo414
    Apr 4, 2016 at 0:30
  • If anybody end up here, I'm creating package, which enables you to set hostname using /boot/bootsetup/hostname, see more github.com/SloCompTech/rpi-boot-setup. Jul 31, 2019 at 21:15

4 Answers 4

7

It is not possible to set the device hostname through config.txt. A full list of commands can be found on the Raspberry Pi Foundation's website.

An Alternative:

You mention that you're creating a custom image. In this case, I believe the best practice would be to write the assigned hostname to /etc/hostname during the card creation process. It does require a reboot (assuming the RPi is currently running), but so does changing anything in config.txt.

If you really want to get around the restart thing, it's possible, but can cause some issues. The hostname can be temporarily changed by the command sudo hostname {super_cool_name_here}. Once that's set, restart the network service with sudo service network restart.

Now, if you run hostname you should see your new hostname as active. This change is not permanent. When you restart the device it will go back to whatever is stored in /etc/hostname.

5
  • 2
    Setting /etc/hostname doesn't require a reboot as far as I'm aware. You should be able to just change it on the card and that's that (I'm presuming the system isn't running, the cards are just being created).
    – goldilocks
    Mar 30, 2016 at 14:56
  • @goldilocks: (assuming the RPi is currently running)
    – Jacobm001
    Mar 30, 2016 at 15:52
  • Thanks! Just to clarify, I made a custom image, installed some packages, made some configs, and now I just used dd from the card to my computer, and then dd again from the computer to another card to create another raspi. So in the best of cases, to be fast, I wanted to just open a file on the pc after ending the dd (this is why i thought of config.txt) and change it.
    – Jo Colina
    Mar 30, 2016 at 18:09
  • HI @JoColina, did you find a solution? Oct 4, 2016 at 6:13
  • @PavelReznikov no I did not.
    – Jo Colina
    Oct 4, 2016 at 10:07
3

Okay, from your comments on the other answer, it looks like you want to change the hostname of Raspberry Pi image without actually booting it. This should be trivial. We want to modify the /etc/hostname in the second partition, so we will find its location in the image using fdisk.

fdisk -l image.img

Where image.img is your image file. Look under the start column for the second (Linux ext4) partition to find the block it starts on. Substitute that into the command below. Note that this won't change after this process, so you can change the hostname, send off the image, and then change it again, without needing to run fdisk and use a new value.

sudo mount -o loop,offset=$((TYPE_START_BLOCK_HERE*512)) image.img /mnt
nano /mnt/etc/hostname

Get rid of the default and type in the hostname you want, and then hit Ctrl-x, then y, and then enter. We can now unmount the image like this.

sudo umount /mnt

Done! Using dd to load the image onto the SD card and booting the card in a Pi will set the Pi's hostname to the one you specified above.

To automate this process and change the hostname of an image quickly between dd's, one could write a bash script:

#!/bin/bash

mkdir tst;
echo ${1:?"Set argument one to filename"} > /dev/null;
echo ${2:?"Set argument two to desired hostname"} > /dev/null;
mount -o loop,offset=$(($(fdisk -l $1 |awk '$7=="Linux"{print $2}')*512)) $1 
tst;
echo $2 > tst/etc/hostname;
umount tst;
rmdir tst;
1
  • 2
    The hostname should also be changed in /etc/hosts (/mnt/etc/hosts).
    – bstipe
    Jul 30, 2017 at 1:30
2

Why not create a service?

[Unit]
Description=Change hostname from sd
ConditionPathExists=/boot/hostname
Before=dhcpcd.service

[Service]
Type=oneshot
ExecStartPre=/bin/bash -c 'CURRENT_HOSTNAME=$(/bin/cat /etc/hostname | /usr/bin/tr -d "\t\n\r");NEW_HOSTNAME=$(/bin/cat /boot/hostname | /usr/bin/tr -d "\t\n\r");/bin/sed -i "s/127.0.1.1.*$CURRENT_HOSTNAME/127.0.1.1\t$NEW_HOSTNAME/g" /etc/hosts'
ExecStart=/bin/mv /boot/hostname /etc/hostname
ExecStartPost=/sbin/reboot

[Install]
WantedBy=multi-user.target
1
  • 1
    Can this be done on a freshly imaged card (before the first boot of the Pi)? Where does the service file go?
    – dlu
    May 1, 2020 at 17:52
1

In the 'modern' Raspberry Pi Imager using the cog wheel in the first screen allows you to set some presets including the hostname but also wifi configuration, default user name, whether SSH is enabled or not, very useful!

Raspberry Pi Imager > Advanced Options

If you select a new hostname, this will create a file on the 'bootfs' partition of your SD card after writing. So if you do not want to use the Raspberry Pi Imager, you can also do this manually. Create a file called firstrun.sh and add this, for changing the hostname to jackfruit.local:

#!/bin/bash

set +e

CURRENT_HOSTNAME=`cat /etc/hostname | tr -d " \t\n\r"`
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then
   /usr/lib/raspberrypi-sys-mods/imager_custom set_hostname jackfruit
else
   echo jackfruit >/etc/hostname
   sed -i "s/127.0.1.1.*$CURRENT_HOSTNAME/127.0.1.1\tjackfruit/g" /etc/hosts
fi
rm -f /boot/firstrun.sh
sed -i 's| systemd.run.*||g' /boot/cmdline.txt
exit 0

and modify cmdline.txt to add systemd.run=/boot/firstrun.sh, for my 'headless raspbian' it currently looks like the below:

console=serial0,115200 console=tty1 root=PARTUUID=544c6228-02 rootfstype=ext4 fsck.repair=yes rootwait quiet init=/usr/lib/raspberrypi-sys-mods/firstboot systemd.run=/boot/firstrun.sh systemd.run_success_action=reboot systemd.unit=kernel-command-line.target%

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