Bash — параметры по умолчанию при подстановке строк, возвращающие неверную подстановку

#bash

#bash

Вопрос:

У меня есть следующий сценарий:

 #!/bin/bash

# usage: [path_to_script]/minecraft.bash [functions_to_run]
# example: /srv/minecraft/minecraft.bash stop "backup 10"

# -------------------------------- settings --------------------------------

# paths
BACKUP_DIRECTORY="backup"
SERVER_NAME="paper-296.jar" # the filename of your server jar
WORLD_NAME="matigcraft" # level-name in server.properties

# messages
BACKUP_KICK_MESSAGE="The server is making a backup, and will be back online in a few minutes"
BACKUP_WARNING_MESSAGE="The server will go offline to make a backup in X minute(s)"
STOP_KICK_MESSAGE="The server is shutting down for maintenance"
STOP_WARNING_MESSAGE="The server will go offline for maintenance in X minute(s)"

# amount of backups to keep when cleaning
BACKUP_AMOUNT=28

# JVM arguments to use when starting the server
JVM_ARGUMENTS="-Xms6G -Xmx6G -XX: UseG1GC -XX: ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX: UnlockExperimentalVMOptions -XX: DisableExplicitGC -XX: AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX: PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true"

# -------------------------------- functions --------------------------------

# check if the server is running
function status {
  screen -ls | grep -q -w "$WORLD_NAME" 
  amp;amp; echo $WORLD_NAME is running amp;amp; return 0 
  || echo $WORLD_NAME is not running amp;amp; return 1
}

# if running, stop the server and wait
# call with number to set as warning delay
# call with additional text to use as warning message, defaults to STOP_WARNING_MESSAGE
# call with additional text to use as kick message, defaults to STOP_KICK_MESSAGE
function stop {
  status > /dev/null amp;amp; {
    [ -z "$1" ] || {
      screen -S "$WORLD_NAME" -X stuff "say ${{2:-$STOP_WARNING_MESSAGE}//X/$1}n"
      sleep $(($1 * 60))
    }
    screen -S "$WORLD_NAME" -X stuff "kick @a ${3:-$STOP_KICK_MESSAGE}n""stopn"
    while status > /dev/null; do sleep 1; done
  }
}

# make a backup of the world
# call with number to set as warning delay
# call with additional text to use as warning message, defaults to BACKUP_WARNING_MESSAGE
# call with additional text to use as kick message, defaults to BACKUP_KICK_MESSAGE
function backup {
  stop "$1" "${2:-$BACKUP_WARNING_MESSAGE}" "${3:-$BACKUP_KICK_MESSAGE}"
  mkdir -p "$BACKUP_DIRECTORY"
  zip -9 -r "$BACKUP_DIRECTORY"/"$WORLD_NAME"_"$(date  %Y_%m_%d_%H%M)".zip "$WORLD_NAME"
}
 

это дает мне ошибку «неправильной подстановки» "say ${{2:-$STOP_WARNING_MESSAGE}//X/$1}n" в stop функции при вызове backup 10 . ShellCheck считает, что мой синтаксис в порядке, и я уверен, что запускаю скрипт в Bash. Когда я делаю T="${2:-$STOP_WARNING_MESSAGE}" и ${T//X/$1}n" , все работает так, как должно.

Я думаю, что это решение работало раньше без проблем, но я могу ошибаться. Что-то не так с моим синтаксисом? Или, возможно, есть проблема с Bash после обновления?

Комментарии:

1. Если кто-то заинтересован в использовании скрипта, вы можете найти полную версию здесь: github.com/JPaalman/Minecraft-Server

Ответ №1:

{2:-$STOP_WARNING_MESSAGE} это присваивание, предоставляющее значение по умолчанию. Это не переменная. Для расширения параметров Bash требуется форма, например

 ${var//substring/replacement}
 

Поскольку ваше выражение, заключенное в фигурные скобки, не является a var , это неверная подстановка. Вы можете использовать временную переменную:

 myvar=${2:-$STOP_WARNING_MESSAGE}
 

и затем

 ${myvar//X/$1}
 

Комментарии:

1. Думаю, я ошибался в том, что это работало до этого. Есть ли какой-либо способ сделать это без временной переменной?

2. Нет. В некоторых случаях ${...} разрешаются до числа, например, длины, которые позволяют им быть вложенными, но когда var требуется a — требуется временное.