Joshua a.k.a sigonasr2’s Blog

Linux Tips

This page will include many Linux tips that I find are just little tidbits of information that you could find useful sometimes.

Bash

Index
-Chmod
-cd
-Multibzfs
-at
-$RANDOM
-Sample Map Script
-$RANDOM simple
-if loop fix
-crontab
-Running Background Tasks

Chmod
Scripts in Linux are created in .sh files, which Linux interprets as a script, but before you can run it, you have to made it executable, in which you do

chmod a+x script.sh

Replacing script with the title of the script/file in the directory.

Cd
Then you can run it. Bash scripts aren’t too hard at all, they basically require you to type in commands based off of the terminal itself.

So you can put in the script

cd /home/sigonasr2/BZFlag

and when you run the script it’ll automatically do it.

Multibzfs
So I do

cd /home/sigonasr2/bzflag

screen -d -m ./keepalive2.sh > /home/sigonasr2/public_html/logs/party_nite12.txt

screen -d -m ./keepalive.sh > /home/sigonasr2/public_html/logs/twilight_backup12.txt

screen -d -m /usr/local/bin/bzfs -conf /home/sigonasr2/bzflag/soccer.conf > /home/sigonasr2/public_html/logs/soccer7.txt

But now I also do something else. Every night when the server’s time is midnight, I let all the servers restart with the ‘at’ command. This allows the map that is currently on to be refreshed, and will help in the near future. (I’m working on a map rotation plugin that may be able to automatically change the map every hour, and also it’ll help when auto-updating the map in the near future.

at
To run this every midnight, I do

at -f “multibzfs.sh” 00:00

This is in a separate file called runscript.sh and runs multibzfs.sh at midnight, hence the 00:00. Also in multibzfs.sh, I add that same line in so that it’ll schedule to do it again the next day, thus only running runscript.sh once to start the process. I also do ‘killall screen’ to kill all my screens before putting up new ones.

$RANDOM
I’m slowly getting closer to creating scripts for random map generators, of course, a random map generator needs random maps, so I found ‘$RANDOM’ today.

The ‘$RANDOM’ function is built into bash, and when used, makes a random number between 0 and 32767, so it allows for many random numbers.

So I made a little script that writes to a file a random number with a few words around it like so.

echo “This number $RANDOM is sooo random” > test.txt

So, I eventually want to create one big bzflag world file from this, so just for a way to make sure I won’t stumble upon this later, I tried variables.

final=”This number $RANDOM is sooo random”
echo “${final}
#This map was generated by a random map generator” > test.bzw

final is a variable I declare, this is what we will write to our final map file.
echo is simply a function that says make the server say this. And we let it say the words and random number we made in variable final and also add to what we will write to test.bzw, the little This map is generated… part.
> test.bzw writes to test.bzw file, so that it will “update” the map soon.

heh, I think I can start making these random generators out of a bash script, and with scheduling. All I need to learn now is how to run loops for checking things and I’m good to go.

(Also, I am finding stuff from this webpage to be very useful, you may find it useful too. http://matrix.csustan.edu/docs/gnu/bash/ScriptingGuide/index.html)

Sample Map Script
Alright! I made my very first map script. It creates random boxes at a random position and at a random height. Not too useful, but very innovative for me! Looks like this is the start of a great time with coding

final=”"
boxes=100
pos1=0
pos2=0
pos3=0
siz1=0
siz2=0
siz3=0
rot=0
#32767

until [ "$boxes" = 0 ]
do
pos1=$[$RANDOM/82-($RANDOM/82)]
pos2=$[$RANDOM/82-($RANDOM/82)]
pos3=$[$RANDOM/3277]
siz1=$[$RANDOM/655-($RANDOM/655)]
siz2=$[$RANDOM/655-($RANDOM/655)]
siz3=$[$RANDOM/3277]
#echo “${boxes}” #DEBUG Variables
#echo “${siz3}” #DEBUG Variables
rot=$[$RANDOM/91]
boxes=$[$boxes-1]
final=”${final}
box
position ${pos1} ${pos2} ${pos3}
size ${siz1} ${siz2} ${siz2}
rotation ${rot}
end”
echo “${final}” #DEBUG Variables
if [ $boxes = 0 ]; then
echo “${final}” > RANDOM_MAP.bzw
fi

done

Walkthrough:

Lines 1-9 | We’re setting some variables here we can use later on.
Line 10 | This is commented out with #. Just a reference to the random max number.
Line 12 | until is a loop command that starts a loop of a function inside until the value inside is reached, in this case, the variable boxes needs to be 0 to end this.
Line 13 | do is used to specify what to do in the until loop.
Lines 14-22 | Using some simple math and some logic, we are able to develop the formulas for determining a random point on the map. (Some debug variables were included for testing earlier to see if it was working correctly).
Line 23 | Just a simple set of variable boxes one less, so that later the until loop can be stopped.
Lines 24-29 | This is where we make the box code. We provide ${final} first so that it knows we’re adding on to the previous code to this instead of overwriting it everytime, we add in the values we got earlier within the code to get our final variable with the whole code in.
Lines 31-33 | An if statement inside this loop checks everytime whether or not we have reached the end of every box created. If so, we take the whole text of variable final and let the server output that, writing to a file RANDOM_MAP.bzw (fi is just ending the if statement so bash doesn’t get confused as to where the if statement ends)
Line 35 | done means we have completed what needs to be done within the until loop. Anything outside of here is not included within the loop.

Hope you all can learn something valuable from this, I think I really do learn alot at night.

$RANDOM simple
Anyway, a new discovery since I haven’t posted one recently.

Bash can also use the $RANDOM function so that it generates what numbers you want in a range. So I can do

number=$[$RANDOM % 10 +1]

This chooses a random number from 1-10. If I don’t have +1, it’ll only look for numbers 0-9.

if loop fix
Another lesson I have learned from bash. This one’s a little more in-depth about the if loop.

When I did these, I assumed that putting loops inside loops would not be a problem, but I am slightly wrong and here is why:

The standard if loop I’ll be using is

potatoes=0
until [ potatoes = 5 ];
do
echo “I don’t have enough potatoes. Let’s add one”
potatoes=$[$potatoes+1]
done

So, pretty simple, we’re testing to see if potatoes is less than 5, then the script will say on-screen “I don’t have enough potatoes. Let’s add one” and then makes potatoes one greator. Now let’s get a little more complicated. Let’s say that a potato can’t be soggy.(I dunno, I’m silly tonight ). So, let’s make it one out of two chance that a potato is soggy.

potatoes=0
until [ potatoes = 5 ];
do
soggy=$[$RANDOM % 2 + 1]
if test soggy -gt 0; then
echo “Ew. This potato is soggy, throw it away.”
if test soggy -lt 1; then
echo “I don’t have enough potatoes. Let’s add one”
potatoes=$[$potatoes+1]
fi fi
done

Now notice how 2 if statements are nested inside each other? Now this isn’t a problem, until you try to get a string output and you get 0. So if we add some output stuff…

potatoes=0
until [ potatoes = 5 ];
do
soggy=$[$RANDOM % 2 + 1]
if test soggy -gt 0; then
echo “Ew. This potato is soggy, throw it away.”
if test soggy -lt 1; then
echo “I don’t have enough potatoes. Let’s add one”
potatoes=$[$potatoes+1]
if test potatoes -eq 5; then
echo “I now have $potatoes potatoes! I am very happy!” > output.txt
fi fi fi
done

Guess what you see in output.txt? 0. You know why? Because we didn’t write this script correctly. If a variable is greater than 1, it goes beyond boolean values (where 0=false and 1=true) to integer/string values which have a different set of rules, so how do we correct this? Simple actually, just add 2 things.

potatoes=0
until [ potatoes = 5 ];
do
soggy=$[$RANDOM % 2 + 1]
if test soggy -gt 0; then
echo “Ew. This potato is soggy, throw it away.”
else if test soggy -lt 1; then
echo “I don’t have enough potatoes. Let’s add one”
potatoes=$[$potatoes+1]
else if test potatoes -eq 5; then
echo “I now have $potatoes potatoes! I am very happy!” > output.txt
fi fi fi
done

If we have else if instead of just if inside if statements, then it won’t focus on the other ones anymore and move back into reality land (or something ). It’s very complicated unless you really understand things, but just make sure you have your if statements in a working order.

crontab
May I suggest to all who do not want to start they’re servers up manually to edit their crontabs so that when the power does come back on, you do not need to do it manually anymore.

crontab -e

from anywhere to start up crontab. (A scheduling daemon, just follow the instructions.)

Now press enter at the end of the line that says
“# m h dom mon dow command”
This is a basic reference. m=minute(0-59) h=hour(0-23) dom=day of month(1-31) mon=month(1-12) dow=day of week(0-6)

Now, if we want to run it at say, 11:00 PM for the server time, we have to type in:

0 23 * * * screen -d -m /usr/local/bin/bzfs -conf bzfs.conf

Now, notice the bzfs -conf bzfs.conf part at the end? That should be familiar to you. Replace that so that it leads to where the file actually is. So mine is in /home/sigonasr2/bzflag/bzfs.conf so I’m gonna put

0 23 * * * screen -d -m /usr/local/bin/bzfs -conf /home/sigonasr2/bzflag/bzfs.conf

That should do it.
Press Ctrl+x, press ‘Y’ then press enter, and the crontab will be saved.

Now, if you read my multibzfs stuff above, you may be able to run all your servers at one time at a night. Make sure you include killall bzfs in your crontab before starting up new screens.

Running Background Tasks
So, even though screen is useful, it may not be your best option. Because screen was not made solely with Linux, it is not completely capable to do exactly what you want in bash. A simple way to run a task in a background is to use the ampersand sign (&). So, I can do:

bzfs -conf bzfs.conf &

and voila, it’ll be sent to the background. I can then close my ssh client and it’ll still be running. As a script, it would run as an at job, decribed earlier. Now, one thing you may want to know, is how to kill the process. You need to use the special command ps to get a list of the current processes. In my example, we need to end bzfs, so we’d look on the right side for bzfs. Once we find that, on the left side is the PID (Process ID). You then need to use kill where is the number that you want to kill for the process. Hope this may help some who are having troubles with the logging in screen.

Video

Used to convert .ogg files to .avi files. video.ogg is the name of the ogg video file, and video.avi is the name of the avi video file that will be created. You will need to do sudo apt-get install mencoder first.

mencoder video.ogg -ovc lavc -oac mp3lame -o video.avi

System

Used to backup the contents of your Linux drive and store it in backup.tgz. You should include –exclude=/boot if you do not plan on needing a bootable backup. (Suitable for a reinstall of GRUB). The second code below the backup code is used to load the backup into your new system. Make sure the current directory is set to where backup.tgz is. (backup.tgz is usually around 1-4 GB)

sudo tar -cvzf /backup.tgz –exclude=/proc –exclude=/lost+found –exclude=/backup.tgz –exclude=/mnt –exclude=/sys –exclude=/media /

sudo tar -xvpzf /backup.tgz -C /

No Comments Yet »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.