📄 shell-scripting.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd"><HTML><HEAD><TITLE>Shell Scripts Made Easy</TITLE> <META NAME="Description" CONTENT="A brief summary of bash shell scripting."> <META NAME="Author" CONTENT="Paul Winkler"></HEAD><LINK REL="stylesheet" TYPE="text/css" HREF="default.css"><BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#7F007F"><H2>Shell Scripting Made Easy</H2><FONT SIZE="-1"><B>Created: December 21, 1999</B></FONT><BR><FONT SIZE="-1"><B>Last updated: December 21, 1999</B></FONT><BR><FONT SIZE="-1"><B>Development stage: Alpha</B></FONT><BR><P>You may have heard that one advantage of Linux is that everythingis programmable. You can automate just about any task. There are a lotof ways of doing this. One of the most common is the <b>shellscript</b>, which is sort of equivalent to a DOS "batch file".</P><p>Simply put, a shell script is a list of commands to run; but it's alot more flexible than that implies.</P><p>If you get into really complicated scripting, especiallyautomatically processing text files, you may be better offlearning a scripting language like python or perl or scheme or tclor...</P><h3>DISCLAIMER</h3>Several things to watch out for:<ol><p><li>The example scripts assume you are running a bourne-compatibleshell, specifically bash. They will not work with tcsh or othershells. <p><li>The example scripts come with <b>no warrantywhatsoever.</b> I will not be held responsible if any of them eat yourfiles, trash your hard drive, etc. I use all these scripts myself, butI make no guarantees.</ol><H3>Index</H3><OL><LI><A HREF="#Overview">Overview</A> - how to start writing bashshellscripts</LI><li><a href="#Basics">Basic Techniques</a> <UL> <li><a href="#comments">Comments</a> - built-in documentation <li><a href="#variables">Variables</a> - how to re-use information <li><a href="#arguments">arguments</a> - using stuff from the command line <li><a href="#backquotes">backquotes</a> - getting command output <LI><A HREF="#if">if...then</A> - conditional actions</LI> <LI><A HREF="#for">for...do</A> - repeating actions</LI> </UL><li><a href="#Examples">Examples</a> - a bunch of my favoritescripts.<LI><A HREF="#books">Related Books</A> - books to consider forfurther information</LI></OL><A NAME="Overview"></A><H3>Overview</H3>To make a shell script, do this:<ol><li>Create a file, let's call it "foo". Put it in a directory in yourpath. I recommend creating a directory called 'sh' in your homedirectory as a special place to put your own shell scripts. Add thisdirectory to your path by putting this command in /etc/profile, or in.bash_profile in your home directory: <tt>exportPATH=$PATH:/home/my-user-name/sh</tt><p><li>In the first line of the file, type this: <tt>#!/bin/sh</tt><p>That's a magic word that tells the system you want to execute thecommands in this file using the 'sh' shell, which on most linuxsystems is actually a <ahref="http://jgo.local.net/LinuxGuide/linux-commands.html#ln">link</a>to /bin/bash.<p><li>Change the permissions on the file, by giving this command:<p><tt>chmod +x foo</tt><p>This makes the file "executable"; now you can execute it just bytyping its name. For more information see <ahref="http://jgo.local.net/LinuxGuide/linux-chmod.html">usingchmod</a>.<p><li>Now put some commands in the file!</ol>As an example, let's take this really simple script:<pre>#!/bin/shecho hello world</pre><p>Make the file executable, then type the file's name as acommand. Guess what... it prints 'hello world.'<a name="Basics"><h3>Basic Techniques</h3></a><a name="comments"><h4>Comments</h4></a><blockquote>You can put comments in your scripts, by typing the '#'character. Anything after the # will be ignored. Use this feature; itwill help you remember what your script is supposed to do later, andit can help anyone else who uses your script.</blockquote><a name="variables"><h4>Variables</h4></a><blockquote>It can confuse you at first, but there's basically only twosyntax rules to remember about variables in the bash shell:<ol><li>to make use of thevariable, put a dollar sign in front of the name;<li>To create the variable, use an equal sign immediately after thevariable name (no spaces!), and DON'T use the dollar sign before thename.</ol> <p>Example: Let's create and then print a variable. Try typing this at the shell prompt:<p>foo='hello' ; echo $foo</blockquote><a name="arguments"><h4>Arguments</h4></a><blockquote>When you run a shell script, you can give arguments. The arguments arestored in variables called $0, $1, $2, $3, ...<p>The first one, $0, actually gives you the name of the shell scriptitself. The rest starting with $1 are the ones you're more likely touse right away. To play with this idea, try this script:<pre>#!/bin/shecho $1echo $2echo $3</pre></blockquote><a name="backquotes"><h4>Backquotes</h4></a>You can get the output of any command just by putting it in backquotes(the backquote key is usually in the upper left of the keyboard).<p>Example: Type this at the command line: <tt>listing=`ls`</tt><p>Now the variable <tt>$listing</tt> contains the output of thecommand <b>ls</b>, namely, a list of files.<a name="if"><h4>if...then</h4></a><blockquote>What if you want your script to do different things under differentcircumstances? Easy, just use an 'if' block, like this:<pre>if some-test-commandthen do-somethingfi</pre>Just replace <i>some-test-command</i> with a command that eithersucceeds ("returns true") or fails ("returns false"). And replace<i>do-something</i> with a command you actually want to run if thetest command returns true!<p>Notice that you always have to use 'fi' to close the block. ('fi'is 'if' backwards, get it? Ahh, unix humor, ha ha.)<p>You can also add an <b>else</b> clause, which tells what to do ifthe test command is false, like this:<pre>if some-test-commandthen do-somethingelse do-something-elsefi</pre><p>You can also add an <b>elif</b> clause, which is shorthand for"else if", meaning, "on the other hand, if something else istrue...". This lets you test for more than one condition.<pre>if some-test-commandthen do-somethingelif some-other-test-commandthen do-something-elseelse do-something-entirely-differentfi</pre>Hopefully this will all become clear in the <ahref="#Examples">Examples</a> below.</blockquote><h4><a name="for">for...do</a></h4><blockquote><b>for</b> provides a way to do the same action a bunch of times witha bunch of different things. For example, say you have a list of filesstored in a variable, and you want to copy all those files. You coulddo that like this:<pre>files="foo bar baz batz"for f in $filesdo cp $f $f.backupdone</pre>Or you could do that all on one line, like this:<tt>for f in $files; do cp $f $f.backup ; done</tt></blockquote><hr><a name="Examples"><h3>Examples</h3></a>These are not guaranteed to be great examples, but they should beunderstandable, and I use them all.<p>For some really great useful shell scripts, see the <ahref="http://www.linuxdoc.org/HOWTO/Tips-HOWTO.html">LinuxTips-HOWTO</a>, which you may have in /usr/doc/HOWTO/Tips-HOWTO.<hr><h4>Backing Up Configuration Files</h4><pre>#!/bin/sh# if [ ! $1 ] # This means, "if there's no first argument..."then echo " "Usage: `basename $0` output.tar.gz # note that `basename $0` gives the name of this script! echo " This creates a tarred, gzipped archive of all" echo " the hidden files in your home directory." echo " Warning: if an archive by that name exists," echo " it will be overwritten." exit 1 # Quit this script now!ficd ~ # go home!rm -f /tmp/skip# Make a list of files to skip... add to this as you wish.ls -1d --color=no .gimp/gimpswap* .gimp/tmp >>/tmp/skipls -1d --color=no .[a-zA-Z]*~ ~/.[a-zA-Z]*bak .[a-zA-Z]*errors>>/tmp/skipls -1d --color=no .[a-zA-Z0-9_]*/*cache .[a-zA-Z0-9_]*/*tmp >>/tmp/skipls -1d --color=no .[a-zA-Z0-9_]*/*~ >> /tmp/skipls -1d --color=no .[a-zA-Z]*/*.bak >>/tmp/skipls -1d --color=no .[a-zA-Z]*/*.BAK >>/tmp/skipls -1d --color=no .[a-zA-Z]*/*.backup >>/tmp/skipls -1d --color=no .[a-zA-Z]*/*.old .[a-zA-Z]*/*.OLD >>/tmp/skipecho "core" >> /tmp/skip# Make the archive, and put it in $OLDPWD, which is the directory we# were in before that cd command above.tar -cvz -X /tmp/skip -f $OLDPWD/$1 `ls -1 -d --color=no.[a-zA-Z]*`# Now clean up and go back where we wererm -f /tmp/skipcd $OLDPWD # go back to where we were before starting the script.</pre><hr><h4>Simple Trash Can</h4><pre>#!/bin/bash# Simple script to throw stuff in a "trash bin" instead of deletingit.# Requires a directory called "trash" in your home directory.# NOTE: Does not work on filenames with embedded spaces.if [ ! $1 ] ; then echo Usage: echo `basename $0` string echo For filenames that contain \"string,\" echo throws all files \(and their contents, if they aredirectories\) echo into a \"trash\" directory in your home directory. echo Options: echo "-u Disk usage of your trash directory." echo "-ls List files in trash." echo "-empty Delete everything in trash." exit 1elif [ $1 = "-u" ] 2> /dev/null ; then echo Disk usage of ~/trash: du ~/trashelif [ $1 = "-empty" ] 2> /dev/null ; then echo Emptying trash... rm ~/trash/* ; rm ~/trash/.* 2> /dev/nullelif [ $1 = "-ls" ] 2> /dev/null ; then ls -a ~/trash else for file in *$1* ; do mv $file ~/trash donefi</pre><hr><h4>Removing Spaces from Filenames</h4><pre>#!/bin/bash# Paul Winkler's second script, for removing spaces from files# that have stupidly been named with them, and substituting# the usual character "_" ...# 'case' is another way of testing things. Basically, the next 3lines# translate as: "if $1 is '-a' do everything up to the line ';;' ".case $1in -a) # If $1 is "-a"... for files in *\ * ; do echo mv \"$files\" `echo $files | sed s/\ /_/g` | bash done echo You just removed spaces in all filenames in `pwd`. echo They have been replaced with \"_\". ;; -s) # If $1 is "-s"... for files in *$2* ; do echo mv \"$files\" `echo $files | sed s/\ /_/` | bash done echo You just removed spaces in all filenames containing echo \"$2\". They have been replaced with \"_\". ;; *) # If $1 is anything else, print instructions! echo Usage: \"`basename $0` -a\" to remove spaces from all filesin this directory \(`pwd`\). echo \"`basename $0` -s anything\" to remove spaces from filescontaining echo the string \"anything.\" echo 'Spaces will be replaced with an underscore ("_").'esac # End of the "case" block.</pre><hr><hr><A NAME="books"></A><H3>Related Books</H3><OL><LI>Linux in a Nutshell - a good overview of all the most commonLinuxcommands, including a comprehensive section on the bash shell.</ol><HR><P><B><FONT SIZE="-1">Copyright © 1999 <AHREF="mailto:slinkp@angelfire.com">Paul Winkler</A>. Allrights reserved. Permission to use, distribute, and copy thisdocument ishereby granted. You may modify this document as long as credit to meisgiven.</FONT></B></P></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -