(standard_in 1:语法错误)如果脚本 运行 在 cronjob 中

(standard_in 1: syntax error) if script run in a cronjob

我有这个脚本可以通过 API(Hetzner 提供商)自动调整卷的大小。 如果我 运行 手动执行此脚本 (bash /opt/tools/volume_size.sh),此脚本运行良好,而在 cronjob 中:

*/20 * * * * /usr/bin/bash /opt/tools/volume_size.sh

它输出这个错误:

(standard_in) 1: syntax error

如您所见,该错误不是很有用,因为没有指定行。根据 shelcheck,该脚本也非常有效。

这是完整的脚本:

#!/bin/bash

# Check available space
AVAILABLE=$(/usr/bin/df -h | /usr/bin/grep encrypted | /usr/bin/awk '{print }' | /usr/bin/sed 's/G//g')

# If available space on volume is less than 100Gb
if (( $(/usr/bin/echo "$AVAILABLE < 100" | /usr/bin/bc -l) )); then

  # Check the volume size with Hetzner API
  VOLSIZE=$(/usr/bin/curl -s \
                -H "Authorization: Bearer $HETZNER_TOKEN" \
                'https://api.hetzner.cloud/v1/volumes/123456' | \
                /usr/bin/grep size | /usr/bin/awk '{print }' | /usr/bin/sed 's/,//g')

  # New volume size will be actual size + 50Gb
  NEWSIZE=$(( "$VOLSIZE" + 50 ))

  # Resize the Hetzner volume trough the API
  /usr/bin/curl -s \
        -X POST \
        -H "Authorization: Bearer $HETZNER_TOKEN" \
        -H "Content-Type: application/json" \
        -d "{\"size\":\"$NEWSIZE\"}" \
        'https://api.hetzner.cloud/v1/volumes/14746432/actions/resize'

  /usr/bin/sleep 5

  # Check the volume size with Hetzner API after resizing
  NEWVOLSIZE=$(/usr/bin/curl -s \
                -H "Authorization: Bearer $HETZNER_TOKEN" \
                'https://api.hetzner.cloud/v1/volumes/123456' | \
                /usr/bin/grep size | /usr/bin/awk '{print }' | /usr/bin/sed 's/,//g')

  # If volume size after resizing is greater than before resizing
  # Resizing was successful, proceed
  if (( $(/usr/bin/echo "$NEWVOLSIZE > $VOLSIZE" | /usr/bin/bc -l) )); then

    # Resize the local ZFS pool
    /usr/sbin/zpool online -e datapool sdb

    # Check the pool size after resizing
    NEWAVAILABLE=$(df -h | /usr/bin/grep encrypted | /usr/bin/awk '{print }' | /usr/bin/sed 's/G//g')

    # If pool available space is greater than 100Gb
    # Resizing was successful
    if (( $(/usr/bin/echo "$NEWAVAILABLE > 100" | /usr/bin/bc -l) )); then
      /usr/bin/echo "ZFS Volume has been automatically resized from $VOLSIZE GB to $NEWSIZE GB. Current available space is $NEWAVAILABLE GB." | \
      /usr/bin/mail -s "[INFO] ZFS Volume has been auto-resized!" root
      exit 0
    else
      # Resizing failed...
      /usr/bin/echo "Please manually check your ZFS Volume as the available space is actually $NEWAVAILABLE GB." | \
      /usr/bin/mail -s "[WARNING] ZFS Volume can't be auto-resized!" root
      exit 1
    fi

  fi

fi

exit 0

如果我 运行 脚本不需要调整大小(+100Gb 可用),它输出:

# bash -x volume_size.sh
++ /usr/bin/df -h
++ /usr/bin/sed s/G//g
++ /usr/bin/awk '{print }'
++ /usr/bin/grep encrypted
+ AVAILABLE=140
++ /usr/bin/echo '140 < 100'
++ /usr/bin/bc -l
+ ((  0  ))
+ exit 0

请注意,只有在需要调整大小时才会输出错误(因此,在第一个 if 条件之后,第 7 行)。

这是我的 100% 工作版本。在全球范围内,我现在检查的是兆字节而不是千兆字节,并避免使用 bc.

#!/bin/bash

# Check available space
AVAILABLE=$(df -B M /datapool | tail -1 | awk '{print }' | sed 's/M//g')

# If available space on volume is less than 100Gb
if (( "$AVAILABLE" < 100000 )); then

  TOKEN="xxxxxxxxxxxxxx"

  # Check the volume size with Hetzner API
  VOLSIZE=$(curl -s \
                 -H "Authorization: Bearer $TOKEN" \
                 'https://api.hetzner.cloud/v1/volumes/1474' | \
                 grep size | awk '{print }' | sed 's/,//g')

  # New volume size will be actual size + 50Gb
  NEWSIZE=$(( "$VOLSIZE" + 50 ))

  # Resize the Hetzner volume trough the API
  curl -s \
       -X POST \
       -H "Authorization: Bearer $TOKEN" \
       -H "Content-Type: application/json" \
       -d "{\"size\":\"$NEWSIZE\"}" \
       'https://api.hetzner.cloud/v1/volumes/1474/actions/resize'

  RESIZED=$(curl -s \
                 -H "Authorization: Bearer $TOKEN" \
                 'https://api.hetzner.cloud/v1/volumes/1474' | \
                 grep size | awk '{print }' | sed 's/,//g')

  if (( "$RESIZED" > "$VOLSIZE" )); then

    # Resize the local ZFS pool
    /usr/sbin/zpool online -e datapool sdb

    # Check the pool size after resizing
    NEWAVAILABLE=$(df -B M /datapool | tail -1 | awk '{print }' | sed 's/M//g')

    # If pool available space is greater than 100Gb
    # Resizing was successful
    if (( "$NEWAVAILABLE" > "$AVAILABLE" )); then
      echo "NFS Volume has been automatically resized from $VOLSIZE GB to $NEWSIZE GB. Current available space is $NEWAVAILABLE GB." | \
      mail -s "[INFO] NFS Volume has been auto-resized!" root
      exit 0
    else
      # Resizing failed...
      echo "Please manually check your NFS Volume as the available space is actually $NEWAVAILABLE GB." | \
      mail -s "[WARNING] NFS Volume needs manual intervention!" root
      exit 1
    fi

  fi

fi

exit 0