Skip to content

Instantly share code, notes, and snippets.

@olibartfast
Created June 4, 2025 09:57
Show Gist options
  • Select an option

  • Save olibartfast/89d0b49dac26b33dcb984c16d47e0d46 to your computer and use it in GitHub Desktop.

Select an option

Save olibartfast/89d0b49dac26b33dcb984c16d47e0d46 to your computer and use it in GitHub Desktop.
How mount a shared folder from your NAS on your Linux Server
#!/bin/bash
# NAS Share Mounter - Mount CIFS/SMB shares with enhanced features
# Prerequisites: sudo apt-get install cifs-utils
set -euo pipefail # Exit on error, undefined variables, pipe failures
# ======= CONFIGURATION =======
SCRIPT_NAME=$(basename "$0")
CONFIG_FILE="$HOME/.nas_mounter.conf"
LOG_FILE="/tmp/nas_mounter_$(date +%Y%m%d).log"
# Default shares (edit as needed)
declare -a SHARES=("Folder1" "Folder2" "FolderN")
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# ======= FUNCTIONS =======
# Logging function
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
}
# Colored output functions
error() {
echo -e "${RED}[ERROR]${NC} $*" >&2
log "ERROR: $*"
}
success() {
echo -e "${GREEN}[SUCCESS]${NC} $*"
log "SUCCESS: $*"
}
warning() {
echo -e "${YELLOW}[WARNING]${NC} $*"
log "WARNING: $*"
}
# Check prerequisites
check_prerequisites() {
if ! command -v mount.cifs &> /dev/null; then
error "cifs-utils not installed"
echo "Please install with: sudo apt-get install cifs-utils"
exit 1
fi
if ! sudo -n true 2>/dev/null; then
warning "This script requires sudo privileges for mounting"
fi
}
# Validate IP address
validate_ip() {
local ip=$1
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
for octet in $(echo "$ip" | tr '.' ' '); do
if (( octet > 255 )); then
return 1
fi
done
return 0
fi
return 1
}
# Save configuration
save_config() {
cat > "$CONFIG_FILE" << EOF
NAS_IP="$nas_ip"
NAS_BASE="$nas_base"
NAS_USER="$nas_user"
MOUNT_BASE="$mount_base"
EOF
chmod 600 "$CONFIG_FILE"
success "Configuration saved to $CONFIG_FILE"
}
# Load configuration
load_config() {
if [[ -f "$CONFIG_FILE" ]]; then
# shellcheck source=/dev/null
source "$CONFIG_FILE"
return 0
fi
return 1
}
# Get user input with defaults
get_input() {
local prompt=$1
local default=$2
local var_name=$3
local is_password=${4:-false}
if [[ -n "$default" ]]; then
prompt="$prompt [$default]"
fi
prompt="$prompt: "
if [[ "$is_password" == "true" ]]; then
read -s -r -p "$prompt" value
echo # New line after password
else
read -r -p "$prompt" value
fi
value="${value:-$default}"
eval "$var_name='$value'"
}
# Collect configuration from user
collect_config() {
echo "=== NAS Mount Configuration ==="
# Try to load existing config
if load_config; then
warning "Found existing configuration. Press Enter to keep current values."
fi
# Get inputs with validation
while true; do
get_input "Enter NAS server IP" "${NAS_IP:-}" "nas_ip"
if validate_ip "$nas_ip"; then
break
else
error "Invalid IP address format. Please try again."
fi
done
get_input "Enter NAS share base path (leave blank for root)" "${NAS_BASE:-}" "nas_base"
get_input "Enter your NAS username" "${NAS_USER:-}" "nas_user"
get_input "Enter local mount base directory" "${MOUNT_BASE:-$HOME/nas_shares}" "mount_base"
# Get password securely
get_input "Enter your NAS password" "" "nas_pass" true
# Mount options
while true; do
get_input "Enter 'r' for read-only or 'w' for read-write" "w" "mount_option"
if [[ "$mount_option" =~ ^[rw]$ ]]; then
break
else
error "Invalid option. Please enter 'r' or 'w'"
fi
done
# Ask to save config
get_input "Save configuration for future use? (y/n)" "y" "save_conf"
if [[ "$save_conf" =~ ^[yY]$ ]]; then
save_config
fi
}
# Mount a share
mount_share() {
local share_name="$1"
local nas_path
# Construct NAS path
if [[ -z "$nas_base" ]]; then
nas_path="//$nas_ip/$share_name"
else
nas_path="//$nas_ip/$nas_base/$share_name"
fi
local mount_point="$mount_base/$share_name"
# Check if already mounted
if mountpoint -q "$mount_point" 2>/dev/null; then
warning "$share_name is already mounted at $mount_point"
return 0
fi
# Create mount point
if ! mkdir -p "$mount_point"; then
error "Failed to create mount point: $mount_point"
return 1
fi
# Prepare mount options
local mount_opts="username=$nas_user,password=$nas_pass,uid=$(id -u),gid=$(id -g)"
mount_opts+=",forceuid,forcegid,dir_mode=0770,file_mode=0660,iocharset=utf8"
if [[ "$mount_option" == "r" ]]; then
mount_opts+=",ro"
else
mount_opts+=",rw"
fi
# Attempt to mount
log "Attempting to mount $nas_path to $mount_point"
if sudo mount -t cifs "$nas_path" "$mount_point" -o "$mount_opts" 2>/tmp/mount_error.log; then
success "Mounted $share_name at $mount_point"
return 0
else
error "Failed to mount $share_name"
if [[ -f /tmp/mount_error.log ]]; then
cat /tmp/mount_error.log >&2
fi
rmdir "$mount_point" 2>/dev/null
return 1
fi
}
# Unmount a share
unmount_share() {
local share_name="$1"
local mount_point="$mount_base/$share_name"
if ! mountpoint -q "$mount_point" 2>/dev/null; then
warning "$share_name is not mounted"
return 0
fi
log "Attempting to unmount $mount_point"
if sudo umount "$mount_point"; then
success "Unmounted $share_name"
rmdir "$mount_point" 2>/dev/null
return 0
else
error "Failed to unmount $share_name"
return 1
fi
}
# List mounted shares
list_mounted() {
echo "=== Currently Mounted Shares ==="
local found=false
for share in "${SHARES[@]}"; do
local mount_point="$mount_base/$share"
if mountpoint -q "$mount_point" 2>/dev/null; then
echo -e "${GREEN}✓${NC} $share -> $mount_point"
found=true
fi
done
if [[ "$found" == "false" ]]; then
echo "No shares currently mounted"
fi
}
# Mount all shares
mount_all() {
echo "=== Mounting All Shares ==="
local success_count=0
local fail_count=0
for share in "${SHARES[@]}"; do
if mount_share "$share"; then
((success_count++))
else
((fail_count++))
fi
done
echo
echo "Summary: $success_count succeeded, $fail_count failed"
}
# Unmount all shares
unmount_all() {
echo "=== Unmounting All Shares ==="
local success_count=0
for share in "${SHARES[@]}"; do
if unmount_share "$share"; then
((success_count++))
fi
done
echo
success "Unmounted $success_count shares"
}
# Interactive menu
show_menu() {
while true; do
echo
echo "=== NAS Share Mounter ==="
echo "1) Mount a specific share"
echo "2) Mount all shares"
echo "3) Unmount a specific share"
echo "4) Unmount all shares"
echo "5) List mounted shares"
echo "6) Reconfigure settings"
echo "7) Quit"
echo
read -r -p "Select an option [1-7]: " choice
case $choice in
1)
echo "Available shares:"
select share in "${SHARES[@]}" "Back"; do
if [[ "$share" == "Back" ]]; then
break
elif [[ -n "$share" ]]; then
mount_share "$share"
break
fi
done
;;
2)
mount_all
;;
3)
echo "Select share to unmount:"
select share in "${SHARES[@]}" "Back"; do
if [[ "$share" == "Back" ]]; then
break
elif [[ -n "$share" ]]; then
unmount_share "$share"
break
fi
done
;;
4)
unmount_all
;;
5)
list_mounted
;;
6)
collect_config
;;
7)
echo "Goodbye!"
exit 0
;;
*)
error "Invalid option. Please select 1-7"
;;
esac
done
}
# Cleanup function
cleanup() {
# Clear password from memory
nas_pass=""
log "Script execution completed"
}
# ======= MAIN EXECUTION =======
# Set trap for cleanup
trap cleanup EXIT
# Start logging
log "Starting $SCRIPT_NAME"
# Check prerequisites
check_prerequisites
# Collect configuration
collect_config
# Show interactive menu
show_menu
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment