Hi Rudolf,

Here's the quick answer.

Copy the text of the script into a text file and save it as SQLOptimize.sh
(or whatever you want to call it).
Change the permissions to make it executable, something like 'chmod 755
./SQLOptimize.sh"
Execute the script by typing ./SQLOptimize.sh at the command prompt. (note:
the ./ specifies that the file is in the same directory as you are working
in). You will be prompted for the username and then the password.

For the mysql part, the original line was this;

TABLES=$(echo "USE $db; SHOW TABLES;" | mysql -u$1 --password=$2 |  grep -v
Tables_in_)

I changed this to;

TABLES=$(echo "SHOW TABLES;" | mysql -D$db -u$1 --password=$2 |  grep -v
Tables_in_)

By removing the "USE $db" from the echo command and using the -D option in
the mysql client it should now be running one less command on the database
for every iteration of the for-loop.
This is assuming the -D option is not using the USE $db command anyway.

################
################

Here's the really really long answer to your questions which hopefully will
help you better understand shell scripting in general. Forgive me for going
over basic stuff that you probably already know.
The original script has the following line;

TABLES=$(echo "USE $db; SHOW TABLES;" | mysql -u$1 --password=$2 |  grep -v
Tables_in_)

Breaking this apart we get the following;
A variable is created called 'TABLES' and is assigned the value from the
result of the commands to the right of the equals.
The entire right hand side of the line is enclose by $( ). This groups
everything together so that the result passed to the variable is whatever
the contents between the brackets evaluates to.
So the following line is executed by the shell;

echo "USE $db; SHOW TABLES;" | mysql -u$1 --password=$2 |  grep -v
Tables_in_

Regarding the pipes, (the | character), this takes the output of the command
on the left of the pipe and uses it as the input to the command on the
right.
The first part of the line;

echo "USE $db; SHOW TABLES;"

outputs the text between the quotations but substitues the content of the
variable 'db' (variables are referenced using a '$'). Assuming the variable
'db' contains the string 'otrs' you would get the following output;

USE otrs; SHOW TABLES;

The output from the above text is 2 mysql commands, seperated by
semi-colons. The first tells mysql to focus on a particular database and the
second tells it to list all the tables in the database it is focused on.
So the output of the echo command (the 2 mysql commands) is piped into the
next command as input.
The next part which is;

mysql -u$1 --password=$2

Starts the mysql client (note: it doesn't use the absolute for mysql so it
has to be in the PATH for this command to work).
It uses the username which is stored in the variable $1 and the password
stored in the variable $2. These numbered variable are special because they
are gotten form the command used to initially start the script on the
command line.
If you're script was called SQLOptimize.sh and you used the following from
the command line (I'm using $> to represent the shell prompt, you don't
enter);

$> ./SQLOptimize.sh dbuser dbpass dbname dbport blah

The following variables would be available to your script
$1 == dbuser
$2 == dbpass
$3 == dbname
$4 == dbport
$5 == blah
In the script only $1 and $2 are used but you can see how you can get much
more information from the user running the script just by separating the
script parameters by a space.

Back to the command at hand, the mysql client has been started and logged in
using the username and password provided by the user. It then takes the
input which has been piped through from the echo command, "USE otrs; SHOW
TABLES;", and runs this in the mysql client. Note that this is 2 commands.
Be cause this is in a loop within the script it must be run at every
iteration of the loop.
By changing the mysql command to include the -D option;

mysql -D$db -u$1 --password=$2

The mysql client logs straight into the database specified in the $db
variable. This means we don't need the "USE $db" command in the echo command
from earlier which means that we have reduced them number of commands run by
the mysql client in the loop by half. This should reduce the amount of
resources used during the script. I also did the same thing in the nested
for-loop as it also contains a call to the mysql client and had a USE $db
entry.
In my previous mail I had mentioned this might not make any difference
because logging into the mysql client with the -D option may just run the
USE $db command anyway.

The output from the mysql portion of the line is as follows;

Tables_in_otrs
article
article_attachment
article_flag
article_plain
article_search
..<SNIP>..
web_upload_cache
xml_storage

This is piped into the next part of the command as input;

grep -v Tables_in_

Grep is a pattern matching tool. You can use it to search line by line to
find a string in a file or in this case a string in the output of another
command. The '-v' option tells grep to invert the results. So if the string
*is* found on a line then *do not* return the line and if the string *is
not* found on the line then *do* return the line.
So in the  grep command from the script it will return every line that does
not contain the string Tables_in_
So the output will be;

article
article_attachment
article_flag
article_plain
article_search
..<SNIP>..
web_upload_cache
xml_storage

This results in only the list of tables being returned and no extra lines
that are not tables.

########

For your question about how to call the script there are a few different
elements to this to understand what's happening.

Firstly, I'm assuming you're doing everything from a shell prompt/command
line and not through a GUI.
The script is a shell script i.e. you could write it out in the Linux shell
and it'd work. It's just put in a script for convenience.
A shell script will normally have the extension .sh, i.e. SQLOptimize.sh
To make the script below usable you create a file using a regular editor
such as 'vim' or 'nano', paste in the code and save with an appropriate name
and extension, SQLOptimize.sh (you don't *need* the .sh extension, it'll
work without it, but it helps to have it for when you are looking at a list
of files)
Before you can run the script you need to make it executable. This is a file
permission and in Linux these can be edited using the command 'chmod'. It is
used in the following format;

chmod <options> <permission> <filename>

The <options> are things like -R for recurrsive.
The <filename> can use wildcards i.e. *.sh
The <permission> is something that needs a bit more detail. Have a look at
this webpage which gives some detail on how Unix permissions are written and
how to set them using the chmod command;
http://www.acm.uiuc.edu/webmonkeys/html_workshop/unix.html

When calling a script often you won't need to do anything more than just
enter the filename. So just entering SQLOptimize.sh at the shell prompt
might work. This would work because there is an entry in you PATH for .
(just a dot on its own).

****
Aside: This is actually a security risk so hopefully it is not in your PATH.
Consider if a malicious site downloaded a file called ifconfig to a folder
on your machine. If your working directory was the same as the location the
file was downloaded you would run the malicious ifconfig instead of the real
one which would allow it to do whatever it likes as your user. Especially
dangerous if you're logged in as root e.g. it could run "rm -rf /" deleting
everything.
****

In order to be specific about the file you wish to run you can use the
relative or absolute path.
The relative path uses your current working directory as the starting point
to find the file you want to run.
The absolute path is the full location of the file you want to run from the
root directory.

Your current working directory is specified by a dot on its own. So if you
entered whats between the commas here 'cd .' you would be telling the system
to change directory to your current working directory.
If you entered 'cd ./scripts' then you're telling the system to change to
the scripts directory which is a sub directory of your current working
directory.

Lets say your script is located at /home/user1/scripts/SQLOptimize.sh
And your current working directory is /home/user1/scripts

To run the script using a relative path you would use
./SQLOptimize.sh

To run the script using the absolute path you would use
/home/user1/scripts/SQLOptimize.sh

If you run the script using the absolute path then it doesn't matter what
your current working directory is. Because of this it is best to use
absolute addressing when writing a script that references any outside files.


#############################

#!/bin/bash

echo "Enter DB User: "
read user
echo "Enter DB Password: "
read -s pass

if [ -z "${user}" ];
then
        echo "Username is blank. Exiting script"
        exit
elif [ -z "${pass}" ];
then
        echo "Password is blank. Exiting script"
        exit
fi

for db in $(echo "SHOW DATABASES;" | mysql -u$user --password=$pass | grep
-v -e "Database" -e "information_schema")
do
        echo "Switching to database $db"
        TABLES=$(echo "SHOW TABLES;" | mysql -D$db -u$user --password=$pass
|  grep -v Tables_in_)

        for table in $TABLES
        do
                echo -n " * Optimizing table $table ... "
                result=$(echo "OPTIMIZE TABLE $table" | mysql -D$db -u$user
--password=$pass 2>&1)
                if [[ $result == *ERROR* ]]
                then
                        echo "FAILED"
                        echo ".... $result"
                else
                        echo "Success"
                fi
        done
done

#############################


Sorry for the mammoth mail, I just thought I'd write all that out because it
covers some fundamentals when working with Unix based systems and you did
say you were just dabbling so I thought it might help.

Rory

On 29 August 2011 14:29, Rudolf Bargholz <bargh...@onlinetravel.ch> wrote:

> Hi Rory,****
>
> ** **
>
> For those of us that are not so well versed on Linux, could you perhaps
> post an example how you call your script, with the appropriate parameters.
> This makes it easier for us Windows users (me) dabbling in Linux to actually
> get your script working.****
>
> ** **
>
> The one sentence I do not understand is “I added the database to the mysql
> command where appropriate to reduce the number of commands run once the
> mysql client was started as an optimization”. An example would probably
> help resolve my questions.****
>
> ** **
>
> Regards****
>
> ** **
>
> Rudolf****
>
>
>
---------------------------------------------------------------------
OTRS mailing list: otrs - Webpage: http://otrs.org/
Archive: http://lists.otrs.org/pipermail/otrs
To unsubscribe: http://lists.otrs.org/cgi-bin/listinfo/otrs

Reply via email to