我有一个 bash 脚本,它检查交换是否存在,如果不存在,则创建一个;
if free | awk '/^Swap:/ {exit !$2}'; then
echo "Have swap, skipping"
sudo swapoff -a
sudo dd if=/dev/zero of=/swapfile bs=1M count=2048
sudo mkswap /swapfile
sudo swapon /swapfile
else
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
sudo echo -e "/swapfile none swap sw 0 0 \n" >> /etc/fstab
fi
现在我还想添加一个检查来找出交换大小 - 如果它已经存在 - 因为如果交换已经存在并且它是 4GB 那么我会将其降级到 2GB 而不是跳过。
我怎样才能做到这一点?
编辑:该脚本当前创建一个 2GB 的交换文件,无论它是否存在,所以如果我有 4GB 交换文件,它会将其更改为 2GB,但如果我也有 2GB 交换文件,它仍然会用 2GB 重新进行交换。我认为这不是一个好的选择,所以这就是为什么我想知道是否应该添加交换大小检查?
答案1
假设您的内核不是很旧并且支持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
by 列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