There is a lot of hype going around with people saying they have 10x or more productivity but a lot of skeptics rightfully ask, where is the tenfold increase in feature volume or quality?

I make no attempt to address this. I suspect that 10x may be very near or already exceeding our capacity to keep up from a planning/design cognitive perspective, so we may feel in the moment that buildout productivity is 10x or more, but in the end we'll be limited by our ideation speed.

Still, one thing I have found very valuable so far in the past few years is a lowered barrier to improving ux in all sorts of areas.

The most recent example is something really narrow and simple that still took some iteration to get to something I like, but I think I will be pretty satisfied with it. It is an example of a tool that maybe I could have attempted to do in the past, and maybe I could have achieved a similar result in 2 hours of work, but I think if I did it without AI the quality would be much lower.

To set the stage: On most computers ejecting a removable disk is done with something in the GUI in the operating system. That does not change even when I am on my Mac and using the terminal. It's far easier, and arguably more suitable, to click the eject button in Finder.

On Linux though, my primary environment is much more so the terminal. The Linux machine in question may be my NAS that is currently under my desk, but I will typically not bother to dedicate and route mouse, keyboard, and display to this machine. Since it is the NAS, and for the time being when it happens to be physically accessible, it becomes the natural place to connect things like SD cards for media dumping into my ZFS pool. Although the eventual setup will involve high speed home networking and dumping media to the same ZFS pool over Samba from another computer, I decided that I was fed up with not having a truly convenient way to quickly eject disks like this from the Linux command line.

So I came up with a script and it took about 30 minutes to do. I expected it to take 2 minutes but there was some iteration that had to happen. You see, following up on the usual barriers to unmounting a filesystem leads down several rabbit holes.

  1. Some random terminal I have open is open to this filesystem
  2. Some shell I can't see is currently on the disk because it is ssh'd to this machine from another of my machines and cd'd to this filesystem
  3. Some tmux pane out of the typically 40+ tmux panes I have is open to this filesystem
  4. Some program I'm not keeping track of (maybe an image viewer) is doing something in this filesystem

Honestly handling all of this is a pretty tall order... but we have "unlimited" productivity on tap.

All I can say is I have this working now, and the first 3 cases are cleanly handled... I now have a script cwd-holders which builds a useful report about what's going on preventing the unmount, and a streamlining script that has simple and sane semantics that i can call that will eject the disk if the current directory is that disk, or it will produce the report for what to clean up before I can cleanly eject the disk. I will flesh this article out with more details on the implementation soon, especially full examples of how this thing looks when you use it, but I can dump it out here for now:

It has two components, a helper shell function that is portable between zsh and bash, inserted in my aliases dotfile (e.g. source this from your bashrc or zshrc):

__eject_decode_findmnt() {
  printf '%b' "$1"
}

__eject_findmnt_target_for_path() {
  __eject_decode_findmnt "$(findmnt -T "$1" -n -o TARGET 2>/dev/null | head -n 1)"
}

__eject_findmnt_source_for_path() {
  __eject_decode_findmnt "$(findmnt -T "$1" -n -o SOURCE 2>/dev/null | head -n 1)"
}

__eject_findmnt_target_for_dev() {
  __eject_decode_findmnt "$(findmnt -rn -S "$1" -o TARGET 2>/dev/null | head -n 1)"
}

eject() {
  if [[ "$(uname -s)" != "Linux" ]]; then
    echo "eject: Linux-only helper" >&2
    return 1
  fi

  if [[ $# -gt 0 ]]; then
    command /usr/bin/eject "$@"
    return
  fi

  local target mountpoint source_dev disk_name disk_dev removable hotplug tran
  local dev mp failed_mountpoint
  local -a mounted_devs

  target="$(pwd -P)"
  mountpoint="$(__eject_findmnt_target_for_path "$target")"
  source_dev="$(__eject_findmnt_source_for_path "$target")"

  [[ -n "$mountpoint" ]] || { echo "eject: could not find a mount containing $target" >&2; return 1; }
  [[ "$target" == "$mountpoint" ]] || { echo "eject: run from the mounted filesystem root, not from $target" >&2; return 1; }

  case "$mountpoint" in
    /run/media/*|/media/*|/mnt/*) ;;
    *) echo "eject: $mountpoint is not under /run/media, /media, or /mnt" >&2; return 1 ;;
  esac

  case "$mountpoint" in
    /|/boot|/boot/*|/dev|/dev/*|/etc|/etc/*|/home|/home/*|/opt|/opt/*|/root|/root/*|/srv|/srv/*|/usr|/usr/*|/var|/var/*)
      echo "eject: refusing to operate on system mountpoint $mountpoint" >&2
      return 1
      ;;
  esac

  [[ "$source_dev" == /dev/* ]] || { echo "eject: $mountpoint is mounted from $source_dev, not a block device" >&2; return 1; }
  source_dev="${source_dev%%\[*}"
  source_dev="$(readlink -f "$source_dev")" || { echo "eject: could not resolve block device for $mountpoint" >&2; return 1; }
  [[ -b "$source_dev" ]] || { echo "eject: $source_dev is not a block device" >&2; return 1; }

  disk_name="$(lsblk -no PKNAME "$source_dev" | head -n 1 | tr -d '[:space:]')"
  if [[ -z "$disk_name" ]]; then
    disk_dev="$source_dev"
  else
    disk_dev="/dev/$disk_name"
  fi
  [[ -b "$disk_dev" ]] || { echo "eject: $disk_dev is not a block device" >&2; return 1; }

  removable="$(lsblk -dno RM "$disk_dev" | tr -d '[:space:]')"
  hotplug="$(lsblk -dno HOTPLUG "$disk_dev" | tr -d '[:space:]')"
  tran="$(lsblk -dno TRAN "$disk_dev" | tr -d '[:space:]')"
  if [[ "$removable" != 1 && "$hotplug" != 1 && "$tran" != usb && "$tran" != mmc && "$tran" != firewire ]]; then
    echo "eject: $disk_dev does not look removable or hotplugged (RM=$removable HOTPLUG=$hotplug TRAN=${tran:-unknown})" >&2
    return 1
  fi

  while IFS= read -r dev; do
    mp="$(__eject_findmnt_target_for_dev "$dev")"
    [[ -n "$mp" ]] && mounted_devs+=("$dev")
  done < <(lsblk -nrpo NAME "$disk_dev")
  [[ ${#mounted_devs[@]} -gt 0 ]] || { echo "eject: no mounted filesystems found on $disk_dev" >&2; return 1; }

  for dev in "${mounted_devs[@]}"; do
    mp="$(__eject_findmnt_target_for_dev "$dev")"
    [[ -n "$mp" ]] || continue
    case "$mp" in
      /run/media/*|/media/*|/mnt/*) ;;
      *) echo "eject: refusing to power off $disk_dev while $dev is mounted at non-removable-media path $mp" >&2; return 1 ;;
    esac
  done

  echo "Unmounting filesystems on $disk_dev:"
  for dev in "${mounted_devs[@]}"; do
    mp="$(__eject_findmnt_target_for_dev "$dev")"
    echo "  $dev${mp:+ mounted at $mp}"
  done

  builtin cd / || return

  for dev in "${mounted_devs[@]}"; do
    if ! sudo udisksctl unmount -b "$dev"; then
      failed_mountpoint="$(__eject_findmnt_target_for_dev "$dev")"
      if command -v cwd-holders >/dev/null 2>&1; then
        cwd-holders "${failed_mountpoint:-$mountpoint}" >&2
      else
        echo "eject: install cwd-holders for detailed cwd/SSH/tmux diagnostics" >&2
      fi
      return 1
    fi
  done

  echo "Powering off $disk_dev"
  sudo udisksctl power-off -b "$disk_dev"
}

And a helper bash script cwd-holders:

#!/usr/bin/env bash
set -euo pipefail

usage() {
    cat >&2 <<'EOF'
Usage: cwd-holders [path]

List shell processes whose current working directory is at or under path.
On Linux, also shows SSH connection details and useful tmux client context.

If path is omitted, the current directory is used.
EOF
}

die() {
    echo "cwd-holders: $*" >&2
    exit 1
}

need_cmd() {
    command -v "$1" >/dev/null 2>&1 || die "missing required command: $1"
}

have_cmd() {
    command -v "$1" >/dev/null 2>&1
}

proc_env_value() {
    local pid=$1
    local name=$2

    [[ -r /proc/"$pid"/environ ]] || return 1
    tr '\0' '\n' < /proc/"$pid"/environ 2>/dev/null |
        awk -F= -v name="$name" '$1 == name { sub(/^[^=]*=/, ""); print; exit }'
}

cmdline_for_pid() {
    local pid=$1
    local cmdline=

    if [[ -r /proc/"$pid"/cmdline ]]; then
        cmdline=$(tr '\0' ' ' < /proc/"$pid"/cmdline 2>/dev/null | sed 's/[[:space:]]*$//')
    fi

    if [[ -z $cmdline ]]; then
        cmdline=$(ps -p "$pid" -o args= 2>/dev/null | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
    fi

    [[ -n $cmdline ]] && printf '%s' "$cmdline"
}

hostname_for_ip() {
    local ip=$1
    local name=

    if have_cmd getent; then
        name=$(getent hosts "$ip" 2>/dev/null | awk 'NR == 1 { print $2 }')
    fi

    if [[ -z $name && $ip == 100.* ]] && have_cmd tailscale; then
        name=$(tailscale status 2>/dev/null | awk -v ip="$ip" '$1 == ip { print $2; exit }')
    fi

    if [[ -n $name && $name != "$ip" ]]; then
        printf '%s(%s)' "$name" "$ip"
    else
        printf '%s' "$ip"
    fi
}

ssh_parts_for_pid() {
    local pid=$1
    local ssh_connection ssh_client
    local -a ssh_parts

    ssh_connection=$(proc_env_value "$pid" SSH_CONNECTION || true)
    if [[ -n $ssh_connection ]]; then
        read -r -a ssh_parts <<< "$ssh_connection"
        if [[ ${#ssh_parts[@]} -ge 4 ]]; then
            printf '%s|%s|%s|%s' "${ssh_parts[0]}" "${ssh_parts[1]}" "${ssh_parts[2]}" "${ssh_parts[3]}"
        else
            printf '%s||||%s' "unknown" "$ssh_connection"
        fi
        return 0
    fi

    ssh_client=$(proc_env_value "$pid" SSH_CLIENT || true)
    if [[ -n $ssh_client ]]; then
        read -r -a ssh_parts <<< "$ssh_client"
        if [[ ${#ssh_parts[@]} -ge 3 ]]; then
            printf '%s|%s|server|%s' "${ssh_parts[0]}" "${ssh_parts[1]}" "${ssh_parts[2]}"
        else
            printf '%s||||%s' "unknown" "$ssh_client"
        fi
    fi
}

ssh_remote_for_pid() {
    local pid=$1
    local client_ip client_port server_ip server_port extra

    IFS='|' read -r client_ip client_port server_ip server_port extra < <(ssh_parts_for_pid "$pid" || true)
    [[ -n ${client_ip:-} ]] || return 0

    if [[ $client_ip == unknown ]]; then
        printf '%s' "${extra:-unknown}"
    else
        printf '%s:%s' "$(hostname_for_ip "$client_ip")" "$client_port"
    fi
}

ssh_route_for_pid() {
    local pid=$1
    local client_ip client_port server_ip server_port extra

    IFS='|' read -r client_ip client_port server_ip server_port extra < <(ssh_parts_for_pid "$pid" || true)
    [[ -n ${client_ip:-} ]] || return 0

    if [[ $client_ip == unknown ]]; then
        printf '%s' "${extra:-unknown}"
    else
        printf '%s:%s->%s:%s' "$client_ip" "$client_port" "$server_ip" "$server_port"
    fi
}

ancestor_summary_for_pid() {
    local pid=$1
    local parent comm chain=

    while [[ $pid =~ ^[0-9]+$ && $pid -gt 1 ]]; do
        parent=$(ps -p "$pid" -o ppid= 2>/dev/null | tr -d '[:space:]')
        [[ -n $parent && $parent =~ ^[0-9]+$ ]] || break

        comm=$(ps -p "$parent" -o comm= 2>/dev/null | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
        [[ -n $comm ]] || break

        case "$comm" in
            sshd|sshd-session|tmux:*|tmux)
                chain="${chain:+$chain<-}$comm($parent)"
                ;;
        esac

        pid=$parent
    done

    [[ -n $chain ]] && printf '%s' "$chain"
}

normalize_tty() {
    case "$1" in
        /dev/*) printf '%s' "$1" ;;
        \?|"") printf '%s' "$1" ;;
        *) printf '/dev/%s' "$1" ;;
    esac
}

tmux_pane_for_tty() {
    local tty=$1
    local line pane_pid pane_tty session_name window_index window_name pane_index pane_id pane_current_path

    have_cmd tmux || return 0
    tty=$(normalize_tty "$tty")

    while IFS= read -r line; do
        IFS='|' read -r pane_pid pane_tty session_name window_index window_name pane_index pane_id pane_current_path <<< "$line"
        [[ $pane_tty == "$tty" ]] || continue
        printf '%s:%s.%s:%s %s pane-root-pid=%s path=%s' \
            "$session_name" "$window_index" "$window_name" "$pane_index" "$pane_id" "$pane_pid" "$pane_current_path"
        return 0
    done < <(tmux list-panes -a -F '#{pane_pid}|#{pane_tty}|#{session_name}|#{window_index}|#{window_name}|#{pane_index}|#{pane_id}|#{pane_current_path}' 2>/dev/null || true)
}

parent_summary_for_pid() {
    local pid=$1
    local parent comm cmdline

    parent=$(ps -p "$pid" -o ppid= 2>/dev/null | tr -d '[:space:]')
    [[ -n $parent && $parent =~ ^[0-9]+$ && $parent -gt 1 ]] || return 0

    comm=$(ps -p "$parent" -o comm= 2>/dev/null | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
    [[ -n $comm ]] || return 0
    cmdline=$(cmdline_for_pid "$parent" || true)

    if [[ -n $cmdline ]]; then
        printf '%s %s -- %s' "$parent" "$comm" "$cmdline"
    else
        printf '%s %s' "$parent" "$comm"
    fi
}

print_details() {
    local ssh_route=$1
    local ancestor_summary=$2
    local detail=

    [[ -n $ssh_route ]] && detail="ssh=$ssh_route"
    [[ -n $ancestor_summary ]] && detail="${detail:+$detail }ancestors=$ancestor_summary"
    [[ -n $detail ]] && printf '  details: %s\n' "$detail"
}

print_optional_field() {
    local label=$1
    local value=$2

    [[ -n $value ]] || return 0
    printf '  %-8s %s\n' "$label:" "$value"
}

is_shell_command() {
    case "$1" in
        bash|zsh|fish|sh|dash|ksh|mksh|tcsh|csh|nu|xonsh|elvish) return 0 ;;
        *) return 1 ;;
    esac
}

print_shell_holders() {
    local target=$1
    local proc_cwd pid real_cwd comm tty cmdline remote_host tmux_pane parent_summary ssh_route ancestor_summary
    local found=0

    for proc_cwd in /proc/[0-9]*/cwd; do
        pid=${proc_cwd#/proc/}
        pid=${pid%/cwd}

        real_cwd=$(readlink -e "$proc_cwd" 2>/dev/null || true)
        [[ -n $real_cwd ]] || continue

        case "$real_cwd" in
            "$target"|"$target"/*) ;;
            *) continue ;;
        esac

        comm=$(ps -p "$pid" -o comm= 2>/dev/null | sed 's/^[[:space:]]*//; s/[[:space:]]*$//' || true)
        is_shell_command "$comm" || continue

        tty=$(ps -p "$pid" -o tty= 2>/dev/null | tr -d '[:space:]' || true)
        cmdline=$(cmdline_for_pid "$pid" || true)
        remote_host=$(ssh_remote_for_pid "$pid" || true)
        tmux_pane=$(tmux_pane_for_tty "$tty" || true)
        parent_summary=$(parent_summary_for_pid "$pid" || true)
        ssh_route=$(ssh_route_for_pid "$pid" || true)
        ancestor_summary=$(ancestor_summary_for_pid "$pid" || true)

        printf 'PID %s  TTY %s  CMD %s\n' "$pid" "${tty:-?}" "${comm:-?}"
        print_optional_field "cmdline" "$cmdline"
        print_optional_field "remote" "$remote_host"
        print_optional_field "tmux" "$tmux_pane"
        print_optional_field "parent" "$parent_summary"
        print_optional_field "cwd" "$real_cwd"
        print_details "$ssh_route" "$ancestor_summary"
        echo
        found=1
    done

    [[ $found -eq 1 ]]
}

print_tmux_clients() {
    local line client_pid client_tty client_name client_session remote_host ssh_route ancestor_summary
    local -a tmux_lines

    have_cmd tmux || return 0

    mapfile -t tmux_lines < <(tmux list-clients -F '#{client_pid}|#{client_tty}|#{client_name}|#{client_session}' 2>/dev/null || true)
    [[ ${#tmux_lines[@]} -gt 0 ]] || return 0

    echo
    echo "Attached tmux clients:"

    for line in "${tmux_lines[@]}"; do
        IFS='|' read -r client_pid client_tty client_name client_session <<< "$line"
        [[ -n $client_pid ]] || continue

        remote_host=$(ssh_remote_for_pid "$client_pid" || true)
        ssh_route=$(ssh_route_for_pid "$client_pid" || true)
        ancestor_summary=$(ancestor_summary_for_pid "$client_pid" || true)

        printf 'PID %s  TTY %s\n' "$client_pid" "${client_tty:-?}"
        print_optional_field "remote" "$remote_host"
        print_optional_field "session" "$client_session"
        print_optional_field "name" "${client_name:-?}"
        print_details "$ssh_route" "$ancestor_summary"
        echo
    done
}

if [[ ${1-} == "-h" || ${1-} == "--help" ]]; then
    usage
    exit 0
fi

[[ "$(uname -s)" == "Linux" ]] || die "Linux only"
[[ $# -le 1 ]] || die "unexpected arguments"

need_cmd awk
need_cmd ps
need_cmd readlink
need_cmd sed
need_cmd tr

target=${1:-$PWD}
orig_target=$target
target=$(readlink -e "$target") || die "could not resolve $orig_target"
[[ -d $target ]] || die "$target is not a directory"

echo "Shell processes with cwd under $target:"
if print_shell_holders "$target"; then
    :
else
    echo "No shell processes with cwd under $target were found."
fi

print_tmux_clients

Pretty boring, pretty narrow tool. But it's clear that if I make a thousand of these tools, quality of life will shoot through the roof. It's also interesting to consider how someone else might have basically zero use for the vast majority of these thousand things of mine. Such is the fractal nature of life.