这是我写的一个bash脚本,它以crontab中指定的间隔自动修剪一个minecraft服务器的所有世界。它将在每个世界上逐个执行“/ wb $ WORLD trim”命令和“/ wb trim confirm”命令,其中$ WORLD是它当前正在处理的世界。通过将每个世界从文件列表加载到for循环中,它将按顺序修剪每个世界。现在,由于世界修剪可能需要不同的时间,我不确定如何告诉它如果尚未完成则不会停止,因为每个世界只分配30秒。我认为读取日志文件以获取命令的状态可能有效,但我不确定如何去做。我认为像“grep”和“awk”这样的东西可能会起作用,但我不确定这是否会起作用,因为这似乎是一个非常复杂的障碍。有任何想法吗?我有一个日志文件的一部分,它在修复在pastebin上发布here的世界时打印。另外,除了我可以做些什么来改进这个脚本?我只编写了几个月的代码,而不是经常那样,所以我是编程/脚本编程的新手。
#!/bin/bash
# Title: World Border Trim Automator
# Author: Jonathan Bondhus
######### CONFIG STARTS HERE #########
# Location of the init script
INIT_SCRIPT="/etc/init.d/minecraft"
# Name to use for the screen instance
SCREEN="minecraft"
# User that should run the server
USERNAME="minecraft"
# Path to minecraft server directory
MCPATH="/home/${USERNAME}/minecraft"
# Where the worlds are located on the disk
WORLDSTORAGE="${MCPATH}/worlds"
######### CONFIG ENDS HERE #########
## Start of script, don't edit anything below this line unless you know what you are doing
as_user() {
if [ $ME == $USERNAME ] ; then
bash -c "$1"
else
su $USERNAME -s /bin/bash -c "$1"
fi
}
my_trim() {
a=1
for NAME in $(ls $WORLDSTORAGE)
do
if [ -d $WORLDSTORAGE/$NAME ]
then
WORLDNAME[$a]=$NAME
a=$a+1
# Run the /wb trim command
echo "Running /wb $NAME trim..."
as_user "screen -p 0 -S $SCREEN -X eval 'stuff \"wb $NAME trim\"\015'"
sleep 2 # Wait 2 seconds
clear
echo "Running /wb trim confirm..."
as_user "screen -p 0 -S $SCREEN -X eval 'stuff \"wb trim confirm\"\015'"
sleep 1
clear
echo "Waiting 30 seconds for trim to complete..."
sleep 30 # Wait 30 seconds
fi
done
}
my_is_running(){
# Checks for the minecraft servers screen session
# returns true if it exists.
if ps ax | grep -v grep | grep "$SCREEN $INVOCATION" > /dev/null
then
return 0
fi
return 1
}
my_main(){
ME=`whoami` # Sets $ME to equal the current user's username
my_is_running
if my_is_running
then
my_trim
else
echo "Server is not running... Starting..."
my_as_user "$INIT_SCRIPT start"
wait 100
fi
}
my_as_user() {
if [ $me == $username ] ; then
bash -c "$1"
else
su $USERNAME -s /bin/bash -c "$1"
fi
}
my_main
exit 0
答案 0 :(得分:0)
你有什么理由在'屏幕'里面运行'东西'吗?
如果删除它,'stuff'将同步执行,并在命令完成后返回。
my_trim() {
a=1
for NAME in $(ls $WORLDSTORAGE)
do
if [ -d $WORLDSTORAGE/$NAME ]
then
WORLDNAME[$a]=$NAME
a=$a+1
# Run the /wb trim command
echo "Running /wb $NAME trim..."
as_user "stuff \"wb $NAME trim\"\015" # will block here until stuff returns
#sleep 2 # no reason this any more
clear
echo "Running /wb trim confirm..."
as_user "stuff \"wb trim confirm\"\015"
#sleep 1
clear
echo "Done"
#sleep 30
fi
done
}
答案 1 :(得分:0)
在下文中,假设变量MCLOGFILE
设置为日志文件名。
my_trim() {
cd $WORLDSTORAGE
for NAME in *
do
if [ -d $NAME ]
then
# Run the /wb trim command
echo "Running /wb $NAME trim..."
as_user "screen -p 0 -S $SCREEN -X eval 'stuff \"wb $NAME trim\"\015'"
sleep 2 # Wait 2 seconds
clear
echo "Running /wb trim confirm..."
kill `((tail -f $MCLOGFILE -n0& echo $! >&3
as_user "screen -p 0 -S $SCREEN -X eval 'stuff \"wb trim confirm\"\015'"
sleep 1
clear >&2
echo "Waiting for trim to complete..." >&2
)|grep -q 'task successfully completed!'
) 3>&1|head -1
`
fi
done
}
有kill
内容,因为否则tail
将继续在后台运行,直到task successfully completed!
之后的一行写入日志文件。