Updating Nash

nash update checks for a newer release, downloads it, verifies it, installs it over the build you are running, and tells you what to do next. Nash is a terminal, so an update is a command instead of a dialog.

The command is possible because nash and nash-gui are different programs. On macOS app bundles and Linux AppImages, nash can replace the application on disk while nash-gui keeps running, and your windows stay open until you decide to restart. Windows installer updates close running Nash processes; save your work before updating.

Before you start

  • You need Nash 0.6.0 or newer. If your build is older, download the latest one from the download page once. After that, nash update does the work.
  • Open a shell inside Nash, or any shell where nash is on your PATH. See The nash Command if nash is not found.

Quick start

nash update --check nash update --dry-run nash update
  1. --check says whether a newer release exists and changes nothing.
  2. --dry-run runs every check that does not need the download and writes nothing.
  3. nash update asks for confirmation, then downloads, verifies, and installs.

A run on a macOS app bundle looks like this. The versions, file names, and sizes are examples.

$ nash update Current version: 0.9.0 Install: macOS app bundle at /Applications/Nash.app Latest release: 0.9.1 Artifact: Nash-arm.zip (zip archive, 74.8 MiB) Checks: Nash-arm.zip.sha256 and the platform signature Install 0.9.1 over macOS app bundle at /Applications/Nash.app? [y/N] y Downloading Nash-arm.zip 100% 74.8 MiB / 74.8 MiB 8.1 MiB/s Downloaded 74.8 MiB. Checksum matches Nash-arm.zip.sha256. Installed 0.9.1. /Applications/Nash.app now holds the new build. 1 Nash window process(es) still run the old build. Restart Nash to switch to the new version. Nash saves the session on exit. It can be restored on restart

The command only looks at the latest stable release. It never installs anything before you confirm, unless you pass --yes.

Options

OptionWhat it does
--checkReports whether a newer release exists and changes nothing. It cannot be combined with --from. The section "Use it in a script" explains the exit status.
--dry-runNames the artifact it would install, runs the checks that do not need the download, and writes nothing.
--yes, -yDoes not ask for confirmation. You need it when stdin is not a terminal.
--forceInstalls the release even when it is not newer than your build.
--restartCloses the Nash windows and starts the new build. The section "Restart after an update" explains how.
--restart-timeout NSeconds to wait for each window to close when you use --restart. The default is 10.
--from FILEInstalls a local .zip, .dmg, .exe, or .AppImage file instead of downloading one. No published digest is checked.
--keep-downloadKeeps the downloaded file instead of removing it.

Which installs Nash replaces

Nash looks at where the running executable came from and replaces it only when Nash owns the files. For everything else it prints the command that updates that install, and stops. Overwriting a file that apt or Homebrew tracks would corrupt that tool's record of what is installed.

Your installWhat nash update does
macOS app bundle, such as /Applications/Nash.appReplaces the bundle.
Windows install made by the Nash installerStarts the installer in silent mode. The installer closes Nash and installs the update.
Linux AppImageReplaces the AppImage file.
Homebrew caskNothing. It prints brew upgrade --cask nash.
winget, Scoop, ChocolateyNothing. It prints winget upgrade nash, scoop update nash, or choco upgrade nash.
Linux package owned by dpkg, rpm, or pacmanNothing. It prints sudo apt-get install --only-upgrade nash, sudo dnf upgrade nash, or sudo pacman -Syu nash.
FlatpakNothing. It prints flatpak update and the application id.
SnapNothing. It prints sudo snap refresh nash.
A build from sourceNothing. It prints just build.
A macOS .app that is a symbolic linkNothing. It names what the link points at, so you can update that bundle or replace the link.
A portable copy, or any other install that Nash cannot placeNothing. It tells you to download a build from the download page.

nash update --check works on every install. On an install that Nash does not replace, it still reports that a release exists and prints the matching command.

What happens on each platform

  • macOS. Nash extracts the downloaded zip, or mounts the disk image. It moves your bundle aside, renames the new bundle into its place, and removes the old one. If the second step fails, Nash puts the old bundle back. Nash picks the artifact that matches your processor (arm or x86) and falls back to the universal build.
  • Windows. Nash starts Nash-Setup.exe with /SILENT /NORESTART and does not wait for it. The installer closes the running Nash processes itself.
  • Linux AppImage. Nash copies the new AppImage next to the old one, marks it executable, and renames it over the file that $APPIMAGE names. It picks the AppImage built for your distribution when the release has more than one.

Before it downloads anything, Nash checks that it can write to the folder that holds your install. Learning that /Applications needs an administrator account after a large download would waste your time, so Nash reports it first:

cannot write to /Applications. Replacing an app there needs an administrator account.

What Nash checks before it installs

Nash installs a download only after at least one independent check can run. It runs every check that applies.

  1. HTTPS only. Every request and every redirect must use https. A redirect to plain HTTP is refused.
  2. Size. Nash compares the number of bytes it received with the size in the release feed. A truncated download is refused. The download lands in a .part file first, so an interrupted download never looks complete.
  3. The published digest. Each release artifact can have a .sha256 file next to it. When it exists, Nash compares it with the SHA-256 of the download.
  4. The code signature, on macOS. If your installed bundle carries a Developer ID, Nash runs codesign --verify --deep --strict on the download, requires the same Developer ID team as the bundle it replaces, and then asks spctl whether Gatekeeper would open it. codesign alone is not enough, because it accepts a signed bundle that Apple never notarized.

The Checks: line of the output tells you whether Nash will check a published digest, the signature, or both. A download that fails a check is not installed.

SituationWhat Nash does
The release publishes a .sha256 fileChecks the digest, and on a signed macOS install the signature too.
No digest, and your macOS install is signedPrints a warning, installs, and relies on the signature check.
No digest, and any other installRefuses. On Windows and Linux the digest is the only check there is.
A different Developer ID team, or no teamRefuses.

The refusal for a missing digest reads:

release 0.9.1 publishes no Nash-arm.zip.sha256, and this install carries no Developer ID signature to check against. Nash will not install a download that it cannot check.

Unsigned installs and quarantine

A bundle with no Developer ID is a local build, so there is no team to compare against. Nash warns you that the signature was not checked.

macOS marks files that arrive from the internet with a quarantine attribute. It makes macOS check an app the first time it opens. Nash removes the attribute only after the download has passed verification (Nash 0.8.1 or newer). When Nash could not verify the download, the attribute stays. macOS then checks the new build when it first opens, and an unsigned build needs your approval under System Settings, Privacy & Security.

Restart after an update

On macOS app bundles and Linux AppImages, nash update leaves your running windows alone by default. It installs the new build and tells you that a restart is needed:

1 Nash window process(es) still run the old build. Restart Nash to switch to the new version. Nash saves the session on exit. It can be restored on restart

Nash saves your window layout when it exits, so the session restore dialog offers your tabs and panes back on the next start.

On those installs, --restart does the restart for you. Nash asks each window to exit, which lets it write the session first. It waits up to --restart-timeout seconds for each window, then starts the new build.

nash update --restart
  • Run it from another terminal. --restart closes every Nash window, which kills every pane, including the one that runs the command. Nash refuses to run it inside a Nash pane and says so. Restart Nash yourself in that case.
  • If a window does not exit in time, the new build is already installed. Close the window, then start Nash yourself.
  • --restart applies to the macOS bundle and the AppImage. The Windows installer closes the running processes by itself, even without --restart. Save your work before starting a Windows installer update.

The multiplexer server

If you use multiplexer sessions, the server owns your panes. Updating never restarts it, because stopping the server closes every pane it owns.

On macOS, nash update also copies the new nash-mux-server out of the fresh bundle into the folder that Nash owns for server binaries, so the next server start runs the new build. The copy does not wait for the running server.

A running server keeps the binary it started with. After an update, nash update tells you so and names the command to use when you can close those panes:

nash mux restart

Use it in a script

nash update --check is built for scripts and exits with status 1 when a release exists. Status 1 is also the status of any failure, such as no network, because Nash exits with 1 for every error. Do not treat status 1 alone as proof that a release exists.

The message that says an update exists goes to standard output. Errors go to standard error. A reliable check reads the output:

if nash update --check 2>/dev/null | grep -q "An update is available"; then nash update --yes fi

A non-interactive run needs --yes. Without it, Nash stops with Pass --yes to answer this from a script.

From the command palette

Two palette entries run the same commands. Each opens a new tab that stays open, so you can read the result:

  • Check for Updates runs nash update --check.
  • Install Update runs nash update.

The background check

Nash also checks for a release on its own. By default it checks about once every 24 hours. When a newer release exists, Nash shows a notice that names nash update, and one Nash process raises a desktop notification that links to the release notes. The background check never downloads or installs anything.

These options are Lua settings. Put them in custom.lua in your configuration directory (~/.config/nash by default) to change them:

return { check_for_updates = false, -- Or keep the check and change how often it runs: -- check_for_updates_interval_seconds = 604800, }

Builds that Linux distributions package can ship with the check turned off.

Install from a local file

--from installs a file that is already on disk. Nash picks the kind of artifact from the file extension (.zip, .dmg, .exe, or .AppImage) and refuses a file that does not suit your install.

nash update --from ~/Downloads/Nash-arm.zip --dry-run

There is no release feed, so there is no digest to check. On macOS the signature check still runs. On Windows and Linux nothing is checked, so use --from only with a file that you produced or downloaded yourself.

Where the files go

PathWhat it is
The updates folder in Nash's cache directoryThe download. Nash removes it unless you pass --keep-download.
<name>.part in that folderA download that is not finished. The next run removes what an interrupted one left.
.nash-update-<pid> next to your installThe staging folder. Nash removes it when the run ends.
.nash-old-<pid>.app next to your installYour previous bundle, during the swap only.

An interrupted run can leave a .nash-old-*.app or a staging folder behind. Your install is fine in that case. The next nash update removes leftovers from runs that ended.

Troubleshooting

Nash does not replace this install

Another tool owns your install. Run the command that the message prints. The table in the section "Which installs Nash replaces" lists them all.

The update stops before it downloads

Read the message. Typical causes are a folder that needs an administrator account, and --restart inside a Nash pane. Both messages name the fix.

The download is signed by a different team

the download is signed by team ABCDE12345, but the installed Nash is signed by team FGHIJ67890. Nash will not install it.

Nash never lowers the trust level of a signed install. Do not work around this message. Download Nash from the download page instead.

The checksum does not match

Nash prints the expected and the found digest and installs nothing. Run the command again. If the digests still differ, do not install the file. Download Nash from the download page.

The command cannot read the release feed

failed to read the release feed means the request failed. Check your network connection, proxy, and the system clock, then try again.

A window does not close with --restart

these Nash processes did not exit within 10s: [1234]. The new build is installed; close them and start Nash yourself.

Close the window, start Nash, or raise the wait with --restart-timeout.

Related pages