Shell script that runs a random shell script

Hi, im trying to make a shell script that basically runs a random shell script form a list of shell scripts i specify. Im not very good at writing shell scripts, and am new to linux.

Thanks in advance :slight_smile:

So you want to invoke the script foo and it picks and runs a script from an internal list.... If that's the case, then here is a simple example:

#!/usr/bin/env ksh

nscripts=5
rn=$(( $RANDOM % $nscripts ))

case $rn in
    0)  echo script_1;;
    1)  echo script_2;;
    2)  echo script_3;;
    3)  echo script_4;;
    4)  echo script_5;;
esac
exit 0

Replace the echo script_n with the command you wish to exeecute and you're in business.

Wonderful, thank you so much for your help you've made my dreams come true :slight_smile:

---------- Post updated at 12:47 PM ---------- Previous update was at 12:39 PM ----------

Could I request some more help ;D

Now that ive got this down, it will use nearly 60 shell scripts. Ive got all of them made but the only difference is each shell script just copies to a different line of text to the end of a text file. Would it be possible to use a scipt similar to this but to have it randomly copy a line of text (actually its just one word) from a list of words to the end of a text file?

Then i could cut it down to only a few scripts.

Are you looking to randomly write one of a series of different texts to the end of a text file. If so you can use the same script as above but replace the case option with something like

case $rn in
1) echo "your text here" >> text_file.txt
esac

the double redirect symbol (I believe it is called something like append) will put the "your text here" at the bottom of the text_file.txt

I hope that helps a little :slight_smile:

1 Like

Yes, that's exactly what i wish to do. Thanks for the info i,ll try it out.

Rather than maintaining a case of 60 lines in your script, and making it easy to add/change the words/strings later, you could try something like this:

#!/usr/bin/env ksh

biscuits=/path/filename          # name of file with one string per line
nstr=$( wc -l <$biscuits)        # count number of biscuits (cookies in the US)
if (( $nstr > 0 ))                   # prevent disaster on an empty file
then
    rn=$(( ($RANDOM % $nstr) + 1 ))      # compute a random one based on the number of biscuits
    rstr=$( tail -$rn $biscuits | head -1 )    # read the biscuit
    echo $rstr                         # for testing
    echo $rstr >>/path/target-file
fi

With this you can modify your strings later without needing to retest your script. You could also use the same script with different lists of words/strings.

Have fun!

I had not even thought of it that way (I guess I am so used to modifying my scripts under development I was not thinking about easy changing). I do have one question for you though agama I am fairly new to shell scripting and I was wondering if adding the "$" before you evaluate an expression while defining a variable... as in...

variable=$(expression)

Thanks for the help if you can.

Not quite sure what you are asking, so I'm guessing here...
The construct varname=$(command) executes the command and assigns the output to the variable. This style obsoletes back quotes, or back ticks.

If you were asking something else, please ask. If I don't get back to it first, someone will likely post an answer.

Ohhh, thanks, I completely forgot about the need for back ticks thing. Do you know if the $ thing will work in most shells or just particular newer ones. Are the parenthesis needed?

Parens are certainly necessary. Works in modern Kshell and bash.

I rarely use bash, so I cannot say how far back it is supported. The version I have loaded on this machine is GNU bash, version 3.2.39(1)-release (i586-suse-linux-gnu) and it works.

I usually live on the edge with Kshell's latest release and have been using $(command) now for several years. I would doubt that you'll run into an instance that doesn't support it.

I really cannot speak for other sh like shells, so maybe, but maybe not.

cant seem to get ifthanwhile's example working. When i execute the shell script i get the following.

./cc.sh: line 8: syntax error near unexpected token `)'
./cc.sh: line 8: `    2) echo 'test2/' >> mtest.txt'

Here is my script.

#!/bin/bash

nscripts=2
rn=$(( $RANDOM % $nscripts ))

case $rn in
    1) echo 'test1/' >> mtest.txt
    2) echo 'test2/' >> mtest.txt
esac
exit 0

By changing the ) to backslashes i get it to somewhat work, but it doesn't copy the test1 text to the end of the file it copies that everything after it and everything until the / on the next line.

---------- Post updated at 06:06 PM ---------- Previous update was at 12:38 AM ----------

Still cant get it working, ive tried multiple things. I know its a very simple script but im to new to shell scripting to troubleshoot this.

There are two issues. First, the result of your mod operation (%) will be 0 through n-1, or in your case either 0 or 1. You need to adjust your case accordingly.

The problem that is causing the odd output is that you are missing the 'termination' semicolon pair at the end of each case action:

#!/bin/bash

nscripts=2
rn=$(( ($RANDOM % $nscripts)+1 ))

case $rn in
    1) echo 'test1/' >> mtest.txt;;
    2) echo 'test2/' >> mtest.txt;;
esac

If you were to run your script through ksh or bash with the -n option, it would identify the area of the problem. Bash reports this:

spot; bash -n t2
t2: line 8: syntax error near unexpected token `)'
t2: line 8: `    2) echo 'test2/' >> mtest.txt'

From experience, the unexpected ')' message means that the ';;' was dropped from the previous block. We all occasionally leave them out, or accidentally delete them while editing.

Hope this gets you going again.

1 Like

Awseome, works well :slight_smile:

So i assume where i have mtest.txt i can also jsut specify a path to a directy containing a tex file, like the following. home/test/user/mtest.txt.

Thank you for your help, i really appreciate it

Glad it is working for you. Yes, any path to a file will work.

Also i was wonder why you removed exit 0 from the script and exactly what it means as well as esac. Thank you.

I probably didn't cut/paste the exit 0 in my example. I generally write/test things and paste them in here.

The esac terminates the case statement (its c a s e backwards). Think of it as the same as the terminating fi on an if statement. Without it the shell will throw an error.