USFOS on linux

As a commercial (engineering) software, USFOS needs to be manually installed. I tried this today on elementary OS, powered by frugal hardware, and USFOS runs just fine. At minimum, the following are needed:

  1. usfos, xact binary, and usfos_etc files
  2. A valid license usfos.key file
  3. A computer with Linux 64-bit OS to run on

As each binary needs to be separately downloaded from USFOS site, I have automated this with a script:

#!/usr/bin/env bash
#
# USFOS on (debian) linux: Installation script
# 2016 ckunte (optimised)
#
# Changes vs original:
#   - fail fast on errors (set -euo pipefail)
#   - verify downloads before acting on them
#   - idempotent PATH / USFOS_HOME setup (no duplicate rc entries on rerun)
#   - only chmod the files we actually downloaded, not everything in bin/
#   - dependency check for wget/tar
#   - clean up temporary archive
#   - clearer progress/error messages

set -euo pipefail

USFOS_DIR="$HOME/usfos"
BIN_DIR="$USFOS_DIR/bin"
ETC_TGZ_URL="http://www.usfos.no/download/Linux/files/usfos_etc.tgz"
DOWNLOAD_LIST_URL="https://gist.githubusercontent.com/ckunte/7836a10f5d418799a8ea/raw/a84df4d072683aa6bd3d513400f2d54aadefe363/downloadlist.txt"

log()  { printf '[install-usfos] %s\n' "$*"; }
die()  { printf '[install-usfos] ERROR: %s\n' "$*" >&2; exit 1; }

# --- Step 0: Check dependencies -------------------------------------------

for cmd in wget tar gunzip; do
    command -v "$cmd" >/dev/null 2>&1 || die "required command '$cmd' not found. Please install it and re-run."
done

# --- Step 1: Create folders -------------------------------------------------

mkdir -p "$BIN_DIR"

# --- Step 2: Download usfos_etc files ---------------------------------------

cd "$USFOS_DIR" || die "could not cd into $USFOS_DIR"

log "Downloading usfos_etc files..."
wget -q --show-progress -O usfos_etc.tgz "$ETC_TGZ_URL" \
    || die "failed to download usfos_etc.tgz from $ETC_TGZ_URL"

[[ -s usfos_etc.tgz ]] || die "downloaded usfos_etc.tgz is empty"

tar -zxvf usfos_etc.tgz || die "failed to extract usfos_etc.tgz"
rm -f usfos_etc.tgz

# --- Step 3: Download usfos and additional modules --------------------------

cd "$BIN_DIR" || die "could not cd into $BIN_DIR"

log "Downloading usfos and additional modules..."
# Record what's here before downloading, so we only touch new files below.
before_download=$(mktemp)
find . -maxdepth 1 -type f -printf '%f\n' > "$before_download"

wget -q --show-progress -i "$DOWNLOAD_LIST_URL" \
    || die "failed to download one or more files from the download list"

# --- Unzip newly downloaded files -------------------------------------------

shopt -s nullglob
gz_files=(*.gz)
if [[ ${#gz_files[@]} -gt 0 ]]; then
    log "Extracting ${#gz_files[@]} gzipped file(s)..."
    gunzip -f "${gz_files[@]}"
else
    log "No .gz files found to extract (they may already be uncompressed)."
fi
shopt -u nullglob

# --- Make only the newly-downloaded binaries executable ---------------------

after_download=$(mktemp)
find . -maxdepth 1 -type f -printf '%f\n' > "$after_download"
new_files=$(comm -13 <(sort "$before_download") <(sort "$after_download"))
rm -f "$before_download" "$after_download"

if [[ -n "$new_files" ]]; then
    log "Marking new binaries as executable..."
    while IFS= read -r f; do
        chmod +x -- "$f"
    done <<< "$new_files"
else
    log "No new files detected; skipping chmod."
fi

# --- Step 4: Add USFOS to $PATH (idempotent) --------------------------------

add_env_lines() {
    local rc_file="$1"
    [[ -f "$rc_file" ]] || return 0

    if ! grep -qF "USFOS_HOME=$USFOS_DIR" "$rc_file"; then
        {
            echo "export PATH=\"$BIN_DIR:\$PATH\""
            echo "export USFOS_HOME=\"$USFOS_DIR\""
        } >> "$rc_file"
        log "Updated $rc_file with USFOS PATH/USFOS_HOME."
    else
        log "$rc_file already configured for USFOS; skipping."
    fi
}

add_env_lines "$HOME/.zshrc"
add_env_lines "$HOME/.bashrc"

# --- Step 5: Final instructions ---------------------------------------------

log "All done."
log "Remember to add a valid usfos.key in the folder: $USFOS_DIR/etc/"
log "Restart your shell (or run 'source ~/.bashrc' / 'source ~/.zshrc') to pick up the new PATH."
log "To run the USFOS UI, type the following in a terminal: xact &"

Run xact & from terminal to load the USFOS’s familiar UI.

Place a valid license key, usfos.key, in ~/usfos/etc folder — this is required to perform analysis. (USFOS team is kind enough to make model and results viewer not depend on the license key.) Docs and examples may be separately downloaded — as required.