我正在编写一个小脚本,将文件上传到远程 ssh 服务器,并且在远程 ssh 服务器上我几乎有2 TB
可用的空间。
我需要在 shell 脚本中检查空间是否已满1.5 TB
,sleep the script
然后**start the script again**
一旦空间恢复,它就会回到1TB
这是我的代码部分,需要运行检查目录大小的逻辑,然后将其放入if else statements
SIZE="$(ssh archiveupload@REMOTESERVER-IP "du -s")"
LIMIT="1.5TB"
if [ $SIZE -gt $LIMIT ];
then
sleep 4h
elif
continue ;
fi
更新脚本:
if [ ! -f /home/user/Tupload/upload-lock ]; then
touch /home/user/Tupload/upload-lock
###Define the File in unix style#############
filename="/home/user/Tupload/20186.txt"
####starting of the while loop.###########
LIMIT='1500000000'
while read line;
do
name="${line%$'\r'}"
SIZE="$(ssh -n USER@REMOTEIP"df /var/www/Upload/" | awk 'NR > 1 {print $4; exit}')"
if [[ $SIZE -gt $LIMIT ]]
then
YEAR=$(echo $name | cut -c 1-4) #####define the Year from the read line ####
MONTH=$(echo $name | cut -c 5-6) #####Define the Month from the read line####
DAY=$(echo $name | cut -c 7-8) #####Define the DAY from the read line####
YM=${YEAR}-${MONTH} ####define the Year and Month######
april="2017-04"
may="2017-05"
june="2017-06"
march="2017-03"
######if else statement ######
if [ "$april" = "$YM" ]; then
cd /mnt/smxfxml/$YEAR/April/
elif [ "$may" = "$YM" ]; then
cd /mnt/smxfxml/$YEAR/May/
elif [ "$june" = "$YM" ]; then
cd /mnt/smxfxml/$YEAR/June/
elif [ "$march" = "$YM" ]; then
cd /mnt/smxfxml/$YEAR/March/
else
cd /mnt/smxfxml/$YEAR/$YM/
fi
ssh USER@REMOTEIP"mkdir $YEAR/$MONTH/$DAY/$name/" < /dev/null
scp $name.mxf USER@REMOTEIP:$YEAR/$MONTH/$DAY/$name/
cd /mnt/smxfxml/XML/$YEAR/$YM/
scp $name.xml USER@REMOTEIP:$YEAR/$MONTH/$DAY/$name/
else
echo 'Not enough space.'; sleep 4h
fi
done <"$filename"
rm -rf /home/user/Tupload/upload-lock
exit 0
else
sleep 0
fi
exit 0
答案1
谢谢pa4080对于“自由空间”一行。
现在您已共享了脚本:
这会稍微困难一些,因为我们不能在不跳过行的情况下在循环continue
内使用while read line
。
您希望在可用空间不超过 0.5 TB 时暂停脚本,并在可用空间至少为 1 TB 时恢复脚本。
为了使脚本简短且易于阅读,定义一个函数来告诉您服务器上是否有足够的空间并以最小大小作为参数:
enough_space () {
local limit=$1
free_space="$(ssh -n user@host "df /" | awk 'NR > 1 {print $4; exit}')"
[ $free_space -ge $limit ]
}
...或者睡觉虽然不是足够的空间:
while ! enough_space $limit; do
sleep 4h
done
...或者睡觉直到足够的空间:
until enough_space $limit; do
sleep 4h
done
将其纳入你的脚本中
将其放在脚本的开头:
pause_limit='500000000' # 0.5TB free space
resume_limit='1000000000' # 1.0TB free space
enough_space () {
local limit=$1
free_space="$(ssh -n user@host "df /" | awk 'NR > 1 {print $4; exit}')"
[ $free_space -ge $limit ]
}
while
我们将在现有循环内引入一个“无限”循环while
。这使我们能够在第一次没有足够的可用空间时再次重试同一个文件。此外,分配变量不依赖于服务器的可用空间,因此应将其保留在语句if
(和内部while
循环)之外。
####starting of the while loop.###########
while read line; do
#### this can all be done before checking the server's free space
# name="${line%$'\r'}"
# YEAR=$(echo $name | cut -c 1-4)
# .
# .
######if else statements ######
# if [ "$april" = "$YM" ]; then
# .
# .
# fi
while true; do
if enough_space $pause_limit;
then
ssh USER@REMOTEIP"mkdir $YEAR/$MONTH/$DAY/$name/" < /dev/null
scp $name.mxf USER@REMOTEIP:$YEAR/$MONTH/$DAY/$name/
cd /mnt/smxfxml/XML/$YEAR/$YM/
scp $name.xml USER@REMOTEIP:$YEAR/$MONTH/$DAY/$name/
break
else
until enough_space $resume_limit; do
sleep 4h
done
fi
done
done <"$filename"
“无限” while 循环将运行一次(如果服务器上有足够的可用空间)或两次(如果再次有足够的可用空间)。
补充笔记
如果您想无限期地反复运行复制例程,请使用无限 while 循环 ( while true; do...
)。不要进行递归调用(在脚本中调用脚本或在函数中调用函数),因为这会增加调用堆栈的大小,并且您的脚本迟早会崩溃。
当然,这只是实现相同目的的众多方法之一。这种方法的一个缺点是,每当可用空间低于 0.5TB 或超过 1.0TB 时,就会有一次不必要的调用enough_space
。
如果我误解了您的问题,请告诉我,以便我可以调整我的答案。
答案2
首先,我建议您使用命令df
获取可用空间。此外,您还应提供系统路径(例如/
)或设备名称(例如/dev/sda1
),以使事情变得简单。在我的 VPS 上执行的命令的输出df /
如下所示:
$ ssh -n user@host "df /"
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/vda1 25671932 8335064 16009768 35% /
我们只需要可用的空间,这样我们就可以通过以下方式过滤输出awk
(例如):
$ ssh -n user@host "df /" | awk 'NR > 1 {print $4; exit}'
16009768
其次使用与上述命令输出相同的单位(1K块)作为变量的值$LIMIT
:1.5 TB = 1500000000 KB。
第三,将主要逻辑放入一个函数中,该函数将在命令之后一次又一次地递归调用自身sleep
。此外,我认为sleep
和的位置continue
应该颠倒过来:)
根据上述内容,脚本可能是这样的:
#!/bin/bash -e
LIMIT='1500000000'
# define the function
main() {
SIZE="$(ssh -n user@host "df /" | awk 'NR > 1 {print $4; exit}')"
if [[ $SIZE -gt $LIMIT ]]
then
echo 'continue'
else
echo 'Not enough space.'; sleep 4h
# call the function
main
fi
}
# initial call of the function
main
根据@丹泽尔的评论我们可以使用无限循环来代替递归while
:
#!/bin/bash -e
LIMIT='1500000000'
while true
do
SIZE="$(ssh -n user@host "df /" | awk 'NR > 1 {print $4; exit}')"
if [[ $SIZE -gt $LIMIT ]]
then
# remove the exit command if you do not want to interupt the loop
echo 'continue'; exit
else
echo 'Not enough space.'; sleep 4h
fi
done