bashserverminecraftdebian-based

Bash - PaperMC install script


I was trying to make a script which automates the process of setting up a Minecraft Java Edition server ( PaperMC platform )

The script should be able to retrieve the latest server version through the PaperMC's JSON API. Also, the installation process of the server should be simple and automatic , with minimal to no manual intervention of the user.

I also want to optimize the server, so that it doesn't consume too much resources.

Below is the attempt I made into making this script :

#!/bin/bash

# Script nane : paper-install.sh

latestVer="$(curl -s 'https://papermc.io/api/v1/paper' | jq -r '.versions[0]')"

if [ ! -e paper-*.jar ]; then
    echo "Downloading PaperMC version $latestVer ..."
    rm -rf paper-*.jar && curl -OLJ https://papermc.io/api/v1/paper/"$latestVer"/latest/download
    timeout 3s echo a
    else
    echo Downloaded
fi


start_script () {

cat <<'EOF' > run_paper
#!/bin/bash

# Find paper-*.jar file
jarfile=$(find . -name paper-*.jar)

# Server run arguments
java -jar $jarfile -Xmx1G -Xms1G -d64 -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseNUMA -XX:+CMSParallelRemarkEnabled -XX:MaxTenuringThreshold=15 -XX:MaxGCPauseMillis=30 -XX:GCPauseIntervalMillis=150 -XX:+UseAdaptiveGCBoundary -XX:-UseGCOverheadLimit -XX:+UseBiasedLocking -XX:SurvivorRatio=8 -XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=15 -Dfml.ignorePatchDiscrepancies=true -Dfml.ignoreInvalidMinecraftCertificates=true -XX:+UseFastAccessorMethods -XX:+UseCompressedOops -XX:+OptimizeStringConcat -XX:+AggressiveOpts -XX:ReservedCodeCacheSize=2048m -XX:+UseCodeCacheFlushing -XX:SoftRefLRUPolicyMSPerMB=2000 -XX:ParallelGCThreads=10 nogui
EOF

# Make the script executable
chmod +x run_paper

}

# Generate script
if [ ! -e run_paper ]; then
    echo "Generating run script ..."
    start_script
    else
    echo .
fi

# Run script
bash run_paper 

# after jar generated eula.txt , run this command
# sed -i 's/false/true/i' eula.txt

When I'm running this script, I encounter multiple errors that I don't know how to debug/describe, which indeed sucks.

I want to know what I did wrong...

ShellCheck website helped me, but on this block of code - not so much...


Solution

  • Attempt at fixing your script

    Advice to use the shellcheck linter still stands.

    #!/usr/bin/env bash
    
    # Script nane : paper-install
    
    API_URL='https://papermc.io/api/v1'
    IFS=$(printf '\n\r\t ')
    
    latestVer=$(curl -s "$API_URL/paper" | jq -r '.versions[0]')
    location="$API_URL/paper/$latestVer/latest/download"
    latestJar=$(
      curl \
        --silent \
        --head \
        --location "$location" |
        awk -F= '/content-disposition: attachment; filename=/{print$2}'
    )
    latestJar=${latestJar%%[$IFS]}
    
    if [ ! -e "$latestJar" ]; then
      
      printf 'Downloading PaperMC version %s from %s as %s ...\n' \
        "$latestVer" "$location" "$latestJar"
      curl \
        --output "$latestJar" \
        --location "$location"
      ln -sf "$latestJar" paper.jar
      timeout 3s echo a
    else
      echo Downloaded
    fi
    
    get_java8() {
      update-alternatives --query java | awk '/Alternative:/{print$2}' |
        while read -r jvm; do
          if "$jvm" -version 2>&1 | grep -q 'version "1.8.*"'; then
            echo "$jvm"
            break
          fi
        done
      # Found no java 8
    }
    
    generate_start_script() {
      cat <<EOF >run_paper
    #!/usr/bin/env bash
    
    # The paper jar
    jarfile=paper.jar
    
    # The java command path
    #java_cmd=\$(command -v java)
    java_cmd=$(env printf %q "$1")
    
    # Long list of unknown wizard's black magic JVM arguments.
    # I have no idea if these help, are really needed,
    # or how many will break with newer java versions
    java_args=(
      -Xmx1G -Xms1G -d64 -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC
      -XX:+UseParNewGC -XX:+UseNUMA -XX:+CMSParallelRemarkEnabled
      -XX:MaxTenuringThreshold=15 -XX:MaxGCPauseMillis=30
      -XX:GCPauseIntervalMillis=150 -XX:+UseAdaptiveGCBoundary
      -XX:-UseGCOverheadLimit -XX:+UseBiasedLocking -XX:SurvivorRatio=8
      -XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=15
      -Dfml.ignorePatchDiscrepancies=true
      -Dfml.ignoreInvalidMinecraftCertificates=true -XX:+UseFastAccessorMethods
      -XX:+UseCompressedOops -XX:+OptimizeStringConcat -XX:+AggressiveOpts
      -XX:ReservedCodeCacheSize=2048m -XX:+UseCodeCacheFlushing
      -XX:SoftRefLRUPolicyMSPerMB=2000 -XX:ParallelGCThreads=10
    )
    
    # Server run arguments
    "\$java_cmd" "\${java_args[@]}" -jar "\$jarfile" nogui
    EOF
    
      # Make the script executable
      chmod +x run_paper
    
      if [ ! -e eula.txt ]; then
        # Run the server to generate eula.txt
        echo 'Running server installation'
        ./run_paper
      fi
    }
    
    # Generate script
    if [ ! -e run_paper ]; then
      # Get java8 path or fail
      java8_path=$(get_java8)
      if [ -n "$java8_path" ]; then
        echo "Generating run script ..."
        generate_start_script "$java8_path"
      else
        echo 'No java8 found on this system!' >&2
      fi
    else
      echo .
    fi