UbuntuHelp:Beginners/BashScripting
来自Ubuntu中文
Bash scripting is one of the easiest types of scripting to learn, and is best compared to Windows Batch scripting. Bash is very flexible, and has many advanced features that you won't see in batch scripts.
To start out programming, it is highly recommended that you have a solid bash foundation to work from, as well as a working knowledge of command line tools that use scripting such as sed or awk. You will find you need to use these commands for more advanced programs that need to parse data.
目录
Intro
Lets start out with the classic, the Hello World script
#!/bin/bash # This is how we tell the shell # what interpreter to use. More on this later echo "Hello World!" # echo is equvilent to C++'s cout or printf, # Java's System.out.println, Python's print or # PHP's echo.
Running a Script
To run this script we need to give execute permissions. use chmod for this.
chmod g+x <script name>
This adds execute permissions to the file's group. run the script using ./, not sh as sh uses sh, not bash and limits the use of some syntax.
./script.sh
The output should say "Hello World", and if it shows then Congrats! You just made your first bash script. Lets move on now to a slightly more advanced topic, variables and input.
Variables
Variables in bash are defined without types, and without spaces ( variable side, that is ). Defining a variable should look like this:
Example
FOO="BAR" number=0
Variables are also case sensitive, but how you define it is up to the programmer. ( thisVar is not the same as THISvaR )
Accessing Variables
To access a variable, you need to put a $ before, like this:
thisVar="FOO" thatVar="Bar" echo $thisVar echo $thatVar
Let's make a script that will ask the user for his or her name and age.
Reading / Writing to Variables
#!/bin/bash #Always remember the sha-bang (#!) then the path #to the interpretative program. echo "Please enter your name" # You should know what this does about now ;) read NAME # read will watch for the user's input # and store it to the variable (NAME, in this case) echo "Please enter your age" read AGE echo "Hello $NAME, $AGE is a great age" # You do not have to get out of quotes for variables # in bash.
the shell should look something like this:
Please enter your name Paul Please enter your age 18 Hello Paul, 18 is a great age
Storing application stdout to a varable:
Application stdout ( what you see on the terminal screen, with an un-piped application ) can be saved and used in Bash. The simplest and most elegant way is to use the back-tick (`) this is not an apostrophe or quote (' or ") and is found on the same key as the tilde (~)
Example
#!/bin/bash fooVar=`who` echo $fooVar
This code should output the current users, their respective ttys, and date of login. Note that this strips newlines. Be sure to do any parsing in line ( | grep, etc ) then pass it to a varable. We will try this again, but grep for tty7, the GUI's tty.
Example 2
fooVar=`who | grep tty7` echo $fooVar
This should output the single user that is currently logged in to the WM. Lets move on to more advanced data manipulation within back ticks.
FUNctions
Bash lets you create a function on the fly, really handy if you plan on using a code block more then once. Functions reduce the amounts of editing you have to do in a script, if and when you have to update your script. Lets get to it:
Example
Here is an example script:
#!/bin/bash echo "echo is Called" echo "Functions are FUN!" echo "echo is Called"
Although this example is simple, you can see that if you want to change "echo is Called" to say "foo is Called" you would have to edit twice. Below is the same app using functions.
#!/bin/bash echoFunction() { echo "echo is Called" } fooBar() { echo "Functions are FUN!" } echoFunction; fooBar; echoFunction; # You call functions without (), just the function name then a semicolon.
This example, as you can see may be longer now, but if you can imagine adding features how this will eliminate code, and reduce complexity. Also you can see if you want to change the echo call, you have to edit one line, not two.
Debugging
I always find it useful to trace a script to find out why something does not work as expected. To trace start it trough bash explicitly and use the -x option, like so:
bash -x ./script.sh
This will write each command to standard error (preceded by a ‘+ ’) before it is executed.
tr
tr is one of the most basic applications to pipe data through that uses a basic scripting syntax. In this case, it accepts Regular Expressions. Lets do a normally complicated task, transforming a string to all uppercase.
Example
#!/bin/bash read foo var=`echo $foo | tr "{a-z}" "{A-Z}" # {a-z} Matches a through z # {A-Z} matches A through Z echo $var
The output should look something like this:
this is a test THIS IS A TEST
tr also can TRanslate strings, so lets translate all foo to bar.
Example
#!/bin/bash read foo var=`echo $foo | tr "t" "b"`
the output should look something like this:
I love tars I love bars
awk
AWK ( Short for Aho, Weinberger & Kernighan ) awk has its own custom scripting language, suitable for a tutorial by its self, so I will cover only the basics, to help assist when you are bash scripting. This is not meant to be complete or comprehensive in any way.
pidof clone
Let's make a quick pidof clone, that prompts for a process identifier, then echoes the process ID.
#!/bin/bash read pname ps -ef | grep -v grep | grep $pname | awk '{print $3}'
awk is called within single quotes to pass to awk. The curly braces are to use the awk language (for stuff like prints, ifs ect). Print prints the column passeed given by the $ markup, space delimited. There is a lot more then the print command, such as if statements, etc and is worth looking into if you are interested in what you see here :)
sed
sed is one of the most complicated scripting languages on the GNU / Linux system. I am only going to cover the s/ command here.
Basic Substitution
Try this out to show that sed can not only replace in line, but unlike tr replace with a longer or shorter string then before.
#!/bin/bash read foo echo $foo | sed "s/foo/bars/"
When this command is run, it should substitute all foo with bars. This is an example of the output.
I love to go to foo I love to go to bars