-3

I have a script to backup game saves from the Steam Deck to a network drive. It works perfectly when I run it on its own. However, when I configure it to run as systemd service at startup, for whatever reason it refuses to read a csv file needed to configure the script. Again, this ONLY happens when run as a service. The service WILL work if I change the current directory in the script to the directory of the csv file (also where the script is located), but then on my next reboot it causes my samba network drive mount to break for some reason. I'm so confused and frustrated, please help.

CODE SECTION IN QUESTION:

... ### Manually set script directory #SCRIPT_DIR=/home/deck/Documents/scripts/SyncSaves SCRIPT_DIR=~/Documents/scripts/SyncSaves ## If I force the current directory to script directory, it works, but when I reboot my mount to the network drive 'xtra' is broken (which is needed for the script). ### -> cd $SCRIPT_DIR # Here is where we read the csv file echo "READING GAMES DATABASE FROM SCRIPT_DIR: " exec < $SCRIPT_DIR/sync_saves.csv read header while IFS="," read -r a b c d e f g h i j k l do # And then we process it, but none of this happens (when run as a systemd service) ... 

FULL CODE:

#!/bin/bash echo "################################################################" #echo "It's $(date +%A)" echo "Sytem is: $HOSTNAME" echo "User is: $USER" echo "Current directory is: $PWD" echo "" TESTING=false if $TESTING; then echo WARNING - TESTING MODE ON - FILES WILL NOT BE SYNCED... fi #echo "param1: $1" if [ -z "$1" ] then echo "No parameter1, defaulting to -backup" op='-backup' else op=$1 fi if [ $op == '-update' ] then echo "Operation is Update" else echo "Operation is Backup" fi if [ -z "$2" ] then ##echo "Parameter2 is empty" alt=false else ##echo "Parameter2 is $2" alt=$2 fi #SCRIPT_DIR=/home/deck/Documents/scripts/SyncSaves SCRIPT_DIR=~/Documents/scripts/SyncSaves IFS='=' while read -r var val do declare $var=$val #done < common.cfg done < <(tr -d '\r' <$SCRIPT_DIR/common.cfg) #echo "lin_user: $lin_user" echo "cloud_path: $cloud_path" if $alt; then echo "Using alt cloud path" lin_cloud_drive=$alt_lin_cloud_drive echo "lin_cloud_drive: $lin_cloud_drive" else echo "lin_cloud_drive: $lin_cloud_drive" fi echo "" echo "READING GAMES DATABASE FROM SCRIPT_DIR: " #echo "$SCRIPT_DIR" exec < $SCRIPT_DIR/sync_saves.csv #exec < /home/deck/Documents/scripts/SyncSaves/sync_saves.csv #exec < <(tr -d '\r' <$SCRIPT_DIR/sync_saves.csv) read header while IFS="," read -r a b c d e f g h i j k l do echo "game_name: $a" #echo "lin_drive: $d" #echo "win_path: $e" #echo "lin_path: $f" #echo "lin_pfx_user: $g" #echo "all_path: $h" #echo "save_folder: $i" #echo "game_user: $j" #echo "skip: $k" #echo "exclude_files: $l" #echo "" game_name=${a} skip=${k} exclude_files="${l//[$'\t\r\n']}" exclude_files="'$exclude_files'" full_path="${d}${f}${h}${i}" full_path="${full_path//[$'\t\r\n']}" full_path="${full_path}\\" #echo "full path: $full_path" full_path="${full_path/'{win_path}'/$e}" full_path="${full_path/'{lin_user}'/$USER}" full_path="${full_path/'{lin_pfx_user}'/$g}" full_path="${full_path/'{game_user}'/$j}" #echo "full path rep: $full_path" full_path=$(echo $full_path | sed -r 's|\{NA\}||g') full_path=$(echo $full_path | sed -r 's|\\\\|\\|g') full_path=$(echo $full_path | sed -r 's/\\/\//g') full_cloud_path="${lin_cloud_drive}${cloud_path}\\${a}\\" full_cloud_path=$(echo $full_cloud_path | sed -r 's|\\\\|\\|g') full_cloud_path=$(echo $full_cloud_path | sed -r 's/\\/\//g') #echo "full path : $full_path" #echo "full cloud: $full_cloud_path" backup_path1=${lin_cloud_drive}${cloud_path}\\backup1\\${a} backup_path1="${backup_path1//[$'\t\r\n']}" backup_path1="${backup_path1}\\" backup_path1=$(echo $backup_path1 | sed -r 's|\\\\|\\|g') backup_path1=$(echo $backup_path1 | sed -r 's/\\/\//g') backup_path2=${lin_cloud_drive}${cloud_path}\\backup2\\${a} backup_path2="${backup_path2//[$'\t\r\n']}" backup_path2="${backup_path2}\\" backup_path2=$(echo $backup_path2 | sed -r 's|\\\\|\\|g') backup_path2=$(echo $backup_path2 | sed -r 's/\\/\//g') backup_only=0 #echo "backup_path1: $backup_path1" #echo "backup_path2: $backup_path2" if test -d $full_path; then if [ $skip == 1 ]; then echo "SKIPPING: $a - $full_path" elif $TESTING; then echo "rsync --update -av --exclude $exclude_files $backup_path1 $backup_path2" echo "rsync --update -av --exclude $exclude_files $full_cloud_path $backup_path1" echo "rsync --update -av --exclude $exclude_files $full_path $full_cloud_path" echo "rsync --update -av --exclude $exclude_files $full_cloud_path $full_path" echo TESTING MODE ON - FILES NOT SYNCED... if [ "$op" == "-backup" ] then echo "OP IS BACKUP" elif [ "$op" == "-update" ] then echo "OP IS update" else echo "ERROR: Unknown Operation" fi else if [ "$op" == "-backup" ] then mkdir -p $full_cloud_path DIFFS="$(diff -qr $full_path $full_cloud_path)" echo "DIFFS: $DIFFS" #if $diffs >/dev/null; then if [ "$DIFFS" == "" ] then echo "No Backups Needed: $full_path"; else echo "backing up previous backups..." rsync --update -va --exclude $exclude_files $backup_path1 $backup_path2 echo "backing up previous saves..." rsync --update -va --exclude $exclude_files $full_cloud_path $backup_path1 echo "backing up current saves..." rsync --update -va --exclude $exclude_files $full_path $full_cloud_path fi elif [ "$op" == "-update" ] then if [ $backup_only == 1 ] then echo "..." echo "$game_name is set to backup ONLY" echo "..." else echo "updating current saves..." rsync --update -va --exclude $exclude_files $full_cloud_path $full_path fi else echo "ERROR: Unknown Operation" fi fi echo "" else echo "-$a not found, skipping: $full_path" echo "" fi done < <(tail -n +2 sync_saves.csv) echo "Writing to log at $SCRIPT_DIR/sync_saves.log..." echo "Last sync - $op - by $USER on $(date) - TESTING: $TESTING" >> $SCRIPT_DIR/sync_saves.log LOG_PATH="${lin_cloud_drive}${cloud_path}/sync_saves.log" LOG_PATH=$(echo $LOG_PATH | sed -r 's|\\\\|\\|g') LOG_PATH=$(echo $LOG_PATH | sed -r 's/\\/\//g') #SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) #$echo "Script is located in: $SCRIPT_DIR" echo "Writing to log at $LOG_PATH" echo "Last sync - $op - by $USER on $(date) - TESTING: $TESTING" >> $LOG_PATH if $TESTING; then echo TESTING MODE ON - FILES WERE NOT SYNCED... fi echo SAVES SYNCHRONIZED echo "################################################################" exit 

SERVICE (SHOULD BE FINE, BUT INCLUDING JUST IN CASE):

[Unit] Description=SyncSaves Startup Requires=home-deck-mnt-xtra.mount After=home-deck-mnt-xtra.mount [Service] Type=oneshot #ExecStart=/home/deck/Documents/scripts/svc_test/svc_test.sh ExecStart=/home/deck/Documents/scripts/SyncSaves/update_and_sync.sh [Install] WantedBy=default.target 

This is set up as a user service, not a system service. I'm not sure if it is possible or advisable to create a system service on SteamOS.

10
  • Try running the script with bash -x /home/deck/Documents/... and see if there are any differences between manual execution and systemd execution. Wait, is this a system service or a user one? A system service is run as root unless specified otherwise (and I don't see it specified otherwise), so ~/... = /root/.... Commented Aug 21, 2024 at 0:53
  • 1
    The execution environments differ. Look at the results of echo "=== id ===";id;echo "=== set ===";set;echo "=== env ===";env | sort;echo "=== alias ===";alias in each of your environments. Also, dont use ~, it's shorthand for "my home directory", and systemd isn't you. Commented Aug 21, 2024 at 3:20
  • @muru This is set up as a user service, not a system service. I'm not sure if it is possible or advisable to create a system service on SteamOS. Commented Aug 21, 2024 at 3:33
  • "it refuses to read a csv file needed to configure the script." - How did you get to this conclusion? I suppose you have a log somewhere? Can you post the log? If not, try and log the execution to a file, then see if the script outputs some relevant message. The script is quite long, we'd better start off somewhere. Commented Aug 21, 2024 at 3:36
  • @muru I ran the script with bash -x and it works fine. Commented Aug 21, 2024 at 3:36

1 Answer 1

1

I found the problem. The config (sync_saves.csv) file is referenced twice. The first time here: exec < $SCRIPT_DIR/sync_saves.csv Then again here: done < <(tail -n +2 sync_saves.csv) The second time, I didn't specify the path. This script and the csv file are in the same directory, so it works fine when running the script directly. When running as a service it needs to know the path so it fails, but for whatever reason doesn't provide any error message.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.