Skip to content

netshare-mounter

CLI utility that configures SMB/CIFS shares as systemd mount units — so they mount on boot, wait for the network, and are managed with systemctl and journalctl rather than fstab. It installs cifs-utils if missing, writes a per-mount credentials file at mode 600, and validates before mounting.

Quick usage lives in USAGE.md; each command also has a man page under man/.

The executable is generated by Bashly from src/:

Terminal window
cd packages/debian-ubuntu/scripts/netshare-mounter
bashly generate # needs Ruby + `gem install bashly`
sudo cp netshare-mounter /usr/local/bin/

Without Ruby, generate through Docker:

Terminal window
docker run --rm --user $(id -u):$(id -g) --volume "$PWD:/app" dannyben/bashly generate
# Windows (Git Bash): docker run --rm --volume "/${PWD}:/app" dannyben/bashly generate
Terminal window
sudo netshare-mounter mount //192.168.1.29/plex_storage /mnt/plex_storage
netshare-mounter status /mnt/plex_storage
sudo netshare-mounter unmount /mnt/plex_storage

Credentials are prompted for when not passed.

OptionDefault
-u, --usernameprompt
-p, --passwordprompt
-d, --domainnone
--uid / --gid1000 / 1000
--file-mode / --dir-mode0644 / 0755
--cifs-version3.0 (1.0, 2.0, 2.1, 3.0, 3.1.1)
-c, --credentials-file~/.netshare-mounter/<unit-name>.credentials
--auto-installinstall cifs-utils without prompting
--enable-onlyenable for next boot without mounting now
OptionEffect
-k, --keep-credentialsLeave the credentials file in place
-m, --keep-mountpointLeave the mount point directory
-f, --forceumount -f even if busy
--purgeRemove credentials, mount point and unit without prompting

Shows all CIFS mounts when the mount point is omitted. -v adds the systemd unit detail; -j emits JSON (… --json | jq -r '.active').

-c, --check-connectivity tests reachability of the SMB server; --check-credentials <file> checks that file’s permissions.

Each mount gets its own credentials file, named after the unit — /mnt/plex_storage → ~/.netshare-mounter/mnt-plex_storage.credentials, stored in the invoking user’s home even under sudo. --credentials-file overrides that when several mounts should share one. Files are written 600, never logged, and shredded on removal.

The generated unit:

[Unit]
Description=Mount SMB Share: //192.168.1.29/plex_storage
After=network-online.target
Wants=network-online.target
RequiresMountsFor=/mnt
[Mount]
What=//192.168.1.29/plex_storage
Where=/mnt/plex_storage
Type=cifs
Options=credentials=…,uid=1000,gid=1000,file_mode=0644,dir_mode=0755,vers=3.0,rw
TimeoutSec=30
[Install]
WantedBy=multi-user.target

systemd derives the unit name from the path — /mnt/plex_storage must be mnt-plex_storage.mount, and spaces in mount paths are not allowed at all.

SymptomCheck
Permission deniedCredentials. Test by hand: sudo mount -t cifs //server/share /mnt/test -o credentials=<file>
Connection timed outnetshare-mounter validate //server/share --check-connectivity, then nc -zv server 445
Unit fails to startsystemctl status mnt-<name>.mount, journalctl -xeu mnt-<name>.mount
Busy during unmountlsof /mnt/<name> or fuser -vm /mnt/<name>, then unmount --force
Wrong credentials permissionsvalidate <share> --check-credentials <file>, or chmod 600 it
Mount fails on an old serverLower --cifs-version to 2.0 or 1.0; modern servers want 3.0/3.1.1

For Active Directory, pass the domain both ways: --username 'DOMAIN\\user' --domain DOMAIN.

netshare-mounter/
├── src/
│ ├── bashly.yml # command definitions
│ ├── {mount,unmount,status,validate}_command.sh
│ └── lib/{helpers,systemd,credentials}.sh
├── netshare-mounter # generated — do not edit
├── USAGE.md
└── man/, docs/ # generated man pages

Edit src/, never the generated executable, and keep shellcheck clean.