📄 writingscripts.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><HTML><HEAD><TITLE>Writing Scripts</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.57"><LINKREL="HOME"TITLE="Advanced Bash-Scripting Guide"HREF="index.html"><LINKREL="UP"TITLE="Exercises"HREF="exercises.html"><LINKREL="PREVIOUS"TITLE="Exercises"HREF="exercises.html"><LINKREL="NEXT"TITLE="Revision History"HREF="revisionhistory.html"><METAHTTP-EQUIV="Content-Style-Type"CONTENT="text/css"><LINKREL="stylesheet"HREF="common/kde-common.css"TYPE="text/css"><METAHTTP-EQUIV="Content-Type"CONTENT="text/html; charset=iso-8859-1"><METAHTTP-EQUIV="Content-Language"CONTENT="en"><LINKREL="stylesheet"HREF="common/kde-localised.css"TYPE="text/css"TITLE="KDE-English"><LINKREL="stylesheet"HREF="common/kde-default.css"TYPE="text/css"TITLE="KDE-Default"></HEAD><BODYCLASS="SECT1"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#AA0000"VLINK="#AA0055"ALINK="#AA0000"STYLE="font-family: sans-serif;"><DIVCLASS="NAVHEADER"><TABLEWIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">Advanced Bash-Scripting Guide: An in-depth exploration of the art of shell scripting</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="exercises.html">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">Appendix M. Exercises</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="revisionhistory.html">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="WRITINGSCRIPTS">M.2. Writing Scripts</A></H1><P><ANAME="WRITINGSCRIPTS1"></A></P><P>Write a script to carry out each of the following tasks.</P><DIVCLASS="VARIABLELIST"><P><B><ANAME="EXEASY1"></A>EASY</B></P><DL><DT><BCLASS="COMMAND">Home Directory Listing</B></DT><DD><P>Perform a recursive directory listing on the user's home directory and save the information to a file. Compress the file, have the script prompt the user to insert a floppy, then press <BCLASS="KEYCAP">ENTER</B>. Finally, save the file to the floppy.</P></DD><DT><BCLASS="COMMAND">Converting <AHREF="loops.html#FORLOOPREF1">for</A> loops to <AHREF="loops.html#WHILELOOPREF">while</A> and <AHREF="loops.html#UNTILLOOPREF">until</A> loops</B></DT><DD><P>Convert the <ICLASS="EMPHASIS">for loops</I> in <AHREF="loops.html#EX22">Example 10-1</A> to <ICLASS="EMPHASIS">while loops</I>. Hint: store the data in an <AHREF="arrays.html#ARRAYREF">array</A> and step through the array elements.</P><P>Having already done the <SPANCLASS="QUOTE">"heavy lifting"</SPAN>, now convert the loops in the example to <ICLASS="EMPHASIS"> until loops</I>.</P></DD><DT><BCLASS="COMMAND">Changing the line spacing of a text file</B></DT><DD><P>Write a script that reads each line of a target file, then writes the line back to <TTCLASS="FILENAME">stdout</TT>, but with an extra blank line following. This has the effect of <ICLASS="EMPHASIS">double-spacing</I> the file.</P><P>Include all necessary code to check whether the script gets the necessary command line argument (a filename), and whether the specified file exists.</P><P>When the script runs correctly, modify it to <ICLASS="EMPHASIS">triple-space</I> the target file.</P><P>Finally, write a script to remove all blank lines from the target file, <ICLASS="EMPHASIS">single-spacing</I> it.</P></DD><DT><BCLASS="COMMAND">Backwards Listing</B></DT><DD><P>Write a script that echoes itself to <TTCLASS="FILENAME">stdout</TT>, but <ICLASS="EMPHASIS">backwards</I>.</P></DD><DT><BCLASS="COMMAND">Automatically Decompressing Files</B></DT><DD><P>Given a list of filenames as input, this script queries each target file (parsing the output of the <AHREF="filearchiv.html#FILEREF">file</A> command) for the type of compression used on it. Then the script automatically invokes the appropriate decompression command (<BCLASS="COMMAND">gunzip</B>, <BCLASS="COMMAND">bunzip2</B>, <BCLASS="COMMAND">unzip</B>, <BCLASS="COMMAND">uncompress</B>, or whatever). If a target file is not compressed, the script emits a warning message, but takes no other action on that particular file.</P></DD><DT><BCLASS="COMMAND">Unique System ID</B></DT><DD><P>Generate a <SPANCLASS="QUOTE">"unique"</SPAN> 6-digit hexadecimal identifier for your computer. Do <ICLASS="EMPHASIS">not</I> use the flawed <AHREF="system.html#HOSTIDREF">hostid</A> command. Hint: <BCLASS="COMMAND"><AHREF="filearchiv.html#MD5SUMREF">md5sum</A> <TTCLASS="FILENAME">/etc/passwd</TT></B>, then select the first 6 digits of output.</P></DD><DT><BCLASS="COMMAND">Backup</B></DT><DD><P>Archive as a <SPANCLASS="QUOTE">"tarball"</SPAN> (<TTCLASS="FILENAME">*.tar.gz</TT> file) all the files in your home directory tree (<TTCLASS="FILENAME">/home/your-name</TT>) that have been modified in the last 24 hours. Hint: use <AHREF="moreadv.html#FINDREF">find</A>.</P></DD><DT><BCLASS="COMMAND">Primes</B></DT><DD><P>Print (to stdout) all prime numbers between 60000 and 63000. The output should be nicely formatted in columns (hint: use <AHREF="internal.html#PRINTFREF">printf</A>).</P></DD><DT><BCLASS="COMMAND">Lottery Numbers</B></DT><DD><P>One type of lottery involves picking five different numbers, in the range of 1 - 50. Write a script that generates five pseudorandom numbers in this range, <ICLASS="EMPHASIS">with no duplicates</I>. The script will give the option of echoing the numbers to <TTCLASS="FILENAME">stdout</TT> or saving them to a file, along with the date and time the particular number set was generated.</P></DD></DL></DIV><DIVCLASS="VARIABLELIST"><P><B><ANAME="EXMEDIUM1"></A>INTERMEDIATE</B></P><DL><DT><BCLASS="COMMAND">Integer or String</B></DT><DD><P>Write a script <AHREF="functions.html#FUNCTIONREF">function</A> that determines if an argument passed to it is an integer or a string. The function will return TRUE (0) if passed an integer, and FALSE (1) if passed a string.</P><P>Hint: What does the following expression return when <TTCLASS="VARNAME">$1</TT> is <ICLASS="EMPHASIS">not</I> an integer?</P><P><TTCLASS="VARNAME">expr $1 + 0</TT></P></DD><DT><BCLASS="COMMAND">Managing Disk Space</B></DT><DD><P>List, one at a time, all files larger than 100K in the <TTCLASS="FILENAME">/home/username</TT> directory tree. Give the user the option to delete or compress the file, then proceed to show the next one. Write to a logfile the names of all deleted files and the deletion times.</P></DD><DT><BCLASS="COMMAND">Removing Inactive Accounts</B></DT><DD><P>Inactive accounts on a network waste disk space and may become a security risk. Write an administrative script (to be invoked by <ICLASS="EMPHASIS">root</I> or the <AHREF="system.html#CRONREF">cron daemon</A>) that checks for and deletes user accounts that have not been accessed within the last 90 days.</P></DD><DT><BCLASS="COMMAND">Enforcing Disk Quotas</B></DT><DD><P>Write a script for a multi-user system that checks users' disk usage. If a user surpasses the preset limit (100 MB, for example) in her <TTCLASS="FILENAME">/home/username</TT> directory, then the script will automatically send her a warning e-mail.</P><P>The script will use the <AHREF="system.html#DUREF">du</A> and <AHREF="communications.html#COMMMAIL1">mail</A> commands. As an option, it will allow setting and enforcing quotas using the <AHREF="system.html#QUOTAREF">quota</A> and <AHREF="system.html#SETQUOTAREF">setquota</A> commands.</P></DD><DT><BCLASS="COMMAND">Logged in User Information</B></DT><DD><P>For all logged in users, show their real names and the time and date of their last login.</P><P>Hint: use <AHREF="system.html#WHOREF">who</A>, <AHREF="system.html#LASTLOGREF">lastlog</A>, and parse <TTCLASS="FILENAME">/etc/passwd</TT>.</P></DD><DT><BCLASS="COMMAND">Safe Delete</B></DT><DD><P>Write, as a script, a <SPANCLASS="QUOTE">"safe"</SPAN> delete command, <TTCLASS="FILENAME">srm.sh</TT>. Filenames passed as command-line arguments to this script are not deleted, but instead <AHREF="filearchiv.html#GZIPREF">gzipped</A> if not already compressed (use <AHREF="filearchiv.html#FILEREF">file</A> to check), then moved to a <TTCLASS="FILENAME">/home/username/trash</TT> directory. At invocation, the script checks the <SPANCLASS="QUOTE">"trash"</SPAN> directory for files older than 48 hours and deletes them.</P></DD><DT><BCLASS="COMMAND">Making Change</B></DT><DD><P>What is the most efficient way to make change for $1.68, using only coins in common circulations (up to 25c)? It's 6 quarters, 1 dime, a nickel, and three cents.</P><P>Given any arbitrary command line input in dollars and cents ($*.??), calculate the change, using the minimum number of coins. If your home country is not the United States, you may use your local currency units instead. The script will need to parse the command line input, then change it to multiples of the smallest monetary unit (cents or whatever). Hint: look at <AHREF="functions.html#EX61">Example 23-8</A>.</P></DD><DT><BCLASS="COMMAND">Quadratic Equations</B></DT><DD><P>Solve a <SPANCLASS="QUOTE">"quadratic"</SPAN> equation of the form <ICLASS="EMPHASIS">Ax^2 + Bx + C = 0</I>. Have a script take as arguments the coefficients, <TTCLASS="USERINPUT"><B>A</B></TT>, <TTCLASS="USERINPUT"><B>B</B></TT>, and <TTCLASS="USERINPUT"><B>C</B></TT>, and return the solutions to four decimal places.</P><P>Hint: pipe the coefficients to <AHREF="mathc.html#BCREF">bc</A>, using the well-known formula, <ICLASS="EMPHASIS">x = ( -B +/- sqrt( B^2 - 4AC ) ) / 2A</I>.</P></DD><DT><BCLASS="COMMAND">Sum of Matching Numbers</B></DT><DD><P>Find the sum of all five-digit numbers (in the range 10000 - 99999) containing <ICLASS="EMPHASIS">exactly two</I> out of the following set of digits: { 4, 5, 6 }. These may repeat within the same number, and if so, they count once for each occurrence.</P><P>Some examples of matching numbers are 42057, 74638, and 89515.</P></DD><DT><BCLASS="COMMAND">Lucky Numbers</B></DT><DD><P>A "lucky number" is one whose individual digits add up to 7, in successive additions. For example, 62431 is a "lucky number" (6 + 2 + 4 + 3 + 1 = 16, 1 + 6 = 7). Find all the "lucky numbers" between 1000 and 10000.</P></DD><DT><BCLASS="COMMAND">Alphabetizing a String</B></DT><DD><P>Alphabetize (in ASCII order) an arbitrary string read from the command line.</P></DD><DT><BCLASS="COMMAND">Parsing</B></DT><DD><P>Parse <TTCLASS="FILENAME">/etc/passwd</TT>, and output its contents in nice, easy-to-read tabular form.</P></DD><DT><BCLASS="COMMAND">Logging Logins</B></DT><DD><P>Parse <TTCLASS="FILENAME">/var/log/messages</TT> to produce a nicely formatted file of user logins and login times. The script may need to run as root. (Hint: Search for the string <SPANCLASS="QUOTE">"LOGIN."</SPAN>)</P></DD><DT><BCLASS="COMMAND">Pretty-Printing a Data File</B></DT><DD><P>Certain database and spreadsheet packages use save-files with <ICLASS="EMPHASIS">comma-separated values</I> (CSVs). Other applications often need to parse these files.</P><P>Given a data file with comma-separated fields, of the form: <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 Jones,Bill,235 S. Williams St.,Denver,CO,80221,(303) 244-7989 2 Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612 3 ...</PRE></TD></TR></TABLE> Reformat the data and print it out to <TTCLASS="FILENAME">stdout</TT> in labeled, evenly-spaced columns.</P></DD><DT><BCLASS="COMMAND">Justification</B></DT><DD><P>Given ASCII text input either from <TTCLASS="FILENAME">stdin</TT> or a file, adjust the word spacing to right-justify each line to a user-specified line-width, then send the output to <TTCLASS="FILENAME">stdout</TT>.</P></DD><DT><BCLASS="COMMAND">Mailing List</B></DT><DD><P>Using the <AHREF="communications.html#COMMMAIL1">mail</A> command, write a script that manages a simple mailing list. The script automatically e-mails the monthly company newsletter, read from a specified text file, and sends it to all the addresses on the mailing list, which the script reads from another specified file.</P></DD><DT><BCLASS="COMMAND">Generating Passwords</B></DT><DD><P>Generate pseudorandom 8-character passwords, using characters in the ranges [0-9], [A-Z], [a-z]. Each password must contain at least two digits.</P></DD><DT><BCLASS="COMMAND">Checking for Broken Links</B></DT><DD><P>Using <AHREF="communications.html#LYNXREF">lynx</A> with the <TTCLASS="OPTION">-traversal</TT> option, write a script that checks a Web site for broken links.</P></DD></DL></DIV><DIVCLASS="VARIABLELIST"><P><B><ANAME="EXDIFFICULT1"></A>DIFFICULT</B></P><DL><DT><B
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -