简体   繁体   中英

Bash script fails in crontab due to script/executable paths not being fully qualified

I've got a bash script that backs up a Minecraft server every night via cron, the script is as follows:

#!/usr/bin/env bash
#
# Usage:
#   backup_server.sh <name>
#
# Options:
#   -h, --help                 Show this screen.
#   --version                  Show version.

set -euo pipefail

#shellcheck disable=SC1091
source /opt/minecraft/bin/docopts.sh
source /opt/minecraft/scripts/mc_functions.sh

rcon() {
  local command=$1
  if [ "$server_name" != "proxy" ] && mc_server_online "$server_name" ; then
    /opt/minecraft/bin/mcrcon "$command"
  fi
}

main() {
  local version='1.0.0'
  usage=$(docopt_get_help_string "$0")
  eval "$(docopts -A ARGS -V "$version" -h "$usage" : "$@")"

  local server_name=${ARGS[<name>]}
  local source=$MC_SERVER_ROOT/$server_name
  local destination=$MC_BACKUP_ROOT/$server_name

  [ -d "$source" ] || { 
    printf "A server named '%s' does not exist.\n" "$server_name" >&2
    exit 1
  }

  mc_set_rcon_credentials "$server_name" || { 
    printf "Failed to set the rcon credentials for the server '%s'.\n" "$server_name" >&2
    exit 1
  }

  rcon "save-off"
  rcon "save-all"
  mkdir -p "$destination"
  tar -cpvzf "$destination/$(date +%F-%H-%M).tar.gz" "$source" >&2
  rcon "save-on"

  unset MCRCON_PASS
  unset MCRCON_PORT

  find "$MC_BACKUP_ROOT" -type f -mtime +7 -name "*.gz" -delete
}

main "$@"

Previously, I wasn't fully qualifying the paths to the scripts in the source command or to mcrcon as these were in my path and the script had no issue finding them when running the script from the terminal.

However, when running the script from cron, the script would fail because it couldn't find the executable or scripts. I'm assuming this is something to do with cron not being able to read or use $PATH ?

My crontab looks like this:

0 1 * * * bash /opt/minecraft/scripts/backup_server.sh proxy
# There's a few other commands here identical to this one except for the server name.

Could someone please explain why I need to fully qualify the path to scripts/executables when using cron or suggest a less tedious way of accomplishing this?

You may try running Bash as a login shell:

0 1 * * * bash -l /opt/minecraft/scripts/backup_server.sh proxy

That way you get a bit more complete environment when compared to what you're used to.

See the manual for explanation: https://www.man7.org/linux/man-pages/man1/bash.1.html#INVOCATION

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM