How do I non-interactively update FreeBSD system (and ports)?

Solution 1:

On FreeBSD 10.0R and later, set PAGER environment variable on freebsd-update

env PAGER=cat freebsd-update fetch
freebsd-update install

For portsnap(8) on FreeBSD 10.0R and later, default behaviour, namely without --interactive option, is non-interactive.

portsnap fetch update

Solution 2:

On FreeBSD-10.2 there's a new option to allow this:

freebsd-update fetch --not-running-from-cron

From the manpage:

        Force freebsd-update fetch to proceed when there is no
        controlling tty.  This is for use by automated scripts and
        orchestration tools.  Please do not run freebsd-update
        fetch from crontab or similar using this flag, see:
        freebsd-update cron

Solution 3:

For FreeBSD < 10, the following works:

Allow freebsd-update to run fetch without stdin attached to a terminal:

sed 's/\[ ! -t 0 \]/false/' /usr/sbin/freebsd-update > /tmp/freebsd-update
chmod +x /tmp/freebsd-update

Allow portsnap to run fetch without stdin attached to a terminal:

sed 's/\[ ! -t 0 \]/false/' /usr/sbin/portsnap > /tmp/portsnap
chmod +x /tmp/portsnap

Credits: veewee

For FreeBSD 10+, the solution in the answer below by @uchida should be preferred!

Solution 4:

Blindly installing updates (even freebsd-update updates) can be a Bad Thing: One option in rc.conf changes, and suddenly your machine has no SSH daemon anymore.

Similarly you probably don't want to blindly install all available port updates via portsnap / portupgrade -a -- you might take a major version number bump and break the universe, or you might just have a port with new configuration options that need to be changed (you can make ports just accept whatever their defaults are, but sometimes that's not what you want).

The best way to do this is to use a configuration management tool like Puppet or radmind to deploy your changes.
Make a machine template based on a box you've successfully upgraded and tested, then deploy that to the rest of your environment. This ensures that you're pushing out a working system configuration, and that you only have to do the manual steps once (on the machine you're templating from).