Difference between revisions of "CSC231 Bash Tutorial 6"

From dftwiki3
Jump to: navigation, search
Line 4: Line 4:
 
<br />
 
<br />
 
{|
 
{|
| style="width: 50%;"
+
| style="width: 50%;" |
 
__TOC__
 
__TOC__
 
|
 
|

Revision as of 15:51, 22 March 2017

--D. Thiebaut (talk) 22:18, 21 March 2017 (EDT)




This lab deals with bash script files. Script files are program files that contain bash commands, and these commands can be interpreted by bash, one after the other, as if the user had typed them at the keyboard. Scripts can be quite complex, and contain functions, if-statements, loops, variables and other programming concepts found in programming languages.



Script File


Let's create a simple batch file that will allow you to automatically assemble, link, and run an assembly program. Furthermore, we'll link it with the 231Lib library, just to be safe. If it doesn't use it, it should be fine.

The commands you normally use to go through this process are the following:

nasm -f elf progName.asm
ld -melf_i386 progName.o 231Lib.o -o progName
./progName

Let's create a script file called nald (for nasm ld) that will run these 3 commands automatically. For now, just copy the code without worrying too much about what happens. We'll explain what's going on later.

  • emacs a new file called nald
  • Store the following lines in it:


 
#! /bin/bash
 
nasm -f elf $1.asm
nasm -f elf 231Lib.asm
ld -melf_i386 $1.o 231Lib.o -o $1
./$1


  • Make sure that the #-sign is the first character on the first line of the script.
  • Make the script executable:
chmod +x nald

chmod is a command that changes the permissions of a file. "+x" means that everybody including you, everybody in the 231 class, and everybody who has an account on Aurora can execute your script.


  • now run the script and pass it the name of one of your assembly files. Let's assume that you have a file called helloWorld.asm in your directory:
./nald  helloWorld

You should see the output of your program printed on the screen.
  • Using emacs, make a slight modification to your helloWorld.asm program. Maybe, make it print something different.
  • reassemble and run it in one command:
./nald  helloWorld

  • You now have a nice script that will save you several keystrokes when you create your next assembly programs!


Explanations


Shebang


#! /bin/bash
the first line of the script starts with the pair "#!" which is referred to as "shebang" in the Linux world. It indicates that the commands in the script should be executed by the bash shell, which is located in the /bin directory of Aurora. If we had Python program that we would want to run automatically, we would use a shebang with Python's path. Let's try that for fun:
  • Create a new file with emacs called hello.py


 #! /usr/bin/python
 
 from  __future__  import print_function
 
 def main():
      print( "Hello world of Python!" )
 
 main()


  • Save the file, and make it executable
chmod +x hello.py

  • run the program from the command line:
./hello.py
Hello world of Python!

  • Notice that you didn't write "python hello.py" to run your program. Just "./hello.py." That's a nice trick.
  • In summary, the shebang defines the interpreter to use to read the file and execute the lines.


$1


Command line parameters
inside the script, we can access the parameters that were typed on the command line using $1, $2, $3, and some others. To best understand how this works, create the following simple shell script with emacs called script1.sh:


#! /bin/bash

echo "You typed $# words on the command line"
echo "The whole collection of words is $@"
echo "Word 0 is $0"
echo "Word 1 is $1"
echo "Word 2 is $2"
echo "Word 3 is $3"
echo "Word 4 is $4"


  • Make the script executable:
 chmod +x  script1.sh

  • And try it with several command line parameters:
 ./script1.sh  hello world 3 20 2017

 ./script1.sh  CSC231


  • so this is how the script can access the parameters passed on the command line. When you typed nald fileName on the command line earlier, the name of your file becomes $1 inside the script.



Challenge #1:

QuestionMark1.jpg


In a recent lab you created a command with a for loop that would run the N-Queens program for several chessboard sizes. A typical command to run the program for several board sizes would be:

 
 for i in `seq 8 14` ; do  
     echo -n "$i " 
     java NQueens $i -q 
 done


(if you have lost your NQueens program, you can get another copy with getcopy NQueens.java, and compile it with javac NQueens.java.)

  • Create a bash script calls runNQueens.sh with the loop above in it. It will run all 7 cases automatically when called:
./runNQueens.sh 
8 0.158674 ms
9 0.093859 ms
10 0.160577 ms
11 0.113491 ms
12 0.355657 ms
13 0.185683 ms
14 12.889715 ms










Challenge #2:

QuestionMark2.jpg


Modify your script so that you can pass the boundaries of the board sizes you want to check, on the command line. For example, if you wanted to run the NQueens for board sizes ranging from 8 to 20, you'd run your script as follows:

./runNQueens.sh 8 20








Scripts Behave as Bash Commands


  • One nice feature of a bash script is that you can use it the same way you would a bash command. For example, if you wanted to capture the output of script1.sh in a file, you could simply type:
./script1.sh  hello world 3 20 2017  > dummy.txt

  • Check the contents of the file dummy.txt and verify that the output of the script was captured correctly.


Bash Variables










<showafterdate after="20170324 11:40" before="20170601 00:00">

Solution to Challenges


Challenge 1


#! /bin/bash
# runNQueens.sh
# D. Thiebaut
# runs and times the execution of the NQueens
# program for board sizes ranging from 8 to 14.

for i in `seq 8 14` ; do  
     echo -n "$i " 
     java NQueens $i -q 
done


Challenge 2


#! /bin/bash
# runNQueens.sh
# D. Thiebaut
# runs and times the execution of the NQueens
# program for board sizes ranging from the first to second
# parameters passed on the command line.
# Example:
#     ./runNQueens.sh 10 21
#

for i in `seq $1 $2` ; do  
     echo -n "$i " 
     java NQueens $i -q 
done

</showafterdate>