2012-06-17 111 views
0

這是我寫的一個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

請參閱[進程管理](http://mywiki.wooledge.org/ProcessManagement),並且不要在$(ls)中爲var進行操作 - 您只需要一個glob。使用'((a ++))'增加變量。你這樣做,'a'是一個不斷增長的'1 + 1 + 1 + 1 ... + 1'串(它在數組的下標中得到數學計算)。 –

+0

你不需要'bash -c「$ 1」' - 你可以直接使用'$ 1'(單獨一行)。 –

+0

Pastebin鏈接已損壞;示例日誌可以在[我的世界服務器的邊界修剪腳本]找到(http://stackoverflow.com/questions/11922982/world-border-trim-script-for-minecraft-server)。 – Armali

回答

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 
} 
+0

'stuff'是一個_screen_命令;因此,它不能在_screen_之外運行。 – Armali

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!的一個被寫入日誌文件之後。

相關問題