I have bash script which should exec, when specific device connected. When i launch it from terminal i have not got any problems, however, when i launch it as systemd service, i got broken pipe error.
мая 07 10:47:49 nixos systemd[1563]: Starting garmin.service...
мая 07 10:47:51 nixos bash[6951]: grep: ошибка записи: Broken pipe
мая 07 10:47:51 nixos systemd[1563]: garmin.service: Control process exited, code=exited, status=127/n/a
мая 07 10:47:51 nixos systemd[1563]: garmin.service: Failed with result 'exit-code'.
мая 07 10:47:51 nixos systemd[1563]: Failed to start garmin.service.
This is my systemd service:
[Unit]
After=run-media-serg-GARMIN.mount
Requires=run-media-serg-GARMIN.mount
[Service]
Environment="LOCALE_ARCHIVE=/nix/store/ckkhm153z75sw6z5nr277kvn2pi4z8jy-glibc-locales-2.35-224/lib/locale/locale-archive"
Environment="PATH=/nix/store/l6jgwxkc3jhr029vfzfwzcy28iyckwsj-coreutils-9.1/bin:/nix/store/gn1s1s5z19cf0wiir2cd38jckcjc6kn6-findutils-4.9.0/bin:/nix/store/pvb117r7fhwb08717ks21a6y9hlnp63b-gnugrep-3.7/bin:/nix/store/v0hg83sdv4v51c0prmdigry6wdmmpzmp-gnused-4.8/bin:/nix/store/34am2kh69ll6q03731imxf21jdbizda2-systemd-251.15/bin:/nix/store/l6jgwxkc3jhr029vfzfwzcy28iyckwsj-coreutils-9.1/sbin:/nix/store/gn1s1s5z19cf0wiir2cd38jckcjc6kn6-findutils-4.9.0/sbin:/nix/store/pvb117r7fhwb08717ks21a6y9hlnp63b-gnugrep-3.7/sbin:/nix/store/v0hg83sdv4v51c0prmdigry6wdmmpzmp-gnused-4.8/sbin:/nix/store/34am2kh69ll6q03731imxf21jdbizda2-systemd-251.15/sbin"
Environment="TZDIR=/nix/store/z0kg1c0f8fx6r4rgg5bdy01lb2b9izqg-tzdata-2023a/share/zoneinfo"
ExecStart=/nix/store/kga2r02rmyxl14sg96nxbdhifq3rb8lc-bash-5.1-p16/bin/bash -c /nix/store/jqfh2bnzag50wlghwnw52mq2nzr8bzz2-garmin-backup/bin/garmin-backup
Type=forking
This is my script:
In a short, it checks, that proper device was mounted, then sync some folders with rsync, and send notify and write log.
#!/usr/bin/env bash
backupDir="/home/serg/Backup/Garmin Edge 830/"
#I need to export this variables for notify-send
export DISPLAY=:0
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
on_error()
{
_MSG_=$1
echo "$_MSG_"
exit 1
}
check_mount()
{
_MOUNT_=$1
_MSG_=$2
if [ ! -d "$_MOUNT_" ]; then
echo "Path to $_MSG_ mount point is not exists"
exit 1
fi
}
writeLog()
{
_LOG_=$1
_SAVE_PATH_=$2
local outputPath="$_SAVE_PATH_/backup_history_${_LOG_}".log
if [ ! -e "$outputPath" ]; then
echo "Backup_log: " > "$outputPath"
fi
date >> "$outputPath"
}
garmin()
{
mpointGarmin="$(df -h | grep -i "Garmin" | awk '{print $NF}')"
check_mount "${mpointGarmin}" "Garmin"
inputDir="${mpointGarmin}/Garmin/"
copyArray=(
"Activities"
"Locations"
"Records"
"Settings"
"Sports"
"Totals"
"Weight"
)
#https://stackoverflow.com/questions/9952000/using-rsync-include-and-exclude-options-to-include-directory-and-file-by-pattern
#https://github.com/JonnyTischbein/rsync-server/blob/master/sync-folder.sh
#Glob should be used inside array (according shellcheck)
#See https://www.shellcheck.net/wiki/SC2125
for val in "${copyArray[@]}"
do
copyStr+=( --include="$val"/*** )
done
#LOG_NAME="_garmin"
rsync --dry-run --no-perms --checksum --progress -v -r "${copyStr[@]}" \
--exclude=* "${inputDir}" "${backupDir}"
RET_CODE=$?
if test $RET_CODE -eq 0; then
#writeLog "$LOG_NAME" "${backupDir}"
notify-send "Garmin 830 Backup is Done"
fi
}
garmin
I have found a line which causes this problem. It's
mpointGarmin="$(df -h | grep -i "Garmin" | awk '{print $NF}')"
When i remove this pipes and subshell and hardcode mount point it works.
As i understand, systemd does not like subshell calling with pipes? Or i am wrong? How can i fix it?