Предполагая, что ваше ядро не очень старое и поддерживает fallocate
системный вызов (, доступный начиная с версии 2.6.23, см.man fallocate(1)
и man fallocate(2)
), fallocate
скорее всего будет быстрым, так как не записывает блоки данных. Следовательно, нет большой проблемы с постоянным созданием нового файла подкачки. Единственный шаг, который вы, вероятно, захотите выполнить условно, — это отредактировать файл fstab
.
Предположим, что у вас либо вообще нет подкачки, либо есть ровно один файл подкачки, путь которого/swapfile
:
swapfile="/swapfile"
# Make sure swap is on
swapon --all
# Check if our assumptions hold
if [ "$(swapon --show --noheadings | wc -l)" -gt 1 ] ||
( [ "$(swapon --show --noheadings | wc -l)" -eq 1 ] &&
( [ "$(swapon --show=TYPE --noheadings)" != 'file' ] ||
[ "$(swapon --show=NAME --noheadings)" != "$swapfile" ]
)
); then
echo "Unsafe to proceed, exiting."
exit
fi
# Edit /etc/fstab if our file is not already there
if ! grep -q '^[[:blank:]]*'"$swapfile"'[[:blank:]]\{1,\}none[[:blank:]]\{1,\}swap[[:blank:]]\{1,\}' /etc/fstab;
then
printf '%s\n' "$swapfile none swap sw 0 0" >> /etc/fstab
fi
# Create/replace the swap file
swapoff --all
[ -f "$swapfile" ] && rm -- "$swapfile"
fallocate -l 2GiB -- "$swapfile"
chmod 600 "$swapfile"
mkswap -- "$swapfile"
swapon --all
Вы все же можете избежать ненужного выключения и повторного включения свопа. :Это может быть медленной операцией, если используется значительная ее часть, и это может иметь нежелательные последствия, если доступно недостаточно памяти.
Чтобы частично решить эти проблемы (, а также ответить на ваш первоначальный вопрос ), последнюю часть приведенного выше кода можно заключить в условный блок:
# Check if we want to shrink the swap file i.e. it is bigger than 2 GiB
# (or if we have no swap file)
if [ "$(free | awk '/^Swap:/ { print $2 }')" = "0" ] ||
[ "$(free --bytes | awk '/^Swap:/ { print $2 }')" -gt 2147483648 ]; then
# Create/replace the swap file
# Same as above...
fi
Наконец, предположив, что версия вашего ядра не ниже 3.14 и предоставляет MemAvailable
в /proc/meminfo
(, значение которого сообщается как столбец available
в free
, см. man free(1)
), вы также можете проверить, достаточно ли у вас доступной памяти, прежде чем пытаться отключить подкачку.
Последний фрагмент кода становится:
# Do we have no swap or more swap than 2GB?
# If yes, do we have more available memory than used swap?
if ( [ "$(free | awk '/^Swap:/ { print $2 }')" = "0" ] ||
[ "$(free --bytes | awk '/^Swap:/ { print $2 }')" -gt 2147483648 ]
) &&
[ "$(awk '/MemAvailable:/ { print $2 }' /proc/meminfo)" -gt "$(free | awk '/Swap:/ { print $3 }')" ];
then
# Create/replace the swap file
# Same as above...
fi
Вот как можно использовать бесконечный цикл while для постоянной проверки.
#!/bin/bash
myip="XXX.XXX.XXX.XXX"
while; do
checkip="$(dig +short myip.opendns.com @resolver1.opendns.com)"
if [ "$checkip" = "$myip" ]; then
/etc/init.d/openvpn.server start
/etc/init.d/openvpn.client stop
else
/etc/init.d/openvpn server stop
/etc/init.d/openvpn.client start
fi
sleep 10
done
sleep 10
в конце цикла вызовет 10-секундную паузу перед повторным запуском цикла.
Я не уверен, что это лучший способ справиться с тем, чего вы пытаетесь достичь, поэтому вы можете рассмотреть другие возможности.