How to have PC speaker beep when log-in is ready?

I'm looking to have my computer's motherboard speaker play a beep whenever boot completes and log-in is available.

I've seen some suggestions about having beep to a script to start on-boot, but I feel there might be a more-integrated way to go about this? speaker_load="YES" and manually playing a sound works.

Perhaps there's something I can do in loader to have it do the beep at the end of the boot process, instead of it starting with the OS via script? I feel as if the boot loader should be signaling the end of its process vs the OS reporting it's ready for log-in, or something in-between that but still before the OS.
 
Put the already working manual sound playing into /etc/rc.local. It is executed at the end of startup.
beep(1) from crontab(5) is executed a touch later than from /etc/rc.local.

/etc/rc.local
Code:
/usr/bin/beep  && logger 'beep from rc.local'

crontab(5)
Code:
@reboot     /usr/bin/beep  &&  logger 'beep from crontab'

/var/log/messages
Code:
Sep 14 15:54:04 14stable root[761]: beep from rc.local
Sep 14 15:54:04 14stable kernel: .
Sep 14 15:54:04 14stable root[814]: beep from crontab

See also dmesg(8) below ("Starting local daemons:" and "Starting cron.")

For a later stage (perhaps after /etc/rc.d/bgfsck - background file system checks), a custom rc(8) script is needed.

dmesg -a
Rich (BB code):
Starting local daemons:.
Starting cron.
Configuring vt: keymap.
Performing sanity check on sshd configuration.
Starting sshd.
Starting background file system checks in 60 seconds.

Sat Sep 14 15:54:04 CEST 2024

EDIT: Probably I'm overtinking the issue, /etc/rc.local will do just fine.
 
Try as root crontab -e
Code:
@reboot   beep
Probably absolutely sufficient in most cases, yet one point of critique: This will make​
Bash:
service cron onerestart
beep, too, which is not what we wanted. ? The @reboot stanza is in fact “when cron(8) is started” (and it is so documented in crontab(5)).​

[…] /etc/rc.local. It is executed at the end of startup.
More like toward the end of changing into a multi‑user run level. I hear it about two seconds, 10 lines of log messages before the login prompt appears. At least in my setup​
Bash:
rcorder /etc/rc.d/* /usr/local/etc/rc.d/* | sed -n '\|^/etc/rc.d/local$|,$p' # more sophisticated than grep -A 999 …
shows numerous commands after /etc/rc.d/local (and thus /etc/rc.local) gets processed.​

[…] and log-in is available. […]
I would put it as close to the login prompt as possible. First I looked at the login(1) configuration file’s manual page login.conf(5), but as it turns out the user name prompt is done by getty(8), the password prompt by login(1). Frankly, I wasn’t aware of that detail. ? Superficially it appeared it was one program.

So, next I looked at the manual page of getty(8)’s configuration file gettytab(5), yet this was inconclusive. There is no hook for “do this before displaying the user name prompt”. I briefly considered inserting \a (?) somewhere, but that’s just terrible design, so I don’t know whether this could even work.

Finally, I settled for altering /etc/ttys(5). ?‍? Append​
Code:
window='/usr/bin/beep'
to the ttyv* lines and run init q (reload ttys(5) file) as root. You may notice a slight delay between the beep(1) and getty(8) showing a prompt, but that’s probably tolerable. Due to this delay it it may seem that logout(1) caused a beep(1), too, so it is not perfect.​
 
Finally, I settled for altering /etc/ttys(5).

You may notice a slight delay between the beep(1) and getty(8) showing a prompt, but that’s probably tolerable. Due to this delay it it may seem that logout(1) caused a beep(1), too, so it is not perfect.​
Nice find, but the delay spoils the experience. There should be a more elegant solution.

I focused on what is displayed on the screen last during the boot process to possibly insert a beep(1) into the source script.

I couldn't find who is printing the last line (login:) or the penultimate line (OS/platform (hostname) (tty0) ).

Ultimately reading init(8) /etc/rc (system startup commands file, executed only once on system startup) cough my attention, which is the origin of the third to last line (date). And indeed, placing beep(1) there executes it at a late stage, nearly before the login prompt.

It is not as close to the login prompt as the /etc/ttys solution, but there is no delay before the login prompt and session log out, also no log out beep.

/etc/rc
Rich (BB code):
150 echo ''
151 date
152 /usr/bin/beep
153 echo "beep from /etc/rc"
154 exit 0

etc_rc.png
 
I think that the best solution is to write a new very simple rc script that would have "REQUIRE: LOGIN" in it and that would execute beep as its start command.
Indeed, but the OP has asked for a beep when the "boot completes and log-in is available". A rc(8) script is executed way before this moment.
 
That actually depends on the script's requirements / dependencies, right?
I thought that "REQUIRE: LOGIN" would help.
LOGIN doesn't mean here at the login prompt:

rc(8)
Code:
                        LOGIN         Check-point before user login services
                                      (inetd and sshd), as well as services
                                      which might run commands as users (cron
                                      and sendmail).

/etc/rc.d/LOGIN
Code:
#!/bin/sh
#
#

# PROVIDE: LOGIN
# REQUIRE: DAEMON

#       This is a dummy dependency to ensure user services such as xdm,
#       inetd, cron and kerberos are started after everything else, in case
#       the administrator has increased the system security level and
#       wants to delay user logins until the system is (almost) fully
#       operational.

This simple script for example is executed seconds before the login prompt:
Code:
#!/bin/sh

# PROVIDE: beep
# REQUIERE: LOGIN

. /etc/rc.subr

name="beep"
rcvar=beep_enable
command="/usr/bin/beep"

: ${beep_enable="NO"}

load_rc_config $name
run_rc_command "$1"

Take note of red highlighted "Starting beep." on top
Rich (BB code):
smbus0: <System Management Bus> on intsmb0
Starting beep.
Setting up harvesting: PURE_RDRAND,[CALLOUT],[UMA],[FS_ATIME],SWI,INTERRUPT,NET_NG,[NET_ETHER],NET_TUN,MOUSE,KEYBOARD,ATTACH,CACHED
Feeding entropy: .
ELF ldconfig path: /lib /usr/lib /usr/lib/compat
32-bit compatibility ldconfig path:
Setting hostname: 14stable.
em0: link state changed to UP
lo0: link state changed to UP
Starting Network: lo0 em0.
em0: link state changed to DOWN
lo0: flags=1008049<UP,LOOPBACK,RUNNING,MULTICAST,LOWER_UP> metric 0 mtu 16384
        options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
        inet 127.0.0.1 netmask 0xff000000
        inet6 ::1 prefixlen 128
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
        groups: lo
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=48505bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,LRO,VLAN_HWFILTER,VLAN_HWTSO,HWSTATS,MEXTPG>
        ether 08:00:27:04:10:78
        media: Ethernet autoselect
        status: no carrier
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
Starting devd.
Starting dhclient.
em0: no link ...
em0: link state changed to UP
 got link
DHCPREQUEST on em0 to 255.255.255.255 port 67
DHCPACK from 192.168.1.3
bound to 192.168.1.81 -- renewal in 300 seconds.
add host 127.0.0.1: gateway lo0 fib 0: route already in table
add host ::1: gateway lo0 fib 0: route already in table
add net fe80::: gateway ::1
add net ff02::: gateway ::1
add net ::ffff:0.0.0.0: gateway ::1
add net ::0.0.0.0: gateway ::1
Updating /var/run/os-release done.
Recovering vi editor sessions:.
Clearing /tmp (X related).
Updating motd:.
Creating and/or trimming log files.
Starting syslogd.
No core dumps found.
Mounting late filesystems:.
Starting local daemons:.
Starting cron.
Configuring vt: keymap.
Performing sanity check on sshd configuration.
Starting sshd.
Starting background file system checks in 60 seconds.

Tue Sep 24 06:05:40 CEST 2024
Sep 24 06:05:59 14stable login[840]: ROOT LOGIN (root) ON ttyv4
 
T-Daemon , yep, that's true. Thank you for the demo.
But I'd also recommend you to run rcorder /etc/rc.d/* /usr/local/etc/rc.d/* > /dev/null just to make sure that your rc script do not have any circular dependencies by accident.
There are some suspicious things in your output.
 
But I'd also recommend you to run rcorder /etc/rc.d/* /usr/local/etc/rc.d/* > /dev/null just to make sure that your rc script do not have any circular dependencies by accident.
There are some suspicious things in your output.
My apologies, I was mistaken. The cause of the early execution of the script was a typo. The LOGIN keyword didn't get passed.
Rich (BB code):
  #!/bin/sh

  # PROVIDE: beep
- # REQUIERE: LOGIN
+ # REQUIRE: LOGIN

"LOGIN" is indeed sufficient to run the script at a late stage.
Rich (BB code):
Starting sshd.
Starting beep.
Starting background file system checks in 60 seconds.

Tue Sep 24 17:49:59 CEST 2024

A touch later with one of the last scripts run as requirement:
Code:
 # rcorder /etc/rc.d/*
...
/etc/rc.d/bgfsck
/etc/rc.d/jail
/etc/rc.d/securelevel

For example # REQUIRE: securelevel
Rich (BB code):
Configuring vt: keymap.
Starting background file system checks in 60 seconds.
Starting beep.

Tue Sep 24 18:03:33 CEST 2024
 
I was looking around at Linux kernel parameters and noticed this:

Code:
        acpi_sleep=     [HW,ACPI] Sleep options
                        Format: { s3_bios, s3_mode, s3_beep, s4_hwsig,
                                  s4_nohwsig, old_ordering, nonvs,
                                  sci_force_enable, nobl }
                        See Documentation/power/video.rst for information on
                        s3_bios and s3_mode.
                        s3_beep is for debugging; it makes the PC's speaker beep
                        as soon as the kernel's real-mode entry point is called.

s3_beep beeping "as soon as the kernel's real-mode entry point is called" sounds particularly interesting. I wonder if something like that could be available as a trigger for a beep between when boot finishes but before log-in prompt?

Also thanks for all the advice!
 
Last edited:
Recently I had bought pc speaker for my desktop PC and it's fun to use it. I also wanted to do this thread topic. I created a rc.d script with people's help in this thread and it's working while tty login screen comes. Thanks.

Code:
% cat /usr/local/etc/rc.d/playmusic
#!/bin/sh
#

# PROVIDE: playmusic
# REQUIRE: securelevel

. /etc/rc.subr

name="playmusic"
rcvar=playmusic_enable
command="/bin/echo"
start_precmd="do_play"

do_play()
{
        echo "msl16oldcd4mll8pcb-agf+4.g4p4<msl16dcd4mll8pa.a+f+4p16g4" > /dev/speaker &
}

: ${playmusic_enable="NO"}

load_rc_config $name
run_rc_command "$1"
 
Back
Top