Parent Directory
|
Revision Log
Revision 1 - (view) (download) (as text)
| 1 : | root | 1 | \input texinfo @c -*-texinfo-*- |
| 2 : | @c ********************************************************************* | ||
| 3 : | @c | ||
| 4 : | @c This is a TEXINFO file. It generates both TEX documentation and | ||
| 5 : | @c the "on line" documentation "info" files. | ||
| 6 : | @c | ||
| 7 : | @c The file is structured like a programming language. Each chapter | ||
| 8 : | @c starts with a chapter comment. | ||
| 9 : | @c | ||
| 10 : | @c Menus list the subsections so that an online inforeader can parse | ||
| 11 : | @c the file hierachically. | ||
| 12 : | @c | ||
| 13 : | @c Each time you add or change a node, you need to update the | ||
| 14 : | @c menus and forward/backward references. You can do this from | ||
| 15 : | @c emacs automatically by writing: | ||
| 16 : | @c | ||
| 17 : | @c ESC-x texinfo-every-node-update | ||
| 18 : | @c ESC-x texinfo-all-menus-update | ||
| 19 : | @c ESC-x texinfo-master-menu | ||
| 20 : | @c | ||
| 21 : | @c In practice you can just type the first few letters and hit TAB | ||
| 22 : | @c to write these long names. | ||
| 23 : | @c | ||
| 24 : | @c Last change: MB 31/08/95 | ||
| 25 : | @c | ||
| 26 : | @c *********************************************************************** | ||
| 27 : | @c %** start of header | ||
| 28 : | @setfilename unix.info | ||
| 29 : | @settitle The unix programming environment | ||
| 30 : | @setchapternewpage odd | ||
| 31 : | @c %** end of header | ||
| 32 : | |||
| 33 : | @include version.texi | ||
| 34 : | |||
| 35 : | @titlepage | ||
| 36 : | @title The unix programming environment | ||
| 37 : | @subtitle Edition @value{EDITION}, @value{UPDATED} | ||
| 38 : | |||
| 39 : | @author Mark Burgess | ||
| 40 : | @author Centre of Science and Technology | ||
| 41 : | @author Faculty of Engineering, Oslo College | ||
| 42 : | |||
| 43 : | @c @smallbook | ||
| 44 : | |||
| 45 : | @page | ||
| 46 : | @vskip 0pt plus 1filll | ||
| 47 : | @ifinfo | ||
| 48 : | Copyright @copyright{} 1996/7 Mark Burgess | ||
| 49 : | |||
| 50 : | Permission is granted to make and distribute verbatim copies of this | ||
| 51 : | manual provided the copyright notice and this permission notice are | ||
| 52 : | preserved on all copies. | ||
| 53 : | |||
| 54 : | Permission is granted to copy and distribute modified versions of | ||
| 55 : | this manual under the conditions for verbatim copying, provided also | ||
| 56 : | that the section entitled "GNU General Public License" is included | ||
| 57 : | exactly as in the original, and provided that the entire resulting | ||
| 58 : | derived work is distributed under the terms of a permission notice | ||
| 59 : | identical to this one. | ||
| 60 : | |||
| 61 : | Permission is granted to copy and distribute translations of this | ||
| 62 : | manual into another language, under the above conditions for modified | ||
| 63 : | versions, except that the section entitled "GNU General Public License" | ||
| 64 : | may be included in a translation approved by the author instead of in | ||
| 65 : | the original English. | ||
| 66 : | @end ifinfo | ||
| 67 : | Copyright @copyright{} 1996/7 Mark Burgess | ||
| 68 : | |||
| 69 : | Permission is granted to make and distribute verbatim copies of this | ||
| 70 : | manual provided the copyright notice and this permission notice are | ||
| 71 : | preserved on all copies. | ||
| 72 : | |||
| 73 : | Permission is granted to copy and distribute modified versions of | ||
| 74 : | this manual under the conditions for verbatim copying, provided also | ||
| 75 : | that the section entitled "GNU General Public License" is included | ||
| 76 : | exactly as in the original, and provided that the entire resulting | ||
| 77 : | derived work is distributed under the terms of a permission notice | ||
| 78 : | identical to this one. | ||
| 79 : | |||
| 80 : | Permission is granted to copy and distribute translations of this | ||
| 81 : | manual into another language, under the above conditions for modified | ||
| 82 : | versions, except that the section entitled "GNU General Public License" | ||
| 83 : | may be included in a translation approved by the author instead of in | ||
| 84 : | the original English. | ||
| 85 : | @end titlepage | ||
| 86 : | |||
| 87 : | @ifinfo | ||
| 88 : | @node Top, Comment, (dir), (dir) | ||
| 89 : | @top UNIX | ||
| 90 : | |||
| 91 : | @end ifinfo | ||
| 92 : | |||
| 93 : | @c ********************************************************************** | ||
| 94 : | @c INTRO | ||
| 95 : | @c ********************************************************************** | ||
| 96 : | |||
| 97 : | @unnumbered Foreword | ||
| 98 : | |||
| 99 : | This is a revised version of the UNIX compendium which is | ||
| 100 : | available in printed form and online via the WWW and info | ||
| 101 : | hypertext readers. It forms the basis for a one or two semester | ||
| 102 : | course in UNIX. The most up-to-date version of this manual | ||
| 103 : | can be found at | ||
| 104 : | |||
| 105 : | @smallexample | ||
| 106 : | http://www.iu.hioslo.no/~mark/unix/unix.html. | ||
| 107 : | @end smallexample | ||
| 108 : | |||
| 109 : | It is a reference guide which contains enough to help you to find what | ||
| 110 : | you need from other sources. It is not (and probably can never be) | ||
| 111 : | a complete and self-contained work. Certain topics are covered | ||
| 112 : | in more detail than others. Some topics are included for future | ||
| 113 : | reference and are not intended to be part of an introductory course, | ||
| 114 : | but will probably be useful later. The chapter on X11 programming | ||
| 115 : | has been deleted for the time being. | ||
| 116 : | |||
| 117 : | Comments to Mark.Burgess@@iu.hioslo.no | ||
| 118 : | |||
| 119 : | Oslo, June 1996 | ||
| 120 : | |||
| 121 : | @c ********************************************************************** | ||
| 122 : | @c CHAPTER | ||
| 123 : | @c ********************************************************************** | ||
| 124 : | |||
| 125 : | @menu | ||
| 126 : | * Comment:: | ||
| 127 : | * Overview:: | ||
| 128 : | * Getting started:: | ||
| 129 : | * The login environment:: | ||
| 130 : | * Files and access:: | ||
| 131 : | * C shell:: | ||
| 132 : | * Bourne shell:: | ||
| 133 : | * Perl:: | ||
| 134 : | * WWW and CGI programming:: | ||
| 135 : | * C programming:: | ||
| 136 : | * Network programming:: | ||
| 137 : | * Programming idioms:: | ||
| 138 : | * Variable Index:: | ||
| 139 : | * Concept Index:: | ||
| 140 : | @end menu | ||
| 141 : | |||
| 142 : | @node Comment, Overview, Top, Top | ||
| 143 : | @unnumbered Welcome | ||
| 144 : | |||
| 145 : | If you are coming to unix for the first time, from a Windows or | ||
| 146 : | MacIntosh environment, be prepared for a rather different culture than | ||
| 147 : | the one you are used to. Unix is not about `products' and off-the-shelf | ||
| 148 : | software, it is about open standards, free software and the ability to | ||
| 149 : | change just about everything. | ||
| 150 : | |||
| 151 : | @itemize @bullet | ||
| 152 : | |||
| 153 : | @item | ||
| 154 : | What you personally might perceive as user friendliness in other | ||
| 155 : | systems, others might perceive as annoying time wasting. Unix offers you | ||
| 156 : | just about every level of friendliness and unfriendliness, if you choose | ||
| 157 : | your programs right. In this book, we take the programmer's point of | ||
| 158 : | view. | ||
| 159 : | |||
| 160 : | @item | ||
| 161 : | Unix is about functionality, not about simplicity. Be prepared | ||
| 162 : | for powerful, not necessarily `simple' solutions. | ||
| 163 : | |||
| 164 : | @end itemize | ||
| 165 : | |||
| 166 : | @noindent | ||
| 167 : | You should approach Unix the way you should approach any new | ||
| 168 : | system: with an open mind. The journey begins... | ||
| 169 : | |||
| 170 : | |||
| 171 : | @node Overview, Getting started, Comment, Top | ||
| 172 : | @chapter Overview | ||
| 173 : | |||
| 174 : | @emph{In this manual the word "host" is used to refer to a single computer | ||
| 175 : | system -- i.e. a single machine which has a name termed its "hostname".} | ||
| 176 : | |||
| 177 : | @c ----------------------------------------------------------------------- | ||
| 178 : | @c SECTION | ||
| 179 : | @c ----------------------------------------------------------------------- | ||
| 180 : | |||
| 181 : | @menu | ||
| 182 : | * What is unix?:: | ||
| 183 : | * Flavours of unix:: | ||
| 184 : | * How to use this reference guide:: | ||
| 185 : | * NEVER-DOs in UNIX:: | ||
| 186 : | * What you should know before starting:: | ||
| 187 : | * The superuser and nobody:: | ||
| 188 : | * The file hierarchy :: | ||
| 189 : | * Symbolic links:: | ||
| 190 : | * Hard links:: | ||
| 191 : | @end menu | ||
| 192 : | |||
| 193 : | @node What is unix?, Flavours of unix, Overview, Overview | ||
| 194 : | @section What is unix? | ||
| 195 : | |||
| 196 : | @cindex UNIX | ||
| 197 : | @cindex UNIX history | ||
| 198 : | Unix is one of the most important operating system in use | ||
| 199 : | today, perhaps even @emph{the} most important. Since its invention | ||
| 200 : | around the beginning of the 1970s it has been an object of continual | ||
| 201 : | research and development. UNIX is not popular because it is the best | ||
| 202 : | operating system one could imagine, but because it is an extremely | ||
| 203 : | flexible system which is easy to extend and modify. It is an ideal | ||
| 204 : | platform for developing new ideas. | ||
| 205 : | |||
| 206 : | Much of the success of UNIX may be attributed to the rapid pace of its | ||
| 207 : | development (a development to which all of its users have been able to | ||
| 208 : | contribute) its efficiency at running programs and the many powerful | ||
| 209 : | tools which have been written for it over the years, such as the C | ||
| 210 : | programming language, @code{make}, shell, @code{lex} and @code{yacc} and | ||
| 211 : | many others. UNIX was written by programmers for programmers. It is | ||
| 212 : | popular in situations where a lot of computing power is required and for | ||
| 213 : | database applications, where timesharing is critical. In contrast to | ||
| 214 : | some operating systems, UNIX performs equally well on large scale | ||
| 215 : | computers (with many processors) and small computers which fit in your | ||
| 216 : | suitcase! | ||
| 217 : | |||
| 218 : | All of the basic mechanisms required of a multi-user operating system | ||
| 219 : | are present in UNIX. During the last few years it has become ever more | ||
| 220 : | popular and has formed the basis of newer, though less mature, systems | ||
| 221 : | like NT. One reason for this that now computers have now become powerful | ||
| 222 : | enough to run UNIX effectively. UNIX places burdens on the resources of | ||
| 223 : | a computer, since it expects to be able to run potentially many programs | ||
| 224 : | simultaneously. | ||
| 225 : | |||
| 226 : | @cindex DOS | ||
| 227 : | If you are coming to UNIX from DOS you may well be used to using | ||
| 228 : | applications software or helpful interactive utilities to solve every | ||
| 229 : | problem. UNIX is not usually like this: the operating system has much | ||
| 230 : | greater functionality and provides the possibilities for making your | ||
| 231 : | own, so it is less common to find applications software which implements | ||
| 232 : | the same things. UNIX has long been in the hands of academics who are | ||
| 233 : | used to making their own applications or writing their own programs, | ||
| 234 : | whereas as the DOS world has been driven by businesses who are willing | ||
| 235 : | to spend money on software. For that reason commerical UNIX software is | ||
| 236 : | often very expensive and therefore not available at this college. On the | ||
| 237 : | other hand, the flexibility of UNIX means that it is easy to write | ||
| 238 : | programs and it is possible to fetch gigabytes of @emph{free software} from the | ||
| 239 : | internet to suit your needs. It may not look like what you are used to | ||
| 240 : | on your PC, but then you have to remember that UNIX users are a | ||
| 241 : | different kind of animal altogether | ||
| 242 : | |||
| 243 : | Like all operating systems, UNIX has many faults. The biggest problem | ||
| 244 : | for any operating system is that it evolves without being redesigned. | ||
| 245 : | Operating systems evolve as more and more patches and hacks are applied | ||
| 246 : | to solve day-to-day problems. The result is either a mess which works | ||
| 247 : | somehow (like UNIX) or a blank refusal to change (like DOS or | ||
| 248 : | MacIntosh). From a practical perspective, Unix is important and | ||
| 249 : | successful because it is a multi-process system which | ||
| 250 : | |||
| 251 : | @itemize @bullet | ||
| 252 : | |||
| 253 : | @item | ||
| 254 : | has an enormous functionality built in, and the capacity to | ||
| 255 : | adapt itself to changing technologies, | ||
| 256 : | |||
| 257 : | @item | ||
| 258 : | is relatively portable, | ||
| 259 : | |||
| 260 : | @item | ||
| 261 : | is good at sharing resources (but not so good at security), | ||
| 262 : | |||
| 263 : | @item | ||
| 264 : | has tools which are each developed to do @emph{one thing well}, | ||
| 265 : | |||
| 266 : | @item | ||
| 267 : | allows these tools to be combined in every imaginable way, | ||
| 268 : | using pipes and channeling of data streams, | ||
| 269 : | |||
| 270 : | @item | ||
| 271 : | incorporates networking almost trivially, because all the right | ||
| 272 : | mechanisms are already there for providing services and sharing, | ||
| 273 : | building client-server pairs etc,. | ||
| 274 : | |||
| 275 : | @item | ||
| 276 : | it is very adaptable and is often used to develop | ||
| 277 : | new ideas because of the rich variety of tools it possesses. | ||
| 278 : | |||
| 279 : | @end itemize | ||
| 280 : | |||
| 281 : | Unix has some problems: it is old, it contains a lot of rubbish which no | ||
| 282 : | one ever bothered to throw away. Although it develops quickly (at light | ||
| 283 : | speed compared to either DOS or MacIntosh) the user interface has been | ||
| 284 : | the slowest thing to change. Unix is not user-friendly for beginners, it | ||
| 285 : | is user-friendly for advanced users: it is made for users who | ||
| 286 : | @emph{know} about computing. It sometimes makes simple things difficult, | ||
| 287 : | but above all it makes things possible! | ||
| 288 : | |||
| 289 : | The aim of this introduction is to | ||
| 290 : | |||
| 291 : | @itemize @bullet | ||
| 292 : | |||
| 293 : | @item | ||
| 294 : | introduce the unix system basics and user interface, | ||
| 295 : | |||
| 296 : | @item | ||
| 297 : | develop the unix philosophy of using and combining tools, | ||
| 298 : | |||
| 299 : | @item | ||
| 300 : | learn how to make new tools and write software, | ||
| 301 : | |||
| 302 : | @item | ||
| 303 : | learn how to understand existing software. | ||
| 304 : | |||
| 305 : | @end itemize | ||
| 306 : | |||
| 307 : | @noindent | ||
| 308 : | To accomplish this task, we must first learn something about | ||
| 309 : | the shell (the way in which UNIX starts programs). Later we shall | ||
| 310 : | learn how to solve more complex problems using Perl and C. | ||
| 311 : | Each of these is a language which can be used to put UNIX to | ||
| 312 : | work. We must also learn when to use which tool, so that | ||
| 313 : | we do not waste time and effort. Typical uses for these | ||
| 314 : | different interfaces are | ||
| 315 : | |||
| 316 : | @table @emph | ||
| 317 : | |||
| 318 : | @item shell | ||
| 319 : | Command line interaction, making scripts which perform simple | ||
| 320 : | jobs such as running programs in batch, installing new software, | ||
| 321 : | simple system configuration and administration. | ||
| 322 : | @cindex shell | ||
| 323 : | |||
| 324 : | @item perl | ||
| 325 : | Text interpretation, text formatting, output filters, mail | ||
| 326 : | robots, WWW cgi (common gateway interface) scripts in forms, | ||
| 327 : | password testing, simple database manipulation, simple client-server | ||
| 328 : | applications. | ||
| 329 : | @cindex perl | ||
| 330 : | |||
| 331 : | @item C | ||
| 332 : | Nearly all of UNIX is written in C. Any program which cannot | ||
| 333 : | be solved quickly using shell or perl can be written in C. | ||
| 334 : | One advantage is that C is a compiled language and many simple | ||
| 335 : | errors can be caught at compile time. | ||
| 336 : | @cindex C | ||
| 337 : | |||
| 338 : | @end table | ||
| 339 : | |||
| 340 : | Much of UNIX's recent popularity has been a result of its networking | ||
| 341 : | abilities: unix is the backbone of the internet. No other widely | ||
| 342 : | available system could keep the internet alive today. | ||
| 343 : | |||
| 344 : | Once you have mastered the unix interface and philosophy you | ||
| 345 : | will find that i) the PC and MacIntosh window environments seem | ||
| 346 : | to be easy to use, but simplistic and primitive by comparison; ii) UNIX is far | ||
| 347 : | from being the perfect operating system---it has a whole different | ||
| 348 : | set of problems and flaws. | ||
| 349 : | @cindex Windows on PC | ||
| 350 : | @cindex MacIntosh | ||
| 351 : | @cindex PC windows | ||
| 352 : | |||
| 353 : | The operating system of the future will not be UNIX as we see | ||
| 354 : | it today, nor will is be DOS or MacIntosh, but one thing is for | ||
| 355 : | certain: it will owe a lot to the UNIX operating system and will | ||
| 356 : | contain many of the tools and mechanisms we shall describe below. | ||
| 357 : | |||
| 358 : | @c ----------------------------------------------------------------------- | ||
| 359 : | @c SECTION | ||
| 360 : | @c ----------------------------------------------------------------------- | ||
| 361 : | |||
| 362 : | @node Flavours of unix, How to use this reference guide, What is unix?, Overview | ||
| 363 : | @section Flavours of unix | ||
| 364 : | |||
| 365 : | @cindex AT&T | ||
| 366 : | @cindex BSD | ||
| 367 : | @cindex System V | ||
| 368 : | @cindex System 5 | ||
| 369 : | |||
| 370 : | Unix is not a single operating system. It has branched out in many | ||
| 371 : | different directions since it was introduced by AT&T. The most | ||
| 372 : | important @samp{fork()} in its history happened early on when the | ||
| 373 : | university of Berkeley, California created the BSD (Berkeley Software | ||
| 374 : | Distribution), adding network support and the C-shell. | ||
| 375 : | |||
| 376 : | Here are some of | ||
| 377 : | the most common implementations of unix. | ||
| 378 : | |||
| 379 : | @table @emph | ||
| 380 : | @item BSD: | ||
| 381 : | Berkeley, BSD | ||
| 382 : | |||
| 383 : | @item SunOS: | ||
| 384 : | Sun Microsystems, BSD/sys 5 | ||
| 385 : | |||
| 386 : | @item Solaris: | ||
| 387 : | Sun Microsystems, Sys 5/BSD | ||
| 388 : | |||
| 389 : | @item Ultrix: | ||
| 390 : | Digital Equipment Corperation, BSD | ||
| 391 : | |||
| 392 : | @item OSF 1: | ||
| 393 : | Digital Equipment Corperation, BSD/sys 5 | ||
| 394 : | |||
| 395 : | @item HPUX: | ||
| 396 : | Hewlett-Packard, Sys 5 | ||
| 397 : | |||
| 398 : | @item AIX: | ||
| 399 : | IBM, Sys 5 / BSD | ||
| 400 : | |||
| 401 : | @item IRIX: | ||
| 402 : | Silicon Graphics, Sys 5 | ||
| 403 : | |||
| 404 : | @item GNU/Linux: | ||
| 405 : | GNU, BSD/Posix | ||
| 406 : | |||
| 407 : | @end table | ||
| 408 : | |||
| 409 : | @c ----------------------------------------------------------------------- | ||
| 410 : | @c SECTION | ||
| 411 : | @c ----------------------------------------------------------------------- | ||
| 412 : | |||
| 413 : | @node How to use this reference guide, NEVER-DOs in UNIX, Flavours of unix, Overview | ||
| 414 : | @section How to use this reference guide | ||
| 415 : | |||
| 416 : | This programming guide is something between a user manual and a tutorial. | ||
| 417 : | The information contained here should be sufficient to get you started | ||
| 418 : | with the unix system, but it is far from complete. | ||
| 419 : | |||
| 420 : | To use this programming guide, you will need to work through the basics | ||
| 421 : | from each chapter. You will find that there is much more information here than | ||
| 422 : | you need straight away, so try not to be overwhelmed by the amount of material. | ||
| 423 : | Use the contents and the indices at the back to find the information | ||
| 424 : | you need. If you are following a one-semester UNIX course, you should | ||
| 425 : | probably concentrate on the following: | ||
| 426 : | |||
| 427 : | @itemize @bullet | ||
| 428 : | @item | ||
| 429 : | The remainder of this introduction | ||
| 430 : | @item | ||
| 431 : | The detailed knowledge of the C shell | ||
| 432 : | @item | ||
| 433 : | An appreciation of the Bourne shell | ||
| 434 : | @item | ||
| 435 : | A detailed knowledge of Perl, guided by chapter 6. This chapter provides | ||
| 436 : | pointers on how to get started in perl. It is not a substitute for the | ||
| 437 : | perl book. | ||
| 438 : | @item | ||
| 439 : | Everything in chapter 7 about C programming. This chapter is written in note | ||
| 440 : | form, since it is assumed that you know a lot about C programming already. | ||
| 441 : | @item | ||
| 442 : | A sound appreciation of chapter 8 on network programming. | ||
| 443 : | |||
| 444 : | @end itemize | ||
| 445 : | |||
| 446 : | The @emph{only} way to learn UNIX is to sit down and try it. As with any | ||
| 447 : | new thing, it is a pain to get started, but once you are started, you | ||
| 448 : | will probably come to agree that UNIX contains a wealth of possibilities, | ||
| 449 : | perhaps more than you had ever though was possible or useful! | ||
| 450 : | |||
| 451 : | One of the advantages of the UNIX system is that the entire UNIX manual | ||
| 452 : | is available on-line. You should get used to looking for information in | ||
| 453 : | the online manual pages. For instance, suppose you do not remember | ||
| 454 : | how to create a new directory, you could do the following: | ||
| 455 : | |||
| 456 : | @smallexample | ||
| 457 : | nexus% man -k dir | ||
| 458 : | |||
| 459 : | dir ls (1) - list contents of directories | ||
| 460 : | dirname dirname (1) - strip non-directory suffix from file name | ||
| 461 : | dirs bash (1) - bash built-in commands, see bash(1) | ||
| 462 : | find find (1) - search for files in a directory hierarchy | ||
| 463 : | ls ls (1) - list contents of directories | ||
| 464 : | mkdir mkdir (1) - make directories | ||
| 465 : | pwd pwd (1) - print name of current/working directory | ||
| 466 : | rmdir rmdir (1) - remove empty directories | ||
| 467 : | @end smallexample | ||
| 468 : | |||
| 469 : | @cindex Making directories | ||
| 470 : | @vindex mkdir | ||
| 471 : | @cindex mkdir | ||
| 472 : | @cindex apropos | ||
| 473 : | @vindex apropos | ||
| 474 : | @vindex man -k | ||
| 475 : | @cindex Finding commands | ||
| 476 : | @noindent | ||
| 477 : | The @samp{man -k} command looks for a keyword in the manual and lists | ||
| 478 : | all the references it finds. The command @samp{apropos} is completely | ||
| 479 : | equivalent to @samp{man -k}. Having discovered that the command to | ||
| 480 : | create a directory is @samp{mkdir} you can now look up the specific | ||
| 481 : | manaul page on @samp{mkdir} to find out how to use it: | ||
| 482 : | |||
| 483 : | @smallexample | ||
| 484 : | man mkdir | ||
| 485 : | @end smallexample | ||
| 486 : | |||
| 487 : | @noindent | ||
| 488 : | Some but no all of the UNIX commands also have a help option which is | ||
| 489 : | activated with the @samp{-h} or @samp{--help} command-line option. | ||
| 490 : | @cindex Help function for commands | ||
| 491 : | @vindex -h | ||
| 492 : | @vindex --help | ||
| 493 : | |||
| 494 : | @smallexample | ||
| 495 : | dax% mkdir --help | ||
| 496 : | Usage: mkdir [OPTION] DIRECTORY... | ||
| 497 : | |||
| 498 : | -p, --parents no error if existing, make parent directories as needed | ||
| 499 : | -m, --mode=MODE set permission mode (as in chmod), not 0777 - umask | ||
| 500 : | --help display this help and exit | ||
| 501 : | --version output version information and exit | ||
| 502 : | dax% | ||
| 503 : | |||
| 504 : | @end smallexample | ||
| 505 : | |||
| 506 : | |||
| 507 : | @c ----------------------------------------------------------------------- | ||
| 508 : | @c SECTION | ||
| 509 : | @c ----------------------------------------------------------------------- | ||
| 510 : | |||
| 511 : | @node NEVER-DOs in UNIX, What you should know before starting, How to use this reference guide, Overview | ||
| 512 : | @section NEVER-DO's in UNIX | ||
| 513 : | |||
| 514 : | @cindex Never do in unix | ||
| 515 : | |||
| 516 : | There are some things that you should never do in UNIX. Some of these | ||
| 517 : | will cause you more serious problems | ||
| 518 : | than others. You can make your own list as you discover more. | ||
| 519 : | |||
| 520 : | @itemize @bullet | ||
| 521 : | |||
| 522 : | @item | ||
| 523 : | You should NEVER EVER switch off the power on a Unix computer unless you | ||
| 524 : | know what you are doing. A Unix machine is not like a PC running | ||
| 525 : | DOS. Even when you are not doing anything, the system is working in the | ||
| 526 : | background. If you switch off the power, you could interrupt the system | ||
| 527 : | while it is writing to the disk drive and destroy your disk. You must | ||
| 528 : | also remember that several users might be using the system even though | ||
| 529 : | you cannot see them: they do not have to be sitting at the machine, they | ||
| 530 : | could be logged in over the network. If you switch off the power, you | ||
| 531 : | might ruin their valuable work. | ||
| 532 : | |||
| 533 : | @item | ||
| 534 : | Once you have deleted a UNIX file using @code{rm} it is impossible | ||
| 535 : | to recover it! Don't use wildcards with @code{rm} without thinking | ||
| 536 : | quite carefully about what you are doing! It has happened to very many | ||
| 537 : | users throughout the history of UNIX that one tries to type | ||
| 538 : | @smallexample | ||
| 539 : | rm *~ | ||
| 540 : | @end smallexample | ||
| 541 : | but instead, by a slip of the hand, one writes | ||
| 542 : | @smallexample | ||
| 543 : | rm * ~ | ||
| 544 : | @end smallexample | ||
| 545 : | Unix then takes these wildcards in turn, so that the first command is | ||
| 546 : | @code{rm *} which deletes all of your files! BE CAREFUL! | ||
| 547 : | |||
| 548 : | @cindex undelete | ||
| 549 : | @cindex delete | ||
| 550 : | |||
| 551 : | @item | ||
| 552 : | Don't ever call a program or an important file @file{core}. Many | ||
| 553 : | scripts go around deleting files called @file{core} because the, when a | ||
| 554 : | program crashes, UNIX dumps the entire kernel image to a file called | ||
| 555 : | @file{core} and these files use up a lot of disk space. If you call a | ||
| 556 : | file @file{core} it might get deleted! | ||
| 557 : | @cindex core | ||
| 558 : | |||
| 559 : | @item | ||
| 560 : | Don't call test programs @code{test}. There is a UNIX command | ||
| 561 : | which is already called test and chances are that when you try to | ||
| 562 : | run your program you will start the UNIX command instead. This | ||
| 563 : | can cause a lot of confusion because the UNIX command doesn't seem | ||
| 564 : | to do very much at all! | ||
| 565 : | @end itemize | ||
| 566 : | @cindex test programs | ||
| 567 : | @cindex test, don't call your program this | ||
| 568 : | |||
| 569 : | @c ----------------------------------------------------------------------- | ||
| 570 : | @c SECTION | ||
| 571 : | @c ----------------------------------------------------------------------- | ||
| 572 : | |||
| 573 : | @node What you should know before starting, The superuser and nobody, NEVER-DOs in UNIX, Overview | ||
| 574 : | @section What you should know before starting | ||
| 575 : | |||
| 576 : | @c ..................................................... | ||
| 577 : | @c SUBSECTION | ||
| 578 : | @c ..................................................... | ||
| 579 : | |||
| 580 : | @menu | ||
| 581 : | * One library:: | ||
| 582 : | * Unix commands are files:: | ||
| 583 : | * Kernel and shell:: | ||
| 584 : | * The role of C:: | ||
| 585 : | * Stdin:: | ||
| 586 : | @end menu | ||
| 587 : | |||
| 588 : | @node One library, Unix commands are files, What you should know before starting, What you should know before starting | ||
| 589 : | @subsection One library: several interfaces | ||
| 590 : | |||
| 591 : | The core of unix is the library of functions (written in C) which | ||
| 592 : | access the system. Everything you do on a unix system goes through | ||
| 593 : | this set of functions. However, you can choose your own interface | ||
| 594 : | to these library functions. Unix has very many different interfaces | ||
| 595 : | to its libraries in the form of languages and command interpreters. | ||
| 596 : | |||
| 597 : | You can use the functions directly in C, or you can use command | ||
| 598 : | programs like @samp{ls}, @samp{cd} etc. These functions just | ||
| 599 : | provide a simple user interface to the C calls. You can also use | ||
| 600 : | a variety of `script' languages: C-shell, Bourne shell, Perl, Tcl, scheme. | ||
| 601 : | You choose the interface which solves your problem most easily. | ||
| 602 : | |||
| 603 : | @c ..................................................... | ||
| 604 : | @c SUBSECTION | ||
| 605 : | @c ..................................................... | ||
| 606 : | |||
| 607 : | @menu | ||
| 608 : | * Unix commands are files:: | ||
| 609 : | * Kernel and shell:: | ||
| 610 : | * The role of C:: | ||
| 611 : | * Stdin:: | ||
| 612 : | @end menu | ||
| 613 : | |||
| 614 : | @node Unix commands are files, Kernel and shell, One library, What you should know before starting | ||
| 615 : | @subsection Unix commands are files | ||
| 616 : | |||
| 617 : | |||
| 618 : | @cindex Commands as files | ||
| 619 : | @cindex Built in commands | ||
| 620 : | @cindex shell | ||
| 621 : | |||
| 622 : | With the exception of a few simple commands which are built into the command | ||
| 623 : | interpreter (shell), all unix commands and programs consist of | ||
| 624 : | executable files. In other words, there is a separate | ||
| 625 : | executable file for each command. This makes it extremely simple | ||
| 626 : | to add new commands to the system. One simply makes a program with | ||
| 627 : | the desired name and places it in the appropriate directory. | ||
| 628 : | |||
| 629 : | @cindex Commands path | ||
| 630 : | @cindex @code{PATH} | ||
| 631 : | @cindex @code{path} | ||
| 632 : | Unix commands live in special directories | ||
| 633 : | (usually called @code{bin} for binary files). The location of | ||
| 634 : | these directories is recorded in a variable called @code{path} or | ||
| 635 : | @code{PATH} which is used by the system to search for | ||
| 636 : | binaries. We shall return to this in more detail in later chapters. | ||
| 637 : | |||
| 638 : | |||
| 639 : | |||
| 640 : | @c ..................................................... | ||
| 641 : | @c SUBSECTION | ||
| 642 : | @c ..................................................... | ||
| 643 : | |||
| 644 : | @node Kernel and shell, The role of C, Unix commands are files, What you should know before starting | ||
| 645 : | @subsection Kernel and Shell | ||
| 646 : | |||
| 647 : | @cindex kernel | ||
| 648 : | @cindex shell | ||
| 649 : | Since users cannot command the kernel directly, UNIX has a command language | ||
| 650 : | known as the @emph{shell}. The word shell implies a layer around the | ||
| 651 : | kernel. A shell is a user interface, or command interpreter. | ||
| 652 : | |||
| 653 : | There are two main versions of the shell, plus a number of enhancements. | ||
| 654 : | |||
| 655 : | @table @emph | ||
| 656 : | @item /bin/sh | ||
| 657 : | The Bourne Shell. The shell is most often used for writing system scripts. | ||
| 658 : | It is part of the original unix system. | ||
| 659 : | @cindex Bourne shell | ||
| 660 : | @vindex @file{/bin/sh} | ||
| 661 : | @cindex @file{sh} | ||
| 662 : | |||
| 663 : | @item /bin/csh | ||
| 664 : | The C-shell. This was added to unix by the Berkeley workers. | ||
| 665 : | The commands and syntax resemble C code. C-shell is better suited for | ||
| 666 : | interactive work than the Bourne shell. | ||
| 667 : | @cindex C shell | ||
| 668 : | @cindex @file{csh} | ||
| 669 : | @vindex @file{/bin/csh} | ||
| 670 : | @end table | ||
| 671 : | |||
| 672 : | @cindex tcsh | ||
| 673 : | @cindex bash | ||
| 674 : | @cindex ksh | ||
| 675 : | The program @code{tcsh} is a public-domain enhancement of the csh and is | ||
| 676 : | in common use. Two improved versions of the Bourne shell also exist: | ||
| 677 : | @code{ksh}, the Korn shell and @code{bash}, the Bourne-again shell. | ||
| 678 : | |||
| 679 : | Although the shells are mainly tools for typing in commands (which are | ||
| 680 : | excutable files to be loaded and run), they contain features such as | ||
| 681 : | aliases, a command history, wildcard-expansions and job control | ||
| 682 : | functions which provide a comfortable user environment. | ||
| 683 : | |||
| 684 : | @c ..................................................... | ||
| 685 : | @c SUBSECTION | ||
| 686 : | @c ..................................................... | ||
| 687 : | |||
| 688 : | @node The role of C, Stdin, Kernel and shell, What you should know before starting | ||
| 689 : | @subsection The role of C | ||
| 690 : | |||
| 691 : | @cindex Role of C in unix | ||
| 692 : | @cindex C, role in unix | ||
| 693 : | |||
| 694 : | Most of the unix kernel and daemons are written in the C programming | ||
| 695 : | language @footnote{In particular they are written in Kernighan and | ||
| 696 : | Ritchie C, not the newer ANSI standard C.}. Calls to the kernel and to | ||
| 697 : | services are made through functions in the standard C library. The | ||
| 698 : | commands like @code{chmod}, @code{mkdir} and @code{cd} are all C | ||
| 699 : | functions. The binary files of the same name @code{/bin/chmod}, | ||
| 700 : | @code{/bin/mkdir} etc. are just trivial "wrapper" programs for these C | ||
| 701 : | functions. | ||
| 702 : | @cindex Wrapper functions | ||
| 703 : | @cindex C library calls and shell commands | ||
| 704 : | @cindex Shell commands and C library calls | ||
| 705 : | |||
| 706 : | Until @emph{Solaris 2}, the C compiler was a standard part of the UNIX | ||
| 707 : | operating system, thus C is the most natural language to program in | ||
| 708 : | in a UNIX environment. Some tools are provided for C programmers: | ||
| 709 : | |||
| 710 : | @table @emph | ||
| 711 : | @item dbx | ||
| 712 : | A symbolic debugger. Also @emph{gdb}, @emph{xxgdb} @emph{ddd}. | ||
| 713 : | @cindex Debugger for C | ||
| 714 : | |||
| 715 : | @item make | ||
| 716 : | A development tool for compiling large programs. | ||
| 717 : | @cindex make | ||
| 718 : | |||
| 719 : | @item lex | ||
| 720 : | A `lexer'. A program which generates C code to recognize | ||
| 721 : | words of text. | ||
| 722 : | @cindex lex | ||
| 723 : | |||
| 724 : | @item yacc | ||
| 725 : | A `parser'. This is a tool which generates C code for | ||
| 726 : | checking the syntax of groups of textual words. | ||
| 727 : | @cindex yacc | ||
| 728 : | |||
| 729 : | @item rpcgen | ||
| 730 : | A protocol compiler which generates C code from a higher | ||
| 731 : | level langauge, for programming RPC applications. | ||
| 732 : | @cindex rpcgen | ||
| 733 : | |||
| 734 : | @end table | ||
| 735 : | |||
| 736 : | @c ..................................................... | ||
| 737 : | @c SUBSECTION | ||
| 738 : | @c ..................................................... | ||
| 739 : | |||
| 740 : | @node Stdin, , The role of C, What you should know before starting | ||
| 741 : | @subsection Stdin, stdout, stderr | ||
| 742 : | |||
| 743 : | Unix has three logical @emph{streams} or @emph{files} which are always | ||
| 744 : | open and are available to any program. | ||
| 745 : | |||
| 746 : | @cindex I/O streams | ||
| 747 : | @cindex Standard input | ||
| 748 : | @cindex Standard output | ||
| 749 : | @cindex Standard error | ||
| 750 : | @vindex stdin | ||
| 751 : | @vindex stdout | ||
| 752 : | @vindex stderr | ||
| 753 : | |||
| 754 : | @table @emph | ||
| 755 : | @item stdin | ||
| 756 : | The standard input - file descriptor 0. | ||
| 757 : | @item stdout | ||
| 758 : | The standard output - file descriptor 1. | ||
| 759 : | @item stderr | ||
| 760 : | The standard error - file descriptor 2. | ||
| 761 : | @end table | ||
| 762 : | |||
| 763 : | The names are a part of the C language and are defined as | ||
| 764 : | pointers of type @code{FILE}. | ||
| 765 : | |||
| 766 : | @smallexample | ||
| 767 : | #include <stdio.h> | ||
| 768 : | |||
| 769 : | /* FILE *stdin, *stdout, *stderr; */ | ||
| 770 : | |||
| 771 : | fprintf(stderr,"This is an error message!\n"); | ||
| 772 : | |||
| 773 : | @end smallexample | ||
| 774 : | |||
| 775 : | @noindent | ||
| 776 : | The names are `logical' in the sense that they do not refer to | ||
| 777 : | a particular device, or a particular place for information to | ||
| 778 : | come from or go. Their role is analogous to the `.' and `..' | ||
| 779 : | directories in the filesystem. Programs can write to these | ||
| 780 : | files without worrying about where the information comes from or | ||
| 781 : | goes to. The user can personally define these places by | ||
| 782 : | @emph{redirecting standard I/O}. This is discussed in the next | ||
| 783 : | chapter. | ||
| 784 : | @vindex . | ||
| 785 : | @vindex .. | ||
| 786 : | @cindex . directory | ||
| 787 : | @cindex .. directory | ||
| 788 : | @cindex Error messages | ||
| 789 : | |||
| 790 : | A separate stream is kept for error messages so that error output | ||
| 791 : | does not get mixed up with a program's intended output. | ||
| 792 : | |||
| 793 : | @c ------------------------------------------------------------------------------- | ||
| 794 : | @c SECTION | ||
| 795 : | @c ------------------------------------------------------------------------------- | ||
| 796 : | |||
| 797 : | @node The superuser and nobody, The file hierarchy , What you should know before starting, Overview | ||
| 798 : | @section The superuser (root) and @emph{nobody} | ||
| 799 : | |||
| 800 : | When logged onto a UNIX system directly, the user whose name is | ||
| 801 : | @code{root} has unlimited access to the files on the system. @code{root} | ||
| 802 : | can also become any other user without having to give a | ||
| 803 : | password. @code{root} is reserved for the system administrator or | ||
| 804 : | @emph{trusted users}. | ||
| 805 : | @cindex root user | ||
| 806 : | @cindex superuser | ||
| 807 : | |||
| 808 : | Certain commands are forbidden to normal users. For example, a regular | ||
| 809 : | user should not be able to halt the system, or change the ownership | ||
| 810 : | of files (see next paragraph). These things are reserved for the | ||
| 811 : | @code{root} or @emph{superuser}. | ||
| 812 : | |||
| 813 : | In a networked environment, @code{root} has no automatic authority on | ||
| 814 : | remote machines. This is to prevent the system administrator of one | ||
| 815 : | machine in Canada from being able to edit files on another in China. He | ||
| 816 : | or she must log in directly and supply a password in order to gain | ||
| 817 : | access privileges. On a network where files are often accessible in | ||
| 818 : | principle to anyone, the username @code{root} gets mapped to the user | ||
| 819 : | @code{nobody}, who has no rights at all. | ||
| 820 : | @cindex nobody | ||
| 821 : | |||
| 822 : | @c ------------------------------------------------------------------------------- | ||
| 823 : | @c SECTION | ||
| 824 : | @c ------------------------------------------------------------------------------- | ||
| 825 : | |||
| 826 : | @node The file hierarchy , Symbolic links, The superuser and nobody, Overview | ||
| 827 : | @section The file hierarchy | ||
| 828 : | |||
| 829 : | @cindex File hierarchy | ||
| 830 : | @cindex Hierarchy, file | ||
| 831 : | |||
| 832 : | Unix has a hierachical filesystem, which makes use of directories and | ||
| 833 : | sub-directories to form a tree. The root of the tree is called the root | ||
| 834 : | filesystem or `/'. Although the details of where every file is located | ||
| 835 : | differ for different versions of unix, some basic features are the | ||
| 836 : | same. The main sub-directories of the root directory together with the | ||
| 837 : | most important file are shown in the figure. Their contents are as | ||
| 838 : | follows. | ||
| 839 : | |||
| 840 : | @table @file | ||
| 841 : | |||
| 842 : | @item /bin | ||
| 843 : | Executable (binary) programs. On most systems this is | ||
| 844 : | a separate directory to /usr/bin. In SunOS, this is a pointer (link) to | ||
| 845 : | /usr/bin. | ||
| 846 : | @vindex @file{/bin} | ||
| 847 : | |||
| 848 : | @item /etc | ||
| 849 : | Miscellaneous programs and configuration files. This directory | ||
| 850 : | has become very messy over the history of UNIX and has become a dumping | ||
| 851 : | ground for almost anything. Recent versions of unix have begun to | ||
| 852 : | tidy up this directory by creating subdirectories @file{/etc/mail}, | ||
| 853 : | @file{/etc/services} etc! | ||
| 854 : | @vindex @file{/etc} | ||
| 855 : | |||
| 856 : | @item /usr | ||
| 857 : | This contains the main meat of UNIX. This is where application software | ||
| 858 : | lives, together with all of the basic libraries used by the OS. | ||
| 859 : | @vindex @file{/usr} | ||
| 860 : | |||
| 861 : | @item /usr/bin | ||
| 862 : | More executables from the OS. | ||
| 863 : | @vindex @file{/usr/bin} | ||
| 864 : | |||
| 865 : | @item /usr/local | ||
| 866 : | This is where users' custom software is normally added. | ||
| 867 : | @vindex @file{/usr/local} | ||
| 868 : | |||
| 869 : | @item /sbin | ||
| 870 : | A special area for statically linked system binaries. They are | ||
| 871 : | placed here to distinguish commands used solely by the | ||
| 872 : | system administrator from user commands and so that they lie | ||
| 873 : | on the system root partition where they are guaranteed to be | ||
| 874 : | accessible during booting. | ||
| 875 : | @vindex @file{/sbin} | ||
| 876 : | |||
| 877 : | @item /sys | ||
| 878 : | This holds the configuration data which go to build the | ||
| 879 : | system kernel. (See below.) | ||
| 880 : | @vindex @file{/sys} | ||
| 881 : | |||
| 882 : | @item /export | ||
| 883 : | |||
| 884 : | Network servers only use this. This contains the disk space set aside for | ||
| 885 : | client machines which do not have their own disks. It is like a `virtual disk' | ||
| 886 : | for diskless clients. | ||
| 887 : | @vindex @file{/export} | ||
| 888 : | |||
| 889 : | @item /dev, /devices | ||
| 890 : | |||
| 891 : | A place where all the `logical devices' are collected. These are | ||
| 892 : | called `device nodes' in unix and are created by @code{mknod}. Logical | ||
| 893 : | devices are UNIX's official entry points for writing to devices. For instance, | ||
| 894 : | @code{/dev/console} is a route to the system console, while @code{/dev/kmem} | ||
| 895 : | is a route for reading kernel memory. Device nodes enable devices to be | ||
| 896 : | treated as though they were files. | ||
| 897 : | @vindex @file{/dev} | ||
| 898 : | @vindex @file{/devices} | ||
| 899 : | |||
| 900 : | @item /home | ||
| 901 : | |||
| 902 : | (Called @emph{/users} on some systems.) Each user has a separate login | ||
| 903 : | directory where files can be kept. These are normally stored under | ||
| 904 : | @code{/home} by some convention decided by the system administrator. | ||
| 905 : | @vindex @file{/home} | ||
| 906 : | @vindex @file{/users} | ||
| 907 : | |||
| 908 : | @item /var | ||
| 909 : | System 5 and mixed systems have a separate directory for spooling. Under | ||
| 910 : | old BSD systems, @code{/usr/spool} contains spool queues and system | ||
| 911 : | data. @code{/var/spool} and @code{/var/adm} etc are used for holding | ||
| 912 : | queues and system log files. | ||
| 913 : | @vindex @file{/var} | ||
| 914 : | @vindex @file{/vr/spool} | ||
| 915 : | @vindex @file{/var/adm} | ||
| 916 : | |||
| 917 : | @item /vmunix | ||
| 918 : | This is the program code for the unix @emph{kernel} (see below). | ||
| 919 : | On HPUX systems with file is called @file{hp-ux}. On | ||
| 920 : | linux it is called @file{linux}. | ||
| 921 : | @vindex @file{vmunix} | ||
| 922 : | @cindex Kernel | ||
| 923 : | |||
| 924 : | @item /kernel | ||
| 925 : | On newer systems the kernel is built up from a number of modules | ||
| 926 : | which are placed in this directory. | ||
| 927 : | |||
| 928 : | @end table | ||
| 929 : | |||
| 930 : | @noindent | ||
| 931 : | Every unix directory contains two `virtual' directories marked | ||
| 932 : | by a single dot and two dots. | ||
| 933 : | |||
| 934 : | @smallexample | ||
| 935 : | ls -a | ||
| 936 : | . .. | ||
| 937 : | @end smallexample | ||
| 938 : | @cindex . directory | ||
| 939 : | @cindex .. directory | ||
| 940 : | |||
| 941 : | @noindent | ||
| 942 : | The single dot represents the directory one is already in (the current | ||
| 943 : | directory). The double dots mean the directory one level up the tree | ||
| 944 : | from the current location. Thus, if one writes | ||
| 945 : | |||
| 946 : | @smallexample | ||
| 947 : | cd /usr/local | ||
| 948 : | cd .. | ||
| 949 : | @end smallexample | ||
| 950 : | |||
| 951 : | @noindent | ||
| 952 : | the final directory is @code{/usr}. The single dot is very useful in | ||
| 953 : | C programming if one wishes to read `the current directory'. Since | ||
| 954 : | this is always called `.' there is no need to keep track of what the | ||
| 955 : | current directory really is. | ||
| 956 : | |||
| 957 : | `.' and `..' are `hard links' to the true | ||
| 958 : | directories. | ||
| 959 : | @cindex Hard links | ||
| 960 : | |||
| 961 : | @c ------------------------------------------------------------------------------- | ||
| 962 : | @c SECTION | ||
| 963 : | @c ------------------------------------------------------------------------------- | ||
| 964 : | |||
| 965 : | @node Symbolic links, Hard links, The file hierarchy , Overview | ||
| 966 : | @section Symbolic links | ||
| 967 : | |||
| 968 : | @cindex Soft links | ||
| 969 : | @cindex Symbolic links | ||
| 970 : | @vindex @code{ln -s} | ||
| 971 : | @cindex @code{ln -s} | ||
| 972 : | |||
| 973 : | A symbolic link is a pointer or an alias to another file. The command | ||
| 974 : | @smallexample | ||
| 975 : | ln -s fromfile /other/directory/tolink | ||
| 976 : | @end smallexample | ||
| 977 : | @noindent | ||
| 978 : | makes the file @code{fromfile} appear to exist at @code{/other/directory/tolink} | ||
| 979 : | simultaneously. The file is not copied, it merely appears to be a | ||
| 980 : | part of the file tree in two places. Symbolic links can be made to | ||
| 981 : | both files and directories. | ||
| 982 : | |||
| 983 : | A symbolic link is just a small file which contains the name of the real | ||
| 984 : | file one is interested in. It cannot be opened like an ordinary file, | ||
| 985 : | but may be read with the C call @code{readlink()} @xref{lstat and readlink}. | ||
| 986 : | If we remove the file a symbolic link | ||
| 987 : | points to, the link remains -- it just points nowhere. | ||
| 988 : | |||
| 989 : | @c ------------------------------------------------------------------------------- | ||
| 990 : | @c SECTION | ||
| 991 : | @c ------------------------------------------------------------------------------- | ||
| 992 : | |||
| 993 : | @node Hard links, , Symbolic links, Overview | ||
| 994 : | @section Hard links | ||
| 995 : | |||
| 996 : | @cindex Hard links | ||
| 997 : | @vindex @code{ln} | ||
| 998 : | |||
| 999 : | |||
| 1000 : | A @emph{hard link} is a duplicate @emph{inode} in the filesystem which | ||
| 1001 : | is in every way equivalent to the original file inode. If a file is | ||
| 1002 : | pointed to by a hard link, it cannot be removed until the link is | ||
| 1003 : | removed. If a file has @math{n} hard links -- all of them must be removed | ||
| 1004 : | before the file can be removed. The number of hard links to a file is | ||
| 1005 : | stored in the filesystem @emph{index node} for the file. | ||
| 1006 : | @cindex inodes | ||
| 1007 : | @cindex Index nodes | ||
| 1008 : | |||
| 1009 : | |||
| 1010 : | |||
| 1011 : | |||
| 1012 : | @c ********************************************************************** | ||
| 1013 : | @c CHAPTER | ||
| 1014 : | @c ********************************************************************** | ||
| 1015 : | |||
| 1016 : | @node Getting started, The login environment, Overview, Top | ||
| 1017 : | @chapter Getting started | ||
| 1018 : | |||
| 1019 : | If you have never met unix, or another multiuser system before, | ||
| 1020 : | then you might find the idea daunting. There are several things | ||
| 1021 : | you should know. | ||
| 1022 : | |||
| 1023 : | @c ----------------------------------------------------------------------- | ||
| 1024 : | @c SECTION | ||
| 1025 : | @c ----------------------------------------------------------------------- | ||
| 1026 : | |||
| 1027 : | @menu | ||
| 1028 : | * Logging in:: | ||
| 1029 : | * Mouse buttons:: | ||
| 1030 : | * Reading mail:: | ||
| 1031 : | * Simple commands:: | ||
| 1032 : | * Text editing and word processing:: | ||
| 1033 : | @end menu | ||
| 1034 : | |||
| 1035 : | @node Logging in, Mouse buttons, Getting started, Getting started | ||
| 1036 : | @section Logging in | ||
| 1037 : | |||
| 1038 : | Each time you use unix you must log on to the system by typing a | ||
| 1039 : | username and a password. Your login name is sometimes called an | ||
| 1040 : | `account' because some unix systems implement strict quotas for | ||
| 1041 : | computer resources which have to be paid for with real | ||
| 1042 : | money@footnote{This is seldom true these days.}. | ||
| 1043 : | |||
| 1044 : | @cartouche | ||
| 1045 : | @example | ||
| 1046 : | |||
| 1047 : | login: mark | ||
| 1048 : | password: | ||
| 1049 : | |||
| 1050 : | @end example | ||
| 1051 : | @end cartouche | ||
| 1052 : | |||
| 1053 : | Once you have typed in your password, you are `logged on'. What | ||
| 1054 : | happens then depends on what kind of system you are logged onto | ||
| 1055 : | and how. If you have a colour monitor and keyboard in front of you, | ||
| 1056 : | with a graphical user interface, you will see a number of | ||
| 1057 : | windows appear, perhaps a menu bar. You then use a mouse and | ||
| 1058 : | keyboard just like any other system. | ||
| 1059 : | |||
| 1060 : | This is not the only way to log onto unix. You can also log in | ||
| 1061 : | remotely, from another machine, using the @code{telnet} or @code{rlogin} | ||
| 1062 : | @cindex telnet | ||
| 1063 : | @cindex Logging on | ||
| 1064 : | programs. If you use these programs, you will normally only get a text | ||
| 1065 : | or command line interface (though graphics can still be arranged). | ||
| 1066 : | |||
| 1067 : | Once you have logged in, a short message will be printed (called Message | ||
| 1068 : | of the Day or motd) and you will see the C-shell prompt: the name of the | ||
| 1069 : | host you are logged onto followed by a percent sign, e.g. | ||
| 1070 : | |||
| 1071 : | @cartouche | ||
| 1072 : | @example | ||
| 1073 : | |||
| 1074 : | SunOS Release 5.5 Version Generic [UNIX(R) System V Release 4.0] | ||
| 1075 : | Copyright (c) 1983-1995, Sun Microsystems, Inc. | ||
| 1076 : | |||
| 1077 : | Please report problems to sysadm@@iu.hioslo.no | ||
| 1078 : | |||
| 1079 : | dax% | ||
| 1080 : | |||
| 1081 : | @end example | ||
| 1082 : | @end cartouche | ||
| 1083 : | |||
| 1084 : | @noindent | ||
| 1085 : | Remember that every unix machine is a separate entity: it is not like | ||
| 1086 : | logging onto a PC system where you log onto the `network' i.e. the PC | ||
| 1087 : | file server. Every unix machine is a server. The network, in unix-land, | ||
| 1088 : | has lots of players. | ||
| 1089 : | |||
| 1090 : | The first thing you should do once you have logged on is to set a | ||
| 1091 : | reliable password. A poor password might be okay on a PC which is not | ||
| 1092 : | attached to a large network, but once you are attached to the internet, | ||
| 1093 : | you have to remember that the whole world will be trying to crack your | ||
| 1094 : | password. Don't think that no one will bother: some people really have | ||
| 1095 : | nothing better to do. A password should not contain any word that could | ||
| 1096 : | be in a list of words (in any language), or be a simple concatenation of | ||
| 1097 : | a word and a number (e.g. mark123). It takes seconds to crack such a | ||
| 1098 : | password. Choose instead something which is easy to remember. Feel free | ||
| 1099 : | to use the PIN number from your bankers card in your password! This will | ||
| 1100 : | leave you with fewer things to remember. e.g. Ma9876rk). Passwords can | ||
| 1101 : | be up to eight characters long. | ||
| 1102 : | |||
| 1103 : | Some sites allow you to change your password | ||
| 1104 : | anywhere. Other sites require you to log onto a special machine to | ||
| 1105 : | change your password: | ||
| 1106 : | |||
| 1107 : | @cartouche | ||
| 1108 : | @example | ||
| 1109 : | |||
| 1110 : | dax% | ||
| 1111 : | dax% passwd | ||
| 1112 : | Change your password on host nexus | ||
| 1113 : | You cannot change it here | ||
| 1114 : | dax% rlogin nexus | ||
| 1115 : | password: ****** | ||
| 1116 : | |||
| 1117 : | nexus% passwd | ||
| 1118 : | Changing password for mark | ||
| 1119 : | Enter login password: ******** | ||
| 1120 : | Enter new password: ******** | ||
| 1121 : | Reenter new passwd: ******** | ||
| 1122 : | |||
| 1123 : | @end example | ||
| 1124 : | @end cartouche | ||
| 1125 : | @noindent | ||
| 1126 : | You will be prompted for your old password and your new | ||
| 1127 : | password twice. If your network is large, it might take the system up to | ||
| 1128 : | an hour or two to register the change in your password, so don't forget | ||
| 1129 : | the old one right away! | ||
| 1130 : | |||
| 1131 : | @c ----------------------------------------------------------------------- | ||
| 1132 : | @c SECTION | ||
| 1133 : | @c ----------------------------------------------------------------------- | ||
| 1134 : | |||
| 1135 : | @menu | ||
| 1136 : | * Mouse buttons:: | ||
| 1137 : | @end menu | ||
| 1138 : | |||
| 1139 : | @node Mouse buttons, Reading mail, Logging in, Getting started | ||
| 1140 : | @section Mouse buttons | ||
| 1141 : | |||
| 1142 : | Unix has three mouse buttons. On some PC's running GNU/Linux or some other | ||
| 1143 : | PC unix, there are only two, but the middle mouse button can be | ||
| 1144 : | simulated by pressing both mouse buttons simultaneously. The mouse | ||
| 1145 : | buttons have the following general functions. They may also have additional | ||
| 1146 : | functions in special software. | ||
| 1147 : | @table @emph | ||
| 1148 : | |||
| 1149 : | @item index finger | ||
| 1150 : | This is used to select and click on objects. | ||
| 1151 : | It is also used to mark out areas and copy by dragging. | ||
| 1152 : | This is the button you normally use. | ||
| 1153 : | |||
| 1154 : | @item middle finger | ||
| 1155 : | Used to pull down menus. It is also used to paste a marked | ||
| 1156 : | area somewhere at the mouse position. | ||
| 1157 : | |||
| 1158 : | @item outer finger | ||
| 1159 : | Pulls down menus. | ||
| 1160 : | |||
| 1161 : | @end table | ||
| 1162 : | @noindent | ||
| 1163 : | On a left-handed system right and left are reversed. | ||
| 1164 : | |||
| 1165 : | |||
| 1166 : | @c ----------------------------------------------------------------------- | ||
| 1167 : | @c SECTION | ||
| 1168 : | @c ----------------------------------------------------------------------- | ||
| 1169 : | |||
| 1170 : | @node Reading mail, Simple commands, Mouse buttons, Getting started | ||
| 1171 : | @section E-mail | ||
| 1172 : | |||
| 1173 : | Reading electronic mail on unix is just like any other system, but there | ||
| 1174 : | are many programs to choose from. There are very old programs from the | ||
| 1175 : | seventies such as | ||
| 1176 : | |||
| 1177 : | @example | ||
| 1178 : | |||
| 1179 : | @end example | ||
| 1180 : | @noindent | ||
| 1181 : | and there are fully graphical mail programs such as | ||
| 1182 : | @example | ||
| 1183 : | tkrat | ||
| 1184 : | mailtool | ||
| 1185 : | @end example | ||
| 1186 : | Choose the program you like best. Not all of the programs support modern | ||
| 1187 : | multimedia extensions because of their age. Some programs like | ||
| 1188 : | @code{tkrat} have immediate mail notification alerts. To start a mail | ||
| 1189 : | program you just type its name. If you have an icon-bar, you can click | ||
| 1190 : | on the mail-icon. | ||
| 1191 : | |||
| 1192 : | @c ----------------------------------------------------------------------- | ||
| 1193 : | @c SECTION | ||
| 1194 : | @c ----------------------------------------------------------------------- | ||
| 1195 : | |||
| 1196 : | @node Simple commands, Text editing and word processing, Reading mail, Getting started | ||
| 1197 : | @section Simple commands | ||
| 1198 : | |||
| 1199 : | Inexperienced computer users often prefer to use file-manager | ||
| 1200 : | programs to avoid typing anything. With a mouse you can click | ||
| 1201 : | your way through directories and files without having to type | ||
| 1202 : | anything (e.g. the @code{fmgr} or @code{tkdesk} programs). | ||
| 1203 : | More experienced users generally find this to be slow and | ||
| 1204 : | tedious after a while and prefer to use written commands. | ||
| 1205 : | Unix has many short cuts and keyboard features which make | ||
| 1206 : | typed commands extremely fast and much more powerful than | ||
| 1207 : | use of the mouse. | ||
| 1208 : | |||
| 1209 : | If you come from a DOS environment, the unix commands can be a little | ||
| 1210 : | strange. Because they stem from an era when keyboards had to be hit with | ||
| 1211 : | hammer force, and machines were very slow, the command names are | ||
| 1212 : | generally as short as possible, so they seem pretty cryptic. Some | ||
| 1213 : | familar ones which DOS borrowed from unix include, | ||
| 1214 : | |||
| 1215 : | @example | ||
| 1216 : | cd | ||
| 1217 : | mkdir | ||
| 1218 : | @end example | ||
| 1219 : | @noindent | ||
| 1220 : | which change to a new directory and make a new directory respectively. | ||
| 1221 : | To list the files in the current directory you use, | ||
| 1222 : | @example | ||
| 1223 : | ls | ||
| 1224 : | @end example | ||
| 1225 : | @noindent | ||
| 1226 : | To rename a file, you `move' it: | ||
| 1227 : | @example | ||
| 1228 : | mv @var{old-name} @var{new-name} | ||
| 1229 : | @end example | ||
| 1230 : | |||
| 1231 : | @c ----------------------------------------------------------------------- | ||
| 1232 : | @c SECTION | ||
| 1233 : | @c ----------------------------------------------------------------------- | ||
| 1234 : | |||
| 1235 : | @node Text editing and word processing, , Simple commands, Getting started | ||
| 1236 : | @section Text editing and word processing | ||
| 1237 : | |||
| 1238 : | Text editing is one of the things which people spend most | ||
| 1239 : | time doing on any computer. It is important to distingiush | ||
| 1240 : | text editing from word processing. On a PC or MacIntosh, you are | ||
| 1241 : | perhaps used to Word or WordPerfect for writing documents. | ||
| 1242 : | |||
| 1243 : | Unix has a Word-like program called @code{lyx}, but for the most part | ||
| 1244 : | Unix users do not use word processors. It is more common in the unix | ||
| 1245 : | community to write all documents, regardless of whether they are | ||
| 1246 : | letters, books or computer programs, using a non-formatting text | ||
| 1247 : | editor. (Unix word processors like @code{Framemaker} do exist, but they | ||
| 1248 : | are very expensive. A version of MS-Word also exists for some unices.) | ||
| 1249 : | Once you have written a document in a normal text editor, you call up | ||
| 1250 : | a text formatter to make it pretty. You might think this strange, but | ||
| 1251 : | the truth of the matter is that this two-stage process gives you the | ||
| 1252 : | most power and flexibilty---and that is what most unix folks like. | ||
| 1253 : | |||
| 1254 : | For writing programs, or anything else, you edit a file by typing: | ||
| 1255 : | @example | ||
| 1256 : | |||
| 1257 : | emacs myfile | ||
| 1258 : | |||
| 1259 : | @end example | ||
| 1260 : | @noindent | ||
| 1261 : | @code{emacs} is one of dozens of text-editors. It is not the simplest or | ||
| 1262 : | most intuitive, but it is the most powerful and if you are going to | ||
| 1263 : | spend time learning an editor, it wouldn't do any harm to make it this | ||
| 1264 : | one. You could also click on emacs' icon if you are relying on a window | ||
| 1265 : | system. Emacs is almost certainly the most powerful text editor that | ||
| 1266 : | exists on any system. It is not a word-processor, it not for formatting | ||
| 1267 : | printed documents, but it can be linked to almost any other program in | ||
| 1268 : | order to format and print text. It contains a powerful programming | ||
| 1269 : | language and has many intelligent features. We shall not go into the | ||
| 1270 : | details of document formatting in this book, but only mention that | ||
| 1271 : | programs like @code{troff} and @code{Tex} or @code{Latex} are used for | ||
| 1272 : | this purpose to obtain typset-quality printing. Text formatting is an | ||
| 1273 : | area where Unix folks do things differently to PC folks. | ||
| 1274 : | |||
| 1275 : | |||
| 1276 : | @c ********************************************************************** | ||
| 1277 : | @c CHAPTER | ||
| 1278 : | @c ********************************************************************** | ||
| 1279 : | |||
| 1280 : | @node The login environment, Files and access, Getting started, Top | ||
| 1281 : | @chapter The login environment | ||
| 1282 : | |||
| 1283 : | @cindex Environment, unix user | ||
| 1284 : | @cindex User environment | ||
| 1285 : | @cindex Login environment | ||
| 1286 : | |||
| 1287 : | Unix began as a timesharing mainframe system in the seventies, when the | ||
| 1288 : | only terminals available were text based @emph{teletype} terminals or | ||
| 1289 : | @emph{tty}-s. Later, the Massachusetts Institute of Technology (MIT) | ||
| 1290 : | developed the X-windows interface which is now a standard across UNIX | ||
| 1291 : | platforms. Because of this history, the X-window system works as a | ||
| 1292 : | front end to the standard UNIX shell and interface, so to understand | ||
| 1293 : | the user environment we must first understand the shell. | ||
| 1294 : | @cindex X-windows | ||
| 1295 : | |||
| 1296 : | @c ----------------------------------------------------------------------- | ||
| 1297 : | @c SECTION | ||
| 1298 : | @c ----------------------------------------------------------------------- | ||
| 1299 : | |||
| 1300 : | @menu | ||
| 1301 : | * Shells:: | ||
| 1302 : | * UNIX command overview:: | ||
| 1303 : | * Terminals:: | ||
| 1304 : | * The X window system:: | ||
| 1305 : | * Multiple screens:: | ||
| 1306 : | @end menu | ||
| 1307 : | |||
| 1308 : | @node Shells, UNIX command overview, The login environment, The login environment | ||
| 1309 : | @section Shells | ||
| 1310 : | |||
| 1311 : | @cindex Command interpreter | ||
| 1312 : | A shell is a command interpreter. In the early days of unix, a shell was | ||
| 1313 : | the only way of issuing commands to the system. Nowadays many window-based | ||
| 1314 : | application programs provide menus and buttons to perform simple commands, | ||
| 1315 : | but the UNIX shell remains the most powerful and flexible way of interacting | ||
| 1316 : | with the system. | ||
| 1317 : | |||
| 1318 : | @cindex @emph{init} | ||
| 1319 : | After logging in and entering a password, the unix process @emph{init} | ||
| 1320 : | starts a shell for the user logging in. Unix has several different kinds | ||
| 1321 : | of shell to choose from, so that each user can pick his/her favourite | ||
| 1322 : | command interface. The type of shell which the system starts at login is | ||
| 1323 : | determined by the user's entry in the @emph{passwd} database. | ||
| 1324 : | On most systems, the standard login shell is a variant of the C-shell. | ||
| 1325 : | |||
| 1326 : | Shells provide facilities and commands which | ||
| 1327 : | |||
| 1328 : | @itemize @bullet | ||
| 1329 : | |||
| 1330 : | @item | ||
| 1331 : | Start and stop processes (programs) | ||
| 1332 : | |||
| 1333 : | @item | ||
| 1334 : | Allow two processes to communicate through a @emph{pipe} | ||
| 1335 : | |||
| 1336 : | @item | ||
| 1337 : | Allow the user to redirect the flow of input or output | ||
| 1338 : | |||
| 1339 : | @item | ||
| 1340 : | Allow simple command line editing and command history | ||
| 1341 : | |||
| 1342 : | @item | ||
| 1343 : | Define aliases to frequently used commands | ||
| 1344 : | |||
| 1345 : | @item | ||
| 1346 : | Define global "environment" variables which are used to configure | ||
| 1347 : | the default behaviour of a variety of programs. These lie in an | ||
| 1348 : | "associated array" for each process and may be seen with the | ||
| 1349 : | @samp{env} command. Environment variables are inherited by all | ||
| 1350 : | processes which are started from a shell. | ||
| 1351 : | @cindex Environment variables | ||
| 1352 : | |||
| 1353 : | @item | ||
| 1354 : | Provide wildcard expansion (joker notation) of filenames using @samp{*,?,[]} | ||
| 1355 : | @cindex Wildcards | ||
| 1356 : | |||
| 1357 : | @item | ||
| 1358 : | Provide a simple script language, with tests and loops, so that users | ||
| 1359 : | can combine system programs to create new programs of their own. | ||
| 1360 : | |||
| 1361 : | @item | ||
| 1362 : | Change and remember the location of the current working directory, or | ||
| 1363 : | location within the file hierarchy. | ||
| 1364 : | |||
| 1365 : | @end itemize | ||
| 1366 : | |||
| 1367 : | The shell does not contain any more specific functions---all other commands, such | ||
| 1368 : | as programs which list files or create directories etc., are executable | ||
| 1369 : | programs which are independent of the shell. When you type @samp{ls}, | ||
| 1370 : | the shell looks for the executable file called @samp{ls} in a special | ||
| 1371 : | list of directories called @emph{the command path} and attempts to start | ||
| 1372 : | this program. This allows such programs to be developed and replaced | ||
| 1373 : | independently of the actual command interpreter. | ||
| 1374 : | |||
| 1375 : | Each shell which is started can be customized and configured by editing | ||
| 1376 : | a setup file. For the C-shell and its variants this file is called | ||
| 1377 : | @file{.cshrc}, and for the Bourne shell and its variants it is called | ||
| 1378 : | @file{.profile}. (Note that files which begin with leading dots are not | ||
| 1379 : | normally visible with the @samp{ls} command. Use @samp{ls -a} to view these.) | ||
| 1380 : | Any commands which are placed in these files are interpreted by the shell | ||
| 1381 : | before the first command prompt is issued. These files are typically | ||
| 1382 : | used to define a command search path and terminal characteristics. | ||
| 1383 : | |||
| 1384 : | @emph{On each new command line you can use the cursor keys to edit the line. | ||
| 1385 : | The up-arrow browses back through earlier commands. @kbd{CTRL-a} takes | ||
| 1386 : | you to the start of the line. @kbd{CTRL-e} takes you to the end of the | ||
| 1387 : | line. The @key{TAB} can be used to save typing with the `completion' | ||
| 1388 : | facility @xref{Command/filename completion}.} | ||
| 1389 : | |||
| 1390 : | @c ..................................................... | ||
| 1391 : | @c SUBSECTION | ||
| 1392 : | @c ..................................................... | ||
| 1393 : | |||
| 1394 : | @menu | ||
| 1395 : | * Shell commands generally:: | ||
| 1396 : | * Environment and shell variables:: | ||
| 1397 : | * Wildcards:: | ||
| 1398 : | * Regular expressions:: | ||
| 1399 : | * Nested shells and reverse apostrophes:: | ||
| 1400 : | @end menu | ||
| 1401 : | |||
| 1402 : | @node Shell commands generally, Environment and shell variables, Shells, Shells | ||
| 1403 : | @subsection Shell commands generally | ||
| 1404 : | |||
| 1405 : | Shell commands are commands like @code{cp}, @code{mv}, | ||
| 1406 : | @code{passwd}, @code{cat}, @code{more}, @code{less}, @code{cc}, | ||
| 1407 : | @code{grep}, @code{ps} etc.. | ||
| 1408 : | |||
| 1409 : | Very few commands are actually built into the shell command line | ||
| 1410 : | interpreter, in the way that they are in DOS -- commands are mostly | ||
| 1411 : | programs which exist as files. When we type a command, the shell | ||
| 1412 : | searches for a program with the same name and tries to execute it. The | ||
| 1413 : | file must be executable, or a @code{Command not found} error will | ||
| 1414 : | result. To see what actually happens when you type a command like | ||
| 1415 : | @code{gcc}, try typing in the following C-shell commands @emph{directly | ||
| 1416 : | into a C-shell}. (We shall discuss these commands soon.) | ||
| 1417 : | |||
| 1418 : | @smallexample | ||
| 1419 : | foreach dir ( $path ) # for every directory in the list path | ||
| 1420 : | if ( -x $dir/gcc ) then # if the file is executable | ||
| 1421 : | echo Found $dir/gcc # Print message found! | ||
| 1422 : | break # break out of loop | ||
| 1423 : | else | ||
| 1424 : | echo Searching $dir/gcc | ||
| 1425 : | endif | ||
| 1426 : | end | ||
| 1427 : | @end smallexample | ||
| 1428 : | |||
| 1429 : | @noindent | ||
| 1430 : | The output of this command is something like | ||
| 1431 : | |||
| 1432 : | @smallexample | ||
| 1433 : | Searching /usr/lang/gcc | ||
| 1434 : | Searching /usr/openwin/bin/gcc | ||
| 1435 : | Searching /usr/openwin/bin/xview/gcc | ||
| 1436 : | Searching /physics/lib/framemaker/bin/gcc | ||
| 1437 : | Searching /physics/motif/bin/gcc | ||
| 1438 : | Searching /physics/mutils/bin/gcc | ||
| 1439 : | Searching /physics/common/scripts/gcc | ||
| 1440 : | Found /physics/bin/gcc | ||
| 1441 : | @end smallexample | ||
| 1442 : | If you type | ||
| 1443 : | @smallexample | ||
| 1444 : | echo $path | ||
| 1445 : | @end smallexample | ||
| 1446 : | you will see the entire list of directories which are searched by the shell. | ||
| 1447 : | If we had left out the `break' command, we might have discovered that | ||
| 1448 : | UNIX often has several programs with the same name, in different directories! | ||
| 1449 : | For example, | ||
| 1450 : | @smallexample | ||
| 1451 : | /bin/mail | ||
| 1452 : | /usr/ucb/mail | ||
| 1453 : | /bin/Mail | ||
| 1454 : | |||
| 1455 : | /bin/make | ||
| 1456 : | /usr/local/bin/make. | ||
| 1457 : | @end smallexample | ||
| 1458 : | Also, different versions of unix have different conventions for placing the | ||
| 1459 : | commands in directories, so the path list needs to be different for | ||
| 1460 : | different types of unix machine. In the C-shell a few basic commands | ||
| 1461 : | like @code{cd} and @code{kill} are built into the shell (as in DOS). | ||
| 1462 : | |||
| 1463 : | You can find out which directory a command is stored in using the | ||
| 1464 : | @smallexample | ||
| 1465 : | which | ||
| 1466 : | @end smallexample | ||
| 1467 : | command. For example | ||
| 1468 : | @smallexample | ||
| 1469 : | nexus% which cd | ||
| 1470 : | cd: shell built-in command. | ||
| 1471 : | nexus% which cp | ||
| 1472 : | /bin/cp | ||
| 1473 : | nexus% | ||
| 1474 : | @end smallexample | ||
| 1475 : | @code{which} only searches the directories in @code{$path} and quits after | ||
| 1476 : | the first match, so if there are several commands with the same name, | ||
| 1477 : | you will only see the first of them using which. | ||
| 1478 : | @cindex path | ||
| 1479 : | @cindex Command path | ||
| 1480 : | |||
| 1481 : | Finally, in the C-shell, the @code{which} command is built in. In the | ||
| 1482 : | Bourne shell it is a program: | ||
| 1483 : | @smallexample | ||
| 1484 : | nexus% which which | ||
| 1485 : | which: shell built-in command. | ||
| 1486 : | nexus% sh | ||
| 1487 : | $ which which | ||
| 1488 : | /bin/which | ||
| 1489 : | $ exit | ||
| 1490 : | nexus% | ||
| 1491 : | @end smallexample | ||
| 1492 : | Take a look at the script @code{/usr/ucb/which}. It is a script written | ||
| 1493 : | in the C-shell. | ||
| 1494 : | @cindex which command | ||
| 1495 : | @vindex which | ||
| 1496 : | |||
| 1497 : | @c ..................................................... | ||
| 1498 : | @c SUBSECTION | ||
| 1499 : | @c ..................................................... | ||
| 1500 : | |||
| 1501 : | @node Environment and shell variables, Wildcards, Shell commands generally, Shells | ||
| 1502 : | @subsection Environment and shell variables | ||
| 1503 : | |||
| 1504 : | @cindex Environment variables | ||
| 1505 : | Environment variables are variables which the shell keeps. They are | ||
| 1506 : | normally used to configure the behaviour of utility programs like | ||
| 1507 : | @code{lpr} (which sends a file to the printer) and @code{mail} (which | ||
| 1508 : | reads and sends mail) so that special options do not have to be typed in | ||
| 1509 : | every time you run these programs. | ||
| 1510 : | |||
| 1511 : | Any program can read these variables to find out how you have | ||
| 1512 : | configured your working environment. We shall meet these variables | ||
| 1513 : | frequently. Here are some important variables | ||
| 1514 : | |||
| 1515 : | @vindex PATH | ||
| 1516 : | @vindex TERM | ||
| 1517 : | @vindex DISPLAY | ||
| 1518 : | @vindex LD_LIBRARY_PATH | ||
| 1519 : | @vindex HOST | ||
| 1520 : | @vindex PRINTER | ||
| 1521 : | @vindex HOME | ||
| 1522 : | @smallexample | ||
| 1523 : | PATH # The search path for shell commands (sh) | ||
| 1524 : | TERM # The terminal type (sh and csh) | ||
| 1525 : | DISPLAY # X11 - the name of your display | ||
| 1526 : | LD_LIBRARY_PATH # Path to search for object and shared libraries | ||
| 1527 : | HOST # Name of this unix host | ||
| 1528 : | PRINTER # Default printer (lpr) | ||
| 1529 : | HOME # The path to your home directory (sh) | ||
| 1530 : | |||
| 1531 : | path # The search path for shell commands (csh) | ||
| 1532 : | term # The terminal type (csh) | ||
| 1533 : | noclobber # See below under redirection | ||
| 1534 : | prompt # The default prompt for csh | ||
| 1535 : | home # The path to your home directory (csh) | ||
| 1536 : | |||
| 1537 : | @end smallexample | ||
| 1538 : | These variables fall into two groups. Traditionally the first group | ||
| 1539 : | always have names in uppercase letters and are called @emph{environment | ||
| 1540 : | variables}, whereas variables in the second group have names with | ||
| 1541 : | lowercase letters and are called @emph{shell variables}-- but this is | ||
| 1542 : | only a convention. The uppercase variables are @emph{global variables}, | ||
| 1543 : | whereas the lower case variables are @emph{local variables}. Local | ||
| 1544 : | variables are not defined for programs or sub-shells started by the | ||
| 1545 : | current shell, while global variables are inherited by all sub-shells. | ||
| 1546 : | @cindex Global variables | ||
| 1547 : | @cindex Variables, global | ||
| 1548 : | @cindex Local variables | ||
| 1549 : | @cindex Variables, local | ||
| 1550 : | |||
| 1551 : | The Bourne-shell and the C-shell use these conventions differently and not | ||
| 1552 : | always consistently. You will see how to define these below. For now | ||
| 1553 : | you just have to know that you can use the following commands from the | ||
| 1554 : | C-shell to list these variables. The command @code{env} can be used | ||
| 1555 : | in either C-shell or Bourne shell to see all of the defined environment | ||
| 1556 : | variables. | ||
| 1557 : | @cindex @code{env} command | ||
| 1558 : | @vindex env | ||
| 1559 : | |||
| 1560 : | @c ..................................................... | ||
| 1561 : | @c SUBSECTION | ||
| 1562 : | @c ..................................................... | ||
| 1563 : | |||
| 1564 : | @node Wildcards, Regular expressions, Environment and shell variables, Shells | ||
| 1565 : | @subsection Wildcards | ||
| 1566 : | |||
| 1567 : | @cindex Wildcards | ||
| 1568 : | @cindex Joker notation | ||
| 1569 : | @vindex ? | ||
| 1570 : | @vindex * | ||
| 1571 : | @vindex [] | ||
| 1572 : | @cindex Matching filenames | ||
| 1573 : | |||
| 1574 : | Sometimes you want to be able to refer to several files in one go. For | ||
| 1575 : | instance, you might want to copy all files ending in `.c' to a new | ||
| 1576 : | directory. To do this one uses @emph{wildcards}. Wildcards are characters | ||
| 1577 : | like @code{* ?} which stand for any character or group of characters. | ||
| 1578 : | In card games the joker is a `wild card' which can be substituted for | ||
| 1579 : | any other card. Use of wildcards is also called @emph{filename substitution} | ||
| 1580 : | in the unix manuals, in the sections on @code{sh} and @code{csh}. | ||
| 1581 : | |||
| 1582 : | The wildcard symbols are, | ||
| 1583 : | |||
| 1584 : | @table @samp | ||
| 1585 : | @item ? | ||
| 1586 : | Match single character. e.g. @code{ls /etc/rc.????} | ||
| 1587 : | |||
| 1588 : | @item * | ||
| 1589 : | Match any number of characters. e.g. @code{ls /etc/rc.*} | ||
| 1590 : | |||
| 1591 : | @item [...] | ||
| 1592 : | Match any character in a list enclosed by these brackets. e.g. @code{ls [abc].C} | ||
| 1593 : | |||
| 1594 : | @end table | ||
| 1595 : | |||
| 1596 : | @noindent | ||
| 1597 : | Here are some examples and explanations. | ||
| 1598 : | |||
| 1599 : | @table @samp | ||
| 1600 : | |||
| 1601 : | @item /etc/rc.???? | ||
| 1602 : | Match all files in /etc whose first three | ||
| 1603 : | characters are @code{rc.} and are 7 characters long. | ||
| 1604 : | |||
| 1605 : | @item *.c | ||
| 1606 : | Match all files ending in `.c' i.e. all C programs. | ||
| 1607 : | |||
| 1608 : | @item *.[Cc] | ||
| 1609 : | List all files ending on `.c' or `.C' i.e. all C and C++ programs. | ||
| 1610 : | |||
| 1611 : | @item *.[a-z] | ||
| 1612 : | Match any file ending in .a, .b, .c, ... up to .z etc. | ||
| 1613 : | @end table | ||
| 1614 : | |||
| 1615 : | @noindent | ||
| 1616 : | @cindex Matching filenames | ||
| 1617 : | It is important to understand that @emph{the shell expands wildcards}. When | ||
| 1618 : | you type a command, the program is not invoked with an argument that | ||
| 1619 : | contains @code{*} or @code{?}. The shell expands the special characters | ||
| 1620 : | first and invokes commands with the entire list of files which | ||
| 1621 : | match the patterns. The programs never see the wildcard characters, only | ||
| 1622 : | the list of files they stand for. To see this in action, you can type | ||
| 1623 : | @smallexample | ||
| 1624 : | echo /etc/rc.* | ||
| 1625 : | @end smallexample | ||
| 1626 : | which gives | ||
| 1627 : | @smallexample | ||
| 1628 : | /etc/rc /etc/rc.boot /etc/rc.ip /etc/rc.local /etc/rc.local% | ||
| 1629 : | /etc/rc.local~ /etc/rc.single /etc/rc~ | ||
| 1630 : | @end smallexample | ||
| 1631 : | All shell commands are invoked with a command line of this form. This | ||
| 1632 : | has an important corollary. It means that multiple renaming @emph{cannot work}! | ||
| 1633 : | |||
| 1634 : | Unix files are renamed using the @code{mv} command. In many microcomputer | ||
| 1635 : | operating systems one can write | ||
| 1636 : | @smallexample | ||
| 1637 : | rename *.x *.y | ||
| 1638 : | @end smallexample | ||
| 1639 : | |||
| 1640 : | @noindent | ||
| 1641 : | which changes the file extension of all files ending in `.x' to the same | ||
| 1642 : | name with a `.y' extension. This cannot work in unix, because the | ||
| 1643 : | shell tries expands everything before passing the arguments to the | ||
| 1644 : | command line. | ||
| 1645 : | |||
| 1646 : | @emph{The local shell variable @code{noglob} switches off wildcard expansion in | ||
| 1647 : | the C shell, but you still cannot rename multiple files using @code{mv}. | ||
| 1648 : | Some free-software programs make this possible.} | ||
| 1649 : | |||
| 1650 : | @c ..................................................... | ||
| 1651 : | @c SUBSECTION | ||
| 1652 : | @c ..................................................... | ||
| 1653 : | |||
| 1654 : | @node Regular expressions, Nested shells and reverse apostrophes, Wildcards, Shells | ||
| 1655 : | @subsection Regular expressions | ||
| 1656 : | |||
| 1657 : | @cindex Matching strings | ||
| 1658 : | @cindex Regular expressions | ||
| 1659 : | @cindex Expressions, regular | ||
| 1660 : | The wildcards belong to the shell. They are used for matching | ||
| 1661 : | filenames. UNIX has a more general and widely used mechanism for | ||
| 1662 : | matching @emph{strings}, this is through @emph{regular expressions}. | ||
| 1663 : | |||
| 1664 : | Regular expressions are used by the @code{egrep} utility, text editors | ||
| 1665 : | like @code{ed}, @code{vi} and @code{emacs} and @code{sed} and @code{awk}. | ||
| 1666 : | They are also used in the C programming language | ||
| 1667 : | for matching input as well as in the Perl programming language and @code{lex} | ||
| 1668 : | tokenizer. Here are some examples using the @code{egrep} command | ||
| 1669 : | which print lines from the file @code{/etc/rc} which match certain | ||
| 1670 : | conditions. The @code{} contruction is part of @code{egrep}. Everything | ||
| 1671 : | in between these symbols is a regular expression. Notice that | ||
| 1672 : | special shell symbols @code{! * &} have to be preceded with a backslash | ||
| 1673 : | @code{\} in order to prevent the shell from expanding them! | ||
| 1674 : | @cindex @code{egrep} command | ||
| 1675 : | |||
| 1676 : | @smallexample | ||
| 1677 : | |||
| 1678 : | # Print all lines beginning with a comment # | ||
| 1679 : | |||
| 1680 : | egrep '(^#)' /etc/rc | ||
| 1681 : | |||
| 1682 : | # Print all lines which DON'T begin with # | ||
| 1683 : | |||
| 1684 : | egrep '(^[^#])' /etc/rc | ||
| 1685 : | |||
| 1686 : | # Print all lines beginning with e, f or g. | ||
| 1687 : | |||
| 1688 : | egrep '(^[efg])' /etc/rc | ||
| 1689 : | |||
| 1690 : | # Print all lines beginning with uppercase | ||
| 1691 : | |||
| 1692 : | egrep '(^[A-Z])' /etc/rc | ||
| 1693 : | |||
| 1694 : | # Print all lines NOT beginning with uppercase | ||
| 1695 : | |||
| 1696 : | egrep '(^[^A-Z])' /etc/rc | ||
| 1697 : | |||
| 1698 : | # Print all lines containing ! * & | ||
| 1699 : | |||
| 1700 : | egrep '([\!\*\&])' /etc/rc | ||
| 1701 : | |||
| 1702 : | # All lines containing ! * & but not starting # | ||
| 1703 : | |||
| 1704 : | egrep '([^#][\!\*\&])' /etc/rc | ||
| 1705 : | @end smallexample | ||
| 1706 : | |||
| 1707 : | @noindent | ||
| 1708 : | Regular expressions are made up of the following `atoms'. | ||
| 1709 : | |||
| 1710 : | @noindent | ||
| 1711 : | These examples assume that the file @file{/etc/rc} exists. | ||
| 1712 : | If it doesn't exist on the machine you are using, try to | ||
| 1713 : | find the equivalent by, for instance, replacing | ||
| 1714 : | @code{/etc/rc} with @code{/etc/rc*} which will try to | ||
| 1715 : | find a match beginning with the rc. | ||
| 1716 : | |||
| 1717 : | @vindex . in regular expressions | ||
| 1718 : | @vindex ^ in regular expressions | ||
| 1719 : | @vindex $ in regular expressions | ||
| 1720 : | @vindex [] in regular expressions | ||
| 1721 : | @vindex * in regular expressions | ||
| 1722 : | @vindex + in regular expressions | ||
| 1723 : | @vindex ? in regular expressions | ||
| 1724 : | @cindex . in regular expressions | ||
| 1725 : | @cindex ^ in regular expressions | ||
| 1726 : | @cindex $ in regular expressions | ||
| 1727 : | @cindex [] in regular expressions | ||
| 1728 : | @cindex * in regular expressions | ||
| 1729 : | @cindex + in regular expressions | ||
| 1730 : | @cindex ? in regular expressions | ||
| 1731 : | |||
| 1732 : | @table @samp | ||
| 1733 : | @item . | ||
| 1734 : | Match any single character except the end of line. | ||
| 1735 : | @item ^ | ||
| 1736 : | Match the beginning of a line as the first character. | ||
| 1737 : | @item $ | ||
| 1738 : | Match end of line as last character. | ||
| 1739 : | @item [..] | ||
| 1740 : | Match any character in the list between the square brackets.(see below). | ||
| 1741 : | @item * | ||
| 1742 : | Match zero or more occurrances of the preceding expression. | ||
| 1743 : | @item + | ||
| 1744 : | Match one or more occurrences of the preceding expression. | ||
| 1745 : | @item ? | ||
| 1746 : | Match zero or one occurrance of the preceding expression. | ||
| 1747 : | @end table | ||
| 1748 : | |||
| 1749 : | You can find a complete list in the unix manual pages. The square | ||
| 1750 : | brackets above are used to define a @emph{class} of characters to be | ||
| 1751 : | matched. Here are some examples, | ||
| 1752 : | |||
| 1753 : | @itemize @bullet | ||
| 1754 : | |||
| 1755 : | @item | ||
| 1756 : | If the square brackets contain a list of | ||
| 1757 : | characters, $[a-z156]$ then a single occurrance of any character in the | ||
| 1758 : | list will match the regular expression: in this case any lowercase | ||
| 1759 : | letter or the numbers 1, 5 and 6. | ||
| 1760 : | |||
| 1761 : | @item | ||
| 1762 : | If the first character in the brackets is the caret | ||
| 1763 : | symbol @samp{^} then any character @emph{except} those in the list will | ||
| 1764 : | be matched. | ||
| 1765 : | |||
| 1766 : | @item | ||
| 1767 : | Normally a dash or minus sign @samp{-} means a range of characters. | ||
| 1768 : | If it is the first character after the @samp{[} or after @samp{[^} then it | ||
| 1769 : | is treated literally. | ||
| 1770 : | @end itemize | ||
| 1771 : | |||
| 1772 : | @c ..................................................... | ||
| 1773 : | @c SUBSECTION | ||
| 1774 : | @c ..................................................... | ||
| 1775 : | |||
| 1776 : | @node Nested shells and reverse apostrophes, , Regular expressions, Shells | ||
| 1777 : | @subsection Nested shell commands and `` | ||
| 1778 : | |||
| 1779 : | |||
| 1780 : | @vindex `` shell construction | ||
| 1781 : | @vindex `...` | ||
| 1782 : | |||
| 1783 : | The backwards apostrophes `...` can be used in all shells and also in | ||
| 1784 : | the programming language Perl. When these are encountered in a | ||
| 1785 : | string the shell tries to execute the command inside the quotes and | ||
| 1786 : | replace the quoted expression by the result of that command. For example: | ||
| 1787 : | @smallexample | ||
| 1788 : | unix% echo "This system's kernel type is `/bin/file /vmunix`" | ||
| 1789 : | This system's kernel type is /vmunix: sparc executable not stripped | ||
| 1790 : | |||
| 1791 : | unix% foreach file ( `ls /etc/rc*` ) | ||
| 1792 : | ? echo I found a config file $file | ||
| 1793 : | ? echo Its type is `/bin/file $file` | ||
| 1794 : | ? end | ||
| 1795 : | |||
| 1796 : | I found a config file /etc/rc | ||
| 1797 : | Its type is /etc/rc: executable shell script | ||
| 1798 : | I found a config file /etc/rc.boot | ||
| 1799 : | Its type is /etc/rc.boot: executable shell script | ||
| 1800 : | I found a config file /etc/rc.ip | ||
| 1801 : | Its type is /etc/rc.ip: executable shell script | ||
| 1802 : | I found a config file /etc/rc.local | ||
| 1803 : | Its type is /etc/rc.local: ascii text | ||
| 1804 : | I found a config file /etc/rc.local~ | ||
| 1805 : | Its type is /etc/rc.local~: ascii text | ||
| 1806 : | I found a config file /etc/rc.single | ||
| 1807 : | Its type is /etc/rc.single: executable shell script | ||
| 1808 : | I found a config file /etc/rc~ | ||
| 1809 : | Its type is /etc/rc~: executable shell script | ||
| 1810 : | |||
| 1811 : | @end smallexample | ||
| 1812 : | |||
| 1813 : | This is how we insert the result of a shell command into a text string or | ||
| 1814 : | variable. | ||
| 1815 : | @cindex Inserting a command into a string | ||
| 1816 : | @cindex Result of a command into a string | ||
| 1817 : | @cindex Getting command output into a string | ||
| 1818 : | |||
| 1819 : | @c ------------------------------------------------------------------------------- | ||
| 1820 : | @c SECTION | ||
| 1821 : | @c ------------------------------------------------------------------------------- | ||
| 1822 : | |||
| 1823 : | |||
| 1824 : | @node UNIX command overview, Terminals, Shells, The login environment | ||
| 1825 : | @section UNIX command overview | ||
| 1826 : | |||
| 1827 : | @menu | ||
| 1828 : | * Keys:: | ||
| 1829 : | * Alternative shells:: | ||
| 1830 : | * terminal emulators:: | ||
| 1831 : | * Remote login:: | ||
| 1832 : | * Text editors:: | ||
| 1833 : | * File handling:: | ||
| 1834 : | * File browsers:: | ||
| 1835 : | * Access control:: | ||
| 1836 : | * Extracting from files:: | ||
| 1837 : | * Locating files:: | ||
| 1838 : | * Disk usage:: | ||
| 1839 : | * Other users:: | ||
| 1840 : | * Contacting users:: | ||
| 1841 : | * Mail:: | ||
| 1842 : | * File transfer:: | ||
| 1843 : | * Compilers:: | ||
| 1844 : | * Interpreted languages:: | ||
| 1845 : | * System statistics:: | ||
| 1846 : | * System identity:: | ||
| 1847 : | * Internet resources:: | ||
| 1848 : | * Text/postscript:: | ||
| 1849 : | * Pictures/graphics:: | ||
| 1850 : | * Miscellaneous:: | ||
| 1851 : | @end menu | ||
| 1852 : | |||
| 1853 : | @node Keys, Alternative shells, UNIX command overview, UNIX command overview | ||
| 1854 : | @subsection Important keys | ||
| 1855 : | |||
| 1856 : | @table @key | ||
| 1857 : | |||
| 1858 : | @item CTRL-A | ||
| 1859 : | Jump to start of line. If @samp{screen} is active, this | ||
| 1860 : | prefixes all control key commands for @samp{screen} and then | ||
| 1861 : | the normal @kbd{CTRL-A} is replaced by @kbd{CTRL-a a}. | ||
| 1862 : | |||
| 1863 : | @cindex @key{CTRL-A} | ||
| 1864 : | @vindex @key{CTRL-A} | ||
| 1865 : | |||
| 1866 : | @item CTRL-C | ||
| 1867 : | Interrupt or break key. Sends signal 15 to a process. | ||
| 1868 : | @cindex @key{CTRL-C} | ||
| 1869 : | @vindex @key{CTRL-C} | ||
| 1870 : | |||
| 1871 : | @item CTRL-D | ||
| 1872 : | Signifies @samp{EOF} (end of file) or shows expansion | ||
| 1873 : | matches in command/filename completion @xref{Command/filename completion}. | ||
| 1874 : | |||
| 1875 : | @cindex @key{CTRL-D} | ||
| 1876 : | @vindex @key{CTRL-D} | ||
| 1877 : | |||
| 1878 : | |||
| 1879 : | @item CTRL-E | ||
| 1880 : | Jump to end of line. | ||
| 1881 : | |||
| 1882 : | @cindex @key{CTRL-E} | ||
| 1883 : | @vindex @key{CTRL-E} | ||
| 1884 : | |||
| 1885 : | |||
| 1886 : | @item CTRL-L | ||
| 1887 : | Clear screen in newer shells and in emacs. Same as @samp{clear} | ||
| 1888 : | in the shell. | ||
| 1889 : | @cindex @key{CTRL-L} | ||
| 1890 : | @vindex @key{CTRL-L} | ||
| 1891 : | |||
| 1892 : | |||
| 1893 : | @item CTRL-Z | ||
| 1894 : | Suspend the present process, but do not destroy it. This sends | ||
| 1895 : | signal 18 to the process. | ||
| 1896 : | |||
| 1897 : | @cindex @key{CTRL-Z} | ||
| 1898 : | @vindex @key{CTRL-Z} | ||
| 1899 : | |||
| 1900 : | @end table | ||
| 1901 : | |||
| 1902 : | @c ---------------------------------------------- | ||
| 1903 : | |||
| 1904 : | @node Alternative shells, terminal emulators, Keys, UNIX command overview | ||
| 1905 : | @subsection Alternative shells | ||
| 1906 : | |||
| 1907 : | @cindex @key{Shells, various} | ||
| 1908 : | |||
| 1909 : | @table @code | ||
| 1910 : | |||
| 1911 : | @item bash | ||
| 1912 : | The Bourne Again shell, an improved sh. | ||
| 1913 : | @cindex bash | ||
| 1914 : | |||
| 1915 : | @item csh | ||
| 1916 : | The standard C-shell. | ||
| 1917 : | @cindex csh | ||
| 1918 : | |||
| 1919 : | @item jsh | ||
| 1920 : | The same as sh, with C-shell style job control. | ||
| 1921 : | @cindex jsh | ||
| 1922 : | |||
| 1923 : | @item ksh | ||
| 1924 : | The Korn shell, an improved sh. | ||
| 1925 : | @cindex ksh | ||
| 1926 : | |||
| 1927 : | @item sh | ||
| 1928 : | The original Bourne shell. | ||
| 1929 : | @cindex sh | ||
| 1930 : | |||
| 1931 : | @item sh5 | ||
| 1932 : | On ULTRIX systems the standard Bourne shell is | ||
| 1933 : | quite stupid. sh5 corresponds to the normal Bourne shell | ||
| 1934 : | on these systems. | ||
| 1935 : | @cindex sh5 | ||
| 1936 : | |||
| 1937 : | @item tcsh | ||
| 1938 : | An improved C-shell. | ||
| 1939 : | @cindex tcsh | ||
| 1940 : | |||
| 1941 : | @item zsh | ||
| 1942 : | An improved sh. | ||
| 1943 : | @cindex zsh | ||
| 1944 : | |||
| 1945 : | @end table | ||
| 1946 : | |||
| 1947 : | @c ---------------------------------------------- | ||
| 1948 : | |||
| 1949 : | @node terminal emulators, Remote login, Alternative shells, UNIX command overview | ||
| 1950 : | @subsection Window based terminal emulators | ||
| 1951 : | |||
| 1952 : | @cindex Terminals | ||
| 1953 : | @cindex Command window | ||
| 1954 : | |||
| 1955 : | @table @code | ||
| 1956 : | |||
| 1957 : | @item xterm | ||
| 1958 : | The standard X11 terminal window. | ||
| 1959 : | |||
| 1960 : | @cindex @samp{xterm} | ||
| 1961 : | @vindex @samp{xterm} | ||
| 1962 : | |||
| 1963 : | @item shelltool, cmdtool | ||
| 1964 : | Openwindows terminals from Sun Microsystems. These are | ||
| 1965 : | not completely X11 compatible during copy/paste operations. | ||
| 1966 : | |||
| 1967 : | |||
| 1968 : | @cindex @samp{shelltool} | ||
| 1969 : | @vindex @samp{shelltool} | ||
| 1970 : | |||
| 1971 : | @cindex @samp{cmdtool} | ||
| 1972 : | @vindex @samp{cmdtool} | ||
| 1973 : | |||
| 1974 : | |||
| 1975 : | |||
| 1976 : | |||
| 1977 : | @item screen | ||
| 1978 : | This is not a window in itself, but allows you to emulate | ||
| 1979 : | having several windows inside a single (say) xterm window. | ||
| 1980 : | The user can switch between different windows and open new | ||
| 1981 : | ones, but can only see one window at a time @xref{Multiple screens}. | ||
| 1982 : | |||
| 1983 : | @cindex @samp{screen} | ||
| 1984 : | @vindex @samp{screen} | ||
| 1985 : | |||
| 1986 : | |||
| 1987 : | @end table | ||
| 1988 : | |||
| 1989 : | @c ---------------------------------------------- | ||
| 1990 : | |||
| 1991 : | @node Remote login, Text editors, terminal emulators, UNIX command overview | ||
| 1992 : | @subsection Remote shells and logins | ||
| 1993 : | |||
| 1994 : | @table @code | ||
| 1995 : | |||
| 1996 : | @item rlogin | ||
| 1997 : | Login onto a remote unix system. | ||
| 1998 : | |||
| 1999 : | |||
| 2000 : | @cindex @samp{rlogin} | ||
| 2001 : | @vindex @samp{rlogin} | ||
| 2002 : | |||
| 2003 : | |||
| 2004 : | |||
| 2005 : | @item rsh | ||
| 2006 : | Open a shell on a remote system (require access rights). | ||
| 2007 : | |||
| 2008 : | @cindex @samp{rsh} | ||
| 2009 : | @vindex @samp{rsh} | ||
| 2010 : | |||
| 2011 : | |||
| 2012 : | @item telnet | ||
| 2013 : | Open a connection to a remove system using the telnet | ||
| 2014 : | protocol. | ||
| 2015 : | |||
| 2016 : | @cindex @samp{telnet} | ||
| 2017 : | @vindex @samp{telnet} | ||
| 2018 : | |||
| 2019 : | |||
| 2020 : | |||
| 2021 : | @end table | ||
| 2022 : | |||
| 2023 : | @c ---------------------------------------------- | ||
| 2024 : | |||
| 2025 : | @node Text editors, File handling, Remote login, UNIX command overview | ||
| 2026 : | @subsection Text editors | ||
| 2027 : | |||
| 2028 : | @table @code | ||
| 2029 : | |||
| 2030 : | @item ed | ||
| 2031 : | An ancient line-editor. | ||
| 2032 : | |||
| 2033 : | @cindex @samp{ed} | ||
| 2034 : | @vindex @samp{ed} | ||
| 2035 : | |||
| 2036 : | |||
| 2037 : | @item vi | ||
| 2038 : | Visual interface to @code{ed}. This is the only "standard" | ||
| 2039 : | unix text editor supplied by vendors. | ||
| 2040 : | |||
| 2041 : | @cindex @samp{vi} | ||
| 2042 : | @vindex @samp{vi} | ||
| 2043 : | |||
| 2044 : | |||
| 2045 : | @item emacs | ||
| 2046 : | The most powerful UNIX editor. A fully configurable, user | ||
| 2047 : | programmable editor which works under X11 and on tty-terminals. | ||
| 2048 : | |||
| 2049 : | @cindex @samp{emacs} | ||
| 2050 : | @vindex @samp{emacs} | ||
| 2051 : | |||
| 2052 : | |||
| 2053 : | @item xemacs | ||
| 2054 : | A pretty version of emacs for X11 windows. | ||
| 2055 : | |||
| 2056 : | @cindex @samp{xemacs} | ||
| 2057 : | @vindex @samp{xemacs} | ||
| 2058 : | |||
| 2059 : | |||
| 2060 : | @item pico | ||
| 2061 : | A tty-terminal only editor, comes as part of the PINE mail | ||
| 2062 : | package. | ||
| 2063 : | |||
| 2064 : | @cindex @samp{pico} | ||
| 2065 : | @vindex @samp{pico} | ||
| 2066 : | |||
| 2067 : | |||
| 2068 : | @item xedit | ||
| 2069 : | A test X11-only editor supplied with X-windows. | ||
| 2070 : | |||
| 2071 : | @cindex @samp{xedit} | ||
| 2072 : | @vindex @samp{xedit} | ||
| 2073 : | |||
| 2074 : | |||
| 2075 : | @item textedit | ||
| 2076 : | A simple X11-only editor supplied by Sun Microsystems. | ||
| 2077 : | |||
| 2078 : | @cindex @samp{textedit} | ||
| 2079 : | @vindex @samp{textedit} | ||
| 2080 : | |||
| 2081 : | |||
| 2082 : | @end table | ||
| 2083 : | |||
| 2084 : | @c ---------------------------------------------- | ||
| 2085 : | |||
| 2086 : | @node File handling, File browsers, Text editors, UNIX command overview | ||
| 2087 : | @subsection File handling commands | ||
| 2088 : | |||
| 2089 : | @table @code | ||
| 2090 : | |||
| 2091 : | @item ls | ||
| 2092 : | List files in specified directory (like @code{dir} on other | ||
| 2093 : | systems). | ||
| 2094 : | |||
| 2095 : | @cindex @samp{ls command} | ||
| 2096 : | @vindex @samp{ls} | ||
| 2097 : | |||
| 2098 : | |||
| 2099 : | @item cp | ||
| 2100 : | Copy files. | ||
| 2101 : | |||
| 2102 : | @cindex @samp{cp} command | ||
| 2103 : | @vindex @samp{cp} | ||
| 2104 : | |||
| 2105 : | |||
| 2106 : | @item mv | ||
| 2107 : | Move or rename files. | ||
| 2108 : | |||
| 2109 : | @cindex @samp{mv} command | ||
| 2110 : | @cindex Renaming files | ||
| 2111 : | @cindex Moving files | ||
| 2112 : | @vindex @samp{mv} | ||
| 2113 : | |||
| 2114 : | |||
| 2115 : | @item touch | ||
| 2116 : | Creates an empty new file if none exists, or updates date | ||
| 2117 : | and time stamps on existing files. | ||
| 2118 : | |||
| 2119 : | @cindex @samp{touch} command | ||
| 2120 : | @vindex @samp{touch} | ||
| 2121 : | @cindex Creating files | ||
| 2122 : | @cindex Time stamp, updating | ||
| 2123 : | @cindex Date stamp, updating | ||
| 2124 : | @cindex Updating file time stamp | ||
| 2125 : | |||
| 2126 : | @item rm, unlink | ||
| 2127 : | Remove a file or link (delete). | ||
| 2128 : | |||
| 2129 : | @cindex @samp{rm} command | ||
| 2130 : | @vindex @samp{unlink} | ||
| 2131 : | |||
| 2132 : | @cindex @samp{unlink} command | ||
| 2133 : | @vindex @samp{unlink} | ||
| 2134 : | |||
| 2135 : | |||
| 2136 : | @item mkdir, rmdir | ||
| 2137 : | Make or remove a directory. A directory must be empty in order | ||
| 2138 : | to be able to remove it. | ||
| 2139 : | |||
| 2140 : | @cindex @samp{mkdir} command | ||
| 2141 : | @vindex @samp{mkdir} | ||
| 2142 : | @cindex Creating directories | ||
| 2143 : | @cindex Directories, creating | ||
| 2144 : | @cindex Directories, deleting | ||
| 2145 : | @cindex @samp{rmdir} command | ||
| 2146 : | @vindex @samp{rmdir} | ||
| 2147 : | |||
| 2148 : | @item cat | ||
| 2149 : | Concatenate or join together a number of files. The output is | ||
| 2150 : | written to the standard output by default. Can also be used | ||
| 2151 : | to simply print a file on screen. | ||
| 2152 : | |||
| 2153 : | @cindex @samp{cat} command | ||
| 2154 : | @vindex @samp{cat} | ||
| 2155 : | |||
| 2156 : | |||
| 2157 : | @item lp, lpr | ||
| 2158 : | Line printer. Send a file to the default printer, or the printer | ||
| 2159 : | defined in the @samp{PRINTER} evironment variable. | ||
| 2160 : | @cindex @samp{PRINTER} variable | ||
| 2161 : | @vindex @samp{PRINTER} | ||
| 2162 : | @cindex @samp{lp} command | ||
| 2163 : | @vindex @samp{lp} | ||
| 2164 : | |||
| 2165 : | @cindex @samp{lpr} command | ||
| 2166 : | @vindex @samp{lp} | ||
| 2167 : | @cindex Printing a file | ||
| 2168 : | |||
| 2169 : | @item lpq, lpstat | ||
| 2170 : | Show the status of the print queue. | ||
| 2171 : | |||
| 2172 : | @cindex @samp{lpq} | ||
| 2173 : | @vindex @samp{lpq} | ||
| 2174 : | @cindex Printer queue | ||
| 2175 : | @cindex Printer status | ||
| 2176 : | @cindex @samp{lpstat} | ||
| 2177 : | @vindex @samp{lpstat} | ||
| 2178 : | |||
| 2179 : | @end table | ||
| 2180 : | |||
| 2181 : | @c ---------------------------------------------- | ||
| 2182 : | |||
| 2183 : | @node File browsers, Access control, File handling, UNIX command overview | ||
| 2184 : | @subsection File browsing | ||
| 2185 : | |||
| 2186 : | @table @code | ||
| 2187 : | |||
| 2188 : | @item more | ||
| 2189 : | Shows one screen full at a time. Possibility to search for | ||
| 2190 : | a string and edit the file. This is like | ||
| 2191 : | @samp{type @var{file} | more} in DOS. | ||
| 2192 : | |||
| 2193 : | @cindex @samp{more} command | ||
| 2194 : | @vindex @samp{more} | ||
| 2195 : | @cindex Viewing a file | ||
| 2196 : | @cindex Browsing through a file | ||
| 2197 : | @cindex @samp{type} in DOS | ||
| 2198 : | |||
| 2199 : | @item less | ||
| 2200 : | An enhanced version of more. | ||
| 2201 : | |||
| 2202 : | @cindex @samp{less} command | ||
| 2203 : | @vindex @samp{less} | ||
| 2204 : | |||
| 2205 : | @cindex nc | ||
| 2206 : | @cindex mc | ||
| 2207 : | @item mc | ||
| 2208 : | Midnight commander, a free version of the `Norton Commander' | ||
| 2209 : | PC utility for unix. (Only for non-serious UNIX users...) | ||
| 2210 : | |||
| 2211 : | @item fmgr | ||
| 2212 : | A window based file manager with icons and all that nonsense. | ||
| 2213 : | |||
| 2214 : | |||
| 2215 : | @end table | ||
| 2216 : | |||
| 2217 : | @c ---------------------------------------------- | ||
| 2218 : | |||
| 2219 : | @node Access control, Extracting from files, File browsers, UNIX command overview | ||
| 2220 : | @subsection Ownership and granting access permission | ||
| 2221 : | |||
| 2222 : | @cindex Access control | ||
| 2223 : | @cindex Granting permission | ||
| 2224 : | @table @code | ||
| 2225 : | |||
| 2226 : | @item chmod | ||
| 2227 : | Change file access mode. | ||
| 2228 : | |||
| 2229 : | @cindex @samp{chmod} command | ||
| 2230 : | @vindex @samp{chmod} | ||
| 2231 : | @cindex Changing file mode | ||
| 2232 : | @cindex File mode, changing | ||
| 2233 : | |||
| 2234 : | @item chown, chgrp | ||
| 2235 : | Change owner and group of a file. The GNU version of @code{chown} | ||
| 2236 : | allows both these operations to be performed together using | ||
| 2237 : | the syntax @code{chown @var{owner}.@var{group} @var{file}}. | ||
| 2238 : | |||
| 2239 : | @cindex @samp{chown} command | ||
| 2240 : | @vindex @samp{chown} | ||
| 2241 : | |||
| 2242 : | @cindex @samp{chgrp} command | ||
| 2243 : | @vindex @samp{chgrp} | ||
| 2244 : | |||
| 2245 : | @item acl | ||
| 2246 : | On newer Unices, Access control lists allow access to be granted | ||
| 2247 : | on a per-user basis rather than by groups. | ||
| 2248 : | |||
| 2249 : | @cindex Access control lists | ||
| 2250 : | @cindex ACLs | ||
| 2251 : | |||
| 2252 : | @cindex @samp{fmgr} file manager | ||
| 2253 : | @vindex @samp{fmgr} | ||
| 2254 : | |||
| 2255 : | |||
| 2256 : | @end table | ||
| 2257 : | |||
| 2258 : | @c ---------------------------------------------- | ||
| 2259 : | |||
| 2260 : | @node Extracting from files, Locating files, Access control, UNIX command overview | ||
| 2261 : | @subsection Extracting from and rebuilding files | ||
| 2262 : | |||
| 2263 : | @table @code | ||
| 2264 : | |||
| 2265 : | @item cut | ||
| 2266 : | Extract a column in a table | ||
| 2267 : | |||
| 2268 : | @cindex @samp{cut} command | ||
| 2269 : | @vindex @samp{cut} | ||
| 2270 : | |||
| 2271 : | @item paste | ||
| 2272 : | Merge several files so that each file becomes a column in | ||
| 2273 : | a table. | ||
| 2274 : | |||
| 2275 : | @cindex @samp{paste} command | ||
| 2276 : | @vindex @samp{paste} | ||
| 2277 : | |||
| 2278 : | |||
| 2279 : | @item sed | ||
| 2280 : | A batch text-editor for searching, replacing and selecting | ||
| 2281 : | text without human intervention. | ||
| 2282 : | |||
| 2283 : | @cindex @samp{sed} editor | ||
| 2284 : | @vindex @samp{sed} | ||
| 2285 : | |||
| 2286 : | |||
| 2287 : | @item awk | ||
| 2288 : | A prerunner to the Perl language, for extracting and modifying | ||
| 2289 : | textfiles. | ||
| 2290 : | |||
| 2291 : | @cindex @samp{awk} | ||
| 2292 : | @vindex @samp{awk} | ||
| 2293 : | |||
| 2294 : | @item rmcr | ||
| 2295 : | Strip carriage return (ASCII 13) characters from a file. | ||
| 2296 : | Useful for converting DOS files to unix. | ||
| 2297 : | |||
| 2298 : | @end table | ||
| 2299 : | |||
| 2300 : | @c ---------------------------------------------- | ||
| 2301 : | |||
| 2302 : | @node Locating files, Disk usage, Extracting from files, UNIX command overview | ||
| 2303 : | @subsection Locating files | ||
| 2304 : | |||
| 2305 : | @table @code | ||
| 2306 : | |||
| 2307 : | @item find | ||
| 2308 : | Search for files from a specified directory using various | ||
| 2309 : | criteria. | ||
| 2310 : | |||
| 2311 : | @cindex @samp{find} command | ||
| 2312 : | @vindex @samp{find} | ||
| 2313 : | |||
| 2314 : | @item locate | ||
| 2315 : | Fast search in a global file database for files containing | ||
| 2316 : | a search-string. | ||
| 2317 : | |||
| 2318 : | @cindex @samp{locate} command | ||
| 2319 : | @vindex @samp{locate} | ||
| 2320 : | |||
| 2321 : | |||
| 2322 : | @item whereis | ||
| 2323 : | Look for a command and its documentation on the system. | ||
| 2324 : | |||
| 2325 : | @cindex @samp{whereis} command | ||
| 2326 : | @vindex @samp{whereis} | ||
| 2327 : | |||
| 2328 : | |||
| 2329 : | @end table | ||
| 2330 : | |||
| 2331 : | @c ---------------------------------------------- | ||
| 2332 : | |||
| 2333 : | @node Disk usage, Other users, Locating files, UNIX command overview | ||
| 2334 : | @subsection Disk usage. | ||
| 2335 : | |||
| 2336 : | @cindex Disk usage. | ||
| 2337 : | |||
| 2338 : | @table @code | ||
| 2339 : | |||
| 2340 : | @item du | ||
| 2341 : | Show number of blocks used by a file or files. | ||
| 2342 : | |||
| 2343 : | @cindex @samp{du} command | ||
| 2344 : | @vindex @samp{du} | ||
| 2345 : | |||
| 2346 : | |||
| 2347 : | @item df | ||
| 2348 : | Show the state of usage for one or more disk partitions. | ||
| 2349 : | |||
| 2350 : | @cindex @samp{df} command | ||
| 2351 : | @vindex @samp{df} | ||
| 2352 : | |||
| 2353 : | |||
| 2354 : | @end table | ||
| 2355 : | |||
| 2356 : | @c ---------------------------------------------- | ||
| 2357 : | |||
| 2358 : | @node Other users, Contacting users, Disk usage, UNIX command overview | ||
| 2359 : | @subsection Show other users logged on | ||
| 2360 : | |||
| 2361 : | @table @code | ||
| 2362 : | |||
| 2363 : | @item users | ||
| 2364 : | Simple list of other users. | ||
| 2365 : | |||
| 2366 : | @cindex @samp{users} command | ||
| 2367 : | @vindex @samp{users} | ||
| 2368 : | |||
| 2369 : | |||
| 2370 : | @item finger | ||
| 2371 : | Show who is logged onto this and other systems. | ||
| 2372 : | |||
| 2373 : | @cindex @samp{finger} service | ||
| 2374 : | @vindex @samp{finger} | ||
| 2375 : | |||
| 2376 : | |||
| 2377 : | @item who | ||
| 2378 : | List of users logged into this system. | ||
| 2379 : | |||
| 2380 : | @cindex @samp{who} command | ||
| 2381 : | @vindex @samp{who} | ||
| 2382 : | |||
| 2383 : | |||
| 2384 : | @item w | ||
| 2385 : | Long list of who is logged onto this system and what they | ||
| 2386 : | are doing. | ||
| 2387 : | |||
| 2388 : | @cindex @samp{w} command | ||
| 2389 : | @vindex @samp{w} | ||
| 2390 : | |||
| 2391 : | |||
| 2392 : | @end table | ||
| 2393 : | |||
| 2394 : | @node Contacting users, Mail, Other users, UNIX command overview | ||
| 2395 : | @subsection Contacting other users | ||
| 2396 : | |||
| 2397 : | @table @code | ||
| 2398 : | |||
| 2399 : | @item write | ||
| 2400 : | Send a simple message to the named user, end with @key{CTRL-D}. | ||
| 2401 : | The command @samp{mesg n} switches off messages receipt. | ||
| 2402 : | |||
| 2403 : | @cindex Sending messages | ||
| 2404 : | @cindex Messages | ||
| 2405 : | @cindex @samp{write} command | ||
| 2406 : | @vindex @samp{write} | ||
| 2407 : | @cindex @samp{mesg} | ||
| 2408 : | @vindex @samp{mesg} | ||
| 2409 : | |||
| 2410 : | |||
| 2411 : | |||
| 2412 : | @item talk | ||
| 2413 : | Interactive two-way conversation with named user. | ||
| 2414 : | |||
| 2415 : | @cindex @samp{talk} service | ||
| 2416 : | @vindex @samp{talk} | ||
| 2417 : | |||
| 2418 : | |||
| 2419 : | @item irc | ||
| 2420 : | Internet relay chat. A conferencing system for realtime | ||
| 2421 : | multi-user conversations, for addicts and losers. | ||
| 2422 : | |||
| 2423 : | @cindex @samp{IRC} | ||
| 2424 : | @cindex Internet relay chat | ||
| 2425 : | @vindex @samp{irc} | ||
| 2426 : | |||
| 2427 : | |||
| 2428 : | @end table | ||
| 2429 : | |||
| 2430 : | @c ---------------------------------------------- | ||
| 2431 : | |||
| 2432 : | @node Mail, File transfer, Contacting users, UNIX command overview | ||
| 2433 : | @subsection Mail senders/readers | ||
| 2434 : | @cindex Mail clients | ||
| 2435 : | |||
| 2436 : | @table @code | ||
| 2437 : | |||
| 2438 : | @item mail | ||
| 2439 : | The standard (old) mail interface. | ||
| 2440 : | |||
| 2441 : | @item Mail | ||
| 2442 : | Another mail interface. | ||
| 2443 : | |||
| 2444 : | @item elm | ||
| 2445 : | Electronic Mail program. Lots of functionality but poor | ||
| 2446 : | support for multimedia. | ||
| 2447 : | |||
| 2448 : | @cindex @samp{elm} mailer | ||
| 2449 : | @vindex @samp{elm} | ||
| 2450 : | |||
| 2451 : | |||
| 2452 : | @item pine | ||
| 2453 : | Rumours (untrue) are that pine stands for Pine is Not Elm; | ||
| 2454 : | it actually stands for nothing at all. | ||
| 2455 : | Improved support for multimedia but very | ||
| 2456 : | slow and rather stupid at times. Some of the best features of | ||
| 2457 : | elm have been removed! | ||
| 2458 : | |||
| 2459 : | @cindex @samp{pine} mailer | ||
| 2460 : | @vindex @samp{pine} | ||
| 2461 : | |||
| 2462 : | |||
| 2463 : | @item mailtool | ||
| 2464 : | Sun's openwindows client program. | ||
| 2465 : | |||
| 2466 : | @item rmail | ||
| 2467 : | A mail interface built into the emacs editor. | ||
| 2468 : | |||
| 2469 : | @cindex @samp{rmail} in emacs | ||
| 2470 : | @vindex @samp{rmail} | ||
| 2471 : | |||
| 2472 : | @item netscape mail | ||
| 2473 : | A mail interface built into the netscape navigator. | ||
| 2474 : | |||
| 2475 : | @item zmail | ||
| 2476 : | A commerical mail package. | ||
| 2477 : | |||
| 2478 : | @cindex @samp{zmail} client | ||
| 2479 : | @vindex @samp{zmail} | ||
| 2480 : | |||
| 2481 : | @item tkrat | ||
| 2482 : | A graphical mail reader which supports most MIME types, written | ||
| 2483 : | in tcl/tk. This program has a nice feel and allows you to create | ||
| 2484 : | a searchable database of old mail messages, but has a hopeless | ||
| 2485 : | locking mechanism. | ||
| 2486 : | |||
| 2487 : | @end table | ||
| 2488 : | |||
| 2489 : | @c ---------------------------------------------- | ||
| 2490 : | |||
| 2491 : | @node File transfer, Compilers, Mail, UNIX command overview | ||
| 2492 : | @subsection File transfer | ||
| 2493 : | |||
| 2494 : | @cindex File transfer | ||
| 2495 : | |||
| 2496 : | @table @code | ||
| 2497 : | |||
| 2498 : | @item ftp | ||
| 2499 : | The File Transfer program - copies files to/from a remote host. | ||
| 2500 : | |||
| 2501 : | @cindex @samp{ftp} program | ||
| 2502 : | @vindex @samp{ftp} | ||
| 2503 : | |||
| 2504 : | |||
| 2505 : | @item ncftp | ||
| 2506 : | An enhanced ftp for anonymous login. | ||
| 2507 : | |||
| 2508 : | @cindex @samp{ncftp} program | ||
| 2509 : | @vindex @samp{ncftp} | ||
| 2510 : | |||
| 2511 : | @end table | ||
| 2512 : | |||
| 2513 : | @c ---------------------------------------------- | ||
| 2514 : | |||
| 2515 : | @node Compilers, Interpreted languages, File transfer, UNIX command overview | ||
| 2516 : | @subsection Compilers | ||
| 2517 : | @cindex Compilers | ||
| 2518 : | |||
| 2519 : | @table @code | ||
| 2520 : | |||
| 2521 : | @item cc | ||
| 2522 : | The C compiler. | ||
| 2523 : | |||
| 2524 : | @cindex @samp{cc} | ||
| 2525 : | @vindex @samp{cc} | ||
| 2526 : | |||
| 2527 : | |||
| 2528 : | @item CC | ||
| 2529 : | The C++ compiler. | ||
| 2530 : | |||
| 2531 : | @cindex @samp{CC} | ||
| 2532 : | @vindex @samp{CC} | ||
| 2533 : | |||
| 2534 : | |||
| 2535 : | @item gcc | ||
| 2536 : | The GNU C compiler. | ||
| 2537 : | |||
| 2538 : | @cindex @samp{gcc} | ||
| 2539 : | @vindex @samp{gcc} | ||
| 2540 : | |||
| 2541 : | |||
| 2542 : | @item g++ | ||
| 2543 : | The GNU C++ compiler. | ||
| 2544 : | |||
| 2545 : | @cindex @samp{g++} | ||
| 2546 : | @vindex @samp{g++} | ||
| 2547 : | |||
| 2548 : | |||
| 2549 : | @item ld | ||
| 2550 : | The system linker/loader. | ||
| 2551 : | |||
| 2552 : | @cindex @samp{ld} loader/linker | ||
| 2553 : | @vindex @samp{ld} | ||
| 2554 : | |||
| 2555 : | |||
| 2556 : | @item ar | ||
| 2557 : | Archive library builder. | ||
| 2558 : | |||
| 2559 : | @cindex @samp{ar} archiver | ||
| 2560 : | @vindex @samp{ar} | ||
| 2561 : | |||
| 2562 : | |||
| 2563 : | @item dbx | ||
| 2564 : | A symbolic debugger. | ||
| 2565 : | |||
| 2566 : | @cindex @samp{dbx} debugger | ||
| 2567 : | @cindex Debugger | ||
| 2568 : | @vindex @samp{dbx} | ||
| 2569 : | |||
| 2570 : | |||
| 2571 : | @item gdb | ||
| 2572 : | The GNU symbolic debugger. | ||
| 2573 : | |||
| 2574 : | @cindex @samp{gdb} debugger | ||
| 2575 : | @vindex @samp{gdb} | ||
| 2576 : | |||
| 2577 : | |||
| 2578 : | @item xxgdb | ||
| 2579 : | The GNU debugger with a windown driven front-end. | ||
| 2580 : | @item ddd | ||
| 2581 : | A motif based front-end to the gdb debugger. | ||
| 2582 : | @vindex ddd | ||
| 2583 : | |||
| 2584 : | @end table | ||
| 2585 : | |||
| 2586 : | |||
| 2587 : | @cindex @samp{xxgdb} | ||
| 2588 : | @cindex Debugger GUI | ||
| 2589 : | @vindex @samp{xxgdb} | ||
| 2590 : | |||
| 2591 : | @c ---------------------------------------------- | ||
| 2592 : | |||
| 2593 : | @node Interpreted languages, System statistics, Compilers, UNIX command overview | ||
| 2594 : | @subsection Other interpreted languages | ||
| 2595 : | |||
| 2596 : | @table @code | ||
| 2597 : | |||
| 2598 : | @item perl | ||
| 2599 : | Practical extraction an report language. | ||
| 2600 : | |||
| 2601 : | @item tcl | ||
| 2602 : | A perl-like language with special support for | ||
| 2603 : | building user interfaces and command shells. | ||
| 2604 : | |||
| 2605 : | @cindex @samp{TCL} | ||
| 2606 : | @vindex @samp{tcl} | ||
| 2607 : | |||
| 2608 : | |||
| 2609 : | @item scheme | ||
| 2610 : | A lisp-like extensible scripting language from GNU. | ||
| 2611 : | |||
| 2612 : | |||
| 2613 : | @cindex scheme | ||
| 2614 : | |||
| 2615 : | @item mercury | ||
| 2616 : | A prolog-like language for artificial intelligence. | ||
| 2617 : | @cindex Mercury | ||
| 2618 : | |||
| 2619 : | @end table | ||
| 2620 : | |||
| 2621 : | @node System statistics, System identity, Interpreted languages, UNIX command overview | ||
| 2622 : | @subsection Processes and system statistics | ||
| 2623 : | |||
| 2624 : | @table @code | ||
| 2625 : | @item ps | ||
| 2626 : | List system process table. | ||
| 2627 : | |||
| 2628 : | @cindex @samp{ps} command | ||
| 2629 : | @vindex @samp{ps} | ||
| 2630 : | |||
| 2631 : | |||
| 2632 : | @item vmstat | ||
| 2633 : | List kernel virtual-memory statistics. | ||
| 2634 : | |||
| 2635 : | @cindex @samp{vmstat} virtual memory stats | ||
| 2636 : | @vindex @samp{vmstat} | ||
| 2637 : | |||
| 2638 : | |||
| 2639 : | @item netstat | ||
| 2640 : | List network connections and statistics. | ||
| 2641 : | |||
| 2642 : | @cindex @samp{netstat} network statistics | ||
| 2643 : | @vindex @samp{netstat} | ||
| 2644 : | |||
| 2645 : | |||
| 2646 : | @item rpcinfo | ||
| 2647 : | Show rpc information. | ||
| 2648 : | |||
| 2649 : | @cindex @samp{rpcinfo} | ||
| 2650 : | @vindex @samp{rcpinfo} | ||
| 2651 : | |||
| 2652 : | |||
| 2653 : | @item showmount | ||
| 2654 : | Show clients mounting local filesystems. | ||
| 2655 : | |||
| 2656 : | @cindex @samp{showmount} | ||
| 2657 : | @cindex Mounted file systems | ||
| 2658 : | @vindex @samp{showmount} | ||
| 2659 : | @end table | ||
| 2660 : | |||
| 2661 : | @node System identity, Internet resources, System statistics, UNIX command overview | ||
| 2662 : | @subsection System identity | ||
| 2663 : | |||
| 2664 : | @table @code | ||
| 2665 : | |||
| 2666 : | @item uname | ||
| 2667 : | Display system name and operating system release. | ||
| 2668 : | |||
| 2669 : | @cindex @samp{System details} | ||
| 2670 : | @vindex @samp{uname} | ||
| 2671 : | @cindex Operating system name | ||
| 2672 : | @cindex System name | ||
| 2673 : | |||
| 2674 : | |||
| 2675 : | |||
| 2676 : | |||
| 2677 : | @item hostname | ||
| 2678 : | Show the name of this host. | ||
| 2679 : | |||
| 2680 : | @cindex @samp{hostname} command | ||
| 2681 : | @vindex @samp{hostname} | ||
| 2682 : | |||
| 2683 : | |||
| 2684 : | @item domainname | ||
| 2685 : | Show the name of the local NIS domain. Normally this is | ||
| 2686 : | chosen to be the same as the BIND/DNS domain, but it | ||
| 2687 : | need not be. | ||
| 2688 : | |||
| 2689 : | @cindex @samp{domainname} command | ||
| 2690 : | @vindex @samp{domainname} | ||
| 2691 : | @cindex Domainname | ||
| 2692 : | |||
| 2693 : | |||
| 2694 : | @item nslookup | ||
| 2695 : | Interrogate the DNS/BIND name service (hostname to IP address | ||
| 2696 : | conversion). | ||
| 2697 : | |||
| 2698 : | @cindex @samp{nslookup} command | ||
| 2699 : | @vindex @samp{nslookup} | ||
| 2700 : | |||
| 2701 : | |||
| 2702 : | @end table | ||
| 2703 : | |||
| 2704 : | @c ---------------------------------------------- | ||
| 2705 : | |||
| 2706 : | @node Internet resources, Text/postscript, System identity, UNIX command overview | ||
| 2707 : | @subsection Internet resources | ||
| 2708 : | |||
| 2709 : | @cindex Internet resources | ||
| 2710 : | @table @code | ||
| 2711 : | |||
| 2712 : | @item archie, xarchie | ||
| 2713 : | Search the internet ftp database for files. | ||
| 2714 : | |||
| 2715 : | @cindex @samp{archie} program | ||
| 2716 : | @vindex @samp{archie} | ||
| 2717 : | @cindex FTP resources, finding | ||
| 2718 : | @cindex Finding FTP files | ||
| 2719 : | @cindex @samp{xarchie} client | ||
| 2720 : | @vindex @samp{xarchie} | ||
| 2721 : | |||
| 2722 : | @item xrn, fnews | ||
| 2723 : | Read news (browser). | ||
| 2724 : | |||
| 2725 : | @cindex @samp{xrn} news reader | ||
| 2726 : | @vindex @samp{xrn} | ||
| 2727 : | |||
| 2728 : | @cindex @samp{fnews} news reader | ||
| 2729 : | @vindex @samp{fnews} | ||
| 2730 : | |||
| 2731 : | @item netscape, xmosaic | ||
| 2732 : | Read world wide web (WWW) (browser). | ||
| 2733 : | |||
| 2734 : | @cindex @samp{mosaic} | ||
| 2735 : | @vindex @samp{xmosaic} | ||
| 2736 : | |||
| 2737 : | |||
| 2738 : | @end table | ||
| 2739 : | |||
| 2740 : | @c ---------------------------------------------- | ||
| 2741 : | |||
| 2742 : | @node Text/postscript, Pictures/graphics, Internet resources, UNIX command overview | ||
| 2743 : | @subsection Text formatting and postscript | ||
| 2744 : | |||
| 2745 : | @cindex Postscript viewers | ||
| 2746 : | @cindex Text formatting | ||
| 2747 : | @table @code | ||
| 2748 : | |||
| 2749 : | @item tex, latex | ||
| 2750 : | Donald Knuth's text formatting language, pronounced "tek" | ||
| 2751 : | (the x is really a greek "chi"). Used widely | ||
| 2752 : | for technical publications. Compiles to dvi (device independent) | ||
| 2753 : | file format. | ||
| 2754 : | |||
| 2755 : | @cindex @samp{tex} | ||
| 2756 : | @vindex @samp{tex} | ||
| 2757 : | |||
| 2758 : | @cindex @samp{latex} | ||
| 2759 : | @vindex @samp{latex} | ||
| 2760 : | |||
| 2761 : | |||
| 2762 : | |||
| 2763 : | @item texinfo | ||
| 2764 : | A hypertext documentation system using tex and "info" | ||
| 2765 : | format. This is the GNU documentation system. | ||
| 2766 : | This UNIX guide is written in texinfo!!! | ||
| 2767 : | |||
| 2768 : | @cindex Hypertext | ||
| 2769 : | @cindex @samp{texinfo} system | ||
| 2770 : | @vindex @samp{texinfo} | ||
| 2771 : | |||
| 2772 : | |||
| 2773 : | |||
| 2774 : | @item xdvi | ||
| 2775 : | View a tex dvi file on screen. | ||
| 2776 : | |||
| 2777 : | @vindex @samp{xdvi} | ||
| 2778 : | |||
| 2779 : | @item dvips | ||
| 2780 : | Convert dvi format into postscript. | ||
| 2781 : | |||
| 2782 : | @cindex dvi to postscript | ||
| 2783 : | @vindex @samp{dvips} | ||
| 2784 : | |||
| 2785 : | |||
| 2786 : | @item ghostview, ghostscript | ||
| 2787 : | View a postscript file on screen. | ||
| 2788 : | |||
| 2789 : | @cindex @samp{ghostview} postscript previewer | ||
| 2790 : | @vindex @samp{ghostview} | ||
| 2791 : | |||
| 2792 : | @cindex @samp{ghostscript} "GNU postscript" interpreter | ||
| 2793 : | @vindex @samp{ghostscript} | ||
| 2794 : | |||
| 2795 : | |||
| 2796 : | |||
| 2797 : | @end table | ||
| 2798 : | |||
| 2799 : | @c ---------------------------------------------- | ||
| 2800 : | |||
| 2801 : | @node Pictures/graphics, Miscellaneous, Text/postscript, UNIX command overview | ||
| 2802 : | @subsection Picture editors and processors | ||
| 2803 : | |||
| 2804 : | @cindex Picture processing | ||
| 2805 : | |||
| 2806 : | @table @code | ||
| 2807 : | |||
| 2808 : | @item xv | ||
| 2809 : | Handles, edits and processes pictures in a variety of | ||
| 2810 : | standard graphics formats (gif, jpg, tiff etc). | ||
| 2811 : | Use @code{xv -quit} to place a picture on your root window. | ||
| 2812 : | |||
| 2813 : | @cindex @samp{xv} picture processor | ||
| 2814 : | @vindex @samp{xv} | ||
| 2815 : | @cindex gif | ||
| 2816 : | @cindex jpg | ||
| 2817 : | @cindex tiff | ||
| 2818 : | |||
| 2819 : | @item xpaint | ||
| 2820 : | A simple paint program. | ||
| 2821 : | |||
| 2822 : | @cindex @samp{xpaint} program | ||
| 2823 : | @vindex @samp{xpaint} | ||
| 2824 : | @cindex Painting program | ||
| 2825 : | |||
| 2826 : | @item xfig | ||
| 2827 : | A line drawing figure editor. Produces postscript, tex, | ||
| 2828 : | and a variety of other output formats. | ||
| 2829 : | |||
| 2830 : | @cindex @samp{xfig} drawing program | ||
| 2831 : | @vindex @samp{xfig} | ||
| 2832 : | @cindex Drawing program | ||
| 2833 : | |||
| 2834 : | |||
| 2835 : | @item xsetroot | ||
| 2836 : | Load an X-bitmap image into the screen (root window) | ||
| 2837 : | background. Small images are tiled. | ||
| 2838 : | |||
| 2839 : | @cindex @samp{Background picture} | ||
| 2840 : | @vindex @samp{setroot} | ||
| 2841 : | |||
| 2842 : | |||
| 2843 : | @end table | ||
| 2844 : | |||
| 2845 : | @c ---------------------------------------------- | ||
| 2846 : | |||
| 2847 : | @node Miscellaneous, , Pictures/graphics, UNIX command overview | ||
| 2848 : | @subsection Miscellaneous | ||
| 2849 : | |||
| 2850 : | @table @code | ||
| 2851 : | |||
| 2852 : | @item date | ||
| 2853 : | Print the date and time. | ||
| 2854 : | |||
| 2855 : | @cindex @samp{date} command | ||
| 2856 : | @vindex @samp{date} | ||
| 2857 : | @cindex Time and date | ||
| 2858 : | |||
| 2859 : | @item ispell | ||
| 2860 : | Spelling checker. | ||
| 2861 : | |||
| 2862 : | @cindex Spelling checker | ||
| 2863 : | @vindex @samp{ispell} | ||
| 2864 : | |||
| 2865 : | |||
| 2866 : | @item xcalc | ||
| 2867 : | A graphical calculator. | ||
| 2868 : | |||
| 2869 : | @cindex Calculator, X windows | ||
| 2870 : | @vindex @samp{xcalc} | ||
| 2871 : | |||
| 2872 : | |||
| 2873 : | @item dc,bc | ||
| 2874 : | Text-based calculators. | ||
| 2875 : | |||
| 2876 : | @cindex Calculator, shell | ||
| 2877 : | @vindex @samp{dc} | ||
| 2878 : | |||
| 2879 : | |||
| 2880 : | @item xclock | ||
| 2881 : | A clock! | ||
| 2882 : | |||
| 2883 : | @item ping | ||
| 2884 : | Send a "sonar" ping to see if another unix host is alive. | ||
| 2885 : | |||
| 2886 : | @cindex @samp{Sonar} ping | ||
| 2887 : | @vindex @samp{ping} | ||
| 2888 : | @cindex Testing reponse from other hosts. | ||
| 2889 : | |||
| 2890 : | @end table | ||
| 2891 : | |||
| 2892 : | @c ----------------------------------------------------------------------- | ||
| 2893 : | @c SECTION | ||
| 2894 : | @c ----------------------------------------------------------------------- | ||
| 2895 : | |||
| 2896 : | @node Terminals, The X window system, UNIX command overview, The login environment | ||
| 2897 : | @section Terminals | ||
| 2898 : | |||
| 2899 : | @cindex tty | ||
| 2900 : | @cindex Teletype terminal | ||
| 2901 : | @cindex xterm program | ||
| 2902 : | In order to communicate with a user, a shell needs to have access to a | ||
| 2903 : | terminal. Unix was designed to work with many different kinds of | ||
| 2904 : | terminals. Input/output commands in Unix read and write to a virtual | ||
| 2905 : | terminal. In @emph{reality} a terminal might be a text-based Teletype | ||
| 2906 : | terminal (called a @emph{tty} for short) or a graphics based terminal; | ||
| 2907 : | it might be 80-characters wide or it might be wider or narrower. Unix | ||
| 2908 : | take into account these possibility by defining a number of instances of | ||
| 2909 : | terminals in a more or less object oriented way. | ||
| 2910 : | |||
| 2911 : | Each user's terminal has to be configured before cursor based input/output | ||
| 2912 : | will work correctly. Normally this is done by choosing one of a number of | ||
| 2913 : | standard terminal types a list which is supplied by the system. In practice | ||
| 2914 : | the user defines the value of the environment variable @samp{TERM} to | ||
| 2915 : | an appropriate name. Typical examples are @samp{vt100} and @samp{xterm}. | ||
| 2916 : | If no standard setup is found, the terminal can always be configured | ||
| 2917 : | manually using UNIX's most cryptic and opaque of commands: @samp{stty}. | ||
| 2918 : | |||
| 2919 : | The job of configuring terminals is much easier now that hardware is more | ||
| 2920 : | standard. Users' terminals are usually configured centrally by the system | ||
| 2921 : | administrator and it is seldom indeed that one ever has to choose anything | ||
| 2922 : | other than @samp{vt100} or @samp{xterm}. | ||
| 2923 : | |||
| 2924 : | @c ----------------------------------------------------------------------- | ||
| 2925 : | @c SECTION | ||
| 2926 : | @c ----------------------------------------------------------------------- | ||
| 2927 : | |||
| 2928 : | @node The X window system, Multiple screens, Terminals, The login environment | ||
| 2929 : | @section The X window system | ||
| 2930 : | |||
| 2931 : | Because UNIX originated before windowing technology was available, the | ||
| 2932 : | user-interface was not designed with windowing in mind. The X window | ||
| 2933 : | system attempts to be like a virtual machine park, running a different | ||
| 2934 : | program in each window. Although the programs appear on one screen, they | ||
| 2935 : | may in fact be running on unix systems anywhere in the world, with only | ||
| 2936 : | the output being local to the user's display. The standard shell | ||
| 2937 : | interface is available by running an X client application called | ||
| 2938 : | @samp{xterm} which is a graphical front-end to the standard UNIX | ||
| 2939 : | textual interface. | ||
| 2940 : | |||
| 2941 : | @cindex rlogin program | ||
| 2942 : | The @samp{xterm} program provides a virtual terminal using the X windows | ||
| 2943 : | graphical user interface. It works in exactly the same way as a @emph{tty} | ||
| 2944 : | terminal, except that standard graphical facilities like copy and paste | ||
| 2945 : | are available. Moreover, the user has the convenience of being able | ||
| 2946 : | to run a different shell in every window. For example, using the @samp{rlogin} | ||
| 2947 : | command, it is possible to work on the local system in one window, and on | ||
| 2948 : | another remote system in another window. The X-window environment allows | ||
| 2949 : | one to cut and paste between windows, regardless of which host the shell | ||
| 2950 : | runs on. | ||
| 2951 : | |||
| 2952 : | @c ..................................................... | ||
| 2953 : | @c SUBSECTION | ||
| 2954 : | @c ..................................................... | ||
| 2955 : | |||
| 2956 : | @menu | ||
| 2957 : | * Components of X:: | ||
| 2958 : | * How to set up X windows:: | ||
| 2959 : | * X displays and authority:: | ||
| 2960 : | @end menu | ||
| 2961 : | |||
| 2962 : | @node Components of X, How to set up X windows, The X window system, The X window system | ||
| 2963 : | @subsection The components of the X-window system | ||
| 2964 : | |||
| 2965 : | The X11 system is based on the client-server model. You might wonder why | ||
| 2966 : | a window system would be based on a model which was introduced for | ||
| 2967 : | interprocess communication, or network communication. | ||
| 2968 : | The answer is straightforward. | ||
| 2969 : | @cindex X window system | ||
| 2970 : | |||
| 2971 : | The designers of the X window system realized that network communication | ||
| 2972 : | was to be the paradigm of the next generation of computer systems. | ||
| 2973 : | They wanted to design a system of windows which would enable a user to sit | ||
| 2974 : | at a terminal in Massachusetts and work on a machine in Tokyo -- and | ||
| 2975 : | still be able to get high quality windows displayed on their terminal. | ||
| 2976 : | The aim of X windows from the beginning is to create a @emph{distributed} | ||
| 2977 : | window environment. | ||
| 2978 : | |||
| 2979 : | When I log onto my friend's Hewlett Packard workstation to use the text | ||
| 2980 : | editor (because I don't like the one on my EUNUCHS workstation) I want | ||
| 2981 : | it to work correctly on my screen, with my keyboard -- even though my | ||
| 2982 : | workstation is manufactured by a different company. I also want the | ||
| 2983 : | colours to be right despite the fact that the HP machine uses a | ||
| 2984 : | completely different video hardware to my machine. When I press the | ||
| 2985 : | curly brace key @code{@{}, I want to see a curly brace, and not some | ||
| 2986 : | hieroglyphic because the HP station uses a different keyboard. | ||
| 2987 : | |||
| 2988 : | These are the problems which X tries to address. In a network | ||
| 2989 : | environment we need a @emph{common window system} which will work on any | ||
| 2990 : | kind of hardware, and hide the differences between different machines as | ||
| 2991 : | far as possible. But it has to be flexible enough to allow us to change | ||
| 2992 : | all of the things we don't like -- to choose our own colours, and the | ||
| 2993 : | kind of window borders we want etc. Other windowing systems (like | ||
| 2994 : | Microsoft windows) ignore these problems and thereby lock the user | ||
| 2995 : | to a single vendors products and a single operating system. (That, of course, | ||
| 2996 : | is no accident.) | ||
| 2997 : | |||
| 2998 : | The way X solves this problem is to use the client server model. Each program | ||
| 2999 : | which wants to open a window on somebody's compute screen is a | ||
| 3000 : | client of the @emph{X window service}. To get something drawn on a user's | ||
| 3001 : | screen, the client asks a server on the host of interest to draw windows | ||
| 3002 : | for it. No client ever draws anything itself -- it asks the server to do it | ||
| 3003 : | on its behalf. There are several reasons for this: | ||
| 3004 : | |||
| 3005 : | @itemize @bullet | ||
| 3006 : | |||
| 3007 : | @item | ||
| 3008 : | The clients can all talk a common `window language' or @emph{protocol}. | ||
| 3009 : | We can hide the difference between different kinds of hardware by making | ||
| 3010 : | the @emph{machine-specific} part of drawing graphics entirely a problem | ||
| 3011 : | of implementing the server on the particular hardware. | ||
| 3012 : | When a new type of hardware comes along, | ||
| 3013 : | we just need to modify the server -- none of the clients need to be | ||
| 3014 : | modified. | ||
| 3015 : | @cindex X protocol | ||
| 3016 : | |||
| 3017 : | @item | ||
| 3018 : | We can contact different servers and send our output to different | ||
| 3019 : | hardware -- thus even though a program is running on a CPU in Tokyo, | ||
| 3020 : | it can ask the server in Massachusetts to display its window for it. | ||
| 3021 : | |||
| 3022 : | @item | ||
| 3023 : | When more than one window is on a user's display, it eventually | ||
| 3024 : | becomes necessary to move the windows around and then figure out | ||
| 3025 : | which windows are on top of which other windows etc. If all of the | ||
| 3026 : | drawing information is kept in a server, it is straightforward to | ||
| 3027 : | work out this information. If every client drew where it wanted to, | ||
| 3028 : | it would be impossible to know which window was supposed to be | ||
| 3029 : | on top of another. | ||
| 3030 : | @cindex X display | ||
| 3031 : | @cindex Display, X | ||
| 3032 : | @end itemize | ||
| 3033 : | |||
| 3034 : | In X, the window manager is a different program to the server | ||
| 3035 : | which does the drawing of graphics -- but the client-server idea | ||
| 3036 : | still applies, it just has one more piece to its puzzle. | ||
| 3037 : | |||
| 3038 : | @c ..................................................... | ||
| 3039 : | @c SUBSECTION | ||
| 3040 : | @c ..................................................... | ||
| 3041 : | |||
| 3042 : | @node How to set up X windows, X displays and authority, Components of X, The X window system | ||
| 3043 : | @subsection How to set up X windows | ||
| 3044 : | |||
| 3045 : | The X windows system is large and complex and not particularly user | ||
| 3046 : | friendly. When you log in to the system, X reads two files in your home | ||
| 3047 : | directory which decide which applications will be started what they will | ||
| 3048 : | look like. The files are called | ||
| 3049 : | @vindex .xsession | ||
| 3050 : | @cindex .xsession file | ||
| 3051 : | @cindex Setting up the x environment | ||
| 3052 : | |||
| 3053 : | @table @emph | ||
| 3054 : | |||
| 3055 : | @item .Xsession | ||
| 3056 : | This file is a shell script which starts up a number of applications | ||
| 3057 : | as background processes and exits by calling a window manager. Here | ||
| 3058 : | is a simple example file | ||
| 3059 : | |||
| 3060 : | @smallexample | ||
| 3061 : | #!/bin/csh | ||
| 3062 : | # | ||
| 3063 : | # .xsession file | ||
| 3064 : | # | ||
| 3065 : | # | ||
| 3066 : | |||
| 3067 : | setenv PATH /usr/bin:/bin:/local/gnu/bin:/usr/X11R6/bin | ||
| 3068 : | |||
| 3069 : | # | ||
| 3070 : | # List applications here, with & at the end | ||
| 3071 : | # so they run in the background | ||
| 3072 : | # | ||
| 3073 : | |||
| 3074 : | xterm -T NewTitle -sl 1000 -geometry 90x45+16+150 -sb & | ||
| 3075 : | xclock & | ||
| 3076 : | xbiff -geometry 80x80+510+0 & | ||
| 3077 : | |||
| 3078 : | # Start a window manager. Exec replaces this script with | ||
| 3079 : | # the fvwm process, so that it doesn't exist as a separate | ||
| 3080 : | # (useless) process. | ||
| 3081 : | |||
| 3082 : | exec /local/bin/fvwm | ||
| 3083 : | |||
| 3084 : | @end smallexample | ||
| 3085 : | |||
| 3086 : | @item .Xdefaults | ||
| 3087 : | This file specifies all of the resources which X programs use. It can be | ||
| 3088 : | used to change the colours used by applications, or font types etc. The subject | ||
| 3089 : | of X-rescources is a large one and we don't have time for it here. Here | ||
| 3090 : | is a simple example, which shows how you can make your over-bright xterm | ||
| 3091 : | and emacs windows less bright grey shade. | ||
| 3092 : | |||
| 3093 : | @smallexample | ||
| 3094 : | xterm*background: LightGrey | ||
| 3095 : | Emacs*background: grey92 | ||
| 3096 : | Xemacs*background: grey92 | ||
| 3097 : | @end smallexample | ||
| 3098 : | |||
| 3099 : | @end table | ||
| 3100 : | |||
| 3101 : | @c ..................................................... | ||
| 3102 : | @c SUBSECTION | ||
| 3103 : | @c ..................................................... | ||
| 3104 : | |||
| 3105 : | @node X displays and authority, , How to set up X windows, The X window system | ||
| 3106 : | @subsection X displays and authority | ||
| 3107 : | |||
| 3108 : | In the terminology used by X11, every client program has to contact a | ||
| 3109 : | @emph{display} in order to open a window. A display is a virtual screen | ||
| 3110 : | which is created by the X server on a particular host. X can create | ||
| 3111 : | several separate displays on a given host, though most machines only have one. | ||
| 3112 : | @cindex DISPLAY variable | ||
| 3113 : | @cindex X display | ||
| 3114 : | |||
| 3115 : | When an X client program wants to open a window, it looks in the UNIX | ||
| 3116 : | environment variable @samp{DISPLAY} for the IP address of a host | ||
| 3117 : | which has an X server it can contact. For example, if we wrote | ||
| 3118 : | @example | ||
| 3119 : | setenv DISPLAY myhost:0 | ||
| 3120 : | @end example | ||
| 3121 : | the client would try to contact the X server on `myhost' and ask for | ||
| 3122 : | a window on display number zero (the usual display). If we wrote | ||
| 3123 : | @example | ||
| 3124 : | setenv DISPLAY 198.112.208.35:0 | ||
| 3125 : | @end example | ||
| 3126 : | |||
| 3127 : | @noindent | ||
| 3128 : | the client would try to open | ||
| 3129 : | display zero on the X server at the host with the IP | ||
| 3130 : | address @samp{198.112.208.35}. | ||
| 3131 : | |||
| 3132 : | Clearly there must be some kind of security mechanism to prevent just | ||
| 3133 : | anybody from opening windows on someone's display. X has two such | ||
| 3134 : | mechanisms: | ||
| 3135 : | @cindex X windows authentification | ||
| 3136 : | @cindex X windows access | ||
| 3137 : | |||
| 3138 : | @table @emph | ||
| 3139 : | |||
| 3140 : | @cindex xhost mechanism | ||
| 3141 : | @item xhost | ||
| 3142 : | This mechanism is now obsolete. The @samp{xhost} command is used to define | ||
| 3143 : | a list of hosts which are allowed to open windows on the user's display. | ||
| 3144 : | It cannot destinguish between individual users. i.e. the command | ||
| 3145 : | @code{xhost yourhost} would allow @emph{anyone} using yourhost to | ||
| 3146 : | access the local display. This mechanism is only present for backward | ||
| 3147 : | compatibility with early versions of X windows. Normally one should | ||
| 3148 : | use the command @code{xhost -} to exclude all others from accessing the | ||
| 3149 : | display. | ||
| 3150 : | |||
| 3151 : | @item Xauthority | ||
| 3152 : | @cindex Xauthority mechanism | ||
| 3153 : | @cindex X access control | ||
| 3154 : | The Xauthority mechanism has replaced the xhost scheme. It provides | ||
| 3155 : | a security mechanism which can distinguish individual users, not just hosts. | ||
| 3156 : | In order for a user to open a window on a display, he/she must have | ||
| 3157 : | a ticket---called a "magic cookie". This is a binary file | ||
| 3158 : | called @file{.Xauthority} which is created in the user's home directory | ||
| 3159 : | when he/she first starts the X-windows system. Anyone who does | ||
| 3160 : | not have a recent copy of this file cannot open windows or read the | ||
| 3161 : | display of the user's terminal. This mechanism is based on the idea | ||
| 3162 : | that the user's home directory is available via NFS on all hosts he/she | ||
| 3163 : | will log onto, and thus the owner of the display will always have access | ||
| 3164 : | to the magic cookie, and will therefore always be able to open windows | ||
| 3165 : | on the display. Other users must obtain a copy of the file in order | ||
| 3166 : | to open windows there. The command @code{xauth} is an | ||
| 3167 : | interactive utility used for controlling the contents of the @file{.Xauthority} | ||
| 3168 : | file. See the @samp{xauth} manual page for more information. | ||
| 3169 : | |||
| 3170 : | @end table | ||
| 3171 : | |||
| 3172 : | @c ----------------------------------------------------------------------- | ||
| 3173 : | @c SECTION | ||
| 3174 : | @c ----------------------------------------------------------------------- | ||
| 3175 : | |||
| 3176 : | @node Multiple screens, , The X window system, The login environment | ||
| 3177 : | @section Multiple screens | ||
| 3178 : | |||
| 3179 : | The window paradigm has been very successful in many ways, but anyone | ||
| 3180 : | who has used a window system knows that the screen is simply not big | ||
| 3181 : | enough for all the windows one would like! Unix has several solutions to | ||
| 3182 : | this problem. | ||
| 3183 : | @cindex Screens | ||
| 3184 : | @cindex Multiple screens | ||
| 3185 : | |||
| 3186 : | One solution is to attach several physical screens to a terminal. | ||
| 3187 : | The X window system can support any number of physical screens of | ||
| 3188 : | different types. A graphical designer might want a high resolution | ||
| 3189 : | colour screen for drawing and a black and white screen for writing | ||
| 3190 : | text, for instance. The disadvantage with this method is the cost | ||
| 3191 : | of the hardware. | ||
| 3192 : | |||
| 3193 : | A cheaper solution is to use a window manager such as @samp{fwvm} which | ||
| 3194 : | creates a virtual screen of unlimited size on a single monitor. As the | ||
| 3195 : | mouse pointer reaches the edge of the true screen, the window manager | ||
| 3196 : | replaces the display with a new "blank screen" in which to place | ||
| 3197 : | windows. A miniaturized image of the windows on a control panel acts as | ||
| 3198 : | a map which makes it possible to find the applications on the virtual | ||
| 3199 : | screen. | ||
| 3200 : | |||
| 3201 : | Yet another possibility is to create virtual displays inside a single | ||
| 3202 : | window. In other words, one can collapse several shell windows into a | ||
| 3203 : | single @samp{xterm} window by running the program @samp{screen}. The | ||
| 3204 : | screen command allows you to start several shells in a single window | ||
| 3205 : | (using @key{CTRL-a CTRL-c}) and to switch between them (by typing | ||
| 3206 : | @key{CTRL-a CTRL-n}). It is only possible to see one shell window at a | ||
| 3207 : | time, but it is still possible to cut and paste between windows and one | ||
| 3208 : | has a considerable saving of space. The @samp{screen} command also | ||
| 3209 : | allows you to suspend a shell session, log out, log in again later and | ||
| 3210 : | resume the session precisely where you left off. | ||
| 3211 : | |||
| 3212 : | Here is a summary of some useful screen commands: | ||
| 3213 : | |||
| 3214 : | @table @kbd | ||
| 3215 : | |||
| 3216 : | @item screen | ||
| 3217 : | Start the screen server. | ||
| 3218 : | |||
| 3219 : | @item screen -r | ||
| 3220 : | Resume a previously suspended screen session if possible. | ||
| 3221 : | |||
| 3222 : | @item CTRL-a CTRL-c | ||
| 3223 : | Start a new shell on top of the others (a fresh `screen') in the | ||
| 3224 : | current window. | ||
| 3225 : | |||
| 3226 : | @item CTRL-a CTRL-n | ||
| 3227 : | Switch to the next `screen'. | ||
| 3228 : | |||
| 3229 : | @item CTRL-a CTRL-a | ||
| 3230 : | Switch to the last screen used. | ||
| 3231 : | |||
| 3232 : | @item CTRL-a a | ||
| 3233 : | When screen is running, @kbd{CTRL-a} is used for screen commands and | ||
| 3234 : | cannot therefore be used in its usual shell meaning of `jump to start | ||
| 3235 : | of line'. @kbd{CTRL-a a} replaces this. | ||
| 3236 : | |||
| 3237 : | @item CTRL-a CTRL-d | ||
| 3238 : | Detach the screen session from the current window so that it | ||
| 3239 : | can be resumed later. It can be resumed | ||
| 3240 : | with the @samp{screen -r} command. | ||
| 3241 : | |||
| 3242 : | @item CTRL-a ? | ||
| 3243 : | Help screen. | ||
| 3244 : | |||
| 3245 : | @end table | ||
| 3246 : | |||
| 3247 : | @c ********************************************************************** | ||
| 3248 : | @c CHAPTER | ||
| 3249 : | @c ********************************************************************** | ||
| 3250 : | |||
| 3251 : | @node Files and access, C shell, The login environment, Top | ||
| 3252 : | @chapter Files and access | ||
| 3253 : | |||
| 3254 : | To prevent all users from being able to access all files on the system, unix | ||
| 3255 : | records information about @emph{who} creates files and also who is allowed | ||
| 3256 : | to access them later. | ||
| 3257 : | |||
| 3258 : | @cindex Access to files | ||
| 3259 : | @cindex Permissions on files | ||
| 3260 : | @cindex Access rights | ||
| 3261 : | @cindex File access permission | ||
| 3262 : | Each user has a unique @emph{username} or @emph{loginname} together with | ||
| 3263 : | a unique @emph{user id} or @emph{uid}. The user id is a number, whereas the login | ||
| 3264 : | name is a text string -- otherwise the two express the same information. | ||
| 3265 : | A file belongs to user A if it is @emph{owned} by user A. User A then | ||
| 3266 : | decides whether or not other users can read, write or execute the | ||
| 3267 : | file by setting the @emph{protection bits} or the @emph{permission} of the | ||
| 3268 : | file using the command @code{chmod}. | ||
| 3269 : | |||
| 3270 : | @cindex groups | ||
| 3271 : | @cindex @file{/etc/group} | ||
| 3272 : | In addition to user identities, there are groups of users. The idea of | ||
| 3273 : | a group is that several named users might want to be able to read | ||
| 3274 : | and work on a file, without other users being able to access it. | ||
| 3275 : | Every user is a member of at least one group, called the @emph{login | ||
| 3276 : | group} and each group has both a textual name and a number (@emph{group id}). | ||
| 3277 : | The @emph{uid} and @emph{gid} of each user is recorded in the | ||
| 3278 : | file @code{/etc/passwd} (See chapter 6). Membership of other groups | ||
| 3279 : | is recorded in the file @code{/etc/group} or on some systems @code{/etc/logingroup}. | ||
| 3280 : | |||
| 3281 : | @c ----------------------------------------------------------------------- | ||
| 3282 : | @c SECTION | ||
| 3283 : | @c ----------------------------------------------------------------------- | ||
| 3284 : | |||
| 3285 : | @menu | ||
| 3286 : | * Protection bits:: | ||
| 3287 : | * chmod:: | ||
| 3288 : | * Umask:: | ||
| 3289 : | * s-bit and t-bit:: | ||
| 3290 : | @end menu | ||
| 3291 : | |||
| 3292 : | @node Protection bits, chmod, Files and access, Files and access | ||
| 3293 : | @section Protection bits | ||
| 3294 : | |||
| 3295 : | @cindex File protection bits | ||
| 3296 : | @cindex Protection bits | ||
| 3297 : | @cindex Access bits | ||
| 3298 : | @cindex Long file listing | ||
| 3299 : | @cindex @code{ls -l} | ||
| 3300 : | The following output is from | ||
| 3301 : | the command @code{ls -lag} executed on a SunOS type machine. | ||
| 3302 : | @smallexample | ||
| 3303 : | |||
| 3304 : | lrwxrwxrwx 1 root wheel 7 Jun 1 1993 bin -> usr/bin | ||
| 3305 : | -r--r--r-- 1 root bin 103512 Jun 1 1993 boot | ||
| 3306 : | drwxr-sr-x 2 bin staff 11264 May 11 17:00 dev | ||
| 3307 : | drwxr-sr-x 10 bin staff 2560 Jul 8 02:06 etc | ||
| 3308 : | drwxr-sr-x 8 root wheel 512 Jun 1 1993 export | ||
| 3309 : | drwx------ 2 root daemon 512 Sep 26 1993 home | ||
| 3310 : | -rwxr-xr-x 1 root wheel 249079 Jun 1 1993 kadb | ||
| 3311 : | lrwxrwxrwx 1 root wheel 7 Jun 1 1993 lib -> usr/lib | ||
| 3312 : | drwxr-xr-x 2 root wheel 8192 Jun 1 1993 lost+found | ||
| 3313 : | drwxr-sr-x 2 bin staff 512 Jul 23 1992 mnt | ||
| 3314 : | dr-xr-xr-x 1 root wheel 512 May 11 17:00 net | ||
| 3315 : | drwxr-sr-x 2 root wheel 512 Jun 1 1993 pcfs | ||
| 3316 : | drwxr-sr-x 2 bin staff 512 Jun 1 1993 sbin | ||
| 3317 : | lrwxrwxrwx 1 root wheel 13 Jun 1 1993 sys->kvm/sys | ||
| 3318 : | drwxrwxrwx 6 root wheel 732 Jul 8 19:23 tmp | ||
| 3319 : | drwxr-xr-x 27 root wheel 1024 Jun 14 1993 usr | ||
| 3320 : | drwxr-sr-x 10 bin staff 512 Jul 23 1992 var | ||
| 3321 : | -rwxr-xr-x 1 root daemon 2182656 Jun 4 1993 vmunix | ||
| 3322 : | |||
| 3323 : | @end smallexample | ||
| 3324 : | The first column is a textual representation of the protection bits for | ||
| 3325 : | each file. Column two is the number of hard links to the file (See exercises | ||
| 3326 : | below). The third and fourth columns are the user name and group name | ||
| 3327 : | and the remainder show the file size in bytes and the creation date. | ||
| 3328 : | Notice that the directories @code{/bin} and @code{/sys} are | ||
| 3329 : | symbolic links to other directories. | ||
| 3330 : | |||
| 3331 : | There are sixteen protection bits for a UNIX file, but only | ||
| 3332 : | twelve of them can be changed by users. These twelve are split into four groups | ||
| 3333 : | of three. Each three-bit number corresponds to one @emph{octal} number. | ||
| 3334 : | |||
| 3335 : | The leading four invisible bits gives information about the type of file: is | ||
| 3336 : | the file a @emph{plain file}, a @emph{directory} or a @emph{link}. In the | ||
| 3337 : | output from @code{ls} this is represented by a single character: | ||
| 3338 : | @code{-}, @code{d} or @code{l}. | ||
| 3339 : | |||
| 3340 : | The next three bits set the | ||
| 3341 : | so-called @emph{s-bits} and @emph{t-bit} which are explained below. | ||
| 3342 : | |||
| 3343 : | The remaining three groups of three bits set flags which indicate | ||
| 3344 : | whether a file can be read @samp{r}, written to @samp{w} or executed | ||
| 3345 : | @samp{x} by (i) the user who created them, (ii) the other users who are | ||
| 3346 : | in the group the file is marked with, and (iii) any user at all. | ||
| 3347 : | |||
| 3348 : | @cindex Text form of access bits | ||
| 3349 : | @cindex Access bits, text form | ||
| 3350 : | |||
| 3351 : | For example, the permission | ||
| 3352 : | |||
| 3353 : | @example | ||
| 3354 : | Type Owner Group Anyone | ||
| 3355 : | d rwx r-x --- | ||
| 3356 : | @end example | ||
| 3357 : | |||
| 3358 : | @noindent | ||
| 3359 : | tells us that the file is a directory, which can be read and written | ||
| 3360 : | to by the owner, can be read by others in its group, but not by | ||
| 3361 : | anyone else. | ||
| 3362 : | |||
| 3363 : | @emph{Note about directories. It is impossible to @code{cd} to a | ||
| 3364 : | directory unless the @code{x} bit is set. That is, directories must be | ||
| 3365 : | `executable' in order to be accessible.} | ||
| 3366 : | |||
| 3367 : | Here are some examples of the relationship between binary, octal | ||
| 3368 : | and the textual representation of file modes. | ||
| 3369 : | @cindex Access bits, octal form | ||
| 3370 : | |||
| 3371 : | @example | ||
| 3372 : | Binary Octal Text | ||
| 3373 : | |||
| 3374 : | 001 1 x | ||
| 3375 : | 010 2 w | ||
| 3376 : | 100 4 r | ||
| 3377 : | 110 6 rw- | ||
| 3378 : | 101 5 r-x | ||
| 3379 : | - 644 rw-r--r-- | ||
| 3380 : | |||
| 3381 : | @end example | ||
| 3382 : | |||
| 3383 : | @noindent | ||
| 3384 : | It is well worth becoming familiar with the octal number representation | ||
| 3385 : | of these permissions. | ||
| 3386 : | |||
| 3387 : | @c ----------------------------------------------------------------------- | ||
| 3388 : | @c SECTION | ||
| 3389 : | @c ----------------------------------------------------------------------- | ||
| 3390 : | |||
| 3391 : | @node chmod, Umask, Protection bits, Files and access | ||
| 3392 : | @section chmod | ||
| 3393 : | |||
| 3394 : | @cindex @code{chmod} command | ||
| 3395 : | The @code{chmod} command changes the permission or @emph{mode} of a file. Only | ||
| 3396 : | the owner of the file or the superuser can change the permission. | ||
| 3397 : | Here are some examples of its use. Try them. | ||
| 3398 : | |||
| 3399 : | @smallexample | ||
| 3400 : | # make read/write-able for everyone | ||
| 3401 : | chmod a+w myfile | ||
| 3402 : | |||
| 3403 : | # add the 'execute' flag for directory | ||
| 3404 : | chmod u+x mydir/ | ||
| 3405 : | |||
| 3406 : | # open all files for everyone | ||
| 3407 : | chmod 755 * | ||
| 3408 : | |||
| 3409 : | # set the s-bit on my-dir's group | ||
| 3410 : | chmod g+s mydir/ | ||
| 3411 : | |||
| 3412 : | # descend recursively into directory opening all files | ||
| 3413 : | chmod -R a+r dir | ||
| 3414 : | @end smallexample | ||
| 3415 : | |||
| 3416 : | @c ----------------------------------------------------------------------- | ||
| 3417 : | @c SECTION | ||
| 3418 : | @c ----------------------------------------------------------------------- | ||
| 3419 : | |||
| 3420 : | @node Umask, s-bit and t-bit, chmod, Files and access | ||
| 3421 : | @section Umask | ||
| 3422 : | |||
| 3423 : | @cindex @code{umask} variable | ||
| 3424 : | @cindex s-bit | ||
| 3425 : | @cindex setuid bit | ||
| 3426 : | @cindex setgid bit | ||
| 3427 : | |||
| 3428 : | When a new file gets created, the operating system must decide what | ||
| 3429 : | default protection bits to set on that file. The variable @code{umask} decides this. | ||
| 3430 : | @code{umask} is normally set by each user in his or her @code{.cshrc} | ||
| 3431 : | file (see next chapter). For example | ||
| 3432 : | @smallexample | ||
| 3433 : | umask 077 # safe | ||
| 3434 : | umask 022 # liberal | ||
| 3435 : | @end smallexample | ||
| 3436 : | |||
| 3437 : | @noindent | ||
| 3438 : | According the UNIX documentation, the value of @code{umask} is | ||
| 3439 : | @samp{XOR}ed (exclusive @samp{OR}) with a value of @code{666 & umask} | ||
| 3440 : | for plain files or @code{777 & umask} for directories in order to find | ||
| 3441 : | out the standard protection. Actually this is not quite true: @samp{umask} | ||
| 3442 : | only removes bits, it never sets bits which were not already set | ||
| 3443 : | in @code{666}. For instance | ||
| 3444 : | |||
| 3445 : | @cindex @code{umask} variable | ||
| 3446 : | @example | ||
| 3447 : | umask Permission | ||
| 3448 : | |||
| 3449 : | 077 600 (plain) | ||
| 3450 : | 077 700 (dir) | ||
| 3451 : | 022 644 (plain) | ||
| 3452 : | 022 755 (dir) | ||
| 3453 : | @end example | ||
| 3454 : | The correct rule for computing permissions is not XOR but @samp{NOT AND}. | ||
| 3455 : | |||
| 3456 : | @c ..................................................... | ||
| 3457 : | @c SUBSECTION | ||
| 3458 : | @c ..................................................... | ||
| 3459 : | |||
| 3460 : | @menu | ||
| 3461 : | * Making programs executable:: | ||
| 3462 : | * chown and chgrp:: | ||
| 3463 : | * Making a group:: | ||
| 3464 : | @end menu | ||
| 3465 : | |||
| 3466 : | @node Making programs executable, chown and chgrp, Umask, Umask | ||
| 3467 : | @subsection Making programs executable | ||
| 3468 : | |||
| 3469 : | @cindex Masking programs executable | ||
| 3470 : | @cindex Executable, making programs | ||
| 3471 : | |||
| 3472 : | A unix program is normally executed by typing its pathname. | ||
| 3473 : | If the @code{x} execute bit is not set on the file, this will generate | ||
| 3474 : | a `Permission denied' error. This protects the system from | ||
| 3475 : | interpreting nonsense files as programs. To make a program executable | ||
| 3476 : | for someone, you must therefore ensure that they can execute | ||
| 3477 : | the file, using a command like | ||
| 3478 : | |||
| 3479 : | @example | ||
| 3480 : | chmod u+x @var{filename} | ||
| 3481 : | @end example | ||
| 3482 : | |||
| 3483 : | @noindent | ||
| 3484 : | This command would set execute permissions for the owner of the file; | ||
| 3485 : | @example | ||
| 3486 : | chmod ug+x @var{filename} | ||
| 3487 : | @end example | ||
| 3488 : | |||
| 3489 : | @noindent | ||
| 3490 : | would set execute permissions for the owner and for any users in the | ||
| 3491 : | same group as the file. Note that script programs must also be readable | ||
| 3492 : | in order to be executable, since the shell has the interpret them by | ||
| 3493 : | reading. | ||
| 3494 : | |||
| 3495 : | @c ----------------------------------------------------------------------- | ||
| 3496 : | @c SECTION | ||
| 3497 : | @c ----------------------------------------------------------------------- | ||
| 3498 : | |||
| 3499 : | @node chown and chgrp, Making a group, Making programs executable, Umask | ||
| 3500 : | @subsection chown and chgrp | ||
| 3501 : | |||
| 3502 : | @cindex @code{chown} command | ||
| 3503 : | @cindex @code{chgrp} command | ||
| 3504 : | |||
| 3505 : | These two commands change the ownership and the group ownership of a | ||
| 3506 : | file. Only the superuser can change the ownership of a file on most | ||
| 3507 : | systems. This is to prevent users from being able to defeat quota | ||
| 3508 : | mechanisms. (On some systems, which do not implement quotas, ordinary | ||
| 3509 : | users can give a file away to another user but not get it back again.) | ||
| 3510 : | The same applies to group ownership. | ||
| 3511 : | |||
| 3512 : | |||
| 3513 : | @c ----------------------------------------------------------------------- | ||
| 3514 : | @c SECTION | ||
| 3515 : | @c ----------------------------------------------------------------------- | ||
| 3516 : | |||
| 3517 : | @node Making a group, , chown and chgrp, Umask | ||
| 3518 : | @subsection Making a group | ||
| 3519 : | |||
| 3520 : | Normally users other than root cannot define their own groups. This | ||
| 3521 : | is a weakness in Unix from older times which no one seems to be in a hurry | ||
| 3522 : | to change. At Oslo College, Computer Science, we use a local solution | ||
| 3523 : | whereby users can edit a file to create their own groups. This file is | ||
| 3524 : | called @file{/iu/nexus/local/iu/etc/iu-group}. The format of the group | ||
| 3525 : | file is: | ||
| 3526 : | |||
| 3527 : | @smallexample | ||
| 3528 : | @var{group-name}::@var{group-number}:@var{comma-separated-list-of-users} | ||
| 3529 : | @end smallexample | ||
| 3530 : | |||
| 3531 : | @c ----------------------------------------------------------------------- | ||
| 3532 : | @c SECTION | ||
| 3533 : | @c ----------------------------------------------------------------------- | ||
| 3534 : | |||
| 3535 : | @node s-bit and t-bit, , Umask, Files and access | ||
| 3536 : | @section s-bit and t-bit (sticky bit) | ||
| 3537 : | |||
| 3538 : | @cindex Sticky bit | ||
| 3539 : | @cindex s-bit | ||
| 3540 : | @cindex t-bit | ||
| 3541 : | |||
| 3542 : | The @code{s} and @code{t} bits have special uses. They are described | ||
| 3543 : | as follows. | ||
| 3544 : | |||
| 3545 : | @example | ||
| 3546 : | Octal Text Name | ||
| 3547 : | |||
| 3548 : | 4000 chmod u+s Setuid bit | ||
| 3549 : | 2000 chmod g+s Setgid bit | ||
| 3550 : | 1000 chmod +t Sticky bit | ||
| 3551 : | @end example | ||
| 3552 : | |||
| 3553 : | @noindent | ||
| 3554 : | The effect of these bits differs for plain files and directories and | ||
| 3555 : | differ between different versions of UNIX. You should check the manual | ||
| 3556 : | page @code{man sticky} to find out about your system! The following is | ||
| 3557 : | common behaviour. | ||
| 3558 : | |||
| 3559 : | For executable files, the setuid bit tells UNIX that @emph{regardless of | ||
| 3560 : | who runs the program} it should be executed with the permissions and | ||
| 3561 : | rights of owner of the file. This is often used to allow normal users | ||
| 3562 : | limited access to @code{root} privileges. A @emph{setuid-root} program | ||
| 3563 : | is executed as @code{root} for any user. The setgid bit sets the group | ||
| 3564 : | execution rights of the program in a similar way. | ||
| 3565 : | |||
| 3566 : | In BSD unix, if the setgid bit is set on a directory then any new | ||
| 3567 : | files created in that directory assume the group ownership of the | ||
| 3568 : | parent directory and not the logingroup of the user who created the | ||
| 3569 : | file. This is standard policy under system 5. | ||
| 3570 : | |||
| 3571 : | A directory for which the sticky bit is set restrict the deletion of | ||
| 3572 : | files within it. A file or directory | ||
| 3573 : | inside a directory with the t-bit set can | ||
| 3574 : | only be deleted or renamed by its owner or the superuser. This is | ||
| 3575 : | useful for directories like the mail spool area and @code{/tmp} | ||
| 3576 : | which must be writable to everyone, but should not allow a user | ||
| 3577 : | to delete another user's files. | ||
| 3578 : | |||
| 3579 : | (Ultrix) If an executable file is marked with a sticky bit, it is held in the | ||
| 3580 : | memory or system swap area. It does not have to be fetched from | ||
| 3581 : | disk each time it is executed. This saves time for frequently | ||
| 3582 : | used programs like @code{ls}. | ||
| 3583 : | |||
| 3584 : | (Solaris 1) If a non-executable file is marked with the sticky bit, it | ||
| 3585 : | will @emph{not} be held in the disk page cache -- that is, it is never | ||
| 3586 : | copied from the disk and held in RAM but is written to directly. | ||
| 3587 : | This is used to prevent certain files from using up valuable memory. | ||
| 3588 : | |||
| 3589 : | On some systems (e.g. ULTRIX), only the superuser can set the sticky bit. | ||
| 3590 : | On others (e.g. SunOS) any user can create a sticky directory. | ||
| 3591 : | |||
| 3592 : | |||
| 3593 : | @c ********************************************************************** | ||
| 3594 : | @c CHAPTER | ||
| 3595 : | @c ********************************************************************** | ||
| 3596 : | |||
| 3597 : | @node C shell, Bourne shell, Files and access, Top | ||
| 3598 : | @chapter C shell | ||
| 3599 : | |||
| 3600 : | The C shell is the command interpreter which you use to run programs and | ||
| 3601 : | utilities. It contains a simple programming language for writing | ||
| 3602 : | tailor-made commands, and allows you to join together unix commands | ||
| 3603 : | with pipes. It is a configurable environment, and once you know it well, | ||
| 3604 : | it is the most efficient way of working with unix. | ||
| 3605 : | |||
| 3606 : | @c ----------------------------------------------------------------------- | ||
| 3607 : | @c SECTION | ||
| 3608 : | @c ----------------------------------------------------------------------- | ||
| 3609 : | |||
| 3610 : | @menu | ||
| 3611 : | * .cshrc and .login:: | ||
| 3612 : | * Defining variables with set and setenv:: | ||
| 3613 : | * Arrays:: | ||
| 3614 : | * Pipes and redirection:: | ||
| 3615 : | * tee and script:: | ||
| 3616 : | * Command history:: | ||
| 3617 : | * Command/filename completion:: | ||
| 3618 : | * Single and double quotes:: | ||
| 3619 : | * Job control:: | ||
| 3620 : | * Scripts with argumemts:: | ||
| 3621 : | * subshells:: | ||
| 3622 : | * Tests and conditions:: | ||
| 3623 : | * Loops in csh:: | ||
| 3624 : | * Input from the user:: | ||
| 3625 : | * Extracting parts of a pathname:: | ||
| 3626 : | * Arithmetic:: | ||
| 3627 : | * Examples:: | ||
| 3628 : | @end menu | ||
| 3629 : | |||
| 3630 : | @node .cshrc and .login, Defining variables with set and setenv, C shell, C shell | ||
| 3631 : | @section .cshrc and .login files | ||
| 3632 : | |||
| 3633 : | @cindex @file{.cshrc} file | ||
| 3634 : | @cindex @file{.login} file | ||
| 3635 : | @cindex Login evironment | ||
| 3636 : | @cindex C shell setup files | ||
| 3637 : | @cindex Setting up the C shell | ||
| 3638 : | |||
| 3639 : | Most users run the C-shell @file{/bin/csh} as their login environment, | ||
| 3640 : | or these days, preferably the @file{tcsh} which is an improved version | ||
| 3641 : | of csh. When a user logs in to a UNIX system the C-shell starts by | ||
| 3642 : | reading some files which configure the environment by defining | ||
| 3643 : | variables like @code{path}. | ||
| 3644 : | |||
| 3645 : | @itemize @bullet | ||
| 3646 : | @item | ||
| 3647 : | The file @file{.cshrc} is searched for in your home directory. | ||
| 3648 : | i.e. @file{~/.cshrc}. If it is found, its contents are interpreted by | ||
| 3649 : | the C-shell as C-shell instructions, before giving you the command | ||
| 3650 : | prompt@footnote{Under HPUX, two other files are also read by the | ||
| 3651 : | C-shell. These are called @file{/etc/csh.login} and @file{/etc/src.csh}, | ||
| 3652 : | enabling some standard set-up to be configured globally. GNU/Linux has a | ||
| 3653 : | similar system. On solaris systems @file{/etc/.login} is read.}. | ||
| 3654 : | |||
| 3655 : | @item | ||
| 3656 : | If and only if this is the @emph{login shell} (not a sub-shell that | ||
| 3657 : | you have started after login) then the file @file{~/.login} is searched | ||
| 3658 : | for and executed. | ||
| 3659 : | @end itemize | ||
| 3660 : | |||
| 3661 : | @noindent | ||
| 3662 : | With the advent of the X11 windowing system, this has changed slightly. | ||
| 3663 : | Since the window system takes over the entire login procedure, users | ||
| 3664 : | never get to run `login shells', since the login shell is used up | ||
| 3665 : | by the X11 system. On an X-terminal or host running X the @file{.login} file | ||
| 3666 : | normally has no effect. | ||
| 3667 : | |||
| 3668 : | With some thought, the @file{.login} file can be eliminated entirely, | ||
| 3669 : | and we can put everything into the @code{.cshrc} file. | ||
| 3670 : | Here is a very simple example @file{.cshrc} file. | ||
| 3671 : | |||
| 3672 : | @smallexample | ||
| 3673 : | # | ||
| 3674 : | # .cshrc - read in by every csh that starts. | ||
| 3675 : | # | ||
| 3676 : | |||
| 3677 : | # Set the default file creation mask | ||
| 3678 : | umask 077 | ||
| 3679 : | |||
| 3680 : | # Set the path | ||
| 3681 : | set path=( /usr/local/bin /usr/bin/X11 /usr/ucb /bin /usr/bin . ) | ||
| 3682 : | |||
| 3683 : | # Exit here if the shell is not interactive | ||
| 3684 : | if ( $?prompt == 0 ) exit | ||
| 3685 : | |||
| 3686 : | # Set some variables | ||
| 3687 : | |||
| 3688 : | set noclobber notify filec nobeep | ||
| 3689 : | set history=100 | ||
| 3690 : | @cindex Setting the prompt | ||
| 3691 : | @cindex Prompt, redefining | ||
| 3692 : | set prompt="`hostname`%" | ||
| 3693 : | set prompt2 = "%m %h>" # tcsh, prompt for foreach and while | ||
| 3694 : | |||
| 3695 : | setenv PRINTER myprinter | ||
| 3696 : | setenv LD_LIBRARY_PATH /usr/lib:/usr/local/lib:/usr/openwin/lib | ||
| 3697 : | |||
| 3698 : | # Aliases are shortcuts to unix commands | ||
| 3699 : | |||
| 3700 : | alias passwd yppasswd | ||
| 3701 : | alias dir 'ls -lg \!* | more' | ||
| 3702 : | alias sys 'ps aux | more' | ||
| 3703 : | alias h history | ||
| 3704 : | @end smallexample | ||
| 3705 : | |||
| 3706 : | It is possible to make a much more complicated .cshrc file than this. | ||
| 3707 : | The advent of distributed computing and NFS (Network file system) | ||
| 3708 : | means that you might log into many different machines running | ||
| 3709 : | different versions of unix. The command path would have to be set | ||
| 3710 : | differently for each type of machine. | ||
| 3711 : | |||
| 3712 : | @c ----------------------------------------------------------------------- | ||
| 3713 : | @c SECTION | ||
| 3714 : | @c ----------------------------------------------------------------------- | ||
| 3715 : | |||
| 3716 : | @node Defining variables with set and setenv, Arrays, .cshrc and .login, C shell | ||
| 3717 : | @section Defining variables with set, setenv | ||
| 3718 : | |||
| 3719 : | We have already seen in the examples above how to define variables in | ||
| 3720 : | C-shell. Let's formalize this. To define a local variable -- that is, | ||
| 3721 : | one which will not get passed on to programs and sub-shells running | ||
| 3722 : | under the current shell, we write | ||
| 3723 : | |||
| 3724 : | @smallexample | ||
| 3725 : | set local = "some string" | ||
| 3726 : | set myname = "`whoami`" | ||
| 3727 : | @end smallexample | ||
| 3728 : | |||
| 3729 : | @noindent | ||
| 3730 : | These variables are then referred to by using the dollar @samp{$} symbol. | ||
| 3731 : | i.e. The value of the variable @samp{local} is @samp{$local}. | ||
| 3732 : | |||
| 3733 : | @smallexample | ||
| 3734 : | echo $local $myname | ||
| 3735 : | @end smallexample | ||
| 3736 : | |||
| 3737 : | @noindent | ||
| 3738 : | Global variables, that is variables which all sub-shells inherit from | ||
| 3739 : | the current shell are defined using @samp{setenv} | ||
| 3740 : | |||
| 3741 : | @smallexample | ||
| 3742 : | setenv GLOBAL "Some other string" | ||
| 3743 : | setenv MYNAME "`who am i`" | ||
| 3744 : | @end smallexample | ||
| 3745 : | |||
| 3746 : | @noindent | ||
| 3747 : | Their values are also referred to using the @samp{$} symbol. Notice that | ||
| 3748 : | @code{set} uses an @samp{=} sign while @samp{setenv} does not. | ||
| 3749 : | @cindex @code{set} command | ||
| 3750 : | @cindex Local variables in csh | ||
| 3751 : | @cindex @code{setenv} command | ||
| 3752 : | @cindex Global variables in csh | ||
| 3753 : | |||
| 3754 : | Variables can be also created without a value. The shell uses this | ||
| 3755 : | method to switch on and off certain features, using variables | ||
| 3756 : | like @samp{noclobber} and @samp{noglob}. For instance | ||
| 3757 : | @smallexample | ||
| 3758 : | nexus% set flag | ||
| 3759 : | nexus% if ($?flag) echo 'Flag is set!' | ||
| 3760 : | Flag is set! | ||
| 3761 : | nexus% unset flag | ||
| 3762 : | nexus% if ( $?flag ) echo 'Flag is set!' | ||
| 3763 : | nexus% | ||
| 3764 : | @end smallexample | ||
| 3765 : | |||
| 3766 : | @noindent | ||
| 3767 : | The operator @samp{$?@var{variable}} is @samp{true} if @var{variable} | ||
| 3768 : | exists and @samp{false} if it does not. It does not matter whether | ||
| 3769 : | the variable holds any information. | ||
| 3770 : | @vindex set | ||
| 3771 : | @vindex unset | ||
| 3772 : | @cindex @code{unset} command | ||
| 3773 : | |||
| 3774 : | The commands @samp{unset} and @samp{unsetenv} can be used to undefine | ||
| 3775 : | or delete variables when you don't want them anymore. | ||
| 3776 : | @cindex Undefining variables | ||
| 3777 : | |||
| 3778 : | @c ----------------------------------------------------------------------- | ||
| 3779 : | @c SECTION | ||
| 3780 : | @c ----------------------------------------------------------------------- | ||
| 3781 : | |||
| 3782 : | @node Arrays, Pipes and redirection, Defining variables with set and setenv, C shell | ||
| 3783 : | @section Arrays | ||
| 3784 : | |||
| 3785 : | @cindex Arrays in csh | ||
| 3786 : | @cindex () operators to make array in csh | ||
| 3787 : | @vindex () in csh | ||
| 3788 : | |||
| 3789 : | A useful facility in the C-shell is the ability to make arrays out of | ||
| 3790 : | strings and other variables. The round parentheses @samp{(..)} do this. | ||
| 3791 : | For example, look at the following commands. | ||
| 3792 : | @smallexample | ||
| 3793 : | nexus% set array = ( a b c d ) | ||
| 3794 : | nexus% echo $array[1] | ||
| 3795 : | a | ||
| 3796 : | nexus% echo $array[2] | ||
| 3797 : | b | ||
| 3798 : | nexus% echo $array[$#array] | ||
| 3799 : | d | ||
| 3800 : | |||
| 3801 : | nexus% set noarray = ( "a b c d" ) | ||
| 3802 : | nexus% echo $noarray[1] | ||
| 3803 : | a b c d | ||
| 3804 : | nexus% echo $noarray[$#noarray] | ||
| 3805 : | a b c d | ||
| 3806 : | @end smallexample | ||
| 3807 : | |||
| 3808 : | @noindent | ||
| 3809 : | The first command defines an array containing the elements @samp{a b c d}. | ||
| 3810 : | The elements of the array are referred to using square brackets @samp{[..]} | ||
| 3811 : | and the first element is @samp{$array[1]}. The last element is | ||
| 3812 : | @samp{$array[4]}. @emph{NOTE: this is not the same as in C or C++ where | ||
| 3813 : | the first element of the array is the zeroth element!} | ||
| 3814 : | |||
| 3815 : | The special operator @samp{$#} returns the number of elements in an array. | ||
| 3816 : | This gives us a simple way of finding the end of the array. | ||
| 3817 : | For example | ||
| 3818 : | @smallexample | ||
| 3819 : | nexus% echo $#path | ||
| 3820 : | 23 | ||
| 3821 : | |||
| 3822 : | nexus% echo "The last element in path is $path[$#path]" | ||
| 3823 : | The last element in path is . | ||
| 3824 : | @end smallexample | ||
| 3825 : | |||
| 3826 : | @noindent | ||
| 3827 : | To find the next last element we need to be able to do arithmetic. We'll | ||
| 3828 : | come back to this later. | ||
| 3829 : | |||
| 3830 : | @c ----------------------------------------------------------------------- | ||
| 3831 : | @c SECTION | ||
| 3832 : | @c ----------------------------------------------------------------------- | ||
| 3833 : | |||
| 3834 : | @node Pipes and redirection, tee and script, Arrays, C shell | ||
| 3835 : | @section Pipes and redirection in csh | ||
| 3836 : | |||
| 3837 : | @cindex Pipes | ||
| 3838 : | @cindex @samp{|} symbol | ||
| 3839 : | @vindex | | ||
| 3840 : | @vindex > | ||
| 3841 : | @vindex < | ||
| 3842 : | @vindex >> | ||
| 3843 : | @vindex << | ||
| 3844 : | @vindex & | ||
| 3845 : | @cindex Redirection of stdio | ||
| 3846 : | @cindex Standard I/O, redirection | ||
| 3847 : | |||
| 3848 : | The symbols | ||
| 3849 : | @smallexample | ||
| 3850 : | < > >> << | & | ||
| 3851 : | @end smallexample | ||
| 3852 : | @noindent | ||
| 3853 : | have a special meaning in the shell. By default, most commands take their | ||
| 3854 : | input from the file @samp{stdin} (the keyboard) and write | ||
| 3855 : | their output to the file @samp{stdout} and their error messages to the | ||
| 3856 : | file @samp{stderr} (normally, both of these output files are defined to be | ||
| 3857 : | the current terminal device @samp{/dev/tty}, or @samp{/dev/console}). | ||
| 3858 : | |||
| 3859 : | @samp{stdin}, @samp{stdout} and @samp{stderr}, known collectively as | ||
| 3860 : | @samp{stdio}, can be redefined or @emph{redirected} so that | ||
| 3861 : | information is taken from | ||
| 3862 : | or sent to a different file. The output direction can be | ||
| 3863 : | changed with the symbol @samp{>}. For example, | ||
| 3864 : | |||
| 3865 : | @cindex Output, sending to a file | ||
| 3866 : | @smallexample | ||
| 3867 : | echo testing > myfile | ||
| 3868 : | @end smallexample | ||
| 3869 : | |||
| 3870 : | @noindent | ||
| 3871 : | produces a file called @file{myfile} which contains the string `testing'. | ||
| 3872 : | The single @samp{>} (greater than) sign always creates a new file, whereas | ||
| 3873 : | the double @samp{>>} appends to the end of a file, if it already exists. | ||
| 3874 : | So the first of the commands | ||
| 3875 : | @smallexample | ||
| 3876 : | echo blah blah >> myfile | ||
| 3877 : | echo Newfile > myfile | ||
| 3878 : | @end smallexample | ||
| 3879 : | |||
| 3880 : | @noindent | ||
| 3881 : | adds a second line to @samp{myfile} after `testing', whereas the second | ||
| 3882 : | command writes over @file{myfile} and ends up with just one line | ||
| 3883 : | `Newfile'. | ||
| 3884 : | |||
| 3885 : | Now suppose we mistype a command | ||
| 3886 : | @smallexample | ||
| 3887 : | ehco test > myfile | ||
| 3888 : | @end smallexample | ||
| 3889 : | |||
| 3890 : | @noindent | ||
| 3891 : | The command @samp{ehco} does not exist and so the error message | ||
| 3892 : | @samp{ehco: Command not found} appears on the terminal. This error | ||
| 3893 : | message was sent to @emph{stderr} -- so even though we redirected output | ||
| 3894 : | to a file, the error message appeared on the screen to tell us that | ||
| 3895 : | an error occurred. Even this can be changed. @samp{stderr} can also | ||
| 3896 : | be redirected by adding an ampersand @samp{&} character | ||
| 3897 : | to the @samp{>} symbol. The command | ||
| 3898 : | @smallexample | ||
| 3899 : | ehco test >& myfile | ||
| 3900 : | @end smallexample | ||
| 3901 : | @noindent | ||
| 3902 : | results in the file @file{myfile} being created, containing the | ||
| 3903 : | error message `ehco: Command not found'. | ||
| 3904 : | |||
| 3905 : | The input direction can be changed using the @samp{<} symbol | ||
| 3906 : | for example | ||
| 3907 : | @smallexample | ||
| 3908 : | /bin/mail mark < message | ||
| 3909 : | @end smallexample | ||
| 3910 : | |||
| 3911 : | @noindent | ||
| 3912 : | would send the file @samp{message} to the user @samp{mark} by | ||
| 3913 : | electronic mail. The mail program takes its input from the file | ||
| 3914 : | instead of waiting for keyboard input. | ||
| 3915 : | |||
| 3916 : | @cindex @code{noclobber} variable | ||
| 3917 : | @cindex Protecting files from overwrite with @samp{>} | ||
| 3918 : | @cindex @code{noclobber} overwrite protection | ||
| 3919 : | There are some refinements to the redirection symbols. First of all, | ||
| 3920 : | let us introduce the C-shell variable @samp{noclobber}. If this variable | ||
| 3921 : | is set with a command like | ||
| 3922 : | @smallexample | ||
| 3923 : | set noclobber | ||
| 3924 : | @end smallexample | ||
| 3925 : | |||
| 3926 : | @noindent | ||
| 3927 : | then files will not be overwritten by the @samp{>} command. If one | ||
| 3928 : | tries to redirect output to an existing file, the following happens. | ||
| 3929 : | @smallexample | ||
| 3930 : | unix% set noclobber | ||
| 3931 : | unix% touch blah # create an empty file blah | ||
| 3932 : | unix% echo test > blah | ||
| 3933 : | blah: File exists. | ||
| 3934 : | @end smallexample | ||
| 3935 : | |||
| 3936 : | If you are nervous about overwriting files, then you can set @samp{noclobber} | ||
| 3937 : | in your @file{.cshrc} file. @samp{noclobber} can be overridden using | ||
| 3938 : | the pling @samp{!} symbol. So | ||
| 3939 : | @smallexample | ||
| 3940 : | unix% set noclobber | ||
| 3941 : | unix% touch blah # create an empty file blah | ||
| 3942 : | unix% echo test >! blah | ||
| 3943 : | @end smallexample | ||
| 3944 : | |||
| 3945 : | @noindent | ||
| 3946 : | writes over the file @samp{blah} even though @samp{noclobber} is set. | ||
| 3947 : | |||
| 3948 : | Here are some other combinations of redirection symbols | ||
| 3949 : | |||
| 3950 : | @cindex Appending to a file with @samp{>>} | ||
| 3951 : | @table @samp | ||
| 3952 : | @item >> | ||
| 3953 : | Append, including @samp{stderr} | ||
| 3954 : | @item >>! | ||
| 3955 : | Append, ignoring @samp{noclobber} | ||
| 3956 : | @item >>&! | ||
| 3957 : | Append @samp{stdout}, @samp{stderr}, ignore @samp{noclobber} | ||
| 3958 : | @item << | ||
| 3959 : | See below. | ||
| 3960 : | @end table | ||
| 3961 : | |||
| 3962 : | @noindent | ||
| 3963 : | The last of these commands reads from the standard input until it | ||
| 3964 : | finds a line which contains a word. It then feeds all of this input | ||
| 3965 : | into the program concerned. For example, | ||
| 3966 : | @smallexample | ||
| 3967 : | nexus% mail mark <<quit | ||
| 3968 : | nexus 1> Hello mark | ||
| 3969 : | nexus 2> Nothing much to say... | ||
| 3970 : | nexus 2> so bye | ||
| 3971 : | nexus 2> | ||
| 3972 : | nexus 2> quit | ||
| 3973 : | Sending mail... | ||
| 3974 : | Mail sent! | ||
| 3975 : | @end smallexample | ||
| 3976 : | |||
| 3977 : | @noindent | ||
| 3978 : | The mail message contains all the lines up to, but not including `marker'. | ||
| 3979 : | This method can also be used to print text verbatim from a file | ||
| 3980 : | without using multiple echo commands. Inside a script one | ||
| 3981 : | may write: | ||
| 3982 : | @cindex Formatting text in a file | ||
| 3983 : | @cindex Printing multiple lines | ||
| 3984 : | |||
| 3985 : | @smallexample | ||
| 3986 : | cat << "marker"; | ||
| 3987 : | |||
| 3988 : | MENU | ||
| 3989 : | |||
| 3990 : | 1) choice 1 | ||
| 3991 : | 2) choice 2 | ||
| 3992 : | ... | ||
| 3993 : | |||
| 3994 : | marker | ||
| 3995 : | @end smallexample | ||
| 3996 : | The @code{cat} command writes directly to @code{stdout} and the | ||
| 3997 : | input is redirected and taken directly from the script file. | ||
| 3998 : | @vindex << | ||
| 3999 : | @cindex Input over many lines | ||
| 4000 : | |||
| 4001 : | |||
| 4002 : | @cindex Pipe | ||
| 4003 : | @cindex @samp{|} symbol | ||
| 4004 : | A very useful construction is the `pipe' facility. Using the @samp{|} | ||
| 4005 : | symbol one can feed the @samp{stdout} of one program straight into | ||
| 4006 : | the @samp{stdin} of another program. Similarly with @samp{|&} both | ||
| 4007 : | @samp{stdout} and @samp{stderr} can be piped into the input of another | ||
| 4008 : | program. This is very convenient. For instance, look up the following | ||
| 4009 : | commands in the manual and try them. | ||
| 4010 : | |||
| 4011 : | @cindex Piping to more to prevent scrolling | ||
| 4012 : | @smallexample | ||
| 4013 : | ps aux | more | ||
| 4014 : | echo 'Keep on sharpenin them there knives!' | mail henry | ||
| 4015 : | vmstat 1 | head | ||
| 4016 : | ls -l /etc | tail | ||
| 4017 : | @end smallexample | ||
| 4018 : | |||
| 4019 : | @noindent | ||
| 4020 : | Note that when piping both standard input and standard error to another | ||
| 4021 : | program, the two files @emph{do not mix synchronously}. Often @samp{stderr} | ||
| 4022 : | appears first. | ||
| 4023 : | |||
| 4024 : | @c ----------------------------------------------------------------------- | ||
| 4025 : | @c SECTION | ||
| 4026 : | @c ----------------------------------------------------------------------- | ||
| 4027 : | |||
| 4028 : | @node tee and script, Command history, Pipes and redirection, C shell | ||
| 4029 : | @section @samp{tee} and @samp{script} | ||
| 4030 : | |||
| 4031 : | @cindex @samp{tee} command | ||
| 4032 : | @cindex Splitting output to several files | ||
| 4033 : | @cindex Copy of output to file | ||
| 4034 : | @cindex Output to file | ||
| 4035 : | Occasionally you might want to have a copy of what you see on your | ||
| 4036 : | terminal sent to a file. @samp{tee} and @samp{script} do this. For | ||
| 4037 : | instance, | ||
| 4038 : | @smallexample | ||
| 4039 : | find / -type l -print | tee myfile | ||
| 4040 : | @end smallexample | ||
| 4041 : | |||
| 4042 : | @noindent | ||
| 4043 : | sends a copy of the output of @samp{find} to the file `myfile'. @samp{tee} | ||
| 4044 : | can split the output into as many files as you want: | ||
| 4045 : | |||
| 4046 : | @smallexample | ||
| 4047 : | @var{command} | tee @var{file1} @var{file2} .... | ||
| 4048 : | @end smallexample | ||
| 4049 : | |||
| 4050 : | @noindent | ||
| 4051 : | You can also choose to record the output an entire shell session using | ||
| 4052 : | the @samp{script} command. | ||
| 4053 : | @smallexample | ||
| 4054 : | nexus% script mysession | ||
| 4055 : | Script started, file is mysession | ||
| 4056 : | |||
| 4057 : | nexus% echo Big brother is scripting you | ||
| 4058 : | Big brother is scripting you | ||
| 4059 : | |||
| 4060 : | nexus% exit | ||
| 4061 : | exit | ||
| 4062 : | Script done, file is mysession | ||
| 4063 : | @end smallexample | ||
| 4064 : | |||
| 4065 : | @noindent | ||
| 4066 : | The file `mysession' is a text file which contains a transcript of the | ||
| 4067 : | session. | ||
| 4068 : | |||
| 4069 : | @c ----------------------------------------------------------------------- | ||
| 4070 : | @c SECTION | ||
| 4071 : | @c ----------------------------------------------------------------------- | ||
| 4072 : | |||
| 4073 : | @node Command history, Command/filename completion, tee and script, C shell | ||
| 4074 : | @section Command history | ||
| 4075 : | |||
| 4076 : | @cindex Command history | ||
| 4077 : | @cindex Up arrow | ||
| 4078 : | The history feature in C-shell means that you do not have to type | ||
| 4079 : | commands over and over again. In the @samp{tcsh} version of the C shell, | ||
| 4080 : | and the @samp{bash} version of the Bourne shell, you can use the @key{UP | ||
| 4081 : | ARROW} key to browse back through the list of commands you have typed | ||
| 4082 : | previously. | ||
| 4083 : | |||
| 4084 : | In the normal C-shell (@samp{csh}) there are three | ||
| 4085 : | main commands. | ||
| 4086 : | @table @samp | ||
| 4087 : | @item !! | ||
| 4088 : | Execute the last command again. | ||
| 4089 : | |||
| 4090 : | @item !-3 | ||
| 4091 : | Execute the third last command again. | ||
| 4092 : | |||
| 4093 : | @item !4 | ||
| 4094 : | Execute command number 4. | ||
| 4095 : | @end table | ||
| 4096 : | |||
| 4097 : | The first of these simply repeats the last command. The second | ||
| 4098 : | counts backwards from the last command to three commands-ago. The | ||
| 4099 : | final command gives an absolute number. The absolute command number | ||
| 4100 : | can be seen by typing @samp{history}. | ||
| 4101 : | |||
| 4102 : | @c ----------------------------------------------------------------------- | ||
| 4103 : | @c SECTION | ||
| 4104 : | @c ----------------------------------------------------------------------- | ||
| 4105 : | |||
| 4106 : | @node Command/filename completion, Single and double quotes, Command history, C shell | ||
| 4107 : | @section Command/filename completion | ||
| 4108 : | |||
| 4109 : | @cindex Filename completion | ||
| 4110 : | @cindex Command completion | ||
| 4111 : | @cindex @key{TAB} completion key | ||
| 4112 : | In the @samp{tcsh} extension of the C-shell, you can save hours worth | ||
| 4113 : | of typing errors by using the completion mechanism. This feature is | ||
| 4114 : | based on the @key{TAB} key. | ||
| 4115 : | |||
| 4116 : | The idea is that if you type half a filename and press @key{TAB}, | ||
| 4117 : | the shell will try to guess the remainder of the filename. It does | ||
| 4118 : | this by looking at the files which match what you have already typed | ||
| 4119 : | and trying to fill in the rest. If there are several files which | ||
| 4120 : | match, the shell sounds the "bell" or beeps. You can then | ||
| 4121 : | type @key{CTRL-D} to obtain a list of the possible alternatives. | ||
| 4122 : | Here is an example: suppose you have just a single file in the | ||
| 4123 : | current directory called @file{very_long_filename}, typing | ||
| 4124 : | |||
| 4125 : | @smallexample | ||
| 4126 : | more @key{TAB} | ||
| 4127 : | @end smallexample | ||
| 4128 : | |||
| 4129 : | @noindent | ||
| 4130 : | results in the following appearing on the command line | ||
| 4131 : | @smallexample | ||
| 4132 : | more very_long_filename | ||
| 4133 : | @end smallexample | ||
| 4134 : | |||
| 4135 : | @noindent | ||
| 4136 : | The shell was able to identify a unique file. Now suppose that | ||
| 4137 : | you have two files called @file{very_long_filename} and @file{very_big_filename}, | ||
| 4138 : | typing | ||
| 4139 : | @smallexample | ||
| 4140 : | more @key{TAB} | ||
| 4141 : | @end smallexample | ||
| 4142 : | |||
| 4143 : | @noindent | ||
| 4144 : | results in the following appearing on the command line | ||
| 4145 : | @smallexample | ||
| 4146 : | more very_ | ||
| 4147 : | @end smallexample | ||
| 4148 : | |||
| 4149 : | @noindent | ||
| 4150 : | and the shell beeps, indicating that the choice was not unique and | ||
| 4151 : | a decision is required. Next, you type @key{CTRL-D} to see which files | ||
| 4152 : | you ahve to choose from and the shell lists them and returns you to | ||
| 4153 : | the command line, exactly where you were. You now choose | ||
| 4154 : | @file{very_long_filename} by typing @samp{l}. This is enough to | ||
| 4155 : | uniquely identify the file. Pressing the @key{TAB} key again | ||
| 4156 : | results in | ||
| 4157 : | @smallexample | ||
| 4158 : | more very_long_filename | ||
| 4159 : | @end smallexample | ||
| 4160 : | |||
| 4161 : | @noindent | ||
| 4162 : | on the screen. As long as you have written enough to select a file | ||
| 4163 : | uniquely, the shell will be able to complete the name for you. | ||
| 4164 : | |||
| 4165 : | Completion also works on shell commands, but it is a little slower since | ||
| 4166 : | the shell must serach through all the directories in the command | ||
| 4167 : | path to complete commands. | ||
| 4168 : | |||
| 4169 : | @c ----------------------------------------------------------------------- | ||
| 4170 : | @c SECTION | ||
| 4171 : | @c ----------------------------------------------------------------------- | ||
| 4172 : | |||
| 4173 : | @node Single and double quotes, Job control, Command/filename completion, C shell | ||
| 4174 : | @section Single and double quotes | ||
| 4175 : | |||
| 4176 : | @cindex Single and double quotes | ||
| 4177 : | @cindex @key{'} and @key{"} | ||
| 4178 : | @vindex ' | ||
| 4179 : | @vindex " | ||
| 4180 : | @vindex ` | ||
| 4181 : | @cindex Backwards quotes | ||
| 4182 : | @cindex @key{`} symbol and embedded shells | ||
| 4183 : | @cindex Embedded shell | ||
| 4184 : | |||
| 4185 : | Two kinds of quotes can be used in shell apart from the | ||
| 4186 : | backward quotes we mentioned above. The essential difference | ||
| 4187 : | between them is that certain | ||
| 4188 : | shell commands work inside @emph{double} quotes but not inside single | ||
| 4189 : | quotes. For example | ||
| 4190 : | @smallexample | ||
| 4191 : | |||
| 4192 : | nexus% echo /etc/rc.* | ||
| 4193 : | /etc/rc.boot /etc/rc.ip /etc/rc.local | ||
| 4194 : | |||
| 4195 : | nexus% echo "/etc/rc.*" | ||
| 4196 : | /etc/rc.* | ||
| 4197 : | |||
| 4198 : | nexus% echo "`who am i` -- my name is $user ???" | ||
| 4199 : | nexus!mark ttyp7 Jul 13 10:16 -- my name is mark ??? | ||
| 4200 : | |||
| 4201 : | nexus% echo '`who am i` -- my name is $user ???' | ||
| 4202 : | `who am i` -- my name is $user ??? | ||
| 4203 : | |||
| 4204 : | @end smallexample | ||
| 4205 : | We see that the single quotes prevent @emph{variable substitution} | ||
| 4206 : | and @emph{sub-shells}. Wildcards do not work inside either single or | ||
| 4207 : | double quotes. | ||
| 4208 : | @c ----------------------------------------------------------------------- | ||
| 4209 : | @c SECTION | ||
| 4210 : | @c ----------------------------------------------------------------------- | ||
| 4211 : | |||
| 4212 : | @node Job control, Scripts with argumemts, Single and double quotes, C shell | ||
| 4213 : | @section Job control, break key, @samp{fg}, @samp{bg} | ||
| 4214 : | |||
| 4215 : | @cindex Job control | ||
| 4216 : | @cindex Foreground process | ||
| 4217 : | @cindex Background process | ||
| 4218 : | |||
| 4219 : | So far we haven't mentioned UNIX's ability to multitask. In the Bourne | ||
| 4220 : | shell (@samp{sh}) there are no facilities for controlling several user | ||
| 4221 : | processes @footnote{Newer versions of the Bourne shell, like the Korn | ||
| 4222 : | shell and Bourne-again-shell do have these facilities.}. C-shell | ||
| 4223 : | provides some commands for starting and stopping processes. These | ||
| 4224 : | originate from the days before windows and X11, so some of them may seem | ||
| 4225 : | a little old-fashioned. They are still very useful nonetheless. | ||
| 4226 : | |||
| 4227 : | Let's begin by looking at the commands which are true for any shell. | ||
| 4228 : | Most programs are run in the @emph{foreground} or @emph{interactively}. | ||
| 4229 : | That means that they are connected to the standard input and send their | ||
| 4230 : | output to the standard output. A program can be made to run in the | ||
| 4231 : | background, if it does not need to use the standard I/O. For example, a | ||
| 4232 : | program which generates output and sends it to a file could run in the | ||
| 4233 : | background. In a window environment, programs which create their own | ||
| 4234 : | windows can also be started as background processes, leaving standard | ||
| 4235 : | I/O in the shell free. | ||
| 4236 : | |||
| 4237 : | @emph{Background processes run independently of what you are doing in the | ||
| 4238 : | foreground.} | ||
| 4239 : | |||
| 4240 : | @c .............................. | ||
| 4241 : | @c SUBSECTION | ||
| 4242 : | @c .............................. | ||
| 4243 : | |||
| 4244 : | @menu | ||
| 4245 : | * Processes and signals:: | ||
| 4246 : | * Child processes and zombies:: | ||
| 4247 : | * Builtins:: | ||
| 4248 : | @end menu | ||
| 4249 : | |||
| 4250 : | @node Processes and signals, Child processes and zombies, Job control, Job control | ||
| 4251 : | @subsection Unix Processes and BSD signals | ||
| 4252 : | |||
| 4253 : | @cindex @samp{find} command | ||
| 4254 : | @cindex Processes | ||
| 4255 : | @cindex Background process | ||
| 4256 : | |||
| 4257 : | A background process is started using the special charcter @samp{&} at | ||
| 4258 : | the end of the command line. | ||
| 4259 : | @smallexample | ||
| 4260 : | find / -name '*lib*' -print >& output & | ||
| 4261 : | @end smallexample | ||
| 4262 : | |||
| 4263 : | @noindent | ||
| 4264 : | The final @samp{&} on the end of this line means that the job will be | ||
| 4265 : | run in the background. Note that this is not confused with the | ||
| 4266 : | redirection operator @samp{>&} since it must be the last character on | ||
| 4267 : | the line. The command above looks for any files in the system containing | ||
| 4268 : | the string `lib' and writes the list of files to a file called | ||
| 4269 : | `output'. This might be a useful way of searching for missing libraries | ||
| 4270 : | which you want to include in your environment variable | ||
| 4271 : | @samp{LD_LIBRARY_PATH}. Searching the enire disk from the root | ||
| 4272 : | directory @samp{/} could take a long time, so it pays to run this in the | ||
| 4273 : | background. | ||
| 4274 : | |||
| 4275 : | If we want to see what processes are running, we can use the | ||
| 4276 : | @samp{ps} command. @samp{ps} without any arguments lists all of | ||
| 4277 : | your processes, i.e. all processes owned by the user name you | ||
| 4278 : | logged in with. @samp{ps} takes many options, for instance | ||
| 4279 : | @samp{ps auxg} will list all processes in gruesome detail. | ||
| 4280 : | (The "g" is for group, not gruesome!) | ||
| 4281 : | @samp{ps} reads the kernel's process tables directly. | ||
| 4282 : | |||
| 4283 : | Processes can be stopped and started, or killed one and for all. | ||
| 4284 : | The @samp{kill} command does this. There are, in fact, two versions | ||
| 4285 : | of the @samp{kill} command. One of them is built into the C-shell | ||
| 4286 : | and the other is not. If you use the C-shell then you will never | ||
| 4287 : | care about the difference. We shall nonetheless mention the | ||
| 4288 : | special features of the C-shell built-ins below. The kill command | ||
| 4289 : | takes a number called a @emph{signal} as an argument and another | ||
| 4290 : | number called the @emph{process identifier} or @emph{PID} for short. | ||
| 4291 : | Kill send signals to processes. Some of these are fatal and some | ||
| 4292 : | are for information only. The two commands | ||
| 4293 : | |||
| 4294 : | @smallexample | ||
| 4295 : | kill -15 127 | ||
| 4296 : | kill 127 | ||
| 4297 : | |||
| 4298 : | @end smallexample | ||
| 4299 : | |||
| 4300 : | @noindent | ||
| 4301 : | are identical. They both send signal 15 to PID 127. This is | ||
| 4302 : | the normal @emph{termination} signal and it is often enough to | ||
| 4303 : | stop any process from running. | ||
| 4304 : | |||
| 4305 : | Programs can choose to ignore certain signals by trapping | ||
| 4306 : | signals with a special handler. One signal they cannot | ||
| 4307 : | ignore is signal 9. | ||
| 4308 : | |||
| 4309 : | @smallexample | ||
| 4310 : | kill -9 127 | ||
| 4311 : | @end smallexample | ||
| 4312 : | |||
| 4313 : | @noindent | ||
| 4314 : | is a sure way of killing PID 127. Even though the process dies, it | ||
| 4315 : | may not be removed from the kernel's process table if it has | ||
| 4316 : | a parent (see next section). | ||
| 4317 : | |||
| 4318 : | Here is the complete list of unix signals which the kernel send to | ||
| 4319 : | processes in different circumstances. | ||
| 4320 : | |||
| 4321 : | @smallexample | ||
| 4322 : | 1 "SIGHUP", /* hangup */ | ||
| 4323 : | 2 "SIGINT", /* interrupt */ | ||
| 4324 : | 3 "SIGQUIT", /* quit */ | ||
| 4325 : | 4 "SIGILL", /* illegal instruction (not reset when caught) */ | ||
| 4326 : | 5 "SIGTRAP", /* trace trap (not reset when caught) */ | ||
| 4327 : | 6 "SIGIOT/SIGABRT", /* IOT instruction */ | ||
| 4328 : | 7 "SIGEMT", /* EMT instruction */ | ||
| 4329 : | 8 "SIGFPE", /* floating point exception */ | ||
| 4330 : | 9 "SIGKILL", /* kill (cannot be caught or ignored) */ | ||
| 4331 : | 10 "SIGBUS", /* bus error */ | ||
| 4332 : | 11 "SIGSEGV", /* segmentation violation */ | ||
| 4333 : | 12 "SIGSYS", /* bad argument to system call */ | ||
| 4334 : | 13 "SIGPIPE", /* write on a pipe with no one to read it */ | ||
| 4335 : | 14 "SIGALRM", /* alarm clock */ | ||
| 4336 : | 15 "SIGTERM", /* software termination signal from kill */ | ||
| 4337 : | 16 "SIGURG", /* urgent condition on IO channel */ | ||
| 4338 : | 17 "SIGSTOP", /* sendable stop signal not from tty */ | ||
| 4339 : | 18 "SIGTSTP", /* stop signal from tty */ | ||
| 4340 : | 19 "SIGCONT", /* continue a stopped process */ | ||
| 4341 : | 20 "SIGCHLD/SIGCLD", /* to parent on child stop or exit */ | ||
| 4342 : | 21 "SIGTTIN", /* to readers pgrp upon background tty read */ | ||
| 4343 : | 22 "SIGTTOU", /* like TTIN for output if (tp->t_local<OSTOP) */ | ||
| 4344 : | 23 "SIGIO/SIGPOLL", /* input/output possible signal */ | ||
| 4345 : | 24 "SIGXCPU", /* exceeded CPU time limit */ | ||
| 4346 : | 25 "SIGXFSZ", /* exceeded file size limit */ | ||
| 4347 : | 26 "SIGVTALRM", /* virtual time alarm */ | ||
| 4348 : | 27 "SIGPROF", /* profiling time alarm */ | ||
| 4349 : | 28 "SIGWINCH", /* window changed */ | ||
| 4350 : | 29 "SIGLOST", /* resource lost (eg, record-lock lost) */ | ||
| 4351 : | 30 "SIGUSR1", /* user defined signal 1 */ | ||
| 4352 : | 31 "SIGUSR2" | ||
| 4353 : | |||
| 4354 : | @end smallexample | ||
| 4355 : | |||
| 4356 : | We have already mentioned 15 and 9 which are the main signals | ||
| 4357 : | for users. Signal 1, or @samp{HUP} can be sent to certain programs | ||
| 4358 : | by the superuser. For instance | ||
| 4359 : | @smallexample | ||
| 4360 : | kill -1 <inetd> | ||
| 4361 : | kill -HUP <inetd> | ||
| 4362 : | @end smallexample | ||
| 4363 : | |||
| 4364 : | @noindent | ||
| 4365 : | which forces @samp{inetd} to reread its configuration file. Sometimes | ||
| 4366 : | it is useful to @emph{suspend} a process temporarily and then | ||
| 4367 : | @emph{restart} it later. | ||
| 4368 : | @smallexample | ||
| 4369 : | kill -18 <PID> # suspend process <PID> | ||
| 4370 : | kill -19 <PID> # resume process <PID> | ||
| 4371 : | @end smallexample | ||
| 4372 : | |||
| 4373 : | @c .............................. | ||
| 4374 : | @c SUBSECTION | ||
| 4375 : | @c .............................. | ||
| 4376 : | |||
| 4377 : | @node Child processes and zombies, Builtins, Processes and signals, Job control | ||
| 4378 : | @subsection Child Processes and zombies | ||
| 4379 : | |||
| 4380 : | When you start a process from a shell, regardless of whether it is | ||
| 4381 : | a background process or a foreground process, the new process becomes | ||
| 4382 : | a @emph{child} of the original shell. Remember that the shell is just | ||
| 4383 : | a unix process itself. Moreover, if one of the children starts a new | ||
| 4384 : | process then it will be a child of the child (a grandchild?)! | ||
| 4385 : | Processes therefore form | ||
| 4386 : | @emph{hierachies}. Several children can have a common @emph{parent}. | ||
| 4387 : | |||
| 4388 : | If we kill a parent, then (unless the child has detached itself from the | ||
| 4389 : | parent) all of its children die too. If a child dies, the parent is not | ||
| 4390 : | affected. Sometimes when a child is killed, it does not die but becomes | ||
| 4391 : | "defunct" or a zombie process. This means that the child has a parent | ||
| 4392 : | which is @emph{waiting} for it to finish. If the parent has not yet been | ||
| 4393 : | informed that the child has died, for example because it has been | ||
| 4394 : | suspended itself, then the dead child is not removed from the kernel's | ||
| 4395 : | process table. When the parent wakes up and receives the message that | ||
| 4396 : | the child has terminated, the process entry for the dead child can be | ||
| 4397 : | removed. | ||
| 4398 : | |||
| 4399 : | @c .............................. | ||
| 4400 : | @c SUBSECTION | ||
| 4401 : | @c .............................. | ||
| 4402 : | |||
| 4403 : | @node Builtins, , Child processes and zombies, Job control | ||
| 4404 : | @subsection C-shell builtins: @samp{jobs}, @samp{kill}, @samp{fg},@samp{bg}, break key | ||
| 4405 : | |||
| 4406 : | @cindex Starting shell jobs | ||
| 4407 : | @cindex @samp{fg} command | ||
| 4408 : | @cindex @samp{bg} command | ||
| 4409 : | @cindex Job numbers in csh | ||
| 4410 : | |||
| 4411 : | Now let's look at some commands which are built into the C-shell for | ||
| 4412 : | starting and stopping processes. C-shell refers to user programs as | ||
| 4413 : | `jobs' rather than processes -- but there is no real difference. The | ||
| 4414 : | added bonus of the C-shell is that each shell has a @emph{job number} in | ||
| 4415 : | addition to its PID. The job numbers are simpler and are private for the | ||
| 4416 : | shell, whereas the PIDs are assigned by the kernel and are often very | ||
| 4417 : | large numbers which are difficult to to remember. When a command is | ||
| 4418 : | executed in the shell, it is assigned a job number. If you never run any | ||
| 4419 : | background jobs then there is only ever one job number: 1, since every | ||
| 4420 : | job exits before the next one starts. However, if you run background | ||
| 4421 : | tasks, then you can have several jobs "active" at any time. Moreover, by | ||
| 4422 : | @emph{suspending} jobs, C-shell allows you to have several interactive | ||
| 4423 : | programs running on the same terminal -- the @samp{fg} and @samp{bg} | ||
| 4424 : | commands allow you to move commands from the background to the | ||
| 4425 : | foreground and vice-versa. | ||
| 4426 : | |||
| 4427 : | Take a look at the following shell session. | ||
| 4428 : | @smallexample | ||
| 4429 : | nexus% emacs myfile & | ||
| 4430 : | [1] 4990 | ||
| 4431 : | nexus% | ||
| 4432 : | |||
| 4433 : | ( other commands ... , edit myfile and close emacs ) | ||
| 4434 : | |||
| 4435 : | |||
| 4436 : | [1] Exit 70 emacs myfile | ||
| 4437 : | @end smallexample | ||
| 4438 : | |||
| 4439 : | @noindent | ||
| 4440 : | When a background job is done, the shell prints a message at a suitable | ||
| 4441 : | moment between prompts. | ||
| 4442 : | |||
| 4443 : | @smallexample | ||
| 4444 : | [1] Done emacs myfile | ||
| 4445 : | @end smallexample | ||
| 4446 : | |||
| 4447 : | @noindent | ||
| 4448 : | This tells you that job number 1 finished normally. If the job | ||
| 4449 : | exits abnormally then the word `Done' may be replaced by some other | ||
| 4450 : | message. For instance, if you kill the job, it will say | ||
| 4451 : | @cindex @samp{kill} command | ||
| 4452 : | @smallexample | ||
| 4453 : | unix% kill %12 | ||
| 4454 : | [12] Terminated textedit file | ||
| 4455 : | @end smallexample | ||
| 4456 : | |||
| 4457 : | @noindent | ||
| 4458 : | You can list the jobs you have running using the @samp{jobs} command. | ||
| 4459 : | The output looks something like | ||
| 4460 : | @smallexample | ||
| 4461 : | [1] + Running textedit c.tex | ||
| 4462 : | [3] Running textedit glossary.tex | ||
| 4463 : | [4] Running textedit net.tex | ||
| 4464 : | [5] Running textedit overview.tex | ||
| 4465 : | [6] Running textedit perl.tex | ||
| 4466 : | [7] Running textedit shell.tex | ||
| 4467 : | [8] Running textedit sysadm.tex | ||
| 4468 : | [9] Running textedit unix.tex | ||
| 4469 : | [10] Running textedit x11.tex | ||
| 4470 : | [11] - Running shelltool | ||
| 4471 : | [15] Suspended emacs myfile | ||
| 4472 : | @end smallexample | ||
| 4473 : | |||
| 4474 : | @noindent | ||
| 4475 : | @cindex Suspending a job | ||
| 4476 : | @cindex Moving a job to the background | ||
| 4477 : | @cindex Job, moving to background | ||
| 4478 : | @cindex Process. moving to background | ||
| 4479 : | |||
| 4480 : | To suspend a program | ||
| 4481 : | which you are running in the foreground | ||
| 4482 : | you can type @key{CTRL-z} (this is like sending a @samp{kill -18} | ||
| 4483 : | signal from the keyboard). @footnote{This does not seem to work in | ||
| 4484 : | solaris?!} You can suspend any number of programs and then restart them | ||
| 4485 : | one at a time using @samp{fg} and @samp{bg}. If you want job 5 to be | ||
| 4486 : | restarted in the foreground, you would type | ||
| 4487 : | |||
| 4488 : | @smallexample | ||
| 4489 : | fg %5 | ||
| 4490 : | @end smallexample | ||
| 4491 : | |||
| 4492 : | @noindent | ||
| 4493 : | When you have had enough of job 5, you can type CTRL-z to suspend it | ||
| 4494 : | and then type | ||
| 4495 : | |||
| 4496 : | @noindent | ||
| 4497 : | @smallexample | ||
| 4498 : | fg %6 | ||
| 4499 : | @end smallexample | ||
| 4500 : | |||
| 4501 : | @noindent | ||
| 4502 : | to activate job 6. Provided a job does not want to send output to | ||
| 4503 : | @samp{stdout}, you can restart any job in the background, using a | ||
| 4504 : | command like. | ||
| 4505 : | @smallexample | ||
| 4506 : | bg %4 | ||
| 4507 : | @end smallexample | ||
| 4508 : | |||
| 4509 : | @emph{This method of working was useful before windows were available.} | ||
| 4510 : | @emph{Using @samp{fg} and @samp{bg}, you can edit several files} | ||
| 4511 : | @emph{or work on several programs without have to quit to} | ||
| 4512 : | @emph{move from one to another.} | ||
| 4513 : | |||
| 4514 : | |||
| 4515 : | See also some related commands for | ||
| 4516 : | batch processing @samp{at}, @samp{batch} and @samp{atq}, @samp{cron}. | ||
| 4517 : | |||
| 4518 : | @cindex Break key | ||
| 4519 : | @cindex Panic button | ||
| 4520 : | NOTE: @key{CTRL-c} sends a @samp{kill -2} signal, which send a standard | ||
| 4521 : | interrupt message to a program. This is always a safe way to interrupt | ||
| 4522 : | a shell command. | ||
| 4523 : | |||
| 4524 : | @c ----------------------------------------------------------------------- | ||
| 4525 : | @c SECTION | ||
| 4526 : | @c ----------------------------------------------------------------------- | ||
| 4527 : | |||
| 4528 : | @node Scripts with argumemts, subshells, Job control, C shell | ||
| 4529 : | @section Scripts with arguments | ||
| 4530 : | |||
| 4531 : | @cindex Script, making | ||
| 4532 : | @cindex Making a script | ||
| 4533 : | @cindex Writing a script | ||
| 4534 : | |||
| 4535 : | One of the useful features of the shell is that you can use the normal | ||
| 4536 : | unix commands to make programs called @emph{scripts}. To make a script, | ||
| 4537 : | you just create a file containing shell commands you want to execute and | ||
| 4538 : | make sure that the first line of the file looks like the following example. | ||
| 4539 : | |||
| 4540 : | @smallexample | ||
| 4541 : | #!/bin/csh -f | ||
| 4542 : | # | ||
| 4543 : | # A simple script: check for user's mail | ||
| 4544 : | # | ||
| 4545 : | # | ||
| 4546 : | |||
| 4547 : | set path = ( /bin /usr/ucb ) # Set the local path | ||
| 4548 : | |||
| 4549 : | cd /var/spool/mail # Change dir | ||
| 4550 : | |||
| 4551 : | foreach uid ( * ) | ||
| 4552 : | |||
| 4553 : | echo "$uid has mail in the intray! " # space prevents an error! | ||
| 4554 : | |||
| 4555 : | end | ||
| 4556 : | |||
| 4557 : | @end smallexample | ||
| 4558 : | |||
| 4559 : | @cindex @samp{#!program} sequence | ||
| 4560 : | The sequence @samp{#!/bin/csh} means that the following commands are to | ||
| 4561 : | be fed into @file{/bin/csh}. The two symbols @samp{#!} must be the very | ||
| 4562 : | first two characters in the file. The @samp{-f} option means that your | ||
| 4563 : | @samp{.cshrc} file is not read by the shell when it starts up. The file | ||
| 4564 : | containing this script must be executable (see @samp{chmod}) and must be | ||
| 4565 : | in the current path, like all other programs. | ||
| 4566 : | |||
| 4567 : | @cindex Command line arguments | ||
| 4568 : | @cindex Argument vector in csh | ||
| 4569 : | @cindex @samp{argv} | ||
| 4570 : | @cindex Arguments, command line | ||
| 4571 : | Like C programs, C-shell scripts can accept command line arguments. | ||
| 4572 : | Suppose you want to make a program to say hello to some other | ||
| 4573 : | users who are logged onto the system. | ||
| 4574 : | @smallexample | ||
| 4575 : | say-hello mark sarah mel | ||
| 4576 : | @end smallexample | ||
| 4577 : | |||
| 4578 : | @noindent | ||
| 4579 : | To do this you need to know the names that were typed on the command | ||
| 4580 : | line. These names are copied into an array in the C-shell called | ||
| 4581 : | the @emph{argument vector}, or @samp{argv}. To read these arguments, | ||
| 4582 : | you just treat @samp{argv} as an array. | ||
| 4583 : | |||
| 4584 : | @cindex @code{foreach} example | ||
| 4585 : | @cindex @code{write} example | ||
| 4586 : | @smallexample | ||
| 4587 : | #!/bin/csh -f | ||
| 4588 : | # | ||
| 4589 : | # Say hello | ||
| 4590 : | # | ||
| 4591 : | |||
| 4592 : | foreach name ( $argv ) | ||
| 4593 : | |||
| 4594 : | echo Saying hello to $name | ||
| 4595 : | echo "Hello from $user! " | write $name | ||
| 4596 : | |||
| 4597 : | end | ||
| 4598 : | |||
| 4599 : | @end smallexample | ||
| 4600 : | The elements of the array can be referred to | ||
| 4601 : | as @samp{argv[1]}..@samp{argv[$#argv]} as usual. They can also be referred | ||
| 4602 : | to as @samp{$1}..@samp{$3} upto the last acceptable number. This makes | ||
| 4603 : | C-shell compatible with the Bourne shell as far as arguments are | ||
| 4604 : | concerned. One extra flourish in this method is that you can also | ||
| 4605 : | refer to the name of the program itself as @samp{$0}. | ||
| 4606 : | For example, | ||
| 4607 : | @smallexample | ||
| 4608 : | #!/bin/csh -f | ||
| 4609 : | |||
| 4610 : | echo This is program $0 running for $user | ||
| 4611 : | @end smallexample | ||
| 4612 : | |||
| 4613 : | @noindent | ||
| 4614 : | @samp{$argv} represents all the arguments. You can also use | ||
| 4615 : | @samp{$*} from the Bourne shell. | ||
| 4616 : | |||
| 4617 : | @c ----------------------------------------------------------------------- | ||
| 4618 : | @c SECTION | ||
| 4619 : | @c ----------------------------------------------------------------------- | ||
| 4620 : | |||
| 4621 : | @node subshells, Tests and conditions, Scripts with argumemts, C shell | ||
| 4622 : | @section Sub-shells () | ||
| 4623 : | |||
| 4624 : | @cindex Subshells and () | ||
| 4625 : | @cindex () and subshells | ||
| 4626 : | |||
| 4627 : | The C-shell does not allow you to define subroutines or functions, but | ||
| 4628 : | you can create a local shell, with its own private variables by | ||
| 4629 : | enclosing commands in parentheses. | ||
| 4630 : | @smallexample | ||
| 4631 : | #!/bin/csh | ||
| 4632 : | |||
| 4633 : | cd /etc | ||
| 4634 : | |||
| 4635 : | ( cd /usr/bin; ls * ) > myfile | ||
| 4636 : | |||
| 4637 : | pwd | ||
| 4638 : | |||
| 4639 : | @end smallexample | ||
| 4640 : | This program changes the working directory to /etc and then executes | ||
| 4641 : | a subshell which @emph{inside the brackets} changes directory to | ||
| 4642 : | /usr/bin and lists the files there. The output of this private | ||
| 4643 : | shell are sent to a file `myfile'. At the end we print out the | ||
| 4644 : | current working directory just to show that the @samp{cd} command | ||
| 4645 : | in brackets had no effect on the main program. | ||
| 4646 : | |||
| 4647 : | Normally both parentheses must be on the same line. | ||
| 4648 : | If a subshell command line gets too long, so that the brackets are not | ||
| 4649 : | on the same line, you have to use backslash characters to continue the | ||
| 4650 : | lines, | ||
| 4651 : | @smallexample | ||
| 4652 : | |||
| 4653 : | ( command \ | ||
| 4654 : | command \ | ||
| 4655 : | command \ | ||
| 4656 : | ) | ||
| 4657 : | @cindex Continuing long lines | ||
| 4658 : | @cindex Long lines, continuing | ||
| 4659 : | |||
| 4660 : | @end smallexample | ||
| 4661 : | |||
| 4662 : | @c ----------------------------------------------------------------------- | ||
| 4663 : | @c SECTION | ||
| 4664 : | @c ----------------------------------------------------------------------- | ||
| 4665 : | |||
| 4666 : | @node Tests and conditions, Loops in csh, subshells, C shell | ||
| 4667 : | @section Tests and conditions | ||
| 4668 : | |||
| 4669 : | @cindex Tests and conditions in csh | ||
| 4670 : | @cindex @code{if..then..else} in csh | ||
| 4671 : | |||
| 4672 : | No programming language would be complete without tests and loops. | ||
| 4673 : | C-shell has two kinds of decision structure: the @samp{if..then..else} | ||
| 4674 : | and the @samp{switch} structure. These are closely related to their | ||
| 4675 : | C counterparts. The syntax of these is | ||
| 4676 : | @smallexample | ||
| 4677 : | if (@var{condition}) @var{command} | ||
| 4678 : | |||
| 4679 : | if (@var{condition}) then | ||
| 4680 : | command | ||
| 4681 : | command.. | ||
| 4682 : | else | ||
| 4683 : | command | ||
| 4684 : | command.. | ||
| 4685 : | endif | ||
| 4686 : | |||
| 4687 : | @cindex @code{switch..case} in csh | ||
| 4688 : | |||
| 4689 : | switch (@var{string}) | ||
| 4690 : | |||
| 4691 : | case @var{one}: | ||
| 4692 : | commands | ||
| 4693 : | breaksw | ||
| 4694 : | |||
| 4695 : | case @var{two}: | ||
| 4696 : | commands | ||
| 4697 : | breaksw | ||
| 4698 : | |||
| 4699 : | ... | ||
| 4700 : | |||
| 4701 : | endsw | ||
| 4702 : | |||
| 4703 : | @end smallexample | ||
| 4704 : | |||
| 4705 : | In the latter case, no commands should appear on the same line as a `case' | ||
| 4706 : | statement, or they will be ignored. Also, if the @samp{breaksw} | ||
| 4707 : | commands are omitted, then control flows through all the commands | ||
| 4708 : | for case 2, case 3 etc, exactly as it does in the C programming | ||
| 4709 : | language. | ||
| 4710 : | |||
| 4711 : | We shall consider some examples | ||
| 4712 : | of these statements in a moment, but first it is worth listing some | ||
| 4713 : | important tests which can be used in @samp{if} questions to find | ||
| 4714 : | out information about files. | ||
| 4715 : | @cindex Testing files | ||
| 4716 : | @vindex -r @var{file} | ||
| 4717 : | @vindex -w @var{file} | ||
| 4718 : | @vindex -e @var{file} | ||
| 4719 : | @vindex -z @var{file} | ||
| 4720 : | @vindex -f @var{file} | ||
| 4721 : | @vindex -d @var{file} | ||
| 4722 : | |||
| 4723 : | @table @samp | ||
| 4724 : | @item -r @var{file} | ||
| 4725 : | True if the file exists and is readable | ||
| 4726 : | @item -w @var{file} | ||
| 4727 : | True if the file exists and is writable | ||
| 4728 : | @item -x @var{file} | ||
| 4729 : | True if the file exists and is executable | ||
| 4730 : | @item -e @var{file} | ||
| 4731 : | True if the file simply exists | ||
| 4732 : | @item -z @var{file} | ||
| 4733 : | True if the file exists and is empty | ||
| 4734 : | @item -f @var{file} | ||
| 4735 : | True if the file is a plain file | ||
| 4736 : | @item -d @var{file} | ||
| 4737 : | True if the file is a directory | ||
| 4738 : | @end table | ||
| 4739 : | |||
| 4740 : | |||
| 4741 : | We shall also have need of the following comparision operators. | ||
| 4742 : | |||
| 4743 : | @cindex Comparison operators in csh | ||
| 4744 : | @cindex Operators in csh | ||
| 4745 : | @vindex @samp{==} | ||
| 4746 : | @vindex @samp{!=} | ||
| 4747 : | @vindex @samp{>} | ||
| 4748 : | @vindex @samp{<} | ||
| 4749 : | @vindex @samp{>=} | ||
| 4750 : | @vindex @samp{<=} | ||
| 4751 : | @vindex @samp{=~} | ||
| 4752 : | @vindex @samp{!~} | ||
| 4753 : | |||
| 4754 : | |||
| 4755 : | @table @samp | ||
| 4756 : | @item == | ||
| 4757 : | is equal to (string comparison) | ||
| 4758 : | @item != | ||
| 4759 : | is not equal to | ||
| 4760 : | @item > | ||
| 4761 : | is greater than | ||
| 4762 : | @item < | ||
| 4763 : | is less than | ||
| 4764 : | @item >= | ||
| 4765 : | is greater than or equal to | ||
| 4766 : | @item <= | ||
| 4767 : | is less than or equal to | ||
| 4768 : | @item =~ | ||
| 4769 : | matches a wildcard | ||
| 4770 : | @item !~ | ||
| 4771 : | does not match a wildcard | ||
| 4772 : | @end table | ||
| 4773 : | |||
| 4774 : | The simplest way to learn about these statements is to use them, so we | ||
| 4775 : | shall now look at some examples. | ||
| 4776 : | |||
| 4777 : | @smallexample | ||
| 4778 : | #!/bin/csh -f | ||
| 4779 : | # | ||
| 4780 : | # Safe copy from <arg[1]> to <arg[2]> | ||
| 4781 : | # | ||
| 4782 : | # | ||
| 4783 : | |||
| 4784 : | if ($#argv != 2) then | ||
| 4785 : | |||
| 4786 : | echo "Syntax: copy <from-file> <to-file>" | ||
| 4787 : | exit 0 | ||
| 4788 : | |||
| 4789 : | endif | ||
| 4790 : | |||
| 4791 : | if ( -f $argv[2] ) then | ||
| 4792 : | |||
| 4793 : | echo "File exists. Copy anyway?" | ||
| 4794 : | |||
| 4795 : | switch ( $< ) # Get a line from user | ||
| 4796 : | |||
| 4797 : | case y: | ||
| 4798 : | breaksw | ||
| 4799 : | |||
| 4800 : | default: | ||
| 4801 : | echo "Doing nothing!" | ||
| 4802 : | exit 0 | ||
| 4803 : | |||
| 4804 : | endsw | ||
| 4805 : | |||
| 4806 : | endif | ||
| 4807 : | |||
| 4808 : | echo -n "Copying $argv[1] to $argv[2]..." | ||
| 4809 : | cp $argv[1] $argv[2] | ||
| 4810 : | echo done | ||
| 4811 : | |||
| 4812 : | endif | ||
| 4813 : | @end smallexample | ||
| 4814 : | |||
| 4815 : | This script tries to copy a file from one location to another. If the | ||
| 4816 : | user does not type exactly two arguments, the script quits with a | ||
| 4817 : | message about the correct syntax. Otherwise it tests to see whether | ||
| 4818 : | a plain file has the same name as the file the user wanted to copy | ||
| 4819 : | to. If such a file exists, it asks the user if he/she wants to | ||
| 4820 : | continue before proceding to copy. | ||
| 4821 : | |||
| 4822 : | |||
| 4823 : | @c --------------------- | ||
| 4824 : | @c Subsection | ||
| 4825 : | @c --------------------- | ||
| 4826 : | |||
| 4827 : | @menu | ||
| 4828 : | * Switch example:: | ||
| 4829 : | @end menu | ||
| 4830 : | |||
| 4831 : | @node Switch example, , Tests and conditions, Tests and conditions | ||
| 4832 : | @subsection Switch example: configure script | ||
| 4833 : | |||
| 4834 : | @cindex @samp{uname} command | ||
| 4835 : | @cindex System identity and @samp{uname} | ||
| 4836 : | Here is another example which compiles a software package. | ||
| 4837 : | This is a problem we shall return to later @xref{Make}. The problem | ||
| 4838 : | this script tries to address is the following. There are many different | ||
| 4839 : | versions of UNIX and they are not exactly compatible with one | ||
| 4840 : | another. The program this file compiles has to work on any kind of UNIX, | ||
| 4841 : | so it tries first to determine what kind of UNIX system the script is | ||
| 4842 : | being run on by calling @samp{uname}. Then it defines a variable | ||
| 4843 : | @samp{MAKE} which contains the path to the `make' program which will | ||
| 4844 : | build @emph{software}. The make program reads a file called `Makefile' | ||
| 4845 : | which contains instructions for compiling the program, but this file | ||
| 4846 : | needs to know the type of UNIX, so the script first copies a file | ||
| 4847 : | `Makefile.src' using @samp{sed} replace a dummy string with the real | ||
| 4848 : | name of the UNIX. Then it calls make and sets the correct permission on | ||
| 4849 : | the file using @samp{chmod}. | ||
| 4850 : | @cindex @samp{sed}, search and replace | ||
| 4851 : | @cindex Swapping text strings | ||
| 4852 : | |||
| 4853 : | @cindex Make software script | ||
| 4854 : | @cindex Build software script | ||
| 4855 : | @cindex Compiler script | ||
| 4856 : | @smallexample | ||
| 4857 : | #!/bin/csh -f | ||
| 4858 : | ################################################# | ||
| 4859 : | # | ||
| 4860 : | # | ||
| 4861 : | # CONFIGURE Makefile AND BUILD software | ||
| 4862 : | # | ||
| 4863 : | # | ||
| 4864 : | ################################################# | ||
| 4865 : | |||
| 4866 : | set NAME = ( `uname -r -s` ) | ||
| 4867 : | |||
| 4868 : | switch ($NAME[1]) | ||
| 4869 : | |||
| 4870 : | case SunOS*: | ||
| 4871 : | switch ($NAME[2]) | ||
| 4872 : | |||
| 4873 : | case 4*: | ||
| 4874 : | setenv TYPE SUN4 | ||
| 4875 : | setenv MAKE /bin/make | ||
| 4876 : | breaksw | ||
| 4877 : | case 5*: | ||
| 4878 : | setenv TYPE SOLARIS | ||
| 4879 : | setenv MAKE /usr/ccs/bin/make | ||
| 4880 : | breaksw | ||
| 4881 : | |||
| 4882 : | endsw | ||
| 4883 : | breaksw | ||
| 4884 : | |||
| 4885 : | case ULTRIX*: | ||
| 4886 : | setenv TYPE ULTRIX | ||
| 4887 : | setenv MAKE /bin/make | ||
| 4888 : | breaksw | ||
| 4889 : | case HP-UX*: | ||
| 4890 : | setenv TYPE HPuUX | ||
| 4891 : | setenv MAKE /bin/make | ||
| 4892 : | breaksw | ||
| 4893 : | case AIX*: | ||
| 4894 : | setenv TYPE AIX | ||
| 4895 : | setenv MAKE /bin/make | ||
| 4896 : | breaksw | ||
| 4897 : | |||
| 4898 : | case OSF*: | ||
| 4899 : | setenv TYPE OSF | ||
| 4900 : | setenv MAKE /bin/make | ||
| 4901 : | breaksw | ||
| 4902 : | case IRIX*: | ||
| 4903 : | setenv TYPE IRIX | ||
| 4904 : | setenv MAKE /bin/make | ||
| 4905 : | breaksw | ||
| 4906 : | |||
| 4907 : | default: | ||
| 4908 : | echo Unknown architecture $NAME[1] | ||
| 4909 : | |||
| 4910 : | endsw | ||
| 4911 : | |||
| 4912 : | # Generate Makefile from source file | ||
| 4913 : | |||
| 4914 : | sed s/HOSTTYPE/$TYPE/ Makefile.src > Makefile | ||
| 4915 : | |||
| 4916 : | echo "Making software. Type CTRL-C to abort and edit Makefile" | ||
| 4917 : | |||
| 4918 : | $MAKE software # call make to build program | ||
| 4919 : | chmod 755 software # set correct protection | ||
| 4920 : | |||
| 4921 : | @end smallexample | ||
| 4922 : | |||
| 4923 : | @c ----------------------------------------------------------------------- | ||
| 4924 : | @c SECTION | ||
| 4925 : | @c ----------------------------------------------------------------------- | ||
| 4926 : | |||
| 4927 : | @node Loops in csh, Input from the user, Tests and conditions, C shell | ||
| 4928 : | @section Loops in csh | ||
| 4929 : | |||
| 4930 : | @cindex Loops in csh | ||
| 4931 : | @cindex @code{foreach} | ||
| 4932 : | @cindex @code{repeat} | ||
| 4933 : | @cindex @code{while} | ||
| 4934 : | @vindex foreach | ||
| 4935 : | @vindex repeat | ||
| 4936 : | @vindex while | ||
| 4937 : | |||
| 4938 : | The C-shell has three loop structures: @samp{repeat}, @samp{while} | ||
| 4939 : | and @samp{foreach}. We have already seen some examples of the @samp{foreach} | ||
| 4940 : | loop. | ||
| 4941 : | |||
| 4942 : | The structure of these loops is as follows | ||
| 4943 : | @smallexample | ||
| 4944 : | repeat @var{number-of-times} @var{command} | ||
| 4945 : | |||
| 4946 : | |||
| 4947 : | while ( @var{test expression} ) | ||
| 4948 : | |||
| 4949 : | @var{commands} | ||
| 4950 : | |||
| 4951 : | end | ||
| 4952 : | |||
| 4953 : | |||
| 4954 : | foreach @var{control-variable} ( @var{list-or-array} ) | ||
| 4955 : | |||
| 4956 : | @var{commands} | ||
| 4957 : | |||
| 4958 : | end | ||
| 4959 : | |||
| 4960 : | @end smallexample | ||
| 4961 : | |||
| 4962 : | @noindent | ||
| 4963 : | @cindex @samp{continue} in csh | ||
| 4964 : | @vindex continue | ||
| 4965 : | The commands @samp{break} and @samp{continue} | ||
| 4966 : | can be used to break out of the loops at any | ||
| 4967 : | time. Here are some examples. | ||
| 4968 : | |||
| 4969 : | @smallexample | ||
| 4970 : | repeat 2 echo "Yo!" | write mark | ||
| 4971 : | @end smallexample | ||
| 4972 : | @noindent | ||
| 4973 : | |||
| 4974 : | This sends the message "Yo!" to mark's terminal twice. | ||
| 4975 : | @smallexample | ||
| 4976 : | repeat 5 echo `echo "Shutdown time! Log out now" | wall ; sleep 30` ; halt | ||
| 4977 : | @end smallexample | ||
| 4978 : | |||
| 4979 : | @noindent | ||
| 4980 : | This example repeats the command `echo Shutdown time...' | ||
| 4981 : | five times at 30 second intervals, before shutting down the system. | ||
| 4982 : | Only the superuser can run this command! Note the strange | ||
| 4983 : | construction with `echo echo'. This is to force the repeat command | ||
| 4984 : | to take two shell commands as an argument. (Try to explain | ||
| 4985 : | why this works for yourself.) | ||
| 4986 : | |||
| 4987 : | @c ----------------------------------------------------------------------- | ||
| 4988 : | @c SECTION | ||
| 4989 : | @c ----------------------------------------------------------------------- | ||
| 4990 : | |||
| 4991 : | @node Input from the user, Extracting parts of a pathname, Loops in csh, C shell | ||
| 4992 : | @section Input from the user | ||
| 4993 : | |||
| 4994 : | @cindex Input in csh | ||
| 4995 : | @cindex @samp{$<} operator | ||
| 4996 : | @vindex breaksw | ||
| 4997 : | @cindex @samp{breaksw} | ||
| 4998 : | |||
| 4999 : | @smallexample | ||
| 5000 : | |||
| 5001 : | # Test a user response | ||
| 5002 : | |||
| 5003 : | echo "Answer y/n (yes or no)" | ||
| 5004 : | |||
| 5005 : | set valid = false | ||
| 5006 : | |||
| 5007 : | while ( $valid == false ) | ||
| 5008 : | |||
| 5009 : | switch ( $< ) | ||
| 5010 : | |||
| 5011 : | case y: | ||
| 5012 : | echo "You answered yes" | ||
| 5013 : | set valid = true | ||
| 5014 : | breaksw | ||
| 5015 : | |||
| 5016 : | case n: | ||
| 5017 : | echo "You answered no" | ||
| 5018 : | set valid = true | ||
| 5019 : | breaksw | ||
| 5020 : | |||
| 5021 : | default: | ||
| 5022 : | echo "Invalid reponse, try again" | ||
| 5023 : | breaksw | ||
| 5024 : | |||
| 5025 : | endsw | ||
| 5026 : | |||
| 5027 : | end | ||
| 5028 : | @end smallexample | ||
| 5029 : | |||
| 5030 : | @noindent | ||
| 5031 : | Notice that it would have been simpler to replace the two lines | ||
| 5032 : | @smallexample | ||
| 5033 : | set valid = true | ||
| 5034 : | breaksw | ||
| 5035 : | @end smallexample | ||
| 5036 : | |||
| 5037 : | @noindent | ||
| 5038 : | by a single line @samp{break}. @samp{breaksw} jumps out of the switch | ||
| 5039 : | construction, after which the @samp{while} test fails. @samp{break} | ||
| 5040 : | jumps out of the entire while loop. | ||
| 5041 : | |||
| 5042 : | @c ----------------------------------------------------------------------- | ||
| 5043 : | @c SECTION | ||
| 5044 : | @c ----------------------------------------------------------------------- | ||
| 5045 : | |||
| 5046 : | @node Extracting parts of a pathname, Arithmetic, Input from the user, C shell | ||
| 5047 : | @section Extracting parts of a pathname | ||
| 5048 : | |||
| 5049 : | @cindex Parts of a filename | ||
| 5050 : | @vindex :h | ||
| 5051 : | @vindex :t | ||
| 5052 : | @vindex :e | ||
| 5053 : | @vindex :r | ||
| 5054 : | @cindex Extracting filename components | ||
| 5055 : | |||
| 5056 : | A path name consists of a number of different parts: | ||
| 5057 : | @itemize @bullet | ||
| 5058 : | @item | ||
| 5059 : | The path to the directory where a file is held. | ||
| 5060 : | @item | ||
| 5061 : | The name of the file itself. | ||
| 5062 : | @item | ||
| 5063 : | The file extension (after a dot). | ||
| 5064 : | @end itemize | ||
| 5065 : | |||
| 5066 : | By using one of the following modifiers, we can extract these | ||
| 5067 : | different elements. | ||
| 5068 : | |||
| 5069 : | @table @samp | ||
| 5070 : | @item :h | ||
| 5071 : | The path to the file | ||
| 5072 : | @item :t | ||
| 5073 : | The filename itself | ||
| 5074 : | @item :e | ||
| 5075 : | The file extension | ||
| 5076 : | @item :r | ||
| 5077 : | The complete file-path minus the file extension | ||
| 5078 : | @end table | ||
| 5079 : | |||
| 5080 : | Here are some examples and the results: | ||
| 5081 : | @smallexample | ||
| 5082 : | set f = ~/progs/c++/test.C | ||
| 5083 : | |||
| 5084 : | echo $f:h | ||
| 5085 : | |||
| 5086 : | /home/mark/progs/c++ | ||
| 5087 : | |||
| 5088 : | echo $f:t | ||
| 5089 : | |||
| 5090 : | test.C | ||
| 5091 : | |||
| 5092 : | echo $f:e | ||
| 5093 : | |||
| 5094 : | C | ||
| 5095 : | echo $f:r | ||
| 5096 : | |||
| 5097 : | /home/mark/progs/c++/test | ||
| 5098 : | @end smallexample | ||
| 5099 : | |||
| 5100 : | @noindent | ||
| 5101 : | |||
| 5102 : | |||
| 5103 : | @c ----------------------------------------------------------------------- | ||
| 5104 : | @c SECTION | ||
| 5105 : | @c ----------------------------------------------------------------------- | ||
| 5106 : | |||
| 5107 : | @node Arithmetic, Examples, Extracting parts of a pathname, C shell | ||
| 5108 : | @section Arithmetic | ||
| 5109 : | |||
| 5110 : | Before using these features in a real script, we need one more possibility: | ||
| 5111 : | numerical addition, subtraction and multiplication etc. | ||
| 5112 : | |||
| 5113 : | @cindex Arithemtic operations in csh | ||
| 5114 : | @vindex @samp{+} | ||
| 5115 : | @vindex @samp{+=} | ||
| 5116 : | @vindex @samp{++} | ||
| 5117 : | @vindex @samp{-} | ||
| 5118 : | @vindex @samp{-=} | ||
| 5119 : | @vindex @samp{--} | ||
| 5120 : | @vindex @samp{==} equal to (compare) | ||
| 5121 : | @vindex @samp{>} greater than | ||
| 5122 : | @vindex @samp{<} less than | ||
| 5123 : | @vindex @samp{||} logical OR | ||
| 5124 : | @vindex @samp{|} OR | ||
| 5125 : | @vindex @samp{&} AND | ||
| 5126 : | @vindex @samp{^} XOR | ||
| 5127 : | @vindex @samp{>>} shift | ||
| 5128 : | @vindex @samp{<<} shift | ||
| 5129 : | @vindex @samp{!} not | ||
| 5130 : | @vindex @samp{=} assignment | ||
| 5131 : | |||
| 5132 : | |||
| 5133 : | To tell the C-shell that you want to perform an operation on numbers | ||
| 5134 : | rather than strings, you use the @samp{@@} symbol followed by a space. | ||
| 5135 : | Then the following operations are possible. | ||
| 5136 : | @smallexample | ||
| 5137 : | @@ var = 45 # Assign a numerical value to var | ||
| 5138 : | echo $var # Print the value | ||
| 5139 : | |||
| 5140 : | @@ var = $var + 34 # Add 34 to var | ||
| 5141 : | @@ var += 34 # Add 34 to var | ||
| 5142 : | |||
| 5143 : | @@ var -= 1 # subtract 1 from var | ||
| 5144 : | @@ var *= 5 # Multiply var by 5 | ||
| 5145 : | |||
| 5146 : | @@ var /= 3 # Divide var by 3 (integer division) | ||
| 5147 : | @@ var %= 3 # Remainder after dividing var by 3 | ||
| 5148 : | |||
| 5149 : | @@ var++ # Increment var by 1 | ||
| 5150 : | @@ var-- # Decrement var by 1 | ||
| 5151 : | |||
| 5152 : | @@ array[1] = 5 # Numerical array | ||
| 5153 : | |||
| 5154 : | @@ logic = ( $x > 6 && $x < 10) # AND | ||
| 5155 : | @@ logic = ( $x > 6 || $x < 10) # OR | ||
| 5156 : | @@ false = ! $var # Logical NOT | ||
| 5157 : | |||
| 5158 : | @@ bits = ( $x | $y ) # Bitwise OR | ||
| 5159 : | @@ bits = ( $x ^ $y ) # Bitwise XOR | ||
| 5160 : | @@ bits = ( $x & $y ) # Bitwise AND | ||
| 5161 : | |||
| 5162 : | @@ shifted = ( $var >> 2 ) # Bitwise shift right | ||
| 5163 : | @@ back = ( $var << 2 ) # Bitwise shift left | ||
| 5164 : | @end smallexample | ||
| 5165 : | These operators are precisely those found in the C | ||
| 5166 : | programming language. | ||
| 5167 : | |||
| 5168 : | @c ----------------------------------------------------------------------- | ||
| 5169 : | @c SECTION | ||
| 5170 : | @c ----------------------------------------------------------------------- | ||
| 5171 : | |||
| 5172 : | @node Examples, , Arithmetic, C shell | ||
| 5173 : | @section Examples | ||
| 5174 : | |||
| 5175 : | The following script uses the operators in the last two sections | ||
| 5176 : | to take a list of files with a given file extension (say @samp{.doc}) | ||
| 5177 : | and change it for another (say @samp{.tex}). This is a partial | ||
| 5178 : | solution to the limitation of not being able to do multiple | ||
| 5179 : | renames in shell. | ||
| 5180 : | |||
| 5181 : | @smallexample | ||
| 5182 : | #!/bin/csh -f | ||
| 5183 : | ############################################################# | ||
| 5184 : | # | ||
| 5185 : | # Change file extension for multiple files | ||
| 5186 : | # | ||
| 5187 : | ############################################################# | ||
| 5188 : | |||
| 5189 : | if ($#argv < 2) then | ||
| 5190 : | echo Syntax: chext oldpattern newextension | ||
| 5191 : | echo "e.g: chext *.doc tex " | ||
| 5192 : | exit 0 | ||
| 5193 : | endif | ||
| 5194 : | |||
| 5195 : | mkdir /tmp/chext.$user # Make a scratch area | ||
| 5196 : | |||
| 5197 : | set newext="$argv[$#argv]" # Last arg is new ext | ||
| 5198 : | set oldext="$argv[1]:e" | ||
| 5199 : | |||
| 5200 : | echo "Old extenstion was ($oldext)"" | ||
| 5201 : | echo "New extension ($newext) -- okay? (y/n)" | ||
| 5202 : | |||
| 5203 : | switch( $< ) | ||
| 5204 : | |||
| 5205 : | case y: | ||
| 5206 : | breaksw | ||
| 5207 : | default: | ||
| 5208 : | echo "Nothing done." | ||
| 5209 : | exit 0 | ||
| 5210 : | endsw | ||
| 5211 : | |||
| 5212 : | |||
| 5213 : | ############################################################## | ||
| 5214 : | # Remove the last file extension from files | ||
| 5215 : | ############################################################## | ||
| 5216 : | |||
| 5217 : | @ i = 0 | ||
| 5218 : | |||
| 5219 : | foreach file ($argv) | ||
| 5220 : | |||
| 5221 : | @ i++ | ||
| 5222 : | if ( $i == $#argv ) break | ||
| 5223 : | cp $file /tmp/chext.$user/$file:r # temporary store | ||
| 5224 : | |||
| 5225 : | end | ||
| 5226 : | |||
| 5227 : | ############################################################### | ||
| 5228 : | # Add .newext file extension to files | ||
| 5229 : | ############################################################### | ||
| 5230 : | |||
| 5231 : | set array = (`ls /tmp/chext.$user`) | ||
| 5232 : | |||
| 5233 : | foreach file ($array) | ||
| 5234 : | |||
| 5235 : | if ( -f $file.$newext ) then | ||
| 5236 : | echo destination file $file.$newext exists. No action taken. | ||
| 5237 : | continue | ||
| 5238 : | endif | ||
| 5239 : | |||
| 5240 : | cp /tmp/chext.$user/$file $file.$newext | ||
| 5241 : | rm $file.$oldext | ||
| 5242 : | |||
| 5243 : | end | ||
| 5244 : | |||
| 5245 : | rm -r /tmp/chext.$user | ||
| 5246 : | |||
| 5247 : | |||
| 5248 : | @end smallexample | ||
| 5249 : | |||
| 5250 : | |||
| 5251 : | Here is another example to try to decipher. Use the manual pages to | ||
| 5252 : | find out about @samp{awk}. This script can be written much more | ||
| 5253 : | easily in Perl or C, as we shall see in the next chapters. It is | ||
| 5254 : | also trivially implemented as a script in the system administration | ||
| 5255 : | language cfengine. | ||
| 5256 : | |||
| 5257 : | @smallexample | ||
| 5258 : | #!/bin/csh -f | ||
| 5259 : | ########################################################### | ||
| 5260 : | # | ||
| 5261 : | # KILL all processes owned by $argv[1] with PID > $argv[2] | ||
| 5262 : | # | ||
| 5263 : | ########################################################### | ||
| 5264 : | |||
| 5265 : | @cindex @samp{whoami} command | ||
| 5266 : | |||
| 5267 : | if ("`whoami`" != "root") then | ||
| 5268 : | echo Permission denied | ||
| 5269 : | exit 0 | ||
| 5270 : | endif | ||
| 5271 : | |||
| 5272 : | if ( $#argv < 1 || $#argv > 2 ) then | ||
| 5273 : | echo Usage: KILL username lowest-pid | ||
| 5274 : | exit 0 | ||
| 5275 : | endif | ||
| 5276 : | |||
| 5277 : | if ( $argv[1] == "root") then | ||
| 5278 : | echo No! Too dangerous -- system will crash | ||
| 5279 : | exit 0 | ||
| 5280 : | endif | ||
| 5281 : | |||
| 5282 : | ############################################################ | ||
| 5283 : | # Kill everything | ||
| 5284 : | ############################################################ | ||
| 5285 : | |||
| 5286 : | if ( $#argv == 1 ) then | ||
| 5287 : | |||
| 5288 : | set killarray = ( `ps aux | awk '@{ if ($1 == user) \ | ||
| 5289 : | @{printf "%s ",$2@}@}' user=$argv[1]` ) | ||
| 5290 : | |||
| 5291 : | foreach process ($killarray) | ||
| 5292 : | |||
| 5293 : | kill -1 $process | ||
| 5294 : | kill -15 $process > /dev/null | ||
| 5295 : | kill -9 $process > /dev/null | ||
| 5296 : | |||
| 5297 : | if ("`kill -9 $process | egrep -e 'No such process'`" == "") then | ||
| 5298 : | echo "Warning - $process would not die - try again" | ||
| 5299 : | endif | ||
| 5300 : | end | ||
| 5301 : | |||
| 5302 : | ############################################################# | ||
| 5303 : | # Start from a certain PID | ||
| 5304 : | ############################################################# | ||
| 5305 : | |||
| 5306 : | else if ( $#argv == 2 ) then | ||
| 5307 : | |||
| 5308 : | set killarray = ( `ps aux | awk '@{ if ($1 == user && $2 > uid) \ | ||
| 5309 : | @{printf "%s ",$2@}@}' user=$argv[1] uid=$argv[2]` ) | ||
| 5310 : | |||
| 5311 : | foreach process ($killarray) | ||
| 5312 : | |||
| 5313 : | @cindex @samp{sleep} command | ||
| 5314 : | kill -1 $process > /dev/null | ||
| 5315 : | kill -15 $process | ||
| 5316 : | sleep 2 | ||
| 5317 : | kill -9 $process > /dev/null | ||
| 5318 : | |||
| 5319 : | if ("`kill -9 $process | egrep -e 'No such process'`" == "") then | ||
| 5320 : | echo "Warning - $process would not die - try again" | ||
| 5321 : | endif | ||
| 5322 : | end | ||
| 5323 : | |||
| 5324 : | endif | ||
| 5325 : | |||
| 5326 : | @end smallexample | ||
| 5327 : | |||
| 5328 : | @noindent | ||
| 5329 : | This program would be better written in C or Perl. | ||
| 5330 : | |||
| 5331 : | |||
| 5332 : | @c ********************************************************************** | ||
| 5333 : | @c CHAPTER | ||
| 5334 : | @c ********************************************************************** | ||
| 5335 : | |||
| 5336 : | @node Bourne shell, Perl, C shell, Top | ||
| 5337 : | @chapter Bourne shell | ||
| 5338 : | |||
| 5339 : | @cindex Bourne shell | ||
| 5340 : | Programmers who are used to C or C++ often find it easier to program in | ||
| 5341 : | C-shell because there are strong similarities between the two. The | ||
| 5342 : | Bourne shell is somewhat different in style, but is structured in a way | ||
| 5343 : | which makes it better suited to more complicated script writing, | ||
| 5344 : | especially for system administrators. Also it is closer to the kernels | ||
| 5345 : | own exec mechanism. The Bourne shell allows subroutines and default | ||
| 5346 : | values for parameters. Most of the system scripts in UNIX are written in | ||
| 5347 : | the Bourne shell. | ||
| 5348 : | |||
| 5349 : | The principles of the Bourne shell are largely the same as those for the C-shell, | ||
| 5350 : | so we shall skip fairly quickly through the details. Historically, | ||
| 5351 : | the Bourne shell came before the C shell. | ||
| 5352 : | |||
| 5353 : | @c ----------------------------------------------------------------------- | ||
| 5354 : | @c SECTION | ||
| 5355 : | @c ----------------------------------------------------------------------- | ||
| 5356 : | |||
| 5357 : | @menu | ||
| 5358 : | * .profile:: | ||
| 5359 : | * Variables and export:: | ||
| 5360 : | * stdin stdout stderr:: | ||
| 5361 : | * Arithmetic in sh:: | ||
| 5362 : | * Scripts and arguments:: | ||
| 5363 : | * Return codes:: | ||
| 5364 : | * Tests in sh:: | ||
| 5365 : | * Input in sh:: | ||
| 5366 : | * Loops in sh:: | ||
| 5367 : | * Procedures and traps:: | ||
| 5368 : | * setuid setgid scripts:: | ||
| 5369 : | * Limitations of shell:: | ||
| 5370 : | * Ex4:: | ||
| 5371 : | @end menu | ||
| 5372 : | |||
| 5373 : | @node .profile, Variables and export, Bourne shell, Bourne shell | ||
| 5374 : | @section .profile | ||
| 5375 : | |||
| 5376 : | @vindex .profile | ||
| 5377 : | @vindex .cshrc | ||
| 5378 : | @cindex @file{.profile} set up in sh | ||
| 5379 : | The @samp{.profile} file is the Bourne shell's answer to @samp{.cshrc}. | ||
| 5380 : | This file is read by interactive @file{/bin/sh} shells on starting | ||
| 5381 : | up. On Sun systems the file @file{/etc/profile} is also read. On | ||
| 5382 : | @samp{HPUX} machines, the file @file{/etc/src.sh} is read. | ||
| 5383 : | |||
| 5384 : | @c ----------------------------------------------------------------------- | ||
| 5385 : | @c SECTION | ||
| 5386 : | @c ----------------------------------------------------------------------- | ||
| 5387 : | |||
| 5388 : | @node Variables and export, stdin stdout stderr, .profile, Bourne shell | ||
| 5389 : | @section Variables and export | ||
| 5390 : | |||
| 5391 : | @cindex Global variables in sh | ||
| 5392 : | @cindex Local variables in sh | ||
| 5393 : | Local and global variables are both defined using the syntax | ||
| 5394 : | @smallexample | ||
| 5395 : | VARIABLE="Some string" | ||
| 5396 : | VAR=13 | ||
| 5397 : | @end smallexample | ||
| 5398 : | |||
| 5399 : | @noindent | ||
| 5400 : | It is important that there be no space between the variable and the | ||
| 5401 : | equals sign. By default these variables are @emph{local}. To make them | ||
| 5402 : | global (so that child processes will inherit them) we use the | ||
| 5403 : | command | ||
| 5404 : | @smallexample | ||
| 5405 : | export VARIABLE | ||
| 5406 : | @end smallexample | ||
| 5407 : | |||
| 5408 : | @cindex @samp{EXPORT} command in sh | ||
| 5409 : | @noindent | ||
| 5410 : | This adds the variable to the process @emph{environment}. It is the analogue of | ||
| 5411 : | making `environment variables' with @code{setenv} in C shell. | ||
| 5412 : | The command | ||
| 5413 : | @smallexample | ||
| 5414 : | set -a | ||
| 5415 : | @end smallexample | ||
| 5416 : | |||
| 5417 : | @noindent | ||
| 5418 : | changes the default so that all variables, after the command are | ||
| 5419 : | created @emph{global}. | ||
| 5420 : | |||
| 5421 : | Arrays or lists are often simulated in shell by sandwiching the colon @samp{:} | ||
| 5422 : | symbol between items | ||
| 5423 : | @smallexample | ||
| 5424 : | PATH=/bin:/usr/bin:/etc:/local/bin:. | ||
| 5425 : | |||
| 5426 : | LD_LIBARAY_PATH=/usr/lib:/usr/openwin/lib:/local/lib | ||
| 5427 : | @end smallexample | ||
| 5428 : | |||
| 5429 : | @noindent | ||
| 5430 : | but there is no real facility for arrays in the Bourne shell. Note that | ||
| 5431 : | the UNIX @samp{cut} command can be used to extract the elements of | ||
| 5432 : | the list. Loops can also read such lists directly @xref{Loops in sh}. | ||
| 5433 : | A Perl script can also be used. | ||
| 5434 : | |||
| 5435 : | The value of a variable is given by the dollar symbol as in C-shell. It | ||
| 5436 : | is also possible to use @emph{curly braces} around the variable name to | ||
| 5437 : | `protect' the variable from interfering text. For example: | ||
| 5438 : | @smallexample | ||
| 5439 : | $ animal=worm | ||
| 5440 : | $ echo book$animal | ||
| 5441 : | bookworm | ||
| 5442 : | $ thing=book | ||
| 5443 : | $ echo $thingworm | ||
| 5444 : | (nothing..) | ||
| 5445 : | $ echo $@{thing@}worm | ||
| 5446 : | bookworm | ||
| 5447 : | |||
| 5448 : | @end smallexample | ||
| 5449 : | |||
| 5450 : | @noindent | ||
| 5451 : | Default values can be given to variables in the Bourne shell. The | ||
| 5452 : | following commands illustrate this. | ||
| 5453 : | |||
| 5454 : | @smallexample | ||
| 5455 : | echo $@{var-"No value set"@} | ||
| 5456 : | echo $@{var="Octopus"@} | ||
| 5457 : | echo $@{var+"Forced value"@} | ||
| 5458 : | echo $@{var?"No such variable"@} | ||
| 5459 : | @end smallexample | ||
| 5460 : | |||
| 5461 : | @noindent | ||
| 5462 : | The first of these prints out the contents of @samp{$var}, if it is | ||
| 5463 : | defined. If it is not defined the variable is substituted for the | ||
| 5464 : | string "No value set". The value of @samp{var} is not changed by this | ||
| 5465 : | operation. It is only for convenience. | ||
| 5466 : | |||
| 5467 : | The second command has the same effect as the first, but here the value | ||
| 5468 : | of @samp{$var} is actually changed to "Octopus" if @samp{$var} | ||
| 5469 : | is not set. | ||
| 5470 : | |||
| 5471 : | The third version is slightly peculiar. If @samp{$var} is @emph{already} | ||
| 5472 : | set, its value will be forced to be "Forced value", otherwise it is | ||
| 5473 : | left undefined. | ||
| 5474 : | |||
| 5475 : | Finally the last instance issues an error message "No such variable" | ||
| 5476 : | if @samp{$var} is not defined. | ||
| 5477 : | |||
| 5478 : | @c ----------------------------------------------------------------------- | ||
| 5479 : | @c SECTION | ||
| 5480 : | @c ----------------------------------------------------------------------- | ||
| 5481 : | |||
| 5482 : | @node stdin stdout stderr, Arithmetic in sh, Variables and export, Bourne shell | ||
| 5483 : | @section Stdin, stdout and stderr | ||
| 5484 : | |||
| 5485 : | In the Bourne shell, the standard input/output files are referred to | ||
| 5486 : | by numbers rather than by names. | ||
| 5487 : | @cindex Standard I/O in sh | ||
| 5488 : | |||
| 5489 : | @table @emph | ||
| 5490 : | @item stdin | ||
| 5491 : | File number 0 | ||
| 5492 : | @item stdout | ||
| 5493 : | File number 1 | ||
| 5494 : | @item stderr | ||
| 5495 : | File number 2 | ||
| 5496 : | @end table | ||
| 5497 : | |||
| 5498 : | @noindent | ||
| 5499 : | The default routes for these files can be changed by @emph{redirection}. | ||
| 5500 : | The redirection commands are more complicated than in C-shell, but they | ||
| 5501 : | are also more flexible. Here is a comparison. | ||
| 5502 : | @cindex Redirecting stdio in sh | ||
| 5503 : | @cindex @samp{1>} in sh | ||
| 5504 : | @cindex @samp{2>} in sh | ||
| 5505 : | @cindex @samp{2>&1} in sh | ||
| 5506 : | |||
| 5507 : | @smallexample | ||
| 5508 : | sh csh Description | ||
| 5509 : | |||
| 5510 : | command > file command > file Stdout to file | ||
| 5511 : | command 1> file command > file Stdout to file | ||
| 5512 : | command 2> errs (No analogue) Stderr only to file errs | ||
| 5513 : | command 1> file 2>&1 command >& file stdout and stderr to file | ||
| 5514 : | command 1> file 2> errs (No analogue) stdout to file, stderr to errs | ||
| 5515 : | @end smallexample | ||
| 5516 : | |||
| 5517 : | @c ----------------------------------------------------------------------- | ||
| 5518 : | @c SECTION | ||
| 5519 : | @c ----------------------------------------------------------------------- | ||
| 5520 : | |||
| 5521 : | @node Arithmetic in sh, Scripts and arguments, stdin stdout stderr, Bourne shell | ||
| 5522 : | @section Arithmetic in sh | ||
| 5523 : | |||
| 5524 : | @cindex Arithemtic in sh | ||
| 5525 : | |||
| 5526 : | Arithmetic is performed entirely `by proxy'. There are no internal | ||
| 5527 : | arithmetic operators as in the C-shell. To evaluate an expression | ||
| 5528 : | we call the @samp{expr} command or the @samp{bc} | ||
| 5529 : | precision calculator. Here are some examples of @samp{expr} | ||
| 5530 : | @smallexample | ||
| 5531 : | a=`expr $a+1` # increment a | ||
| 5532 : | a=`expr 4 + 10 \* 5` # 4+10*5 | ||
| 5533 : | check = `expr $a \> $b` # true=1, false=0. True if $a > $b | ||
| 5534 : | @end smallexample | ||
| 5535 : | |||
| 5536 : | @noindent | ||
| 5537 : | @samp{expr} is very sensitive to spaces and backslash characters. | ||
| 5538 : | |||
| 5539 : | @c ----------------------------------------------------------------------- | ||
| 5540 : | @c SECTION | ||
| 5541 : | @c ----------------------------------------------------------------------- | ||
| 5542 : | |||
| 5543 : | @node Scripts and arguments, Return codes, Arithmetic in sh, Bourne shell | ||
| 5544 : | @section Scripts and arguments | ||
| 5545 : | |||
| 5546 : | Scripts are created by making an executable file which begins | ||
| 5547 : | with the sequence of characters | ||
| 5548 : | |||
| 5549 : | @cindex Scripts in sh, making | ||
| 5550 : | @cindex Making scripts in sh | ||
| 5551 : | @cindex @samp{#!program} sequence | ||
| 5552 : | |||
| 5553 : | @smallexample | ||
| 5554 : | #!/bin/sh | ||
| 5555 : | @end smallexample | ||
| 5556 : | |||
| 5557 : | @noindent | ||
| 5558 : | Although we didn't discuss it before, this construction is quite | ||
| 5559 : | general: any executable file which begins with a sequence | ||
| 5560 : | @smallexample | ||
| 5561 : | #!myprogram -option | ||
| 5562 : | @end smallexample | ||
| 5563 : | |||
| 5564 : | @noindent | ||
| 5565 : | will cause the shell to attempt to execute | ||
| 5566 : | @smallexample | ||
| 5567 : | myprogam -option filename | ||
| 5568 : | @end smallexample | ||
| 5569 : | |||
| 5570 : | @noindent | ||
| 5571 : | where @var{filename} is the name of the file. | ||
| 5572 : | |||
| 5573 : | @cindex Command line arguments in sh | ||
| 5574 : | |||
| 5575 : | If a script is to accept arguments then these can be referred to as | ||
| 5576 : | @samp{ $1 $2 $3..$9}. There is a logical limit of nine arguments to | ||
| 5577 : | a script, but in practice it is possibile to get around this | ||
| 5578 : | limitation. @samp{$0} is the name of the script itself. | ||
| 5579 : | |||
| 5580 : | Here is a simple script in the Bourne shell which prints out | ||
| 5581 : | all its arguments. | ||
| 5582 : | @cindex @code{for} loop in sh | ||
| 5583 : | @smallexample | ||
| 5584 : | |||
| 5585 : | #!/bin/sh | ||
| 5586 : | # | ||
| 5587 : | # Print all arguments (version 1) | ||
| 5588 : | # | ||
| 5589 : | |||
| 5590 : | for arg in $* | ||
| 5591 : | do | ||
| 5592 : | echo Argument $arg | ||
| 5593 : | done | ||
| 5594 : | |||
| 5595 : | echo Total number of arguments was $# | ||
| 5596 : | |||
| 5597 : | @end smallexample | ||
| 5598 : | |||
| 5599 : | @noindent | ||
| 5600 : | The @samp{$*} symbol stands for the entire list of arguments (like | ||
| 5601 : | @samp{$argv} in C-shell) and @samp{$#} is the total number of | ||
| 5602 : | arguments (like @samp{$#argv} in C-shell). | ||
| 5603 : | |||
| 5604 : | Another way of achieving the same is to use the @samp{shift} command. | ||
| 5605 : | We shall meet this again in the Perl programming language. @samp{shift} | ||
| 5606 : | takes the first argument from the argument list and deletes it, moving | ||
| 5607 : | all of the other arguments down one number -- this is how we can | ||
| 5608 : | handle long lists of arguments in @samp{sh}. | ||
| 5609 : | @cindex @code{while} loop in sh | ||
| 5610 : | @cindex @code{shift} operator on strings | ||
| 5611 : | |||
| 5612 : | @smallexample | ||
| 5613 : | #!/bin/sh | ||
| 5614 : | # | ||
| 5615 : | # Print all arguments (version 2) | ||
| 5616 : | # | ||
| 5617 : | |||
| 5618 : | while ( true ) | ||
| 5619 : | do | ||
| 5620 : | arg=$1; | ||
| 5621 : | shift; | ||
| 5622 : | echo $arg was an argument; | ||
| 5623 : | if [ $# -eq 0 ]; then | ||
| 5624 : | break | ||
| 5625 : | fi | ||
| 5626 : | done | ||
| 5627 : | |||
| 5628 : | @end smallexample | ||
| 5629 : | |||
| 5630 : | @c ----------------------------------------------------------------------- | ||
| 5631 : | @c SECTION | ||
| 5632 : | @c ----------------------------------------------------------------------- | ||
| 5633 : | |||
| 5634 : | @node Return codes, Tests in sh, Scripts and arguments, Bourne shell | ||
| 5635 : | @section Return codes | ||
| 5636 : | |||
| 5637 : | @cindex Return codes | ||
| 5638 : | @cindex Decisions and return codes in sh | ||
| 5639 : | |||
| 5640 : | All programs which execute in UNIX return a value through the C | ||
| 5641 : | @samp{return} command. There is a convention that a return value | ||
| 5642 : | of zero (0) means that everything went well, whereas any | ||
| 5643 : | other value implies that some error occurred. The return | ||
| 5644 : | value is usually the value returned in @samp{errno}, the | ||
| 5645 : | extenal error variable in C. | ||
| 5646 : | |||
| 5647 : | Shell scripts can | ||
| 5648 : | test for these values either by placing the command | ||
| 5649 : | directly inside an `if' test, or by testing the variable @samp{$?} | ||
| 5650 : | which is always set to the return code of the last command. | ||
| 5651 : | Some examples are given following the next two sections. | ||
| 5652 : | |||
| 5653 : | @c ----------------------------------------------------------------------- | ||
| 5654 : | @c SECTION | ||
| 5655 : | @c ----------------------------------------------------------------------- | ||
| 5656 : | |||
| 5657 : | @node Tests in sh, Input in sh, Return codes, Bourne shell | ||
| 5658 : | @section Tests and conditionals | ||
| 5659 : | |||
| 5660 : | @cindex Tests in sh | ||
| 5661 : | |||
| 5662 : | The Bourne shell has the usual array of tests. They are written as | ||
| 5663 : | follows. Notice that @samp{test} is itself not a part of the shell, | ||
| 5664 : | but is a program which works out conditions and provides a return | ||
| 5665 : | code. See the manual page on @samp{test} for more details. | ||
| 5666 : | |||
| 5667 : | @vindex @samp{-f} in sh | ||
| 5668 : | @vindex @samp{-d} in sh | ||
| 5669 : | @vindex @samp{-r} in sh | ||
| 5670 : | @vindex @samp{-w} in sh | ||
| 5671 : | @vindex @samp{-x} in sh | ||
| 5672 : | @vindex @samp{-s} in sh | ||
| 5673 : | @vindex @samp{-g} in sh | ||
| 5674 : | @vindex @samp{-u} in sh | ||
| 5675 : | @vindex @samp{=} in sh | ||
| 5676 : | @vindex @samp{!=} in sh | ||
| 5677 : | @vindex @samp{-eq} in sh | ||
| 5678 : | @vindex @samp{-ne} in sh | ||
| 5679 : | @vindex @samp{-gt} in sh | ||
| 5680 : | @vindex @samp{-lt} in sh | ||
| 5681 : | @vindex @samp{-ge} in sh | ||
| 5682 : | @vindex @samp{-le} in sh | ||
| 5683 : | @vindex @samp{!} in sh | ||
| 5684 : | @vindex @samp{-a} in sh | ||
| 5685 : | @vindex @samp{-o} in sh | ||
| 5686 : | |||
| 5687 : | @table @code | ||
| 5688 : | @item test -f @var{file} | ||
| 5689 : | True if the file is a plain file | ||
| 5690 : | @item test -d @var{file} | ||
| 5691 : | True if the file is a directory | ||
| 5692 : | @item test -r @var{file} | ||
| 5693 : | True if the file is readable | ||
| 5694 : | @item test -w @var{file} | ||
| 5695 : | True if the file is writable | ||
| 5696 : | @item test -x @var{file} | ||
| 5697 : | True if the file is executable | ||
| 5698 : | @item test -s @var{file} | ||
| 5699 : | True if the file contains something | ||
| 5700 : | @item test -g @var{file} | ||
| 5701 : | True if setgid bit is set | ||
| 5702 : | @item test -u @var{file} | ||
| 5703 : | True if setuid bit is set | ||
| 5704 : | @item test s1 = s2 | ||
| 5705 : | True if strings s1 and s2 are equal | ||
| 5706 : | @item test s1 != s2 | ||
| 5707 : | True if strings s1 and s2 are unequal | ||
| 5708 : | @item test @var{x} -eq @var{y} | ||
| 5709 : | True if the integers @var{x} and @var{y} are numerically equal | ||
| 5710 : | @item test @var{x} -ne @var{y} | ||
| 5711 : | True if integers are not equal | ||
| 5712 : | @item test @var{x} -gt @var{y} | ||
| 5713 : | True if @var{x} is greater than @var{y} | ||
| 5714 : | @item test @var{x} -lt @var{y} | ||
| 5715 : | True if @var{x} is less than @var{y} | ||
| 5716 : | @item test @var{x} -ge @var{y} | ||
| 5717 : | True if @var{x}>=@var{y} | ||
| 5718 : | @item test @var{x} -le @var{y} | ||
| 5719 : | True if @var{x} <= @var{y} | ||
| 5720 : | @item ! | ||
| 5721 : | Logical NOT operator | ||
| 5722 : | @item -a | ||
| 5723 : | Logical AND | ||
| 5724 : | @item -o | ||
| 5725 : | Logical OR | ||
| 5726 : | @end table | ||
| 5727 : | |||
| 5728 : | Note that an alternate syntax for writing these commands if to use the | ||
| 5729 : | square brackets, instead of writing the word test. | ||
| 5730 : | @cindex @samp{test} in sh | ||
| 5731 : | @cindex @samp{[]} for test in sh | ||
| 5732 : | @smallexample | ||
| 5733 : | [ $x -lt $y ] "==" test $x -lt $y | ||
| 5734 : | @end smallexample | ||
| 5735 : | |||
| 5736 : | @cindex @code{if..then..else..fi} in sh | ||
| 5737 : | |||
| 5738 : | The conditional structures have the following syntax. | ||
| 5739 : | @smallexample | ||
| 5740 : | if @var{unix-command} | ||
| 5741 : | then | ||
| 5742 : | @var{command} | ||
| 5743 : | else | ||
| 5744 : | @var{commands} | ||
| 5745 : | fi | ||
| 5746 : | @end smallexample | ||
| 5747 : | |||
| 5748 : | @noindent | ||
| 5749 : | The @samp{else} clause is, of course, optional. | ||
| 5750 : | As noted before, the first unix command could be @emph{anything}, since | ||
| 5751 : | every command has a return code. The result is TRUE if it evaluates | ||
| 5752 : | to @emph{zero} and false otherwise (in contrast to the conventions in most | ||
| 5753 : | languages). | ||
| 5754 : | Multiple tests can be made using | ||
| 5755 : | @smallexample | ||
| 5756 : | if @var{unix-command} | ||
| 5757 : | then | ||
| 5758 : | @var{commands} | ||
| 5759 : | elif @var{unix-command} | ||
| 5760 : | then | ||
| 5761 : | @var{commands} | ||
| 5762 : | elif @var{unix-command} | ||
| 5763 : | then | ||
| 5764 : | @var{commands} | ||
| 5765 : | else | ||
| 5766 : | @var{commands} | ||
| 5767 : | fi | ||
| 5768 : | @end smallexample | ||
| 5769 : | |||
| 5770 : | @noindent | ||
| 5771 : | where @samp{elif} means `else-if'. | ||
| 5772 : | |||
| 5773 : | The equivalent of the C-school's @samp{switch} statement is a more | ||
| 5774 : | Pascal-like @samp{case} structure. | ||
| 5775 : | @smallexample | ||
| 5776 : | case @var{unix-command-or-variable} in | ||
| 5777 : | |||
| 5778 : | wildcard1) @var{commands} ;; | ||
| 5779 : | wildcard2) @var{commands} ;; | ||
| 5780 : | wildcard3) @var{commands} ;; | ||
| 5781 : | |||
| 5782 : | esac | ||
| 5783 : | @end smallexample | ||
| 5784 : | |||
| 5785 : | @noindent | ||
| 5786 : | This structure uses the wildcards to match the output of the command | ||
| 5787 : | or variable in the first line. The first pattern which matches gets | ||
| 5788 : | executed. | ||
| 5789 : | |||
| 5790 : | @c ----------------------------------------------------------------------- | ||
| 5791 : | @c SECTION | ||
| 5792 : | @c ----------------------------------------------------------------------- | ||
| 5793 : | |||
| 5794 : | @node Input in sh, Loops in sh, Tests in sh, Bourne shell | ||
| 5795 : | @section Input from the user in sh | ||
| 5796 : | |||
| 5797 : | In shell you can read the value of a variable using the @samp{read} | ||
| 5798 : | command, with syntax | ||
| 5799 : | |||
| 5800 : | @smallexample | ||
| 5801 : | read @var{variable} | ||
| 5802 : | @end smallexample | ||
| 5803 : | @noindent | ||
| 5804 : | This reads in a string from the keyboard and terminates on a newline | ||
| 5805 : | character. Another way to do this is to use the @samp{input} | ||
| 5806 : | command to access a particular logical device. The keyboard device | ||
| 5807 : | in the current terminal is @file{/dev/tty}, so that one writes | ||
| 5808 : | @smallexample | ||
| 5809 : | @var{variable} = `line < /dev/tty` | ||
| 5810 : | @end smallexample | ||
| 5811 : | @noindent | ||
| 5812 : | which fetches a single line from the user. | ||
| 5813 : | |||
| 5814 : | @cindex Input in sh | ||
| 5815 : | Here are some examples of these commands. | ||
| 5816 : | First a program which asks yes or no... | ||
| 5817 : | @smallexample | ||
| 5818 : | #!/bin/sh | ||
| 5819 : | # | ||
| 5820 : | # Yes or no | ||
| 5821 : | # | ||
| 5822 : | |||
| 5823 : | echo "Please answer yes or no: " | ||
| 5824 : | |||
| 5825 : | answer=`line < /dev/tty` | ||
| 5826 : | |||
| 5827 : | case $answer in | ||
| 5828 : | |||
| 5829 : | y* | Y* | j* | J* ) echo YES!! ;; | ||
| 5830 : | |||
| 5831 : | n* | N* ) echo NO!! ;; | ||
| 5832 : | |||
| 5833 : | *) echo "Can't you answer a simple question?" | ||
| 5834 : | |||
| 5835 : | esac | ||
| 5836 : | |||
| 5837 : | echo The end | ||
| 5838 : | @end smallexample | ||
| 5839 : | |||
| 5840 : | @noindent | ||
| 5841 : | Notice the use of pattern matching and the @samp{|} `OR' symbol. | ||
| 5842 : | @smallexample | ||
| 5843 : | #!/bin/sh | ||
| 5844 : | # | ||
| 5845 : | # Kernel check | ||
| 5846 : | # | ||
| 5847 : | |||
| 5848 : | if test ! -f /vmunix # Check that the kernel is there! | ||
| 5849 : | then | ||
| 5850 : | echo "This is not BSD unix...hmmm" | ||
| 5851 : | if [ -f /hp-ux ] | ||
| 5852 : | then | ||
| 5853 : | echo "It's a Hewlett Packard machine!" | ||
| 5854 : | fi | ||
| 5855 : | elif [ -w /vmunix ] | ||
| 5856 : | then | ||
| 5857 : | echo "HEY!! The kernel is writable my me!"; | ||
| 5858 : | else | ||
| 5859 : | echo "The kernel is write protected." | ||
| 5860 : | echo "The system is safe from me today." | ||
| 5861 : | fi | ||
| 5862 : | @end smallexample | ||
| 5863 : | |||
| 5864 : | @c ----------------------------------------------------------------------- | ||
| 5865 : | @c SECTION | ||
| 5866 : | @c ----------------------------------------------------------------------- | ||
| 5867 : | |||
| 5868 : | @node Loops in sh, Procedures and traps, Input in sh, Bourne shell | ||
| 5869 : | @section Loops in sh | ||
| 5870 : | |||
| 5871 : | @cindex Loops in sh | ||
| 5872 : | @cindex @samp{while} in sh | ||
| 5873 : | |||
| 5874 : | The loop structures in the Bourne shell have the following syntax. | ||
| 5875 : | @smallexample | ||
| 5876 : | while @var{unix-command} | ||
| 5877 : | do | ||
| 5878 : | commands | ||
| 5879 : | done | ||
| 5880 : | @end smallexample | ||
| 5881 : | |||
| 5882 : | @noindent | ||
| 5883 : | The first command will most likely be a test but, as before, it | ||
| 5884 : | could in principle be any UNIX command. The @samp{until} loop, | ||
| 5885 : | reminiscent of BCPL, carries out a task until its argument evaluates | ||
| 5886 : | to TRUE. | ||
| 5887 : | @smallexample | ||
| 5888 : | until @var{unix-command} | ||
| 5889 : | do | ||
| 5890 : | commands | ||
| 5891 : | done | ||
| 5892 : | @end smallexample | ||
| 5893 : | |||
| 5894 : | @cindex @samp{until} | ||
| 5895 : | @noindent | ||
| 5896 : | Finally the @samp{for} structure has already been used above. | ||
| 5897 : | @smallexample | ||
| 5898 : | for @var{variable} in @var{list} | ||
| 5899 : | do | ||
| 5900 : | @var{commands} | ||
| 5901 : | done | ||
| 5902 : | @end smallexample | ||
| 5903 : | |||
| 5904 : | Often we want to be able to use an array of values as the list which | ||
| 5905 : | @code{for} parses, but Bourne shell has no array variables. This | ||
| 5906 : | problem is usually solved by making a long string separated by, for | ||
| 5907 : | example, colons. For example, the @code{$PATH} variable has the | ||
| 5908 : | form | ||
| 5909 : | @smallexample | ||
| 5910 : | PATH = /usr/bin:/bin:/local/gnu/bin | ||
| 5911 : | @end smallexample | ||
| 5912 : | |||
| 5913 : | @cindex @samp{IFS} variable in sh | ||
| 5914 : | @cindex Redefining list separator in sh | ||
| 5915 : | @cindex Loops and list separators | ||
| 5916 : | @noindent | ||
| 5917 : | Bourne shell allows us to split such a string on whatever character | ||
| 5918 : | we wish. Normally the split is made on spaces, but the variable | ||
| 5919 : | @samp{IFS} can be defined with a replacement. To make a loop over | ||
| 5920 : | all directories in the command path we would therefore write | ||
| 5921 : | @smallexample | ||
| 5922 : | IFS=: | ||
| 5923 : | |||
| 5924 : | for name in $PATH; do | ||
| 5925 : | |||
| 5926 : | @var{commands} | ||
| 5927 : | |||
| 5928 : | done | ||
| 5929 : | |||
| 5930 : | @end smallexample | ||
| 5931 : | |||
| 5932 : | @noindent | ||
| 5933 : | The best way to gain experience with these commands is through some | ||
| 5934 : | examples. | ||
| 5935 : | @smallexample | ||
| 5936 : | #!/bin/sh | ||
| 5937 : | # | ||
| 5938 : | # Get text from user repeatedly | ||
| 5939 : | # | ||
| 5940 : | |||
| 5941 : | echo "Type away..." | ||
| 5942 : | |||
| 5943 : | while read TEXT | ||
| 5944 : | do | ||
| 5945 : | |||
| 5946 : | echo You typed $TEXT | ||
| 5947 : | |||
| 5948 : | if [ "$TEXT" = "quit" ]; then | ||
| 5949 : | echo "(So I quit!)" | ||
| 5950 : | exit 0 | ||
| 5951 : | fi | ||
| 5952 : | |||
| 5953 : | done | ||
| 5954 : | |||
| 5955 : | echo "HELP!" | ||
| 5956 : | |||
| 5957 : | @end smallexample | ||
| 5958 : | |||
| 5959 : | @noindent | ||
| 5960 : | @cindex @key{CTRL-D} and EOF | ||
| 5961 : | @cindex End of file @key{CTRL-D} | ||
| 5962 : | This very simple script is a typical use for a while-loop. It | ||
| 5963 : | gets text repeatedly until the user type `quit'. Since read | ||
| 5964 : | never returns `false' unless an error occurs or it detects | ||
| 5965 : | an EOF (end of file) character @key{CTRL-D}, it will never | ||
| 5966 : | exit without some help from an `if' test. If it does receive | ||
| 5967 : | a @key{CTRL-D} signal, the script prints `HELP!'. | ||
| 5968 : | |||
| 5969 : | |||
| 5970 : | @smallexample | ||
| 5971 : | #!/bin/sh | ||
| 5972 : | # | ||
| 5973 : | # Watch in the background for a particular user | ||
| 5974 : | # and give alarm if he/she logs in | ||
| 5975 : | # | ||
| 5976 : | # To be run in the background, using & | ||
| 5977 : | # | ||
| 5978 : | |||
| 5979 : | if [ $# -ne 1 ]; then | ||
| 5980 : | echo "Give the name of the user as an argument" > /dev/tty | ||
| 5981 : | exit 1 | ||
| 5982 : | fi | ||
| 5983 : | |||
| 5984 : | echo "Looking for $1" | ||
| 5985 : | |||
| 5986 : | until users | grep -s $1 | ||
| 5987 : | do | ||
| 5988 : | sleep 60 | ||
| 5989 : | done | ||
| 5990 : | |||
| 5991 : | echo "!!! WAKE UP !!!" > /dev/tty | ||
| 5992 : | echo "User $1 just logged in" > /dev/tty | ||
| 5993 : | |||
| 5994 : | @end smallexample | ||
| 5995 : | |||
| 5996 : | This script uses @samp{grep} in `silent mode' (-s option). i.e. grep never | ||
| 5997 : | writes anything to the terminal. The only thing we are interested | ||
| 5998 : | in is the return code the piped command produces. If `grep' | ||
| 5999 : | detects a line containing the username we are interested in, | ||
| 6000 : | then the result evaluates to TRUE and the sleep-loop exits. | ||
| 6001 : | |||
| 6002 : | Our final example is the kind of script which is useful for | ||
| 6003 : | a system administrator. It transfers over the Network Information | ||
| 6004 : | Service database files so that a slave server is up to date. | ||
| 6005 : | All we have to do is make a list of the files and place it in a | ||
| 6006 : | @samp{for} loop. The names used below are the actual names | ||
| 6007 : | of the NIS maps, well known to system administrators. | ||
| 6008 : | @smallexample | ||
| 6009 : | #!/bin/sh | ||
| 6010 : | # | ||
| 6011 : | # Update the NIS database maps on a client server. This program | ||
| 6012 : | # shouldn't have to be run, but sometimes things go wrong and we | ||
| 6013 : | # have to force a download from the main sever. | ||
| 6014 : | # | ||
| 6015 : | PATH=/etc/yp:/usr/etc/yp:$PATH | ||
| 6016 : | |||
| 6017 : | MASTER=myNISserver | ||
| 6018 : | |||
| 6019 : | for map in auto.direct auto.master ethers.byaddr ethers.byname\ | ||
| 6020 : | group.bygid group.byname hosts.byaddr hosts.byname\ | ||
| 6021 : | mail.aliases netgroup.byhost netgroup.byuser netgroup\ | ||
| 6022 : | netid.byname networks.byaddr networks.byname passwd.byname\ | ||
| 6023 : | passwd.byuid priss.byname protocols.byname protocols.bynumber\ | ||
| 6024 : | rpc.bynumber services.byname services usenetgroups.byname; | ||
| 6025 : | do | ||
| 6026 : | ypxfr $1 -h $MASTER $map | ||
| 6027 : | done | ||
| 6028 : | |||
| 6029 : | @end smallexample | ||
| 6030 : | |||
| 6031 : | @c ----------------------------------------------------------------------- | ||
| 6032 : | @c SECTION | ||
| 6033 : | @c ----------------------------------------------------------------------- | ||
| 6034 : | |||
| 6035 : | @node Procedures and traps, setuid setgid scripts, Loops in sh, Bourne shell | ||
| 6036 : | @section Procedures and traps | ||
| 6037 : | |||
| 6038 : | @cindex Procedures and subroutines in sh | ||
| 6039 : | @cindex Signal handler in sh | ||
| 6040 : | @cindex Interrupt handler in sh | ||
| 6041 : | @cindex Traps in sh | ||
| 6042 : | |||
| 6043 : | One of the worthy features of the Bourne shell is that it allows | ||
| 6044 : | you to define @emph{subroutines} or @emph{procedures}. Subroutines | ||
| 6045 : | work just like subroutines in any other programming language. They are | ||
| 6046 : | executed in same shell (not as a sub-process). | ||
| 6047 : | |||
| 6048 : | Here is an interesting program which demonstrates two useful | ||
| 6049 : | things at the same time. First of all, it shows how to make | ||
| 6050 : | a hierachical subroutine structure using the Bourne shell. | ||
| 6051 : | Secondly, it shows how the @samp{trap} directive can be used | ||
| 6052 : | to trap signals, so that Bourne shell programs can exit safely | ||
| 6053 : | when they are killed or when CTRL-C is typed. | ||
| 6054 : | |||
| 6055 : | |||
| 6056 : | @smallexample | ||
| 6057 : | #!/bin/sh | ||
| 6058 : | # | ||
| 6059 : | # How to make a signal handler in Bourne Shell | ||
| 6060 : | # using subroutines | ||
| 6061 : | # | ||
| 6062 : | |||
| 6063 : | ##################################################### | ||
| 6064 : | # Level 2 | ||
| 6065 : | ##################################################### | ||
| 6066 : | |||
| 6067 : | ReallyQuit() | ||
| 6068 : | @{ | ||
| 6069 : | while true | ||
| 6070 : | do | ||
| 6071 : | echo "Do you really want to quit?" | ||
| 6072 : | read answer | ||
| 6073 : | |||
| 6074 : | case $answer in | ||
| 6075 : | |||
| 6076 : | y* | Y* ) return 0;; | ||
| 6077 : | *) echo "Resuming..." | ||
| 6078 : | return 1;; | ||
| 6079 : | |||
| 6080 : | esac | ||
| 6081 : | |||
| 6082 : | done | ||
| 6083 : | @} | ||
| 6084 : | |||
| 6085 : | ##################################################### | ||
| 6086 : | # Level 1 | ||
| 6087 : | ##################################################### | ||
| 6088 : | |||
| 6089 : | SignalHandler() | ||
| 6090 : | |||
| 6091 : | @{ | ||
| 6092 : | if ReallyQuit # Call a function | ||
| 6093 : | then | ||
| 6094 : | exit 0 | ||
| 6095 : | else | ||
| 6096 : | return 0 | ||
| 6097 : | fi | ||
| 6098 : | @} | ||
| 6099 : | |||
| 6100 : | ##################################################### | ||
| 6101 : | # Level 0 : main program | ||
| 6102 : | ##################################################### | ||
| 6103 : | |||
| 6104 : | trap SignalHandler 2 15 # Trap kill signals 2 and 15 | ||
| 6105 : | |||
| 6106 : | echo "Type some lines of text..." | ||
| 6107 : | |||
| 6108 : | while read text | ||
| 6109 : | do | ||
| 6110 : | |||
| 6111 : | echo "$text - CTRL-C to exit" | ||
| 6112 : | |||
| 6113 : | done | ||
| 6114 : | |||
| 6115 : | @end smallexample | ||
| 6116 : | |||
| 6117 : | Note that the logical tree structure of this program is upside down | ||
| 6118 : | (the highest level comes at the bottom). This is because all subroutines | ||
| 6119 : | must be defined before they are used. | ||
| 6120 : | |||
| 6121 : | This example concludes our brief survey of the Bourne shell. | ||
| 6122 : | |||
| 6123 : | @c ----------------------------------------------------------------------- | ||
| 6124 : | @c SECTION | ||
| 6125 : | @c ----------------------------------------------------------------------- | ||
| 6126 : | |||
| 6127 : | @node setuid setgid scripts, Limitations of shell, Procedures and traps, Bourne shell | ||
| 6128 : | @section setuid and setgid scripts | ||
| 6129 : | |||
| 6130 : | @cindex SetUID scripts | ||
| 6131 : | @cindex Root privileges | ||
| 6132 : | |||
| 6133 : | The superuser @samp{root} is the only privileged user in UNIX. All other | ||
| 6134 : | users have only restricted access to the system. Usually this is desirable, | ||
| 6135 : | but sometimes it is a nuisance. | ||
| 6136 : | |||
| 6137 : | A setuid script is a script which has its @emph{setuid-bit} set. When | ||
| 6138 : | such a script is executed by a user, it is run with all the rights and | ||
| 6139 : | privileges of the owner of the script. All of the commands in the script | ||
| 6140 : | are executed as the owner of the file and not with the user-id of the person who ran | ||
| 6141 : | the script. If the owner of the setuid script is @samp{root} then the | ||
| 6142 : | commands in the script are run with @emph{root privileges}! | ||
| 6143 : | |||
| 6144 : | Setuid scripts are clearly a touchy security issue. When giving | ||
| 6145 : | away one's rights to another user (especially those of @samp{root}) | ||
| 6146 : | one is tempting hackers. Setuid scripts should be @emph{avoided}. | ||
| 6147 : | |||
| 6148 : | A setgid program is almost the same, but only the group id is set to | ||
| 6149 : | that of the owner of the file. Often the effect is the same. | ||
| 6150 : | |||
| 6151 : | An example of a setuid program is the @samp{ps} program. @samp{ps} | ||
| 6152 : | lists all of the processes running in the kernel. In order to | ||
| 6153 : | do this it needs permission to access the private data structures | ||
| 6154 : | in the kernel. By making @samp{ps} setgid root, it allows ordinary | ||
| 6155 : | users to be able to read as much as the writers of @samp{ps} | ||
| 6156 : | thought fit, but no more. | ||
| 6157 : | |||
| 6158 : | Naturally, only the superuser can make a file setuid or setgid root. | ||
| 6159 : | |||
| 6160 : | @c ----------------------------------------------------------------------- | ||
| 6161 : | @c SECTION | ||
| 6162 : | @c ----------------------------------------------------------------------- | ||
| 6163 : | |||
| 6164 : | @node Limitations of shell, Ex4, setuid setgid scripts, Bourne shell | ||
| 6165 : | @section Summary: Limitations of shell programming | ||
| 6166 : | |||
| 6167 : | @cindex Limitations of shell programs | ||
| 6168 : | |||
| 6169 : | To summarize the last two long and oppressive chapters we shall take a | ||
| 6170 : | step back from the details and look at what we have achieved. | ||
| 6171 : | |||
| 6172 : | The idea behind the shell is to provide a user | ||
| 6173 : | interface, with access to the system's facilities at a simple level. | ||
| 6174 : | In the 70's user interfaces were not deisgned to be user-friendly. | ||
| 6175 : | The UNIX shell is not particularly use friendly, but it is very powerful. | ||
| 6176 : | Perhaps it would have been enough to provide only commands to allow users | ||
| 6177 : | to write C programs. Since all of the system functions are | ||
| 6178 : | available from C, that would certainly allow everyone to do what | ||
| 6179 : | anything that UNIX can do. But shell programming is much more | ||
| 6180 : | @emph{immediate} than C. It is an environment of @emph{frequently used tools}. | ||
| 6181 : | Also for quick programming solutions: C is a compiled language, whereas the | ||
| 6182 : | shell is an interpreter. A quick shell program can solve many | ||
| 6183 : | problems in no time at all, without having to compile anything. | ||
| 6184 : | |||
| 6185 : | Shell programming is only useful for `quick and easy' programs. To use | ||
| 6186 : | it for anything serious is an abuse. Programming difficult things in | ||
| 6187 : | shell is clumsy, and it is difficult to get returned-information (like | ||
| 6188 : | error messages) back in a useful form. Besides, shell scripts are | ||
| 6189 : | slow compared to real programs since they involve starting | ||
| 6190 : | a new program for each new command. | ||
| 6191 : | |||
| 6192 : | These difficulties are solved partly by Perl, which we shall consider | ||
| 6193 : | next -- but in the final analysis, real programs of substance | ||
| 6194 : | need to be written in C. Contrary to popular belief, this is | ||
| 6195 : | not more difficult than programming in the shell -- in fact, many | ||
| 6196 : | things are much simpler, because all of the shell commands originated | ||
| 6197 : | as C functions. The shell is an extra layer of the UNIX onion which | ||
| 6198 : | we have to battle our way through to get where we're going. | ||
| 6199 : | |||
| 6200 : | Sometimes it is helpful to be shielded from @emph{low level} details | ||
| 6201 : | -- sometimes it is a @emph{hindrance}. In the remaining chapters | ||
| 6202 : | we shall consider more involved programming needs. | ||
| 6203 : | |||
| 6204 : | @c ----------------------------------------------------------------------- | ||
| 6205 : | @c SECTION | ||
| 6206 : | @c ----------------------------------------------------------------------- | ||
| 6207 : | |||
| 6208 : | @node Ex4, , Limitations of shell, Bourne shell | ||
| 6209 : | @section Exercises | ||
| 6210 : | |||
| 6211 : | @enumerate | ||
| 6212 : | @item | ||
| 6213 : | Write an improved @samp{which} command in C-shell. | ||
| 6214 : | |||
| 6215 : | @item | ||
| 6216 : | Make a counter program which records in a file how many times | ||
| 6217 : | you log in to your account. You can call this in your .cshrc file. | ||
| 6218 : | |||
| 6219 : | @item | ||
| 6220 : | Make a Bourne shell script to kill all the processes owned by a particular | ||
| 6221 : | user. (Note, that if you are not the superuser, you cannot kill processes | ||
| 6222 : | owned by other users.) | ||
| 6223 : | |||
| 6224 : | @item | ||
| 6225 : | Write a script to replace the @samp{rm} command with something | ||
| 6226 : | safer. Think about a way of implementing @samp{rm} so that it is | ||
| 6227 : | possible to get deleted files back again in case of emergencies. This is | ||
| 6228 : | not possible using the normal @samp{rm} command. Hint: save files | ||
| 6229 : | in a hidden directory @samp{.deleted}. Make your script delete | ||
| 6230 : | files in the @samp{.deleted} directory if they are older than | ||
| 6231 : | a week, so that you don't fill up the disk with rubbish. | ||
| 6232 : | |||
| 6233 : | @item | ||
| 6234 : | Suppose you have a bunch of files with a particular file-extension: | ||
| 6235 : | write a script in csh to change the extension to something else. e.g. | ||
| 6236 : | to change *.C into *.c. Give the old and new extensions as arguments to | ||
| 6237 : | the script. | ||
| 6238 : | |||
| 6239 : | @item | ||
| 6240 : | Write a program in sh to search for files in the current directory | ||
| 6241 : | which contain a certain string. e.g. search for all files which contain | ||
| 6242 : | the word "if". Hint: use the "find" command. | ||
| 6243 : | |||
| 6244 : | @item | ||
| 6245 : | Use the manual pages to find out about the commands @samp{at}, | ||
| 6246 : | @samp{batch} and @samp{atq}. Test these commands by executing the | ||
| 6247 : | shell command @samp{date} at some time of your choice. Use the @samp{-m} | ||
| 6248 : | option so that the result of the job is mailed to you. | ||
| 6249 : | @cindex @samp{batch} command | ||
| 6250 : | @cindex @samp{at} command | ||
| 6251 : | |||
| 6252 : | @item | ||
| 6253 : | Write a script in sh or csh to list all of the files bigger | ||
| 6254 : | than a certain size starting from the current directory, and including | ||
| 6255 : | all subdirectories. This kind of program is useful for system administrators | ||
| 6256 : | when a disk becomes full. | ||
| 6257 : | @end enumerate | ||
| 6258 : | |||
| 6259 : | |||
| 6260 : | @c ********************************************************************** | ||
| 6261 : | @c CHAPTER | ||
| 6262 : | @c ********************************************************************** | ||
| 6263 : | |||
| 6264 : | @node Perl, WWW and CGI programming, Bourne shell, Top | ||
| 6265 : | @chapter Perl | ||
| 6266 : | |||
| 6267 : | @cindex Perl | ||
| 6268 : | So far, we have been looking at shell programming for performing | ||
| 6269 : | fairly simple tasks. Now let's extend the idea of shell programming | ||
| 6270 : | to cover more complex tasks like systems programming and network | ||
| 6271 : | communications. Perl is a language which was designed to retain the | ||
| 6272 : | immediateness of shell languages, but at the same time capture some | ||
| 6273 : | of the flexibility of C. Perl is an acronym for @emph{Practical extraction | ||
| 6274 : | and report language}. In this chapter, we shall not aim to teach Perl | ||
| 6275 : | from scratch -- the best way to learn it is to use it! Rather | ||
| 6276 : | we shall concentrate on demonstrating some principles. | ||
| 6277 : | |||
| 6278 : | @c ----------------------------------------------------------------------- | ||
| 6279 : | @c SECTION | ||
| 6280 : | @c ----------------------------------------------------------------------- | ||
| 6281 : | |||
| 6282 : | @menu | ||
| 6283 : | * sed awk cut paste:: | ||
| 6284 : | * Perl structure:: | ||
| 6285 : | * Perl variables:: | ||
| 6286 : | * Loops and conditionals:: | ||
| 6287 : | * Files in perl:: | ||
| 6288 : | * Perl subroutines:: | ||
| 6289 : | * die:: | ||
| 6290 : | * stat():: | ||
| 6291 : | * Perl examples:: | ||
| 6292 : | * Pattern matching:: | ||
| 6293 : | * search and replace:: | ||
| 6294 : | * WWW example:: | ||
| 6295 : | * WWW example 2:: | ||
| 6296 : | * Other functions:: | ||
| 6297 : | * Perl summary:: | ||
| 6298 : | * Ex5:: | ||
| 6299 : | * Proj5:: | ||
| 6300 : | @end menu | ||
| 6301 : | |||
| 6302 : | @node sed awk cut paste, Perl structure, Perl, Perl | ||
| 6303 : | @section Sed and awk, cut and paste | ||
| 6304 : | |||
| 6305 : | @cindex @samp{sed} batch editor | ||
| 6306 : | @cindex @samp{awk} pattern extractor | ||
| 6307 : | @cindex @samp{cut} | ||
| 6308 : | @cindex @samp{paste} | ||
| 6309 : | |||
| 6310 : | One of the reasons for using Perl is that it is extremely good at | ||
| 6311 : | textfile handling--one of the most important things for UNIX users, and | ||
| 6312 : | particularly useful in connection with CGI script processing on the | ||
| 6313 : | World Wide Web. It has simple built-in constructs for searching and | ||
| 6314 : | replacing text, storing information in arrays and retrieving them in | ||
| 6315 : | sorted form. All of the these things have previously been possible using | ||
| 6316 : | the UNIX shell commands | ||
| 6317 : | @smallexample | ||
| 6318 : | sed | ||
| 6319 : | awk | ||
| 6320 : | cut | ||
| 6321 : | paste | ||
| 6322 : | @end smallexample | ||
| 6323 : | |||
| 6324 : | @noindent | ||
| 6325 : | but these commands were designed to work primarily in the Bourne shell | ||
| 6326 : | and are a bit @samp{awk}ward to use for all but the simplest applications. | ||
| 6327 : | |||
| 6328 : | @table @samp | ||
| 6329 : | @item sed | ||
| 6330 : | is a stream editor. It takes command line instructions, reads input from | ||
| 6331 : | the stream @code{stdin} and produces output on @emph{stdout} according | ||
| 6332 : | to those instructions. @samp{sed} works line by line from the start of a | ||
| 6333 : | textfile. | ||
| 6334 : | |||
| 6335 : | @item awk | ||
| 6336 : | is a pattern matching and processing language. It takes a textfile and | ||
| 6337 : | reads it line by line, matching @emph{regular expressions} and acting on | ||
| 6338 : | them. @samp{awk} is powerful enough to have conditional instructions | ||
| 6339 : | like @samp{if..then..else} and uses C's @samp{printf} construction for | ||
| 6340 : | output. | ||
| 6341 : | |||
| 6342 : | @item cut | ||
| 6343 : | Takes a line of input and cuts it into @emph{fields}, | ||
| 6344 : | separated by some character. For instance, a normal line of text is | ||
| 6345 : | a string of words separated by spaces. Each word is a different field. | ||
| 6346 : | @samp{cut} can be used, for instance, to pick out the third column in a | ||
| 6347 : | table. Any character can be specified as the separator. | ||
| 6348 : | |||
| 6349 : | @item paste | ||
| 6350 : | is the logical opposite of cut. It concatenates @math{n} | ||
| 6351 : | files, and makes each line in the file into a column of a table. For instance, | ||
| 6352 : | @samp{paste one two three} would make a table in which the first | ||
| 6353 : | column consisted of all lines in @samp{one}, the second of all lines | ||
| 6354 : | in @samp{two} and the third of all lines in @samp{three}. If one file | ||
| 6355 : | is longer than the others, then some columns have blank spaces. | ||
| 6356 : | @end table | ||
| 6357 : | |||
| 6358 : | Perl unifies all of these operations and more. It also | ||
| 6359 : | makes them much simpler. | ||
| 6360 : | |||
| 6361 : | @c ----------------------------------------------------------------------- | ||
| 6362 : | @c SECTION | ||
| 6363 : | @c ----------------------------------------------------------------------- | ||
| 6364 : | |||
| 6365 : | @node Perl structure, Perl variables, sed awk cut paste, Perl | ||
| 6366 : | @section Program structure | ||
| 6367 : | |||
| 6368 : | To summarize Perl, we need to know about the structure of a Perl | ||
| 6369 : | program, the conditional constructs it has, its loops and its variables. | ||
| 6370 : | In the latest versions of Perl (Perl 5), you can write object oriented | ||
| 6371 : | programs of great complexity. We shall not go into this depth, for the | ||
| 6372 : | simple reason that Perl's strength is not as a general programming | ||
| 6373 : | language but as a specialized language for textfile handling. The | ||
| 6374 : | syntax of Perl is in many ways like the C programming language, but | ||
| 6375 : | there are important differences. | ||
| 6376 : | |||
| 6377 : | @itemize @bullet | ||
| 6378 : | |||
| 6379 : | @item | ||
| 6380 : | Variables do not have @emph{types}. They are interpreted | ||
| 6381 : | in a context sensitive way. The operators which acts upon variables | ||
| 6382 : | determine whether a variable is to be considered a string or as an integer etc. | ||
| 6383 : | @cindex Perl variables and types | ||
| 6384 : | @cindex Types in perl | ||
| 6385 : | |||
| 6386 : | @item | ||
| 6387 : | Although there are no types, Perl defines @emph{arrays} of | ||
| 6388 : | different kinds. There are three different kinds of array, labelled by the | ||
| 6389 : | symbols @samp{$}, @samp{@@} and @samp{%}. | ||
| 6390 : | @cindex Arrays in perl | ||
| 6391 : | |||
| 6392 : | @item | ||
| 6393 : | Perl keeps a number of standard variables with special names | ||
| 6394 : | e.g. @samp{$_ @@ARGV} and @samp{%ENV}. Special attention should be paid | ||
| 6395 : | to these. They are very important! | ||
| 6396 : | @cindex Argument vector in perl | ||
| 6397 : | @cindex Command line arguments in perl | ||
| 6398 : | @cindex Environment variables in perl | ||
| 6399 : | |||
| 6400 : | @item | ||
| 6401 : | The shell reverse | ||
| 6402 : | apostrophe notation @code{`command`} can be used to execute UNIX | ||
| 6403 : | programs and get the result into a Perl variable. | ||
| 6404 : | @cindex @samp{`..`} in perl | ||
| 6405 : | |||
| 6406 : | @end itemize | ||
| 6407 : | |||
| 6408 : | Here is a simple `structured hello world' program in Perl. Notice | ||
| 6409 : | that subroutines are called using the @samp{&} symbol. There is | ||
| 6410 : | no special way of marking the main program -- it is simply | ||
| 6411 : | that part of the program which starts at line 1. | ||
| 6412 : | |||
| 6413 : | |||
| 6414 : | @smallexample | ||
| 6415 : | #!/local/bin/perl | ||
| 6416 : | # | ||
| 6417 : | # Comments | ||
| 6418 : | # | ||
| 6419 : | |||
| 6420 : | &Hello(); | ||
| 6421 : | &World; | ||
| 6422 : | |||
| 6423 : | # end of main | ||
| 6424 : | |||
| 6425 : | sub Hello | ||
| 6426 : | @{ | ||
| 6427 : | print "Hello"; | ||
| 6428 : | @} | ||
| 6429 : | |||
| 6430 : | |||
| 6431 : | sub World | ||
| 6432 : | @{ | ||
| 6433 : | print "World\n"; | ||
| 6434 : | @} | ||
| 6435 : | |||
| 6436 : | |||
| 6437 : | @end smallexample | ||
| 6438 : | |||
| 6439 : | @noindent | ||
| 6440 : | The parentheses on subroutines are optional, if there are no parameters passed. | ||
| 6441 : | Notice that each line must end in a semi-colon. | ||
| 6442 : | |||
| 6443 : | @c ----------------------------------------------------------------------- | ||
| 6444 : | @c SECTION | ||
| 6445 : | @c ----------------------------------------------------------------------- | ||
| 6446 : | |||
| 6447 : | @node Perl variables, Loops and conditionals, Perl structure, Perl | ||
| 6448 : | @section Perl variables | ||
| 6449 : | |||
| 6450 : | @c ..................................................... | ||
| 6451 : | @c SUBSECTION | ||
| 6452 : | @c ..................................................... | ||
| 6453 : | |||
| 6454 : | @menu | ||
| 6455 : | * Scalar variables:: | ||
| 6456 : | * The default scalar variable:: | ||
| 6457 : | * Array variables:: | ||
| 6458 : | * Array commands:: | ||
| 6459 : | * Associated arrays:: | ||
| 6460 : | * Array example:: | ||
| 6461 : | @end menu | ||
| 6462 : | |||
| 6463 : | @node Scalar variables, The default scalar variable, Perl variables, Perl variables | ||
| 6464 : | @subsection Scalar variables | ||
| 6465 : | |||
| 6466 : | @cindex Scalar variables in perl | ||
| 6467 : | @cindex Strings in perl | ||
| 6468 : | @cindex Perl, strings and scalar | ||
| 6469 : | |||
| 6470 : | In Perl, variables do not have to be declared before they are used. | ||
| 6471 : | Whenever you use a new symbol, Perl automatically adds the symbol to | ||
| 6472 : | its symbol table and initializes the variable to the empty | ||
| 6473 : | string. | ||
| 6474 : | |||
| 6475 : | It is important to understand that there is no | ||
| 6476 : | practical difference between zero and the empty string in perl -- except in the way that you, the user, choose to | ||
| 6477 : | use it. Perl makes no distinction between strings and integers or any other | ||
| 6478 : | types of data -- except when it wants to interpret them. For instance, | ||
| 6479 : | to compare two variables as strings is not the same as comparing them | ||
| 6480 : | as integers, even if the string contains a textual representation of an | ||
| 6481 : | integer. Take a look at the following program. | ||
| 6482 : | |||
| 6483 : | @smallexample | ||
| 6484 : | #!/local/bin/perl | ||
| 6485 : | # | ||
| 6486 : | # Nothing! | ||
| 6487 : | # | ||
| 6488 : | |||
| 6489 : | print "Nothing == $nothing\n"; | ||
| 6490 : | |||
| 6491 : | print "Nothing is zero!\n" if ($nothing == 0); | ||
| 6492 : | |||
| 6493 : | if ($nothing eq "") | ||
| 6494 : | @{ | ||
| 6495 : | print STDERR "Nothing is really nothing!\n"; | ||
| 6496 : | @} | ||
| 6497 : | |||
| 6498 : | $nothing = 0; | ||
| 6499 : | |||
| 6500 : | print "Nothing is now $nothing\n"; | ||
| 6501 : | @end smallexample | ||
| 6502 : | |||
| 6503 : | @noindent | ||
| 6504 : | The output from this program is | ||
| 6505 : | |||
| 6506 : | @smallexample | ||
| 6507 : | |||
| 6508 : | Nothing == | ||
| 6509 : | Nothing is zero! | ||
| 6510 : | Nothing is really nothing! | ||
| 6511 : | Nothing is now 0 | ||
| 6512 : | |||
| 6513 : | @end smallexample | ||
| 6514 : | |||
| 6515 : | @cindex Interpretation of values in perl | ||
| 6516 : | |||
| 6517 : | There are several important things to note here. First of all, we never | ||
| 6518 : | declare the variable `nothing'. When we try to write its value, perl | ||
| 6519 : | creates the name and associates a NULL value to it i.e. the empty | ||
| 6520 : | string. There is no error. Perl knows it is a variable because of the | ||
| 6521 : | @samp{$} symbol in front of it. All @emph{scalar} variables are | ||
| 6522 : | identified by using the dollar symbol. | ||
| 6523 : | |||
| 6524 : | @cindex @samp{eq} and @samp{==} in perl | ||
| 6525 : | @vindex @samp{eq} | ||
| 6526 : | @vindex @samp{==} | ||
| 6527 : | |||
| 6528 : | Next, we compare the value of @samp{$nothing} to the integer `0' using | ||
| 6529 : | the integer comparison symbol @samp{==}, and then we compare it to the | ||
| 6530 : | empty string using the string comparison symbol @samp{eq}. Both tests | ||
| 6531 : | are true! That means that the empty string is interpreted as having a | ||
| 6532 : | numerical value of zero. In fact @emph{any string} which does not form a | ||
| 6533 : | valid integer number has a numerical value of zero. | ||
| 6534 : | |||
| 6535 : | Finally we can set @samp{$nothing} explicitly to a valid integer | ||
| 6536 : | string zero, which would now pass the first test, but fail the | ||
| 6537 : | second. | ||
| 6538 : | |||
| 6539 : | As extra spice, this program also demonstrates two different ways | ||
| 6540 : | of writing the @samp{if} command in perl. | ||
| 6541 : | |||
| 6542 : | @c ..................................................... | ||
| 6543 : | @c SUBSECTION | ||
| 6544 : | @c ..................................................... | ||
| 6545 : | |||
| 6546 : | @node The default scalar variable, Array variables, Scalar variables, Perl variables | ||
| 6547 : | @subsection The default scalar variable. | ||
| 6548 : | |||
| 6549 : | The special variable @samp{$_} is used for many purposes in Perl. | ||
| 6550 : | It is used as a buffer to contain the result of the last operation, | ||
| 6551 : | the last line read in from a file etc. It is so general that many | ||
| 6552 : | functions which act on scalar variables work by default on @samp{$_} | ||
| 6553 : | if no other argument is specified. For example, | ||
| 6554 : | @smallexample | ||
| 6555 : | print; | ||
| 6556 : | @end smallexample | ||
| 6557 : | |||
| 6558 : | @noindent | ||
| 6559 : | is the same as | ||
| 6560 : | @smallexample | ||
| 6561 : | print $_; | ||
| 6562 : | @end smallexample | ||
| 6563 : | |||
| 6564 : | @c ..................................................... | ||
| 6565 : | @c SUBSECTION | ||
| 6566 : | @c ..................................................... | ||
| 6567 : | |||
| 6568 : | @node Array variables, Array commands, The default scalar variable, Perl variables | ||
| 6569 : | @subsection Array (vector) variables | ||
| 6570 : | |||
| 6571 : | @cindex Arrays (normal) in perl | ||
| 6572 : | The complement of scalar variables is arrays. An array, in Perl is | ||
| 6573 : | identified by the @samp{@@} symbol and, like scalar variables, is | ||
| 6574 : | allocated and initialized dynamically. | ||
| 6575 : | @smallexample | ||
| 6576 : | |||
| 6577 : | @@array[0] = "This little piggy went to market"; | ||
| 6578 : | @@array[2] = "This little piggy stayed at home"; | ||
| 6579 : | |||
| 6580 : | print "@@array[0] @@array[1] @@array[2]"; | ||
| 6581 : | |||
| 6582 : | @end smallexample | ||
| 6583 : | |||
| 6584 : | @noindent | ||
| 6585 : | The index of an array is always understood to be a number, not | ||
| 6586 : | a string, so if you use a non-numerical string to refer to an array | ||
| 6587 : | element, you will always get the zeroth element, since a non-numerical | ||
| 6588 : | string has an integer value of zero. | ||
| 6589 : | |||
| 6590 : | An important array which every program defines is | ||
| 6591 : | @smallexample | ||
| 6592 : | @@ARGV | ||
| 6593 : | @end smallexample | ||
| 6594 : | |||
| 6595 : | @noindent | ||
| 6596 : | This is the argument vector array, and contains the commands line arguments | ||
| 6597 : | by analogy with the C-shell variable @samp{$argv[]}. | ||
| 6598 : | |||
| 6599 : | Given an array, we can find the last element by using the @samp{$#} | ||
| 6600 : | operator. For example, | ||
| 6601 : | @smallexample | ||
| 6602 : | $last_element = $ARGV[$#ARGV]; | ||
| 6603 : | @end smallexample | ||
| 6604 : | |||
| 6605 : | @noindent | ||
| 6606 : | Notice that each element in an array is a scalar variable. The @samp{$#} | ||
| 6607 : | cannot be interpreted directly as the number of elements in the array, | ||
| 6608 : | as it can in the C-shell. You should experiment with the value of this | ||
| 6609 : | quantity -- it often necessary to add 1 or 2 to its value in order to | ||
| 6610 : | get the behaviour one is used to in the C-shell. | ||
| 6611 : | |||
| 6612 : | Perl does not support multiple-dimension arrays directly, but it is | ||
| 6613 : | possible to simulate them yourself. (See the Perl book.) | ||
| 6614 : | |||
| 6615 : | @cindex Argument vector in perl | ||
| 6616 : | @cindex Command line arguments in perl | ||
| 6617 : | |||
| 6618 : | @c ..................................................... | ||
| 6619 : | @c SUBSECTION | ||
| 6620 : | @c ..................................................... | ||
| 6621 : | |||
| 6622 : | @node Array commands, Associated arrays, Array variables, Perl variables | ||
| 6623 : | @subsection Special array commands | ||
| 6624 : | |||
| 6625 : | The @samp{shift} command acts on arrays and returns and removes the | ||
| 6626 : | first element of the array. Afterwards, all of the elements are shifted | ||
| 6627 : | down one place. So one way to read the elements of an array in order is | ||
| 6628 : | to repeatedly call @samp{shift}. | ||
| 6629 : | |||
| 6630 : | @smallexample | ||
| 6631 : | $next_element=shift(@@myarray); | ||
| 6632 : | @end smallexample | ||
| 6633 : | |||
| 6634 : | @cindex @samp{shift} and arrays in perl | ||
| 6635 : | @cindex @samp{shift} and arrays | ||
| 6636 : | @noindent | ||
| 6637 : | Note that, if the array argument is omitted, then @samp{shift} | ||
| 6638 : | works on @samp{@@ARGV} by default. | ||
| 6639 : | |||
| 6640 : | @cindex @samp{split} command | ||
| 6641 : | @cindex @samp{split} and arrays | ||
| 6642 : | @cindex Arrays and @samp{split} | ||
| 6643 : | Another useful function is @samp{split}, which takes a string and turns | ||
| 6644 : | it into an array of strings. @samp{split} works by choosing a character | ||
| 6645 : | (usually a space) to delimit the array elements, so a string containing | ||
| 6646 : | a sentence separated by spaces would be turned into an array of | ||
| 6647 : | words. The syntax is | ||
| 6648 : | |||
| 6649 : | @smallexample | ||
| 6650 : | @@array = split; # works with spaces on $_ | ||
| 6651 : | @@array = split(pattern,string); # Breaks on pattern | ||
| 6652 : | ($v1,$v2...) = split(pattern,string); # Name array elements with scalars | ||
| 6653 : | @end smallexample | ||
| 6654 : | |||
| 6655 : | @noindent | ||
| 6656 : | In the first of these cases, it is assumed that the variable @samp{$_} | ||
| 6657 : | is to be split on whitespace characters. In the second case, we decide | ||
| 6658 : | on what characterthe split is to take place and on what string the | ||
| 6659 : | function is to act. For instance | ||
| 6660 : | |||
| 6661 : | @smallexample | ||
| 6662 : | @@new_array = split(":","name:passwd:uid:gid:gcos:home:shell"); | ||
| 6663 : | @end smallexample | ||
| 6664 : | |||
| 6665 : | @noindent | ||
| 6666 : | The result is a seven element array called @samp{@@new_array}, where | ||
| 6667 : | @samp{$new_array[0]} is @samp{name} etc. | ||
| 6668 : | |||
| 6669 : | @noindent | ||
| 6670 : | In the final example, the left hand side shows that we wish to capture | ||
| 6671 : | elements of the array in a named set of scalar variables. If the | ||
| 6672 : | number of variables on the lefthand side is fewer than the number of | ||
| 6673 : | strings which are generated on the right hand side, they are | ||
| 6674 : | discarded. If the number on the left hand side is greater, then the | ||
| 6675 : | remainder variables are empty. | ||
| 6676 : | |||
| 6677 : | |||
| 6678 : | |||
| 6679 : | @c ..................................................... | ||
| 6680 : | @c SUBSECTION | ||
| 6681 : | @c ..................................................... | ||
| 6682 : | |||
| 6683 : | @node Associated arrays, Array example, Array commands, Perl variables | ||
| 6684 : | @subsection Associated arrays | ||
| 6685 : | |||
| 6686 : | @cindex Arrays (associated) in perl | ||
| 6687 : | One of the very nice features of Perl is the ability to use one string | ||
| 6688 : | as an index to another string in an array. For example, we can make a | ||
| 6689 : | short encyclopaedia of zoo animals by constructing an associative array | ||
| 6690 : | in which the keys (or indices) of the array are the names of animals, and | ||
| 6691 : | the contents of the array are the information about them. | ||
| 6692 : | |||
| 6693 : | @smallexample | ||
| 6694 : | |||
| 6695 : | $animals@{"Penguin"@} = "A suspicious animal, good with cheese crackers..."; | ||
| 6696 : | $animals@{"dog"@} = "Plays stupid, but could be a cover..."; | ||
| 6697 : | |||
| 6698 : | if ($index eq "fish") | ||
| 6699 : | @{ | ||
| 6700 : | $animals@{$index@} = "Often comes in square boxes. Very cold."; | ||
| 6701 : | @} | ||
| 6702 : | |||
| 6703 : | @end smallexample | ||
| 6704 : | |||
| 6705 : | @noindent | ||
| 6706 : | An entire associated array is written @samp{%array}, while the elements | ||
| 6707 : | are @samp{$array@{$key@}}. | ||
| 6708 : | |||
| 6709 : | Perl provides a special associative array for every program called @samp{%ENV}. | ||
| 6710 : | This contains the @emph{environment variables} defined in the parent | ||
| 6711 : | shell which is running the Perl program. For example | ||
| 6712 : | @smallexample | ||
| 6713 : | print "Username = $ENV@{"USER"@}\n"; | ||
| 6714 : | |||
| 6715 : | $ld = "LD_LIBRARY_PATH"; | ||
| 6716 : | print "The link editor path is $ENV@{$ld@}\n"; | ||
| 6717 : | |||
| 6718 : | @end smallexample | ||
| 6719 : | |||
| 6720 : | @cindex Environment variables in perl | ||
| 6721 : | @noindent | ||
| 6722 : | To get the current path into an ordinary array, one could write, | ||
| 6723 : | @smallexample | ||
| 6724 : | @@path_array= split(":",$ENV@{"PATH"@}); | ||
| 6725 : | @end smallexample | ||
| 6726 : | |||
| 6727 : | @c ..................................................... | ||
| 6728 : | @c SUBSECTION | ||
| 6729 : | @c ..................................................... | ||
| 6730 : | |||
| 6731 : | @node Array example, , Associated arrays, Perl variables | ||
| 6732 : | @subsection Array example program | ||
| 6733 : | |||
| 6734 : | Here is an example which prints out a list of files in a specified | ||
| 6735 : | directory, in order of their UNIX protection bits. The @emph{least} | ||
| 6736 : | protected file files come first. | ||
| 6737 : | |||
| 6738 : | @smallexample | ||
| 6739 : | #!/local/bin/perl | ||
| 6740 : | # | ||
| 6741 : | # Demonstration of arrays and associated arrays. | ||
| 6742 : | # Print out a list of files, sorted by protection, | ||
| 6743 : | # so that the least secure files come first. | ||
| 6744 : | # | ||
| 6745 : | # e.g. arrays <list of words> | ||
| 6746 : | # arrays *.C | ||
| 6747 : | # | ||
| 6748 : | ############################################################ | ||
| 6749 : | |||
| 6750 : | |||
| 6751 : | print "You typed in ",$#ARGV+1," arguments to command\n"; | ||
| 6752 : | |||
| 6753 : | if ($#ARGV < 1) | ||
| 6754 : | @{ | ||
| 6755 : | print "That's not enough to do anything with!\n"; | ||
| 6756 : | @} | ||
| 6757 : | |||
| 6758 : | while ($next_arg = shift(@@ARGV)) | ||
| 6759 : | @{ | ||
| 6760 : | if ( ! ( -f $next_arg || -d $next_arg)) | ||
| 6761 : | @{ | ||
| 6762 : | print "No such file: $next_arg\n"; | ||
| 6763 : | next; | ||
| 6764 : | @} | ||
| 6765 : | |||
| 6766 : | ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size) = stat($next_arg); | ||
| 6767 : | $octalmode = sprintf("%o",$mode & 0777); | ||
| 6768 : | |||
| 6769 : | $assoc_array@{$octalmode@} .= $next_arg. | ||
| 6770 : | " : size (".$size."), mode (".$octalmode.")\n"; | ||
| 6771 : | @} | ||
| 6772 : | |||
| 6773 : | print "In order: LEAST secure first!\n\n"; | ||
| 6774 : | |||
| 6775 : | foreach $i (reverse sort keys(%assoc_array)) | ||
| 6776 : | @{ | ||
| 6777 : | print $assoc_array@{$i@}; | ||
| 6778 : | @} | ||
| 6779 : | |||
| 6780 : | @end smallexample | ||
| 6781 : | |||
| 6782 : | |||
| 6783 : | @c ----------------------------------------------------------------------- | ||
| 6784 : | @c SECTION | ||
| 6785 : | @c ----------------------------------------------------------------------- | ||
| 6786 : | |||
| 6787 : | @node Loops and conditionals, Files in perl, Perl variables, Perl | ||
| 6788 : | @section Loops and conditionals | ||
| 6789 : | |||
| 6790 : | @cindex For loops in perl | ||
| 6791 : | @cindex @code{for} loop in perl | ||
| 6792 : | @cindex @code{foreach} loop in perl | ||
| 6793 : | Here are some of the most commonly used decision-making | ||
| 6794 : | constructions and loops in Perl. The following is not a | ||
| 6795 : | comprehensive list -- for that, you will have to look | ||
| 6796 : | in the Perl bible: @emph{Programming Perl}, by Larry Wall | ||
| 6797 : | and Randal Schwartz. The basic pattern follows the C | ||
| 6798 : | programming language quite closely. In the | ||
| 6799 : | case of the @samp{for} loop, Perl has both the C-like | ||
| 6800 : | version, called @samp{for} and a @samp{foreach} command | ||
| 6801 : | which is like the C-shell implementation. | ||
| 6802 : | |||
| 6803 : | @cindex @samp{if} in perl | ||
| 6804 : | @cindex @samp{unless} in perl | ||
| 6805 : | @cindex @samp{while} in perl | ||
| 6806 : | @cindex @samp{do..while} in perl | ||
| 6807 : | @smallexample | ||
| 6808 : | if (@var{expression}) | ||
| 6809 : | @{ | ||
| 6810 : | block; | ||
| 6811 : | @} | ||
| 6812 : | else | ||
| 6813 : | @{ | ||
| 6814 : | block; | ||
| 6815 : | @} | ||
| 6816 : | |||
| 6817 : | command if (@var{expression}); | ||
| 6818 : | |||
| 6819 : | unless (@var{expression}) | ||
| 6820 : | @{ | ||
| 6821 : | block; | ||
| 6822 : | @} | ||
| 6823 : | else | ||
| 6824 : | @{ | ||
| 6825 : | block; | ||
| 6826 : | @} | ||
| 6827 : | |||
| 6828 : | while (@var{expression}) | ||
| 6829 : | @{ | ||
| 6830 : | block; | ||
| 6831 : | @} | ||
| 6832 : | |||
| 6833 : | do | ||
| 6834 : | @{ | ||
| 6835 : | block; | ||
| 6836 : | @} | ||
| 6837 : | while (@var{expression}); | ||
| 6838 : | |||
| 6839 : | for (@var{initializer}; @var{expression}; @var{statement}) | ||
| 6840 : | @{ | ||
| 6841 : | block; | ||
| 6842 : | @} | ||
| 6843 : | |||
| 6844 : | foreach @var{variable}(@var{array}) | ||
| 6845 : | @{ | ||
| 6846 : | block; | ||
| 6847 : | @} | ||
| 6848 : | |||
| 6849 : | @end smallexample | ||
| 6850 : | |||
| 6851 : | @noindent | ||
| 6852 : | In all cases, the @samp{else} clauses may be omitted. | ||
| 6853 : | |||
| 6854 : | Strangely, perl does not have a @samp{switch} statement, but the Perl book | ||
| 6855 : | describes how to make one using the features provided. | ||
| 6856 : | |||
| 6857 : | |||
| 6858 : | @c ..................................................... | ||
| 6859 : | @c SUBSECTION | ||
| 6860 : | @c ..................................................... | ||
| 6861 : | |||
| 6862 : | @menu | ||
| 6863 : | * The for loop:: | ||
| 6864 : | * The foreach loop:: | ||
| 6865 : | * Iterating over elements in arrays:: | ||
| 6866 : | * Iterating over lines in a file:: | ||
| 6867 : | @end menu | ||
| 6868 : | |||
| 6869 : | @node The for loop, The foreach loop, Loops and conditionals, Loops and conditionals | ||
| 6870 : | @subsection The for loop | ||
| 6871 : | |||
| 6872 : | The for loop is exactly like that in C or C++ and is used | ||
| 6873 : | to iterate over a numerical index, like this: | ||
| 6874 : | |||
| 6875 : | @smallexample | ||
| 6876 : | |||
| 6877 : | for ($i = 0; $i < 10; $i++) | ||
| 6878 : | @{ | ||
| 6879 : | print $i, "\n"; | ||
| 6880 : | @} | ||
| 6881 : | |||
| 6882 : | @end smallexample | ||
| 6883 : | @cindex For loop | ||
| 6884 : | |||
| 6885 : | @c ..................................................... | ||
| 6886 : | @c SUBSECTION | ||
| 6887 : | @c ..................................................... | ||
| 6888 : | |||
| 6889 : | @node The foreach loop, Iterating over elements in arrays, The for loop, Loops and conditionals | ||
| 6890 : | @subsection The foreach loop | ||
| 6891 : | |||
| 6892 : | The foreach loop is like its counterpart in the C shell. It | ||
| 6893 : | is used for reading elements one by one from a regular array. | ||
| 6894 : | For example, | ||
| 6895 : | |||
| 6896 : | @smallexample | ||
| 6897 : | |||
| 6898 : | foreach $i ( @@array ) | ||
| 6899 : | @{ | ||
| 6900 : | print $i, "\n"; | ||
| 6901 : | @} | ||
| 6902 : | |||
| 6903 : | @end smallexample | ||
| 6904 : | @cindex Foreach loop | ||
| 6905 : | |||
| 6906 : | @c ..................................................... | ||
| 6907 : | @c SUBSECTION | ||
| 6908 : | @c ..................................................... | ||
| 6909 : | |||
| 6910 : | @node Iterating over elements in arrays, Iterating over lines in a file, The foreach loop, Loops and conditionals | ||
| 6911 : | @subsection Iterating over elements in arrays | ||
| 6912 : | |||
| 6913 : | One of the main uses for @samp{for} type loops is to iterate | ||
| 6914 : | over successive values in an array. This can be done in | ||
| 6915 : | two ways which show the essential difference between | ||
| 6916 : | @code{for} and @code{foreach}. | ||
| 6917 : | |||
| 6918 : | If we want to fetch each value in an array in turn, without caring about | ||
| 6919 : | numerical indices, the it is simpest to use the @code{foreach} loop. | ||
| 6920 : | @cindex Iteration over arrays | ||
| 6921 : | |||
| 6922 : | @smallexample | ||
| 6923 : | |||
| 6924 : | @@array = split(" ","a b c d e f g"); | ||
| 6925 : | |||
| 6926 : | foreach $var ( @@array ) | ||
| 6927 : | @{ | ||
| 6928 : | print $var, "\n"; | ||
| 6929 : | @} | ||
| 6930 : | |||
| 6931 : | @end smallexample | ||
| 6932 : | |||
| 6933 : | @noindent | ||
| 6934 : | This example prints each letter on a separate line. | ||
| 6935 : | If, on the other hand, we are interested in the index, | ||
| 6936 : | for the purposes of some calculation, then the @code{for} | ||
| 6937 : | loop is preferable. | ||
| 6938 : | |||
| 6939 : | @smallexample | ||
| 6940 : | |||
| 6941 : | @@array = split(" ","a b c d e f g"); | ||
| 6942 : | |||
| 6943 : | for ($i = 0; $i <= $#array; $i++) | ||
| 6944 : | @{ | ||
| 6945 : | print $array[$i], "\n"; | ||
| 6946 : | @} | ||
| 6947 : | |||
| 6948 : | @end smallexample | ||
| 6949 : | |||
| 6950 : | @noindent | ||
| 6951 : | Notice that, unlike the for-loop idiom in C/C++, the limit | ||
| 6952 : | is @samp{$i <= $#array}, i.e. `less than or equal to' rather | ||
| 6953 : | than `less than'. This is because the @samp{$#} operator | ||
| 6954 : | does not return the number of elements in the array but | ||
| 6955 : | rather the last element. | ||
| 6956 : | |||
| 6957 : | Associated arrays are slightly different, since they do not | ||
| 6958 : | use numerical keys. Instead they use a set of strings, | ||
| 6959 : | like in a database, so that you can use one string to look | ||
| 6960 : | up another. In order to iterate over the values in the array | ||
| 6961 : | we need to get a list of these strings. The @code{keys} | ||
| 6962 : | command is used for this. | ||
| 6963 : | @vindex keys | ||
| 6964 : | @cindex Associated arrays, iteration | ||
| 6965 : | |||
| 6966 : | @smallexample | ||
| 6967 : | $assoc@{"mark"@} = "cool"; | ||
| 6968 : | $assoc@{"GNU"@} = "brave"; | ||
| 6969 : | $assoc@{"zebra"@} = "stripy"; | ||
| 6970 : | |||
| 6971 : | foreach $var ( keys %assoc ) | ||
| 6972 : | @{ | ||
| 6973 : | print "$var , $assoc@{$var@} \n"; | ||
| 6974 : | @} | ||
| 6975 : | @end smallexample | ||
| 6976 : | |||
| 6977 : | @noindent | ||
| 6978 : | The order of the keys is not defined in the above example, | ||
| 6979 : | but you can choose to sort them alphabetically by writing | ||
| 6980 : | |||
| 6981 : | @smallexample | ||
| 6982 : | foreach $var ( sort keys %assoc ) | ||
| 6983 : | @end smallexample | ||
| 6984 : | |||
| 6985 : | @noindent | ||
| 6986 : | instead. | ||
| 6987 : | |||
| 6988 : | @c ..................................................... | ||
| 6989 : | @c SUBSECTION | ||
| 6990 : | @c ..................................................... | ||
| 6991 : | |||
| 6992 : | @node Iterating over lines in a file, , Iterating over elements in arrays, Loops and conditionals | ||
| 6993 : | @subsection Iterating over lines in a file | ||
| 6994 : | |||
| 6995 : | Since Perl is about file handling we are very interested in | ||
| 6996 : | reading files. Unlike C and C++, perl likes to read files | ||
| 6997 : | line by line. The angle brackets are used for this, @xref{Files in perl}. | ||
| 6998 : | Assuming that we have some file handle @samp{<file>}, for instance | ||
| 6999 : | @samp{<STDIN>}, we can always read the file line by line | ||
| 7000 : | with a while-loop like this. | ||
| 7001 : | |||
| 7002 : | @smallexample | ||
| 7003 : | |||
| 7004 : | while ($line = <file>) | ||
| 7005 : | @{ | ||
| 7006 : | print $line; | ||
| 7007 : | @} | ||
| 7008 : | |||
| 7009 : | @end smallexample | ||
| 7010 : | |||
| 7011 : | @noindent | ||
| 7012 : | Note that @code{$line} includes the end of line character on the end | ||
| 7013 : | of each line. If you want to remove it, you should add a `chop' | ||
| 7014 : | command: | ||
| 7015 : | |||
| 7016 : | @smallexample | ||
| 7017 : | |||
| 7018 : | while ($line = <file>) | ||
| 7019 : | @{ | ||
| 7020 : | chop $line; | ||
| 7021 : | print "line = ($line)\n"; | ||
| 7022 : | @} | ||
| 7023 : | |||
| 7024 : | @end smallexample | ||
| 7025 : | @cindex Iterating over files | ||
| 7026 : | @cindex Files, iterating over lines | ||
| 7027 : | |||
| 7028 : | @c ----------------------------------------------------------------------- | ||
| 7029 : | @c SECTION | ||
| 7030 : | @c ----------------------------------------------------------------------- | ||
| 7031 : | |||
| 7032 : | @node Files in perl, Perl subroutines, Loops and conditionals, Perl | ||
| 7033 : | @section Files in perl | ||
| 7034 : | |||
| 7035 : | @cindex Files in perl | ||
| 7036 : | @cindex Standard I/O in perl | ||
| 7037 : | @cindex @samp{open} command in perl | ||
| 7038 : | @cindex @samp{close} command in perl | ||
| 7039 : | Opening files is straightforward in Perl. Files must be opened | ||
| 7040 : | and closed using -- wait for it -- the commands | ||
| 7041 : | @samp{open} and @samp{close}. You should be careful to | ||
| 7042 : | close files after you have finished with them -- especially | ||
| 7043 : | if you are writing @emph{to} a file. Files are buffered | ||
| 7044 : | and often large parts of a file are not actually written | ||
| 7045 : | until the @samp{close} command is received. | ||
| 7046 : | |||
| 7047 : | Three files are, of course, always open for every program, | ||
| 7048 : | namely @samp{STDIN}, @samp{STDOUT}and @samp{STDERR}. | ||
| 7049 : | |||
| 7050 : | Formally, to open a file, we must obtain a file descriptor | ||
| 7051 : | or file handle. This is done using @samp{open}; | ||
| 7052 : | |||
| 7053 : | @cindex @samp{<>} filehandle in perl | ||
| 7054 : | @cindex File handles in perl | ||
| 7055 : | @smallexample | ||
| 7056 : | open (file_descrip,"Filename"); | ||
| 7057 : | @end smallexample | ||
| 7058 : | @noindent | ||
| 7059 : | The angular brackets @samp{<..>} are used to read from the file. | ||
| 7060 : | For example, | ||
| 7061 : | |||
| 7062 : | @smallexample | ||
| 7063 : | $line = <file_descrip>; | ||
| 7064 : | @end smallexample | ||
| 7065 : | |||
| 7066 : | @noindent | ||
| 7067 : | reads one line from the file associated with @samp{file_descrip}. | ||
| 7068 : | |||
| 7069 : | Let's look at some examples of filing opening. | ||
| 7070 : | Here is how we can implement UNIX's @samp{cut} and @samp{paste} | ||
| 7071 : | commands in perl: | ||
| 7072 : | |||
| 7073 : | @cindex Cut as a perl script | ||
| 7074 : | @smallexample | ||
| 7075 : | #!/local/bin/perl | ||
| 7076 : | # | ||
| 7077 : | # Cut in perl | ||
| 7078 : | # | ||
| 7079 : | |||
| 7080 : | |||
| 7081 : | # Cut second column | ||
| 7082 : | |||
| 7083 : | while (<>) | ||
| 7084 : | @{ | ||
| 7085 : | @@cut_array = split; | ||
| 7086 : | |||
| 7087 : | print "@@cut_array[1]\n"; | ||
| 7088 : | @} | ||
| 7089 : | |||
| 7090 : | @end smallexample | ||
| 7091 : | |||
| 7092 : | @noindent | ||
| 7093 : | This is the simplest way to open a file. The empty file | ||
| 7094 : | descriptor @samp{<>} tells perl to take the argument of the | ||
| 7095 : | command as a filename and open that file for reading. | ||
| 7096 : | This is really short for @samp{while($_=<STDIN>)} with the | ||
| 7097 : | standard input redirected to the named file. | ||
| 7098 : | |||
| 7099 : | @cindex Paste as a perl script | ||
| 7100 : | The @samp{paste}program can be written as follows: | ||
| 7101 : | |||
| 7102 : | @smallexample | ||
| 7103 : | #!/local/bin/perl | ||
| 7104 : | # | ||
| 7105 : | # Paste in perl | ||
| 7106 : | # | ||
| 7107 : | # Two files only, syntax : paste file 1file2 | ||
| 7108 : | # | ||
| 7109 : | |||
| 7110 : | open (file1,"@@ARGV[0]") || die "Can't open @@ARGV[0]\n"; | ||
| 7111 : | open (file2,"@@ARGV[1]") || die "Can't open @@ARGV[1]\n"; | ||
| 7112 : | |||
| 7113 : | while (($line1 = <file1>) || ($line2 = <file2>)) | ||
| 7114 : | @{ | ||
| 7115 : | chop $line1; | ||
| 7116 : | chop $line2; | ||
| 7117 : | |||
| 7118 : | print "$line1 $line2\n"; # tab character between | ||
| 7119 : | @} | ||
| 7120 : | |||
| 7121 : | @end smallexample | ||
| 7122 : | |||
| 7123 : | |||
| 7124 : | Here we see more formally how to read from two separate | ||
| 7125 : | files at the same time. Notice that, by putting the | ||
| 7126 : | read commands into the test-expression for the @samp{while} | ||
| 7127 : | loop, we are using the fact that @samp{<..>} returns | ||
| 7128 : | a non-zero (true) value unless we have reached the | ||
| 7129 : | end of the file. | ||
| 7130 : | |||
| 7131 : | To write and append to files, we use the shell redirection symbols | ||
| 7132 : | inside the @samp{open} command. | ||
| 7133 : | @smallexample | ||
| 7134 : | open(fd,"> filename"); # open file for writing | ||
| 7135 : | open(fd,">> filename"); # open file for appending | ||
| 7136 : | @end smallexample | ||
| 7137 : | |||
| 7138 : | @noindent | ||
| 7139 : | We can also open a pipe from an arbitrary UNIX command | ||
| 7140 : | and receive the output of that command as our input: | ||
| 7141 : | @smallexample | ||
| 7142 : | open (fd,"/bin/ps aux | "); | ||
| 7143 : | @end smallexample | ||
| 7144 : | |||
| 7145 : | @c ..................................................... | ||
| 7146 : | @c SUBSECTION | ||
| 7147 : | @c ..................................................... | ||
| 7148 : | |||
| 7149 : | @menu | ||
| 7150 : | * Simplest perl program:: | ||
| 7151 : | * == and eq:: | ||
| 7152 : | * chop:: | ||
| 7153 : | @end menu | ||
| 7154 : | |||
| 7155 : | @node Simplest perl program, == and eq, Files in perl, Files in perl | ||
| 7156 : | @subsection A simple perl program | ||
| 7157 : | |||
| 7158 : | Let us now write the simplest perl program which illustrates | ||
| 7159 : | the way in which perl can save time. We shall write it in three | ||
| 7160 : | different ways to show what the short cuts mean. Let us implement | ||
| 7161 : | the @samp{cat} command, which copies files to the standard output. | ||
| 7162 : | The simplest way to write this is perl is the following: | ||
| 7163 : | |||
| 7164 : | @smallexample | ||
| 7165 : | |||
| 7166 : | #!/local/bin/perl | ||
| 7167 : | |||
| 7168 : | while (<>) | ||
| 7169 : | @{ | ||
| 7170 : | print; | ||
| 7171 : | @} | ||
| 7172 : | |||
| 7173 : | @end smallexample | ||
| 7174 : | |||
| 7175 : | @noindent | ||
| 7176 : | Here we have made heavy use of the many default assumptions which perl | ||
| 7177 : | makes. The program is simple, but difficult to understand for | ||
| 7178 : | novices. First of all we use the default file handle @code{<>} which | ||
| 7179 : | means, take one line of input from a default file. This object returns | ||
| 7180 : | true as long as it has not reached the end of the file, so this loop | ||
| 7181 : | continues to read lines until it reaches the end of file. The default | ||
| 7182 : | file is standard input, unless this script is invoked with a command | ||
| 7183 : | line argument, in which case the argument is treated as a filename and | ||
| 7184 : | perl attempts to open the argument-filename for reading. The | ||
| 7185 : | @code{print} statement has no argument telling it what to print, but | ||
| 7186 : | perl takes this to mean: print the default variable @samp{$_}. | ||
| 7187 : | |||
| 7188 : | We can therefore write this more explicitly as follows: | ||
| 7189 : | |||
| 7190 : | @smallexample | ||
| 7191 : | |||
| 7192 : | #!/local/bin/perl | ||
| 7193 : | |||
| 7194 : | open (HANDLE,"$ARGV[1]"); | ||
| 7195 : | |||
| 7196 : | while (<HANDLE>) | ||
| 7197 : | @{ | ||
| 7198 : | print $_; | ||
| 7199 : | @} | ||
| 7200 : | @end smallexample | ||
| 7201 : | |||
| 7202 : | @noindent | ||
| 7203 : | Here we have simply filled in the assumptions explicitly. | ||
| 7204 : | The command @samp{<HANDLE>} now reads a single line from the | ||
| 7205 : | named file-handle into the default variable @samp{$_}. | ||
| 7206 : | To make this program more general, we can elimiate the defaults | ||
| 7207 : | entirely. | ||
| 7208 : | |||
| 7209 : | @smallexample | ||
| 7210 : | |||
| 7211 : | #!/local/bin/perl | ||
| 7212 : | |||
| 7213 : | open (HANDLE,"$ARGV[1]"); | ||
| 7214 : | |||
| 7215 : | while ($line=<HANDLE>) | ||
| 7216 : | @{ | ||
| 7217 : | print $line; | ||
| 7218 : | @} | ||
| 7219 : | @end smallexample | ||
| 7220 : | |||
| 7221 : | @c ..................................................... | ||
| 7222 : | @c SUBSECTION | ||
| 7223 : | @c ..................................................... | ||
| 7224 : | |||
| 7225 : | @node == and eq, chop, Simplest perl program, Files in perl | ||
| 7226 : | @subsection == and @samp{eq} | ||
| 7227 : | |||
| 7228 : | Be careful to distinguish between the comparison operator for integers | ||
| 7229 : | @samp{==} and the corresponding operator for strings @samp{eq}. These | ||
| 7230 : | do not work in each other's places so if you get the wrong comparison | ||
| 7231 : | operator your program might not work and it is quite difficult to | ||
| 7232 : | find the error. | ||
| 7233 : | |||
| 7234 : | @c ..................................................... | ||
| 7235 : | @c SUBSECTION | ||
| 7236 : | @c ..................................................... | ||
| 7237 : | |||
| 7238 : | @node chop, , == and eq, Files in perl | ||
| 7239 : | @subsection chop | ||
| 7240 : | |||
| 7241 : | @cindex Truncating strings in perl | ||
| 7242 : | @cindex Perl, truncating strings | ||
| 7243 : | @cindex @samp{chop} command in perl | ||
| 7244 : | |||
| 7245 : | The command @samp{chop} cuts off the last character of a string. | ||
| 7246 : | This is useful for removing newline characters when reading | ||
| 7247 : | files etc. The syntax is | ||
| 7248 : | @smallexample | ||
| 7249 : | chop; # chop $_; | ||
| 7250 : | |||
| 7251 : | chop $scalar; # remove last character in $scalar | ||
| 7252 : | @end smallexample | ||
| 7253 : | |||
| 7254 : | |||
| 7255 : | |||
| 7256 : | |||
| 7257 : | @c ----------------------------------------------------------------------- | ||
| 7258 : | @c SECTION | ||
| 7259 : | @c ----------------------------------------------------------------------- | ||
| 7260 : | |||
| 7261 : | @node Perl subroutines, die, Files in perl, Perl | ||
| 7262 : | @section Perl subroutines | ||
| 7263 : | |||
| 7264 : | @cindex Subroutines in perl | ||
| 7265 : | |||
| 7266 : | Subroutines are indicated, as in the example above, by the ampersand | ||
| 7267 : | @samp{&} symbol. When parameters are passed to a Perl subroutine, they | ||
| 7268 : | are handed over as an array called @samp{@@_}. Which is analogous | ||
| 7269 : | to the @samp{$_} variable. Here is a simple example: | ||
| 7270 : | |||
| 7271 : | @smallexample | ||
| 7272 : | #!/local/bin/perl | ||
| 7273 : | |||
| 7274 : | $a="silver"; | ||
| 7275 : | $b="gold"; | ||
| 7276 : | |||
| 7277 : | &PrintArgs($a,$b); | ||
| 7278 : | |||
| 7279 : | # end of main | ||
| 7280 : | |||
| 7281 : | sub PrintArgs | ||
| 7282 : | |||
| 7283 : | @{ | ||
| 7284 : | ($local_a,$local_b) = @@_; | ||
| 7285 : | |||
| 7286 : | print "$local_a, $local_b\n"; | ||
| 7287 : | @} | ||
| 7288 : | |||
| 7289 : | @end smallexample | ||
| 7290 : | @cindex Local variables in perl | ||
| 7291 : | @cindex Parameters in perl functions | ||
| 7292 : | |||
| 7293 : | |||
| 7294 : | |||
| 7295 : | @c ----------------------------------------------------------------------- | ||
| 7296 : | @c SECTION | ||
| 7297 : | @c ----------------------------------------------------------------------- | ||
| 7298 : | |||
| 7299 : | @node die, stat(), Perl subroutines, Perl | ||
| 7300 : | @section die - exit on error | ||
| 7301 : | |||
| 7302 : | @cindex Exiting on errors in perl | ||
| 7303 : | @cindex @samp{die} | ||
| 7304 : | @cindex Errors in perl | ||
| 7305 : | When a program has to quit and give a message, the @samp{die} | ||
| 7306 : | command is normally used. If called without an argument, | ||
| 7307 : | Perl generates its own message including a line number at which | ||
| 7308 : | the error occurred. To include your own message, | ||
| 7309 : | you write | ||
| 7310 : | |||
| 7311 : | @smallexample | ||
| 7312 : | die "My message...."; | ||
| 7313 : | @end smallexample | ||
| 7314 : | |||
| 7315 : | @noindent | ||
| 7316 : | If the string is terminated with a @samp{\n} newline character, | ||
| 7317 : | the line number of the error is not printed, otherwise Perl | ||
| 7318 : | appends the line number to your string. | ||
| 7319 : | |||
| 7320 : | When opening files, it is common to see the syntax: | ||
| 7321 : | @smallexample | ||
| 7322 : | open (filehandle,"Filename") || die "Can't open..."; | ||
| 7323 : | @end smallexample | ||
| 7324 : | |||
| 7325 : | @noindent | ||
| 7326 : | The logical @samp{OR} symbol is used, because @samp{open} | ||
| 7327 : | returns true if all goes well, in which case the right | ||
| 7328 : | hand side is never evaluated. If @samp{open} is false, | ||
| 7329 : | then die is executed. You can decide for yourself whether | ||
| 7330 : | or not you think this is good programming style -- we mention | ||
| 7331 : | it here because it is common practice. | ||
| 7332 : | |||
| 7333 : | @c ----------------------------------------------------------------------- | ||
| 7334 : | @c SECTION | ||
| 7335 : | @c ----------------------------------------------------------------------- | ||
| 7336 : | |||
| 7337 : | @node stat(), Perl examples, die, Perl | ||
| 7338 : | @section The @code{stat()} idiom | ||
| 7339 : | |||
| 7340 : | The unix library function @code{stat()} is used to find out information | ||
| 7341 : | about a given file. This function is available both in C and in Perl. | ||
| 7342 : | In perl, it returns an array of values. Usually we are interested in | ||
| 7343 : | knowing the access permissions of a file. @code{stat()} is called | ||
| 7344 : | using the syntax | ||
| 7345 : | |||
| 7346 : | @smallexample | ||
| 7347 : | |||
| 7348 : | @@array = stat ("@var{filename}"); | ||
| 7349 : | |||
| 7350 : | @end smallexample | ||
| 7351 : | |||
| 7352 : | @noindent | ||
| 7353 : | or alternatively, using a named array | ||
| 7354 : | |||
| 7355 : | @smallexample | ||
| 7356 : | |||
| 7357 : | ($device,$inode,$mode) = stat("@var{filename}"); | ||
| 7358 : | |||
| 7359 : | @end smallexample | ||
| 7360 : | |||
| 7361 : | The value returned in the @var{mode} variable is a bit-pattern, | ||
| 7362 : | @xref{Protection bits}. The most useful way of treating these | ||
| 7363 : | bit patterns is to use octal numbers to interpret their meaning. | ||
| 7364 : | |||
| 7365 : | To find out whether a file is readable or writable to a group of | ||
| 7366 : | users, we use a programming idiom which is very common for dealing | ||
| 7367 : | with bit patterns: first we define a mask which zeroes out all | ||
| 7368 : | of the bits in the mode string except those which we are | ||
| 7369 : | specifically interested in. This is done by defining a mask | ||
| 7370 : | value in which the bits we want are set to 1 and all others are | ||
| 7371 : | set to zero. Then we AND the mask with the mode string. If the | ||
| 7372 : | result is different from zero then we know that all of the | ||
| 7373 : | bits were also set in the mode string. | ||
| 7374 : | As in C, the bitwise AND operator in perl is called @samp{&}. | ||
| 7375 : | |||
| 7376 : | For example, to test whether a file is writable to other users | ||
| 7377 : | in the same group as the file, we would write the following. | ||
| 7378 : | |||
| 7379 : | @smallexample | ||
| 7380 : | |||
| 7381 : | $mask = 020; # Leading 0 means octal number | ||
| 7382 : | |||
| 7383 : | ($device,$inode,$mode) = stat("@var{file}"); | ||
| 7384 : | |||
| 7385 : | if ($mode & $mask) | ||
| 7386 : | @{ | ||
| 7387 : | print "File is writable by the group\n"; | ||
| 7388 : | @} | ||
| 7389 : | |||
| 7390 : | @end smallexample | ||
| 7391 : | |||
| 7392 : | @noindent | ||
| 7393 : | Here the 2 in the second octal number means "write", the fact that | ||
| 7394 : | it is the second octal number from the right means that it refers | ||
| 7395 : | to "group". Thus the result of the if-test is only true if that | ||
| 7396 : | particular bit is true. We shall see this idiom in action below. | ||
| 7397 : | |||
| 7398 : | @c ----------------------------------------------------------------------- | ||
| 7399 : | @c SECTION | ||
| 7400 : | @c ----------------------------------------------------------------------- | ||
| 7401 : | |||
| 7402 : | @node Perl examples, Pattern matching, stat(), Perl | ||
| 7403 : | @section Perl example programs | ||
| 7404 : | |||
| 7405 : | @c ..................................................... | ||
| 7406 : | @c SUBSECTION | ||
| 7407 : | @c ..................................................... | ||
| 7408 : | |||
| 7409 : | @menu | ||
| 7410 : | * Passwd example program:: | ||
| 7411 : | * Fork example:: | ||
| 7412 : | * Database example:: | ||
| 7413 : | @end menu | ||
| 7414 : | |||
| 7415 : | @node Passwd example program, Fork example, Perl examples, Perl examples | ||
| 7416 : | @subsection The passwd program and @samp{crypt()} function | ||
| 7417 : | |||
| 7418 : | Here is a simple implementation of the UNIX @samp{passwd} | ||
| 7419 : | program in Perl. | ||
| 7420 : | @cindex @file{passwd} file | ||
| 7421 : | @cindex Encryption | ||
| 7422 : | @cindex @samp{stty} and switching off term echo | ||
| 7423 : | @cindex Terminal echo and @samp{stty} | ||
| 7424 : | @vindex @code{crypt()} | ||
| 7425 : | |||
| 7426 : | @smallexample | ||
| 7427 : | #!/local/bin/perl | ||
| 7428 : | # | ||
| 7429 : | # A perl version of the passwd program. | ||
| 7430 : | # | ||
| 7431 : | # Note - the real passwd program needs to be much more | ||
| 7432 : | # secure than this one. This is just to demonstrate the | ||
| 7433 : | # use of the crypt() function. | ||
| 7434 : | # | ||
| 7435 : | ############################################################# | ||
| 7436 : | |||
| 7437 : | print "Changing passwd for $ENV@{'USER'@} on $ENV@{'HOST'@}\n"; | ||
| 7438 : | |||
| 7439 : | |||
| 7440 : | system 'stty','-echo'; | ||
| 7441 : | print "Old passwd: "; | ||
| 7442 : | |||
| 7443 : | $oldpwd = <STDIN>; | ||
| 7444 : | chop $oldpwd; | ||
| 7445 : | |||
| 7446 : | ($name,$coded_pwd,$uid,$gid,$x,$y,$z,$gcos,$home,$shell) | ||
| 7447 : | = getpwnam($ENV@{"USER"@}); | ||
| 7448 : | |||
| 7449 : | if (crypt($oldpwd,$coded_pwd) ne $coded_pwd) | ||
| 7450 : | @{ | ||
| 7451 : | print "\nPasswd incorrect\n"; | ||
| 7452 : | exit (1); | ||
| 7453 : | @} | ||
| 7454 : | |||
| 7455 : | $oldpwd = ""; # Destroy the evidence! | ||
| 7456 : | |||
| 7457 : | print "\nNew passwd: "; | ||
| 7458 : | |||
| 7459 : | $newpwd = <STDIN>; | ||
| 7460 : | |||
| 7461 : | print "\nRepeat new passwd: "; | ||
| 7462 : | |||
| 7463 : | $rnewpwd = <STDIN>; | ||
| 7464 : | |||
| 7465 : | chop $newpwd; | ||
| 7466 : | chop $rnewpwd; | ||
| 7467 : | |||
| 7468 : | if ($newpwd ne $rnewpwd) | ||
| 7469 : | @{ | ||
| 7470 : | print "\n Incorrectly typed. Password unchanged.\n"; | ||
| 7471 : | exit (1); | ||
| 7472 : | @} | ||
| 7473 : | |||
| 7474 : | @vindex @code{rand()} | ||
| 7475 : | $salt = rand(); | ||
| 7476 : | $new_coded_pwd = crypt($newpwd,$salt); | ||
| 7477 : | |||
| 7478 : | print "\n\n$name:$new_coded_pwd:$uid:$gid:$gcos:$home:$shell\n"; | ||
| 7479 : | |||
| 7480 : | |||
| 7481 : | @end smallexample | ||
| 7482 : | |||
| 7483 : | @c ..................................................... | ||
| 7484 : | @c SUBSECTION | ||
| 7485 : | @c ..................................................... | ||
| 7486 : | |||
| 7487 : | @node Fork example, Database example, Passwd example program, Perl examples | ||
| 7488 : | @subsection Example with @samp{fork()} | ||
| 7489 : | |||
| 7490 : | The following example uses the @samp{fork} function to | ||
| 7491 : | start a daemon which goes into the background and watches the | ||
| 7492 : | system to which process is using the greatest amount of | ||
| 7493 : | CPU time each minute. A pipe is opened from the BSD @samp{ps} | ||
| 7494 : | command. | ||
| 7495 : | @vindex @code{fork()} | ||
| 7496 : | @cindex Forking new processes | ||
| 7497 : | |||
| 7498 : | @smallexample | ||
| 7499 : | #!/local/bin/perl | ||
| 7500 : | # | ||
| 7501 : | # A fork() demo. This program will sit in the background and | ||
| 7502 : | # make a list of the process which uses the maximum CPU average | ||
| 7503 : | # at 1 minute intervals. On a quiet BSD like system this will | ||
| 7504 : | # normally be the swapper (long term scheduler). | ||
| 7505 : | # | ||
| 7506 : | |||
| 7507 : | $true = 1; | ||
| 7508 : | $logfile="perl.cpu.logfile"; | ||
| 7509 : | |||
| 7510 : | print "Max CPU logfile, forking daemon...\n"; | ||
| 7511 : | |||
| 7512 : | if (fork()) | ||
| 7513 : | @{ | ||
| 7514 : | exit(0); | ||
| 7515 : | @} | ||
| 7516 : | |||
| 7517 : | while ($true) | ||
| 7518 : | @{ | ||
| 7519 : | open (logfile,">> $logfile") || die "Can't open $logfile\n"; | ||
| 7520 : | open (ps,"/bin/ps aux |") || die "Couldn't open a pipe from ps !!\n"; | ||
| 7521 : | |||
| 7522 : | $skip_first_line = <ps>; | ||
| 7523 : | $max_process = <ps>; | ||
| 7524 : | close(ps); | ||
| 7525 : | |||
| 7526 : | print logfile $max_process; | ||
| 7527 : | close(logfile); | ||
| 7528 : | sleep 60; | ||
| 7529 : | |||
| 7530 : | ($a,$b,$c,$d,$e,$f,$g,$size) = stat($logfile); | ||
| 7531 : | |||
| 7532 : | if ($size > 500) | ||
| 7533 : | @{ | ||
| 7534 : | print STDERR "Log file getting big, better quit!\n"; | ||
| 7535 : | exit(0); | ||
| 7536 : | @} | ||
| 7537 : | @} | ||
| 7538 : | |||
| 7539 : | |||
| 7540 : | @end smallexample | ||
| 7541 : | |||
| 7542 : | @c ..................................................... | ||
| 7543 : | @c SUBSECTION | ||
| 7544 : | @c ..................................................... | ||
| 7545 : | |||
| 7546 : | @node Database example, , Fork example, Perl examples | ||
| 7547 : | @subsection Example reading databases | ||
| 7548 : | |||
| 7549 : | @cindex Database support | ||
| 7550 : | @cindex User database support | ||
| 7551 : | |||
| 7552 : | Here is an example program with several of the above features | ||
| 7553 : | demonstrated simultaneously. This following program lists | ||
| 7554 : | all users who have home directories on the current host. | ||
| 7555 : | If the home area has sub-directories, corresponding to | ||
| 7556 : | groups, then this is specified on the command line. The | ||
| 7557 : | word `home' causes the program to print out the home | ||
| 7558 : | directories of the users. | ||
| 7559 : | |||
| 7560 : | @smallexample | ||
| 7561 : | #!/local/bin/perl | ||
| 7562 : | ################################################################## | ||
| 7563 : | # | ||
| 7564 : | # allusers - list all users on named host, i.e. all | ||
| 7565 : | # users who can log into this machine. | ||
| 7566 : | # | ||
| 7567 : | # Syntax: allusers group | ||
| 7568 : | # allusers mygroup home | ||
| 7569 : | # allusers myhost group home | ||
| 7570 : | # | ||
| 7571 : | # NOTE : This command returns only users who are registered on | ||
| 7572 : | # the current host. It will not find users which cannot | ||
| 7573 : | # be validated in the passwd file, or in the named groups | ||
| 7574 : | # in NIS. It assumes that the users belonging to | ||
| 7575 : | # different groups are saved in subdirectories of | ||
| 7576 : | # /home/hostname. | ||
| 7577 : | # | ||
| 7578 : | ################################################################## | ||
| 7579 : | |||
| 7580 : | &arguments(); | ||
| 7581 : | |||
| 7582 : | die "\n" if ( ! -d "/home/$server" ); | ||
| 7583 : | |||
| 7584 : | $disks = `/bin/ls -d /home/$server/$group`; | ||
| 7585 : | |||
| 7586 : | foreach $home (split(/\s/,$disks)) | ||
| 7587 : | @{ | ||
| 7588 : | open (LS,"cd $home; /bin/ls $home |") || die "allusers: Pipe didn't open"; | ||
| 7589 : | |||
| 7590 : | while (<LS>) | ||
| 7591 : | @{ | ||
| 7592 : | $exists = ""; | ||
| 7593 : | ($user) = split; | ||
| 7594 : | ($exists,$pw,$uid,$gid,$qu,$cm,$gcos,$dir)=getpwnam($user); | ||
| 7595 : | |||
| 7596 : | if ($exists) | ||
| 7597 : | @{ | ||
| 7598 : | if ($printhomes) | ||
| 7599 : | @{ | ||
| 7600 : | print "$dir\n"; | ||
| 7601 : | @} | ||
| 7602 : | else | ||
| 7603 : | @{ | ||
| 7604 : | print "$user\n"; | ||
| 7605 : | @} | ||
| 7606 : | @} | ||
| 7607 : | @} | ||
| 7608 : | close(LS); | ||
| 7609 : | @} | ||
| 7610 : | |||
| 7611 : | ######################################################## | ||
| 7612 : | |||
| 7613 : | sub arguments | ||
| 7614 : | @{ | ||
| 7615 : | $printhomes = 0; | ||
| 7616 : | $group = "*"; | ||
| 7617 : | $server = `/bin/hostname`; | ||
| 7618 : | chop $server; | ||
| 7619 : | |||
| 7620 : | foreach $arg (@@ARGV) | ||
| 7621 : | @{ | ||
| 7622 : | if (substr($arg,0,1) eq "u") | ||
| 7623 : | @{ | ||
| 7624 : | $group = $arg; | ||
| 7625 : | next; | ||
| 7626 : | @} | ||
| 7627 : | |||
| 7628 : | if ($arg eq "home") | ||
| 7629 : | @{ | ||
| 7630 : | $printhomes = 1; | ||
| 7631 : | next; | ||
| 7632 : | @} | ||
| 7633 : | |||
| 7634 : | $server= $arg; #default is to interpret as a server. | ||
| 7635 : | @} | ||
| 7636 : | @} | ||
| 7637 : | |||
| 7638 : | @end smallexample | ||
| 7639 : | |||
| 7640 : | |||
| 7641 : | @c ----------------------------------------------------------------------- | ||
| 7642 : | @c SECTION | ||
| 7643 : | @c ----------------------------------------------------------------------- | ||
| 7644 : | |||
| 7645 : | @node Pattern matching, search and replace, Perl examples, Perl | ||
| 7646 : | @section Pattern matching and extraction | ||
| 7647 : | |||
| 7648 : | Perl has regular expression operators for identifying patterns. The | ||
| 7649 : | operator | ||
| 7650 : | @smallexample | ||
| 7651 : | |||
| 7652 : | /@var{regular expression}/ | ||
| 7653 : | |||
| 7654 : | @end smallexample | ||
| 7655 : | @noindent | ||
| 7656 : | returns true of false depending on whether the regular expression matches the | ||
| 7657 : | contents of @code{$_}. For example | ||
| 7658 : | |||
| 7659 : | @smallexample | ||
| 7660 : | |||
| 7661 : | if (/perl/) | ||
| 7662 : | @{ | ||
| 7663 : | print "String contains perl as a substring"; | ||
| 7664 : | @} | ||
| 7665 : | |||
| 7666 : | if (/(Sat|Sun)day/) | ||
| 7667 : | @{ | ||
| 7668 : | print "Weekend day...."; | ||
| 7669 : | @} | ||
| 7670 : | @end smallexample | ||
| 7671 : | The effect is rather like the @code{grep} command. | ||
| 7672 : | To use this operator on other variables you would write: | ||
| 7673 : | @smallexample | ||
| 7674 : | |||
| 7675 : | $variable =~ /@var{regexp}/ | ||
| 7676 : | |||
| 7677 : | @end smallexample | ||
| 7678 : | Regular expression can contain parenthetic sub-expressions, e.g. | ||
| 7679 : | @smallexample | ||
| 7680 : | |||
| 7681 : | if (/(Sat|Sun)day (..)th (.*)/) | ||
| 7682 : | @{ | ||
| 7683 : | $first = $1; | ||
| 7684 : | $second = $2; | ||
| 7685 : | $third = $3; | ||
| 7686 : | @} | ||
| 7687 : | @end smallexample | ||
| 7688 : | @noindent | ||
| 7689 : | in which case perl places the objects matched by such sub-expressions | ||
| 7690 : | in the variables @code{$1}, @code{$2} etc. | ||
| 7691 : | |||
| 7692 : | @c ----------------------------------------------------------------------- | ||
| 7693 : | @c SECTION | ||
| 7694 : | @c ----------------------------------------------------------------------- | ||
| 7695 : | |||
| 7696 : | @node search and replace, WWW example, Pattern matching, Perl | ||
| 7697 : | @section Searching and replacing text | ||
| 7698 : | |||
| 7699 : | @cindex @samp{sed} as a perl script | ||
| 7700 : | @cindex Pattern matching in perl | ||
| 7701 : | @cindex Pattern replacement in perl | ||
| 7702 : | @noindent | ||
| 7703 : | The @samp{sed}-like function for replacing all occurances of a string | ||
| 7704 : | is easily implemented in Perl using | ||
| 7705 : | |||
| 7706 : | @smallexample | ||
| 7707 : | while (<input>) | ||
| 7708 : | @{ | ||
| 7709 : | s/$search/$replace/g; | ||
| 7710 : | print output; | ||
| 7711 : | @} | ||
| 7712 : | @end smallexample | ||
| 7713 : | |||
| 7714 : | @noindent | ||
| 7715 : | This example replaces the string inside the default variable. To replace | ||
| 7716 : | in a general variable we use the operator @samp{=~}, with syntax: | ||
| 7717 : | |||
| 7718 : | @smallexample | ||
| 7719 : | $variable =~ s/@var{search}/@var{replace}/ | ||
| 7720 : | @end smallexample | ||
| 7721 : | |||
| 7722 : | Here is an example of some of this operator in use. The following is a | ||
| 7723 : | program which searches and replaces a string in several files. This is | ||
| 7724 : | useful program indeed for making a change globally in a group of files! | ||
| 7725 : | The program is called `file-replace'. | ||
| 7726 : | |||
| 7727 : | @smallexample | ||
| 7728 : | #!/local/bin/perl | ||
| 7729 : | ############################################################## | ||
| 7730 : | # | ||
| 7731 : | # Look through files for findstring and change to newstring | ||
| 7732 : | # in all files. | ||
| 7733 : | # | ||
| 7734 : | ############################################################## | ||
| 7735 : | |||
| 7736 : | # | ||
| 7737 : | # Define a temporary file and check it doesn't exist | ||
| 7738 : | # | ||
| 7739 : | |||
| 7740 : | $outputfile = "tmpmarkfind"; | ||
| 7741 : | unlink $outputfile; | ||
| 7742 : | |||
| 7743 : | # | ||
| 7744 : | # Check command line for list of files | ||
| 7745 : | # | ||
| 7746 : | |||
| 7747 : | if ($#ARGV < 0) | ||
| 7748 : | @{ | ||
| 7749 : | die "Syntax: file-replace [file list]\n"; | ||
| 7750 : | @} | ||
| 7751 : | |||
| 7752 : | print "Enter the string you want to find (Don't use quotes):\n\n:"; | ||
| 7753 : | $findstring=<STDIN>; | ||
| 7754 : | chop $findstring; | ||
| 7755 : | |||
| 7756 : | print "Enter the string you want to replace with (Don't use quotes):\n\n:"; | ||
| 7757 : | $replacestring=<STDIN>; | ||
| 7758 : | chop $replacestring; | ||
| 7759 : | |||
| 7760 : | # | ||
| 7761 : | |||
| 7762 : | print "\nFind: $findstring\n"; | ||
| 7763 : | print "Replace: $replacestring\n"; | ||
| 7764 : | print "\nConfirm (y/n) "; | ||
| 7765 : | $y = <STDIN>; | ||
| 7766 : | chop $y; | ||
| 7767 : | |||
| 7768 : | if ( $y ne "y") | ||
| 7769 : | @{ | ||
| 7770 : | die "Aborted -- nothing done.\n"; | ||
| 7771 : | @} | ||
| 7772 : | else | ||
| 7773 : | @{ | ||
| 7774 : | print "Use CTRL-C to interrupt...\n"; | ||
| 7775 : | @} | ||
| 7776 : | |||
| 7777 : | # | ||
| 7778 : | # Now shift default array @@ARGV to get arguments 1 by 1 | ||
| 7779 : | # | ||
| 7780 : | |||
| 7781 : | while ($file = shift) | ||
| 7782 : | @{ | ||
| 7783 : | if ($file eq "file-replace") | ||
| 7784 : | @{ | ||
| 7785 : | print "Findmark will not operate on itself!"; | ||
| 7786 : | next; | ||
| 7787 : | @} | ||
| 7788 : | |||
| 7789 : | # | ||
| 7790 : | # Save existing mode of file for later | ||
| 7791 : | # | ||
| 7792 : | |||
| 7793 : | ($dev,$ino,$mode)=stat($file); | ||
| 7794 : | |||
| 7795 : | open (INPUT,$file) || warn "Couldn't open $file\n"; | ||
| 7796 : | open (OUTPUT,"> $outputfile") || warn "Can't open tmp"; | ||
| 7797 : | |||
| 7798 : | $notify = 1; | ||
| 7799 : | |||
| 7800 : | while (<INPUT>) | ||
| 7801 : | @{ | ||
| 7802 : | if (/$findstring/ && $notify) | ||
| 7803 : | @{ | ||
| 7804 : | print "Fixing $file...\n"; | ||
| 7805 : | $notify = 0; | ||
| 7806 : | @} | ||
| 7807 : | s/$findstring/$replacestring/g; | ||
| 7808 : | @cindex Searching and replacing in perl (example) | ||
| 7809 : | print OUTPUT; | ||
| 7810 : | @} | ||
| 7811 : | |||
| 7812 : | close (OUTPUT); | ||
| 7813 : | |||
| 7814 : | # | ||
| 7815 : | # If nothing went wrong (if outfile not empty) | ||
| 7816 : | # move temp file to original and reset the | ||
| 7817 : | # file mode saved above | ||
| 7818 : | # | ||
| 7819 : | |||
| 7820 : | @vindex -z in perl | ||
| 7821 : | if (! -z $outputfile) | ||
| 7822 : | @{ | ||
| 7823 : | rename ($outputfile,$file); | ||
| 7824 : | @vindex @samp{rename} in perl | ||
| 7825 : | chmod ($mode,$file); | ||
| 7826 : | @} | ||
| 7827 : | else | ||
| 7828 : | @{ | ||
| 7829 : | print "Warning: file empty!\n."; | ||
| 7830 : | @} | ||
| 7831 : | @} | ||
| 7832 : | @end smallexample | ||
| 7833 : | |||
| 7834 : | @noindent | ||
| 7835 : | Similarly we can search for lines containing a string. Here is | ||
| 7836 : | the grep program written in perl | ||
| 7837 : | |||
| 7838 : | @smallexample | ||
| 7839 : | #!/local/bin/perl | ||
| 7840 : | # | ||
| 7841 : | # grep as a perl program | ||
| 7842 : | # | ||
| 7843 : | |||
| 7844 : | # Check arguments etc | ||
| 7845 : | |||
| 7846 : | while (<>) | ||
| 7847 : | @{ | ||
| 7848 : | print if (/$ARGV[1]/); | ||
| 7849 : | @} | ||
| 7850 : | |||
| 7851 : | @end smallexample | ||
| 7852 : | @noindent | ||
| 7853 : | The operator @samp{/@var{search-string}/} returns true if the search | ||
| 7854 : | string is a substring of the default variable @code{$_}. To search | ||
| 7855 : | an arbitrary string, we write | ||
| 7856 : | @smallexample | ||
| 7857 : | .... if (@var{teststring} =~ /@var{search-string}/); | ||
| 7858 : | @end smallexample | ||
| 7859 : | |||
| 7860 : | @noindent | ||
| 7861 : | Here @var{teststring} is searched for occurrances of @var{search-string} | ||
| 7862 : | and the result is true if one is found. | ||
| 7863 : | @cindex Pattern matching in perl | ||
| 7864 : | |||
| 7865 : | In perl you can use regular expressions to search for text patterns. | ||
| 7866 : | Note however that, like all regular expression dialects, perl has | ||
| 7867 : | its own conventions. For example the dollar sign does not mean | ||
| 7868 : | "match the end of line" in perl, instead one uses the @samp{\n} symbol. | ||
| 7869 : | Here is an example program which illustrates the use of regular expressions | ||
| 7870 : | in perl: | ||
| 7871 : | |||
| 7872 : | @smallexample | ||
| 7873 : | #!/local/bin/perl | ||
| 7874 : | # | ||
| 7875 : | # Test regular expressions in perl | ||
| 7876 : | # | ||
| 7877 : | # NB - careful with \ $ * symbols etc. Use '' quotes since | ||
| 7878 : | # the shell interprets these! | ||
| 7879 : | # | ||
| 7880 : | |||
| 7881 : | open (FILE,"regex_test"); | ||
| 7882 : | |||
| 7883 : | $regex = $ARGV[$#ARGV]; | ||
| 7884 : | |||
| 7885 : | print "Looking for $ARGV[$#ARGV] in file...\n"; | ||
| 7886 : | |||
| 7887 : | while (<FILE>) | ||
| 7888 : | @{ | ||
| 7889 : | if (/$regex/) | ||
| 7890 : | @{ | ||
| 7891 : | print; | ||
| 7892 : | @} | ||
| 7893 : | @} | ||
| 7894 : | |||
| 7895 : | |||
| 7896 : | # | ||
| 7897 : | # Test like this: | ||
| 7898 : | # | ||
| 7899 : | # regex '.*' - prints every line (matches everything) | ||
| 7900 : | # regex '.' - all lines except those containing only blanks | ||
| 7901 : | # (. doesn't match ws/white-space) | ||
| 7902 : | # regex '[a-z]' - matches any line containing lowercase | ||
| 7903 : | # regex '[^a-z]' - matches any line containg something which is | ||
| 7904 : | # not lowercase a-z | ||
| 7905 : | # regex '[A-Za-z]' - matches any line containing letters of any kind | ||
| 7906 : | # regex '[0-9]' - match any line containing numbers | ||
| 7907 : | # regex '#.*' - line containing a hash symbol followed by anything | ||
| 7908 : | # regex '^#.*' - line starting with hash symbol (first char) | ||
| 7909 : | # regex ';\n' - match line ending in a semi-colon | ||
| 7910 : | # | ||
| 7911 : | |||
| 7912 : | @end smallexample | ||
| 7913 : | |||
| 7914 : | @noindent | ||
| 7915 : | Try running this program with the test data on the following file | ||
| 7916 : | which is called @file{regex_test} in the example program. | ||
| 7917 : | |||
| 7918 : | @smallexample | ||
| 7919 : | |||
| 7920 : | |||
| 7921 : | # A line beginning with a hash symbol | ||
| 7922 : | |||
| 7923 : | JUST UPPERCASE LETTERS | ||
| 7924 : | |||
| 7925 : | just lowercase letters | ||
| 7926 : | |||
| 7927 : | Letters and numbers 123456 | ||
| 7928 : | |||
| 7929 : | 123456 | ||
| 7930 : | |||
| 7931 : | A line ending with a semi-colon; | ||
| 7932 : | |||
| 7933 : | Line with a comment # COMMENT... | ||
| 7934 : | |||
| 7935 : | @end smallexample | ||
| 7936 : | |||
| 7937 : | |||
| 7938 : | @c ----------------------------------------------------------------------- | ||
| 7939 : | @c SECTION | ||
| 7940 : | @c ----------------------------------------------------------------------- | ||
| 7941 : | |||
| 7942 : | @node WWW example, WWW example 2, search and replace, Perl | ||
| 7943 : | @section Example: convert mail to WWW pages | ||
| 7944 : | |||
| 7945 : | Here is an example program which you could use to automatically | ||
| 7946 : | turn a mail message of the form | ||
| 7947 : | |||
| 7948 : | @smallexample | ||
| 7949 : | From: Newswire | ||
| 7950 : | To: Mail2html | ||
| 7951 : | Subject: Nothing happened | ||
| 7952 : | |||
| 7953 : | On the 13th February at kl. 09:30 nothing happened. No footprints | ||
| 7954 : | were found leading to the scene of a terrible murder, no evidence | ||
| 7955 : | of a struggle .... etc etc | ||
| 7956 : | |||
| 7957 : | @end smallexample | ||
| 7958 : | |||
| 7959 : | @noindent | ||
| 7960 : | into an html-file for the world wide web. The program works | ||
| 7961 : | by extracting the message body and subject from the mail | ||
| 7962 : | and writing html-commands around these to make a web page. | ||
| 7963 : | The subject field of the mail becomes the title. The other headers | ||
| 7964 : | get skipped, since the script searches for lines containing the | ||
| 7965 : | sequence "colon-space" or @samp{: }. A regular expression | ||
| 7966 : | is used for this. | ||
| 7967 : | |||
| 7968 : | @smallexample | ||
| 7969 : | #!/local/bin/perl | ||
| 7970 : | # | ||
| 7971 : | # Make HTML from mail | ||
| 7972 : | # | ||
| 7973 : | |||
| 7974 : | &BeginWebPage(); | ||
| 7975 : | &ReadNewMail(); | ||
| 7976 : | &EndWebPage(); | ||
| 7977 : | |||
| 7978 : | |||
| 7979 : | ########################################################## | ||
| 7980 : | |||
| 7981 : | sub BeginWebPage | ||
| 7982 : | |||
| 7983 : | @{ | ||
| 7984 : | print "<HTML>\n"; | ||
| 7985 : | print "<BODY>\n"; | ||
| 7986 : | @} | ||
| 7987 : | |||
| 7988 : | ########################################################## | ||
| 7989 : | |||
| 7990 : | sub EndWebPage | ||
| 7991 : | |||
| 7992 : | @{ | ||
| 7993 : | print "</BODY>\n"; | ||
| 7994 : | print "</HTML>\n"; | ||
| 7995 : | @} | ||
| 7996 : | |||
| 7997 : | ########################################################## | ||
| 7998 : | |||
| 7999 : | sub ReadNewMail | ||
| 8000 : | |||
| 8001 : | @{ | ||
| 8002 : | while (<>) | ||
| 8003 : | @{ | ||
| 8004 : | if (/Subject:/) # Search for subject line | ||
| 8005 : | @{ | ||
| 8006 : | # Extract subject text... | ||
| 8007 : | |||
| 8008 : | chop; | ||
| 8009 : | ($left,$right) = split(":",$_); | ||
| 8010 : | print "<H1> $right </H1>\n"; | ||
| 8011 : | next; | ||
| 8012 : | @} | ||
| 8013 : | elsif (/.*: .*/) # Search for - anything: anything | ||
| 8014 : | @{ | ||
| 8015 : | next; # skip other headers | ||
| 8016 : | @} | ||
| 8017 : | |||
| 8018 : | print; | ||
| 8019 : | @} | ||
| 8020 : | @} | ||
| 8021 : | |||
| 8022 : | @end smallexample | ||
| 8023 : | |||
| 8024 : | @c ----------------------------------------------------------------------- | ||
| 8025 : | @c SECTION | ||
| 8026 : | @c ----------------------------------------------------------------------- | ||
| 8027 : | |||
| 8028 : | @node WWW example 2, Other functions, WWW example, Perl | ||
| 8029 : | @section Generate WWW pages automagically | ||
| 8030 : | |||
| 8031 : | The following program scans through the password database and | ||
| 8032 : | build a standardized html-page for each user it finds there. It | ||
| 8033 : | fills in the name of the user in each case. Note the use of | ||
| 8034 : | the @samp{<<} operator for extended input, already used in the | ||
| 8035 : | context of the shell, @xref{Pipes and redirection}. This allows | ||
| 8036 : | us to format a whole passage of text, inserting variables at | ||
| 8037 : | strategic places, and avoid having to the @code{print} over | ||
| 8038 : | many lines. | ||
| 8039 : | |||
| 8040 : | @smallexample | ||
| 8041 : | |||
| 8042 : | #!/local/bin/perl | ||
| 8043 : | # | ||
| 8044 : | # Build a default home page for each user in /etc/passwd | ||
| 8045 : | # | ||
| 8046 : | # | ||
| 8047 : | |||
| 8048 : | #################################################################### | ||
| 8049 : | # Level 0 (main) | ||
| 8050 : | #################################################################### | ||
| 8051 : | |||
| 8052 : | $true = 1; | ||
| 8053 : | $false = 0; | ||
| 8054 : | |||
| 8055 : | # First build an associated array of users and full names | ||
| 8056 : | |||
| 8057 : | setpwent(); | ||
| 8058 : | |||
| 8059 : | while ($true) | ||
| 8060 : | @{ | ||
| 8061 : | ($name,$passwd,$uid,$gid,$quota,$comment,$fullname) = getpwent; | ||
| 8062 : | $FullName@{$name@} = $fullname; | ||
| 8063 : | print "$name - $FullName@{$name@}\n"; | ||
| 8064 : | last if ($name eq ""); | ||
| 8065 : | @} | ||
| 8066 : | |||
| 8067 : | print "\n"; | ||
| 8068 : | |||
| 8069 : | # Now make a unique filename for each page and open a file | ||
| 8070 : | |||
| 8071 : | foreach $user (sort keys(%FullName)) | ||
| 8072 : | @{ | ||
| 8073 : | next if ($user eq ""); | ||
| 8074 : | |||
| 8075 : | print "Making page for $user\n"; | ||
| 8076 : | $outputfile = "$user.html"; | ||
| 8077 : | |||
| 8078 : | open (OUT,"> $outputfile") || die "Can't open $outputfile\n"; | ||
| 8079 : | |||
| 8080 : | &MakePage; | ||
| 8081 : | |||
| 8082 : | close (OUT); | ||
| 8083 : | @} | ||
| 8084 : | |||
| 8085 : | |||
| 8086 : | #################################################################### | ||
| 8087 : | # Level 1 | ||
| 8088 : | #################################################################### | ||
| 8089 : | |||
| 8090 : | sub MakePage | ||
| 8091 : | |||
| 8092 : | @{ | ||
| 8093 : | print OUT <<ENDMARKER; | ||
| 8094 : | |||
| 8095 : | <HTML> | ||
| 8096 : | <BODY> | ||
| 8097 : | <HEAD><TITLE>$FullName@{$user@}'s Home Page</TITLE></HEAD> | ||
| 8098 : | <H1>$FullName@{$user@}'s Home Page</H1> | ||
| 8099 : | |||
| 8100 : | Hi welcome to my home page. In case you hadn't | ||
| 8101 : | got it yet my name is: $FullName@{$user@}... | ||
| 8102 : | |||
| 8103 : | I study at <a href=http://www.iu.hioslo.no>Høgskolen i Oslo</a>. | ||
| 8104 : | |||
| 8105 : | </BODY> | ||
| 8106 : | </HTML> | ||
| 8107 : | |||
| 8108 : | ENDMARKER | ||
| 8109 : | @} | ||
| 8110 : | |||
| 8111 : | @end smallexample | ||
| 8112 : | |||
| 8113 : | @c ----------------------------------------------------------------------- | ||
| 8114 : | @c SECTION | ||
| 8115 : | @c ----------------------------------------------------------------------- | ||
| 8116 : | |||
| 8117 : | @node Other functions, Perl summary, WWW example 2, Perl | ||
| 8118 : | @section Other supported functions | ||
| 8119 : | |||
| 8120 : | Perl has very many functions which come directly from the C library. | ||
| 8121 : | To give a taster, a few are listed here. The Perl book contains | ||
| 8122 : | a comprehensive description of these. | ||
| 8123 : | |||
| 8124 : | @table @emph | ||
| 8125 : | @item Fork | ||
| 8126 : | The standard UNIX fork command for spawning new processes. | ||
| 8127 : | @item Sockets | ||
| 8128 : | Support for network socket communication. | ||
| 8129 : | @item Directories | ||
| 8130 : | Directory opening and handling routines. | ||
| 8131 : | @item Databases | ||
| 8132 : | Reading from the password files and the host databases is supported through | ||
| 8133 : | the standard C functions @samp{getpasswdbyname} etc. dressed up to look like Perl. | ||
| 8134 : | @item Crypt | ||
| 8135 : | The password encryption function. | ||
| 8136 : | @item Regexp | ||
| 8137 : | Regular expressions and pattern matching, search and replace functions | ||
| 8138 : | as in @samp{sed}. | ||
| 8139 : | @item Operators | ||
| 8140 : | Perl has the full set of C's logical operators. | ||
| 8141 : | @item File testing | ||
| 8142 : | Tests from the shell like @samp{if (-f file)}. | ||
| 8143 : | @end table | ||
| 8144 : | |||
| 8145 : | @noindent | ||
| 8146 : | Here are some of the most frequently used functions | ||
| 8147 : | |||
| 8148 : | @table @code | ||
| 8149 : | @item chmod | ||
| 8150 : | Change the file mode of a file. e.g. @code{chmod 755,@var{filename}} | ||
| 8151 : | @item chdir | ||
| 8152 : | Change the current working directory. e.g. @code{chdir /etc} | ||
| 8153 : | @item stat | ||
| 8154 : | Get info about permissions, ownership and type of a file. | ||
| 8155 : | @item open | ||
| 8156 : | Open a file for reading, @samp{>} writing, @samp{|} as a pipe. | ||
| 8157 : | @item close | ||
| 8158 : | Close an open file handle. | ||
| 8159 : | @item system | ||
| 8160 : | Execute a shell command as a child process. e.g. @code{system "ls";} | ||
| 8161 : | @item split | ||
| 8162 : | Split a string variable into an array of elements, by searching for a | ||
| 8163 : | special character (space or @samp{:} etc.) | ||
| 8164 : | e.g. @code{@@array=split(":",$string)}. | ||
| 8165 : | @item rename | ||
| 8166 : | Rename a file. e.g. @code{rename @var{old name} @var{new-name}} | ||
| 8167 : | @item mkdir | ||
| 8168 : | Make a new directory. @code{mkdir @var{newdir}} | ||
| 8169 : | @item shift | ||
| 8170 : | Read the first element of an array and delete it, shifting all the | ||
| 8171 : | array elements down by one. (e.g. @code{$first=shift(@@array);)}. | ||
| 8172 : | @item chop | ||
| 8173 : | Chops off the last character of a string. Often used for deleting the | ||
| 8174 : | end-of-line character when reading from a file. | ||
| 8175 : | @item oct | ||
| 8176 : | Interprets a number as octal (converts to decimal). e.g. | ||
| 8177 : | @code{$decimal = oct(755);} | ||
| 8178 : | @item kill | ||
| 8179 : | Send a kill signal to a list of processes. | ||
| 8180 : | e.g. @code{kill -9, @var{pid1},@var{pid2}...} | ||
| 8181 : | @end table | ||
| 8182 : | |||
| 8183 : | @noindent | ||
| 8184 : | You should explore Perl's possibilities yourself. Perl is a good alternative | ||
| 8185 : | to the shell which has much of the power of C and is therefore | ||
| 8186 : | ideal for simple and more complex system programming tasks. | ||
| 8187 : | If you intend to be a system administrator for UNIX systems, you could | ||
| 8188 : | do much worse than to read the Perl book and learn Perl inside out. | ||
| 8189 : | |||
| 8190 : | @c ----------------------------------------------------------------------- | ||
| 8191 : | @c SECTION | ||
| 8192 : | @c ----------------------------------------------------------------------- | ||
| 8193 : | |||
| 8194 : | @node Perl summary, Ex5, Other functions, Perl | ||
| 8195 : | @section Summary | ||
| 8196 : | |||
| 8197 : | The Practical Extraction and Report Language is a powerful tool which | ||
| 8198 : | goes beyond shell programming, but which retains much of the | ||
| 8199 : | immediateness of shell programming in a more formal programming | ||
| 8200 : | environment. | ||
| 8201 : | |||
| 8202 : | The success of Perl has led many programmers to use it exclusively. In | ||
| 8203 : | the next section, I would like to argue that programming directly in C | ||
| 8204 : | is not much harder. In fact it has advantages in the long run. The power | ||
| 8205 : | of Perl is that it is as @emph{immediate} as shell programming. If you | ||
| 8206 : | are inexperienced, Perl is a little easier than C because many features | ||
| 8207 : | are ready programmed into the language, but with time one also builds up | ||
| 8208 : | a repertoire of C functions which can do the same tricks. | ||
| 8209 : | |||
| 8210 : | |||
| 8211 : | |||
| 8212 : | @c ----------------------------------------------------------------------- | ||
| 8213 : | @c SECTION | ||
| 8214 : | @c ----------------------------------------------------------------------- | ||
| 8215 : | |||
| 8216 : | @node Ex5, Proj5, Perl summary, Perl | ||
| 8217 : | @section Exercises | ||
| 8218 : | |||
| 8219 : | @enumerate | ||
| 8220 : | |||
| 8221 : | @item | ||
| 8222 : | Write a progam which prints out all of its arguments alphabetically | ||
| 8223 : | together with the first and the last, and the number of arguments. | ||
| 8224 : | |||
| 8225 : | @item | ||
| 8226 : | Write a program which prints out the pathname of the home directory | ||
| 8227 : | for a given user. The user's login name should be given as an argument. | ||
| 8228 : | |||
| 8229 : | @item | ||
| 8230 : | Write a program called `search-replace' which looks for a given | ||
| 8231 : | string in a list of files and replaces it with a new string. You should | ||
| 8232 : | be able to specify a list of files using ordinary unix wildcards. e.g. | ||
| 8233 : | @samp{search-replace search-string replace-string *.text}. This is a | ||
| 8234 : | dangerous operation! What if the user types the strings incorrectly? | ||
| 8235 : | How can you may the program safer? | ||
| 8236 : | |||
| 8237 : | @item | ||
| 8238 : | Write a program which opens a pipe from @samp{ps} and computes the | ||
| 8239 : | total cpu-time used by each user. Print the results in order of maximum | ||
| 8240 : | to minimum. Hint: use an associated array to store the information. | ||
| 8241 : | |||
| 8242 : | @item | ||
| 8243 : | Write a program which forks and goes into the background. Make the | ||
| 8244 : | program send you mail when some other user of your choice logs in. | ||
| 8245 : | Use sleep to check only every few minutes. | ||
| 8246 : | |||
| 8247 : | @item | ||
| 8248 : | Open a pipe from @samp{find} and collect statistics over how many | ||
| 8249 : | files there are in all of your sub-directories. | ||
| 8250 : | @end enumerate | ||
| 8251 : | |||
| 8252 : | @c ----------------------------------------------------------------------- | ||
| 8253 : | @c SECTION | ||
| 8254 : | @c ----------------------------------------------------------------------- | ||
| 8255 : | |||
| 8256 : | @node Proj5, , Ex5, Perl | ||
| 8257 : | @section Project | ||
| 8258 : | |||
| 8259 : | Write a program which checks the `sanity' of your UNIX system. | ||
| 8260 : | @enumerate | ||
| 8261 : | @item Check that the password file /etc/passwd is not writable | ||
| 8262 : | by general users. | ||
| 8263 : | @item Check that the processes @samp{cron} and @samp{sendmail} are running. | ||
| 8264 : | |||
| 8265 : | @item Check that, if the file @samp{/etc/exports} | ||
| 8266 : | or @file{/etc/dfs/dfstab} exists, the @emph{nfsd} daemon | ||
| 8267 : | is running. | ||
| 8268 : | |||
| 8269 : | @item Check that if the filesystem table @samp{/etc/fstab} (or its | ||
| 8270 : | equivalent on non-BSD systems) contains NFS mounted filesystems, the | ||
| 8271 : | @samp{biod} or @samp{nfsiod} daemon is running. | ||
| 8272 : | |||
| 8273 : | @item Check that the file @samp{/etc/resolv.conf} contains the correct | ||
| 8274 : | domain name. It | ||
| 8275 : | may or may not be the same as that returned by the shell | ||
| 8276 : | command @samp{domainname}. If it is not the same, you should | ||
| 8277 : | print the message `NIS domain has different name to DNS domain'. | ||
| 8278 : | |||
| 8279 : | @end enumerate | ||
| 8280 : | |||
| 8281 : | @c ********************************************************************** | ||
| 8282 : | @c CHAPTER | ||
| 8283 : | @c ********************************************************************** | ||
| 8284 : | |||
| 8285 : | @node WWW and CGI programming, C programming, Perl, Top | ||
| 8286 : | @chapter WWW and CGI programming | ||
| 8287 : | |||
| 8288 : | CGI stands for the Common Gateway Interface. It is the name | ||
| 8289 : | given to scripts which can be executed from within pages of the | ||
| 8290 : | world wide web. Although it is possible to use any language in | ||
| 8291 : | CGI programs (hence the word `common'), the usual choice is | ||
| 8292 : | Perl, because of the ease with which Perl can handle text. | ||
| 8293 : | |||
| 8294 : | The CGI interface is pretty unintelligent, in order to | ||
| 8295 : | be as general as possible, so we need to do a bit of work in | ||
| 8296 : | order to make scripts work. | ||
| 8297 : | |||
| 8298 : | @c ----------------------------------------------------------------------- | ||
| 8299 : | @c SECTION | ||
| 8300 : | @c ----------------------------------------------------------------------- | ||
| 8301 : | |||
| 8302 : | @menu | ||
| 8303 : | * Permissions:: | ||
| 8304 : | * Protocols:: | ||
| 8305 : | * HTML coding:: | ||
| 8306 : | * Perl and the web:: | ||
| 8307 : | * PHP and the web:: | ||
| 8308 : | @end menu | ||
| 8309 : | |||
| 8310 : | @node Permissions, Protocols, WWW and CGI programming, WWW and CGI programming | ||
| 8311 : | @section Permissions | ||
| 8312 : | |||
| 8313 : | The key thing about the WWW which often causes a lot of confusion | ||
| 8314 : | is that the W3 service runs with a user ID of `nobody'. The purpose | ||
| 8315 : | of this is to ensure that nobody has the right to read or write files | ||
| 8316 : | unless they are opened very explicitly by the user who owns them. | ||
| 8317 : | |||
| 8318 : | In order for files to be readable on the WWW, they must have file mode | ||
| 8319 : | @samp{644} and they must lie in a directory which has mode | ||
| 8320 : | @samp{755}. In order for a CGI program to be executable, it must have | ||
| 8321 : | permission @samp{755} and in order for such a program to write to | ||
| 8322 : | a file in a user's directory, it must be possible for the file | ||
| 8323 : | to be created (if necessary) and everyone must be able to write | ||
| 8324 : | to it. That means that files which are written to by the WWW must have | ||
| 8325 : | mode @samp{666} and must either exist already or lie in a directory | ||
| 8326 : | with permission @samp{777}@footnote{You could also set the sticky bit | ||
| 8327 : | @samp{1777} in order to prevent malicious users from deleting | ||
| 8328 : | your file.}. | ||
| 8329 : | |||
| 8330 : | @c ----------------------------------------------------------------------- | ||
| 8331 : | @c SECTION | ||
| 8332 : | @c ----------------------------------------------------------------------- | ||
| 8333 : | |||
| 8334 : | @node Protocols, HTML coding, Permissions, WWW and CGI programming | ||
| 8335 : | @section Protocols | ||
| 8336 : | |||
| 8337 : | CGI script programs communicate with W3 browsers using a very simple | ||
| 8338 : | protocol. It goes like this: | ||
| 8339 : | |||
| 8340 : | @itemize @bullet | ||
| 8341 : | |||
| 8342 : | @item | ||
| 8343 : | A web page sends data to a script using the `forms' interface. Those | ||
| 8344 : | data are concatenated into @emph{a single line}. The data in separate | ||
| 8345 : | fields of a form are separated by @samp{&} signs. New lines are replaced | ||
| 8346 : | by the text @samp{%0D%0A}, which is the DOS ASCII representation of a | ||
| 8347 : | newline, and spaces are replaced by @samp{+} symbols. | ||
| 8348 : | |||
| 8349 : | @item | ||
| 8350 : | A CGI script reads this single line of text on the standard input. | ||
| 8351 : | |||
| 8352 : | @item | ||
| 8353 : | The CGI script replies to the web browser. The first line | ||
| 8354 : | of the reply @emph{must} be a line which is tells the browser | ||
| 8355 : | what mime-type the data are sent in. Usually, a CGI script | ||
| 8356 : | replies in HTML code, in which case the first line in the | ||
| 8357 : | reply must be: | ||
| 8358 : | |||
| 8359 : | @smallexample | ||
| 8360 : | Content-type: text/html | ||
| 8361 : | @end smallexample | ||
| 8362 : | @cindex CGI protocol | ||
| 8363 : | @cindex Mime types in W3 | ||
| 8364 : | @noindent | ||
| 8365 : | This must be followed by a blank line. | ||
| 8366 : | |||
| 8367 : | @end itemize | ||
| 8368 : | |||
| 8369 : | @c ----------------------------------------------------------------------- | ||
| 8370 : | @c SECTION | ||
| 8371 : | @c ----------------------------------------------------------------------- | ||
| 8372 : | |||
| 8373 : | @node HTML coding, Perl and the web, Protocols, WWW and CGI programming | ||
| 8374 : | @section HTML coding of forms | ||
| 8375 : | |||
| 8376 : | To start a CGI program from a web page we use a @emph{form} | ||
| 8377 : | @cindex Forms in HTML | ||
| 8378 : | which is a part of the HTML code enclosed with the parentheses | ||
| 8379 : | |||
| 8380 : | @smallexample | ||
| 8381 : | |||
| 8382 : | <FORM method="POST" ACTION="/cgi-script-alias/program.pl"> | ||
| 8383 : | ... | ||
| 8384 : | </FORM> | ||
| 8385 : | @end smallexample | ||
| 8386 : | |||
| 8387 : | @noindent | ||
| 8388 : | The method `post' means that the data which get typed into | ||
| 8389 : | this form will be piped into the CGI program via its standard | ||
| 8390 : | input. The `action' specifies which program you want to start. | ||
| 8391 : | Note that | ||
| 8392 : | @cindex Script aliases in W3 | ||
| 8393 : | you cannot simply use the absolute path of the file, for security | ||
| 8394 : | reasons. You must use something called a `script alias' to tell the web | ||
| 8395 : | browser where to find the program. If you do not have a script alias | ||
| 8396 : | defined for you personally, then you need to get one from your system | ||
| 8397 : | administrator. By using a script alias, no one from outside your site | ||
| 8398 : | can see where your files are located, only that you have a `cgi-bin' | ||
| 8399 : | area somewhere on your system. | ||
| 8400 : | |||
| 8401 : | Within these parentheses, you can arrange to collect different kinds of | ||
| 8402 : | input. The simplest kind of input is just a button which starts | ||
| 8403 : | the CGI program. This has the form | ||
| 8404 : | @smallexample | ||
| 8405 : | |||
| 8406 : | <INPUT TYPE="submit" VALUE="Start my program"> | ||
| 8407 : | |||
| 8408 : | @end smallexample | ||
| 8409 : | |||
| 8410 : | @noindent | ||
| 8411 : | This code creates a button. When you click on it the program | ||
| 8412 : | in your `action' string gets started. More generally, you will | ||
| 8413 : | want to create input boxes where you can type in data. To create | ||
| 8414 : | a single line input field, you use the following syntax: | ||
| 8415 : | @smallexample | ||
| 8416 : | |||
| 8417 : | <INPUT NAME="variable-name" SIZE=40> | ||
| 8418 : | |||
| 8419 : | @end smallexample | ||
| 8420 : | @noindent | ||
| 8421 : | This creates a single line text field of width 40 characters. This is | ||
| 8422 : | not the limit on the length of the string which can be typed into the | ||
| 8423 : | field, only a limit on the amount which is visible at any time. It is | ||
| 8424 : | for visual formatting only. The NAME field is used to identify the data | ||
| 8425 : | in the CGI script. The string you enter here will be sent to the CGI | ||
| 8426 : | script in the form @samp{variable-name=value of input...}. Another type | ||
| 8427 : | of input is a text area. This is a larger box where one can type in text | ||
| 8428 : | on several lines. The syntax is: | ||
| 8429 : | @smallexample | ||
| 8430 : | |||
| 8431 : | <TEXTAREA NAME="variable-name" ROW=50 COLS=50> | ||
| 8432 : | |||
| 8433 : | @end smallexample | ||
| 8434 : | @noindent | ||
| 8435 : | which means: create a text area of fifty rows by fifty columns | ||
| 8436 : | with a prompt to the left of the box. Again, the size has only | ||
| 8437 : | to do with the visual formatting, not to do with limits | ||
| 8438 : | on the amount of text which can be entered. | ||
| 8439 : | |||
| 8440 : | As an example, let's create a WWW page with a complete | ||
| 8441 : | form which can be used to make a guest book, or order | ||
| 8442 : | form. | ||
| 8443 : | |||
| 8444 : | @smallexample | ||
| 8445 : | <HTML> | ||
| 8446 : | <HEAD> | ||
| 8447 : | <TITLE>Example form</TITLE> | ||
| 8448 : | <!-- Comment: Mark Burgess, 27-Jan-1997 --> | ||
| 8449 : | <LINK REV="made" HREF="mailto:mark@@iu.hioslo.no"> | ||
| 8450 : | </HEAD> | ||
| 8451 : | <BODY> | ||
| 8452 : | <CENTER><H1>Write in my guest book...</H1></CENTER> | ||
| 8453 : | <HR> | ||
| 8454 : | |||
| 8455 : | <CENTER><H2>Please leave a comment using the form below.</H2><P> | ||
| 8456 : | <FORM method="POST" ACTION="/cgi-bin-mark/comment.pl"> | ||
| 8457 : | |||
| 8458 : | Your Name/e-mail: <INPUT NAME="variable1" SIZE=40> <BR><BR> | ||
| 8459 : | |||
| 8460 : | <P> | ||
| 8461 : | <TEXTAREA NAME="variable2" cols=50 rows=8></TEXTAREA> | ||
| 8462 : | <P> | ||
| 8463 : | |||
| 8464 : | <INPUT TYPE=submit VALUE="Add message to book"> | ||
| 8465 : | <INPUT TYPE=reset VALUE="Clear message"> | ||
| 8466 : | </FORM> | ||
| 8467 : | |||
| 8468 : | <P> | ||
| 8469 : | |||
| 8470 : | </BODY> | ||
| 8471 : | </HTML> | ||
| 8472 : | |||
| 8473 : | @end smallexample | ||
| 8474 : | @noindent | ||
| 8475 : | |||
| 8476 : | The reset button clears the form. When the submit button is pressed, | ||
| 8477 : | the CGI program is activated. | ||
| 8478 : | |||
| 8479 : | @c ----------------------------------------------------------------------- | ||
| 8480 : | @c SECTION | ||
| 8481 : | @c ----------------------------------------------------------------------- | ||
| 8482 : | |||
| 8483 : | @node Perl and the web, PHP and the web, HTML coding, WWW and CGI programming | ||
| 8484 : | @section Perl and the web | ||
| 8485 : | |||
| 8486 : | |||
| 8487 : | @c ----------------------------------------------------------------------- | ||
| 8488 : | @c SECTION | ||
| 8489 : | @c ----------------------------------------------------------------------- | ||
| 8490 : | |||
| 8491 : | @menu | ||
| 8492 : | * Interpreting the data:: | ||
| 8493 : | * A complete guestbook example:: | ||
| 8494 : | @end menu | ||
| 8495 : | |||
| 8496 : | @node Interpreting the data, A complete guestbook example, Perl and the web, Perl and the web | ||
| 8497 : | @subsection Interpreting data from forms | ||
| 8498 : | |||
| 8499 : | To interpret and respond to the data in a form, we must write a program | ||
| 8500 : | which satsifies the protocol above, @xref{Protocols}. We use | ||
| 8501 : | perl as a script langauge. The simplest valid CGI script is the | ||
| 8502 : | following: | ||
| 8503 : | |||
| 8504 : | @smallexample | ||
| 8505 : | |||
| 8506 : | #!/local/bin/perl | ||
| 8507 : | |||
| 8508 : | # | ||
| 8509 : | # Reply with proper protocol | ||
| 8510 : | # | ||
| 8511 : | |||
| 8512 : | print "Content-type: text/html\n\n"; | ||
| 8513 : | |||
| 8514 : | # | ||
| 8515 : | # Get the data from the form ... | ||
| 8516 : | # | ||
| 8517 : | |||
| 8518 : | $input = <STDIN>; | ||
| 8519 : | |||
| 8520 : | # | ||
| 8521 : | # ... and echo them back | ||
| 8522 : | # | ||
| 8523 : | |||
| 8524 : | print $input, "\n Done! \n"; | ||
| 8525 : | |||
| 8526 : | @end smallexample | ||
| 8527 : | |||
| 8528 : | @noindent | ||
| 8529 : | Although rather banal, this script is a useful starting point for CGI | ||
| 8530 : | programming, because it shows you just how the input arrives at the | ||
| 8531 : | script from the HTML form. The data arrive all in a single, enormously | ||
| 8532 : | long line, full of funny characters. The first job of any script is to | ||
| 8533 : | decode this line. | ||
| 8534 : | |||
| 8535 : | Before looking at how to decode the data, we should make an important | ||
| 8536 : | point about the protocol line. If a web browser does not get this | ||
| 8537 : | `Content-type' line from the CGI script it returns with an error: | ||
| 8538 : | |||
| 8539 : | @example | ||
| 8540 : | |||
| 8541 : | 500 Server Error | ||
| 8542 : | |||
| 8543 : | The server encountered an internal error or misconfiguration and was | ||
| 8544 : | unable to complete your request. | ||
| 8545 : | |||
| 8546 : | Please contact the server administrator, and inform them of the time | ||
| 8547 : | the error occurred, and anything you might have done that may have | ||
| 8548 : | caused the error. | ||
| 8549 : | |||
| 8550 : | Error: HTTPd: malformed header from script www/cgi-bin/comment.pl | ||
| 8551 : | |||
| 8552 : | @end example | ||
| 8553 : | |||
| 8554 : | @noindent | ||
| 8555 : | Before finishing your CGI script, you will probably ecounter this error | ||
| 8556 : | several times. A common reason for getting the error is a syntax error | ||
| 8557 : | in your script. If your program contains an error, the first thing a | ||
| 8558 : | browser gets in return is not the `Content-type' line, but an error | ||
| 8559 : | message. The browser does not pass on this error message, it just | ||
| 8560 : | prints the uninformative message above. | ||
| 8561 : | |||
| 8562 : | If you can get the above script to work, then you are ready to | ||
| 8563 : | decode the data which are sent to the script. The first thing | ||
| 8564 : | is to use perl to split the long line into an array of lines, by | ||
| 8565 : | splitting on @samp{&}. We can also convert all of the @samp{+} | ||
| 8566 : | symbols back into spaces. The script now looks like this: | ||
| 8567 : | |||
| 8568 : | @smallexample | ||
| 8569 : | #!/local/bin/perl | ||
| 8570 : | |||
| 8571 : | # | ||
| 8572 : | # Reply with proper protocol | ||
| 8573 : | # | ||
| 8574 : | |||
| 8575 : | print "Content-type: text/html\n\n"; | ||
| 8576 : | |||
| 8577 : | # | ||
| 8578 : | # Get the data from the form ... | ||
| 8579 : | # | ||
| 8580 : | |||
| 8581 : | $input = <STDIN>; | ||
| 8582 : | |||
| 8583 : | # | ||
| 8584 : | # ... and echo them back | ||
| 8585 : | # | ||
| 8586 : | |||
| 8587 : | print "$input\n\n\n"; | ||
| 8588 : | |||
| 8589 : | $input =~ s/\+/ /g; | ||
| 8590 : | |||
| 8591 : | # | ||
| 8592 : | # Now split the lines and convert | ||
| 8593 : | # | ||
| 8594 : | |||
| 8595 : | @@array = split('&',$input); | ||
| 8596 : | |||
| 8597 : | foreach $var ( @@array ) | ||
| 8598 : | @{ | ||
| 8599 : | print "$var\n"; | ||
| 8600 : | @} | ||
| 8601 : | |||
| 8602 : | print "Done! \n"; | ||
| 8603 : | |||
| 8604 : | @end smallexample | ||
| 8605 : | |||
| 8606 : | @noindent | ||
| 8607 : | We now have a series of elements in our array. The output from this | ||
| 8608 : | script is something like this: | ||
| 8609 : | |||
| 8610 : | @smallexample | ||
| 8611 : | |||
| 8612 : | variable1=Mark+Burgess&variable2=%0D%0AI+just+called+to+say+ @var{(wrap)} | ||
| 8613 : | ....%0D%0A...hey+pig%2C+nothing%27s+working+out+the+way+I+planned | ||
| 8614 : | variable1=Mark Burgess variable2=%0D%0AI just called to say @var{(wrap)} | ||
| 8615 : | ....%0D%0A...hey pig%2Cnothing%27s working out the way I planned Done! | ||
| 8616 : | |||
| 8617 : | @end smallexample | ||
| 8618 : | @noindent | ||
| 8619 : | As you can see, all control characters are converted into the form @samp{%XX}. | ||
| 8620 : | We should now try to do something with these. Since we are usually not interested | ||
| 8621 : | in keeping new lines, or any other control codes, we can simply null-out these | ||
| 8622 : | with a line of the form | ||
| 8623 : | |||
| 8624 : | @smallexample | ||
| 8625 : | |||
| 8626 : | $input =~ s/%..//g; | ||
| 8627 : | |||
| 8628 : | @end smallexample | ||
| 8629 : | @noindent | ||
| 8630 : | The regular expression @samp{%..} matches anything beginning with a percent | ||
| 8631 : | symbol followed by two characters. The resulting output is then free of | ||
| 8632 : | these symbols. We can then separate the variable contents from their names | ||
| 8633 : | by splitting the input. Here is the complete code: | ||
| 8634 : | |||
| 8635 : | @smallexample | ||
| 8636 : | #!/local/bin/perl | ||
| 8637 : | |||
| 8638 : | # | ||
| 8639 : | # Reply with proper protocol | ||
| 8640 : | # | ||
| 8641 : | |||
| 8642 : | print "Content-type: text/html\n\n"; | ||
| 8643 : | |||
| 8644 : | # | ||
| 8645 : | # Get the data from the form ... | ||
| 8646 : | # | ||
| 8647 : | |||
| 8648 : | $input = <STDIN>; | ||
| 8649 : | |||
| 8650 : | # | ||
| 8651 : | # ... and echo them back | ||
| 8652 : | # | ||
| 8653 : | |||
| 8654 : | print "$input\n\n\n"; | ||
| 8655 : | |||
| 8656 : | $input =~ s/%..//g; | ||
| 8657 : | |||
| 8658 : | $input =~ s/\+/ /g; | ||
| 8659 : | |||
| 8660 : | @@array = split('&',$input); | ||
| 8661 : | |||
| 8662 : | foreach $var ( @@array ) | ||
| 8663 : | @{ | ||
| 8664 : | print "$var<br>"; | ||
| 8665 : | @} | ||
| 8666 : | |||
| 8667 : | print "<hr>\n"; | ||
| 8668 : | |||
| 8669 : | ($name,$variable1) = split("variable1=",$array[0]); | ||
| 8670 : | ($name,$variable2) = split("variable2=",$array[1]); | ||
| 8671 : | |||
| 8672 : | print "<br>var1 = $variable1<br>"; | ||
| 8673 : | print "<br>var2 = $variable2<br>"; | ||
| 8674 : | |||
| 8675 : | print "<br>Done! \n"; | ||
| 8676 : | |||
| 8677 : | @end smallexample | ||
| 8678 : | @noindent | ||
| 8679 : | and the output | ||
| 8680 : | |||
| 8681 : | @cartouche | ||
| 8682 : | @smallexample | ||
| 8683 : | variable1=Mark+Burgess&variable2=%0D%0AI+just+called+to+say @var{(wrap)} | ||
| 8684 : | +....%0D%0A...hey+pig%2C+nothing%27s+working+out+the+way+I+planned | ||
| 8685 : | variable1=Mark Burgess | ||
| 8686 : | variable2=I just called to say .......hey pig nothings working @var{(wrap)} | ||
| 8687 : | out the way I planned | ||
| 8688 : | |||
| 8689 : | |||
| 8690 : | var1 = Mark Burgess | ||
| 8691 : | |||
| 8692 : | var2 = I just called to say .......hey pig nothings working out @var{(wrap)} | ||
| 8693 : | the way I planned | ||
| 8694 : | |||
| 8695 : | Done! | ||
| 8696 : | @end smallexample | ||
| 8697 : | @end cartouche | ||
| 8698 : | |||
| 8699 : | @c ----------------------------------------------------------------------- | ||
| 8700 : | @c SECTION | ||
| 8701 : | @c ----------------------------------------------------------------------- | ||
| 8702 : | |||
| 8703 : | @node A complete guestbook example, , Interpreting the data, Perl and the web | ||
| 8704 : | @subsection A complete guestbook example in perl | ||
| 8705 : | |||
| 8706 : | Let us now use this technique to develop a guest book aplication. | ||
| 8707 : | Based on the code above, analyze the following code. | ||
| 8708 : | |||
| 8709 : | @smallexample | ||
| 8710 : | #!/local/bin/perl | ||
| 8711 : | #################################################################### | ||
| 8712 : | # | ||
| 8713 : | # Guest book | ||
| 8714 : | # | ||
| 8715 : | #################################################################### | ||
| 8716 : | |||
| 8717 : | $guestbook_page = "/iu/nexus/ud/mark/www/tmp/cfguest.html"; | ||
| 8718 : | |||
| 8719 : | $tmp_page = "/iu/nexus/ud/mark/www/tmp/guests.tmp"; | ||
| 8720 : | |||
| 8721 : | $remote_host = $ENV@{"REMOTE_HOST"@}; | ||
| 8722 : | |||
| 8723 : | print "Content-type: text/html\n\n"; | ||
| 8724 : | print "<br><hr><br>\n"; | ||
| 8725 : | print "Thank you for submitting your comment!<br><br>\n"; | ||
| 8726 : | print "best wishes,<br><br>"; | ||
| 8727 : | print "-Mark<br><br><br>"; | ||
| 8728 : | print "Return to <a href=http://www.iu.hioslo.no/~mark/menu.html>menu</a>\n"; | ||
| 8729 : | |||
| 8730 : | $input = <STDIN>; | ||
| 8731 : | |||
| 8732 : | $input =~ s/%..//g; | ||
| 8733 : | |||
| 8734 : | $input =~ s/\+/ /g; | ||
| 8735 : | |||
| 8736 : | @@array = split('&',$input); | ||
| 8737 : | |||
| 8738 : | ($skip,$name) = split("var1=",$array[0]); | ||
| 8739 : | ($skip,$message) = split("var2=",$array[1]); | ||
| 8740 : | |||
| 8741 : | if (! open (PAGE, $guestbook_page)) | ||
| 8742 : | @{ | ||
| 8743 : | print "Content-type: text/html\n\n"; | ||
| 8744 : | print "couldn't open guestbook page file!"; | ||
| 8745 : | @} | ||
| 8746 : | |||
| 8747 : | if (! open (TMP, "+>$tmp_page")) | ||
| 8748 : | @{ | ||
| 8749 : | print "Content-type: text/html\n\n"; | ||
| 8750 : | print "couldn't open temporary output file!"; | ||
| 8751 : | @} | ||
| 8752 : | |||
| 8753 : | while ($line = <PAGE>) | ||
| 8754 : | @{ | ||
| 8755 : | if ($line =~ /<h3>Number of entries: (..)/) | ||
| 8756 : | @{ | ||
| 8757 : | $entry_no = $1; | ||
| 8758 : | $entry_no++; | ||
| 8759 : | $line = "<h3>Number of entries: $entry_no </h3>\n"; | ||
| 8760 : | @} | ||
| 8761 : | |||
| 8762 : | if ($line =~ /<!-- LAST ENTRY -->/) | ||
| 8763 : | @{ | ||
| 8764 : | $date = `date +"%A, %b %d %Y"`; | ||
| 8765 : | print TMP "<b>Entry $date from host: $remote_host</b>\n<p>\n"; | ||
| 8766 : | print TMP "From: $name\n<p>\n"; | ||
| 8767 : | print TMP $message; | ||
| 8768 : | print TMP "\n<hr>\n"; | ||
| 8769 : | @} | ||
| 8770 : | |||
| 8771 : | print TMP "$line"; | ||
| 8772 : | @} | ||
| 8773 : | |||
| 8774 : | close PAGE; | ||
| 8775 : | close TMP; | ||
| 8776 : | |||
| 8777 : | if (! rename ($tmp_page, $guestbook_page)) | ||
| 8778 : | @{ | ||
| 8779 : | print "Oops! Rename operation failed!\n"; | ||
| 8780 : | @} | ||
| 8781 : | |||
| 8782 : | chmod (0600, $guestbook_page); | ||
| 8783 : | |||
| 8784 : | @end smallexample | ||
| 8785 : | |||
| 8786 : | This script works by reading through the old guest book file, opening a | ||
| 8787 : | new copy of the guest book file and appending a new messages at the | ||
| 8788 : | end. The end of the message section (not counting the @samp{</HTML>} | ||
| 8789 : | tags) is marked by a comment line. | ||
| 8790 : | |||
| 8791 : | @smallexample | ||
| 8792 : | <!-- LAST ENTRY --> | ||
| 8793 : | @end smallexample | ||
| 8794 : | |||
| 8795 : | @noindent | ||
| 8796 : | Note that a provisional guest book file has to exist in the first place. | ||
| 8797 : | The script writes to a new file and then swaps the new file for the old | ||
| 8798 : | one. The guest book file looks something like this: | ||
| 8799 : | @smallexample | ||
| 8800 : | <html><head> | ||
| 8801 : | <title>Comments</title> | ||
| 8802 : | </head> | ||
| 8803 : | <body> | ||
| 8804 : | <h1>My guest book</h1> | ||
| 8805 : | |||
| 8806 : | <b>Entry no. Wednesday, Feb 28 1996 | ||
| 8807 : | from host: dax</b> | ||
| 8808 : | <p> | ||
| 8809 : | From: Mark.Burgess@@iu.hioslo.no | ||
| 8810 : | <p> | ||
| 8811 : | Just to start the ball rolling.... | ||
| 8812 : | |||
| 8813 : | <hr> | ||
| 8814 : | |||
| 8815 : | <b>Entry no. Tuesday, Mar 26 1996 | ||
| 8816 : | from host: enterprise.subspace.net</b> | ||
| 8817 : | <p> | ||
| 8818 : | From: spock@@enterprise | ||
| 8819 : | <p> | ||
| 8820 : | Registering a form of energy never before encountered. | ||
| 8821 : | |||
| 8822 : | <!-- LAST ENTRY --> | ||
| 8823 : | |||
| 8824 : | </body> <address><a href="http://www.iu.hioslo.no/~mark">Mark | ||
| 8825 : | Burgess</a> - Mark.Burgess@@iu.hioslo.no</addre ss> </html> | ||
| 8826 : | |||
| 8827 : | |||
| 8828 : | @end smallexample | ||
| 8829 : | The directory in which this file lies needs to be writable to | ||
| 8830 : | the user nobody (the WWW user) and the files within need to be | ||
| 8831 : | deletable by nobody but no one else. Some users try to make | ||
| 8832 : | guest book scripts setuid-themselves in order to overcome the | ||
| 8833 : | problem that httpd runs with uid nobody, but this opens many | ||
| 8834 : | security issues. In short it is asking for trouble. Unfortunately | ||
| 8835 : | an ordinary user cannot use @code{chown} in order to give access | ||
| 8836 : | only to the WWW user nobody, so this approach needs the cooperation | ||
| 8837 : | of the system administrator. Nevertheless this is the most secure | ||
| 8838 : | approach. | ||
| 8839 : | Try to work through this example step for step. | ||
| 8840 : | |||
| 8841 : | @c ----------------------------------------------------------------------- | ||
| 8842 : | @c SECTION | ||
| 8843 : | @c ----------------------------------------------------------------------- | ||
| 8844 : | |||
| 8845 : | @node PHP and the web, , Perl and the web, WWW and CGI programming | ||
| 8846 : | @section PHP and the web | ||
| 8847 : | |||
| 8848 : | The PHP 3 language makes the whole business of web programming rather | ||
| 8849 : | simpler than perl. It hides the business of translating variables | ||
| 8850 : | from forms into new variables in a CGI program and it even allows you | ||
| 8851 : | to embed active code into you HTML pages. PHP has special support for | ||
| 8852 : | querying data in an SQL database like MySQL or Oracle. PHP documentation | ||
| 8853 : | lives at @uref{http://www.php.net}. | ||
| 8854 : | |||
| 8855 : | @menu | ||
| 8856 : | * Embedded PHP:: | ||
| 8857 : | * PHP and forms:: | ||
| 8858 : | @end menu | ||
| 8859 : | |||
| 8860 : | @node Embedded PHP, PHP and forms, PHP and the web, PHP and the web | ||
| 8861 : | @subsection Embedded PHP | ||
| 8862 : | |||
| 8863 : | PHP code can be embedded inside HTML pages provided your WWW server is | ||
| 8864 : | configurered with PHP support. PHP code lives inside a tag with the | ||
| 8865 : | general form | ||
| 8866 : | @smallexample | ||
| 8867 : | |||
| 8868 : | <?php @var{code...} ?> | ||
| 8869 : | |||
| 8870 : | @end smallexample | ||
| 8871 : | @noindent | ||
| 8872 : | For example, we could use this to import one file into another | ||
| 8873 : | and print out a table of numbers: | ||
| 8874 : | @smallexample | ||
| 8875 : | <html> | ||
| 8876 : | <body> | ||
| 8877 : | |||
| 8878 : | <?php | ||
| 8879 : | |||
| 8880 : | include "file.html" | ||
| 8881 : | |||
| 8882 : | for ($i = 0; $i < 10; $i++) | ||
| 8883 : | @{ | ||
| 8884 : | print "Counting $i<br>"; | ||
| 8885 : | @} | ||
| 8886 : | |||
| 8887 : | ?> | ||
| 8888 : | |||
| 8889 : | </body> | ||
| 8890 : | </html> | ||
| 8891 : | @end smallexample | ||
| 8892 : | This makes it easy to generate WWW pages with a fixed visual layout: | ||
| 8893 : | |||
| 8894 : | @smallexample | ||
| 8895 : | <?php | ||
| 8896 : | # | ||
| 8897 : | # Standard layout | ||
| 8898 : | # | ||
| 8899 : | |||
| 8900 : | # Set $title, $comment and $contents | ||
| 8901 : | |||
| 8902 : | ########################################################################## | ||
| 8903 : | |||
| 8904 : | print "<body>\n"; | ||
| 8905 : | print "<img src=img/header.gif>"; | ||
| 8906 : | |||
| 8907 : | print "<h1>"$title</h1>"; | ||
| 8908 : | print "<em>$comment</em>"; | ||
| 8909 : | print "<blockquote>\n"; | ||
| 8910 : | |||
| 8911 : | include $contents; | ||
| 8912 : | |||
| 8913 : | print ("</blockquote>\n"); | ||
| 8914 : | print ("</body>\n"); | ||
| 8915 : | print ("</html>\n"); | ||
| 8916 : | |||
| 8917 : | @end smallexample | ||
| 8918 : | |||
| 8919 : | @noindent | ||
| 8920 : | Variables are easily set by calling PHP code in the form of a CGI program | ||
| 8921 : | from a form. | ||
| 8922 : | |||
| 8923 : | @node PHP and forms, , Embedded PHP, PHP and the web | ||
| 8924 : | @subsection PHP and forms | ||
| 8925 : | |||
| 8926 : | PHP is particularly good at dealing with forms, as a CGI scripting | ||
| 8927 : | langauge. Consider the following form: | ||
| 8928 : | |||
| 8929 : | @smallexample | ||
| 8930 : | <html> | ||
| 8931 : | <body> | ||
| 8932 : | <form action="/cgi-bin-scriptalias/spititout.php" method="post"> | ||
| 8933 : | |||
| 8934 : | Name: <input type="text" name="personal[name]"><br> | ||
| 8935 : | Email: <input type="text" name="personal[email]"><br> | ||
| 8936 : | Preferred language: | ||
| 8937 : | <select multiple name="language[]"> | ||
| 8938 : | <option value="English">English | ||
| 8939 : | <option value="Norwegian">Norwegian | ||
| 8940 : | <option value="Gobbledigook">Gobbledigook | ||
| 8941 : | </select> | ||
| 8942 : | |||
| 8943 : | <input type=image src="image.gif" name="sub"> | ||
| 8944 : | |||
| 8945 : | </form> | ||
| 8946 : | </body> | ||
| 8947 : | </html> | ||
| 8948 : | @end smallexample | ||
| 8949 : | This produces a page into which one types a name and email address | ||
| 8950 : | and chooses a language from a list of three possible choices. When the | ||
| 8951 : | user clicks on a button marked by the file @file{image.gif} the | ||
| 8952 : | form is posted. Here is a program which unravels the data sent to the | ||
| 8953 : | CGI program: | ||
| 8954 : | |||
| 8955 : | @smallexample | ||
| 8956 : | |||
| 8957 : | #!/local/bin/php | ||
| 8958 : | |||
| 8959 : | <?php | ||
| 8960 : | # | ||
| 8961 : | # A CGI program which handles a form | ||
| 8962 : | # Variables a translated automatically | ||
| 8963 : | # | ||
| 8964 : | |||
| 8965 : | $title = "This page title"; | ||
| 8966 : | $comment = "This pages talks about the following....."; | ||
| 8967 : | |||
| 8968 : | ########################################################################## | ||
| 8969 : | |||
| 8970 : | echo "<body>"; | ||
| 8971 : | echo "<h1>$title</h1>"; | ||
| 8972 : | echo "<em>$comment</em>"; | ||
| 8973 : | echo "<blockquote>\n"; | ||
| 8974 : | |||
| 8975 : | ### | ||
| 8976 : | |||
| 8977 : | echo "Your name is $personal[name]<br><br>"; | ||
| 8978 : | echo "Your email is $personal[email]<br><br>"; | ||
| 8979 : | |||
| 8980 : | echo "Language options: "; | ||
| 8981 : | echo "<table> "; | ||
| 8982 : | |||
| 8983 : | for ($i = 0; strlen($language[$i]) > 0; $i++) | ||
| 8984 : | @{ | ||
| 8985 : | echo "<tr><td bgcolor=#ff0000>Variable language[$i] = $language[$i]</td></tr>"; | ||
| 8986 : | @} | ||
| 8987 : | |||
| 8988 : | if ($language[0] == "Norwegian") | ||
| 8989 : | @{ | ||
| 8990 : | echo "Hei alle sammen<p>"; | ||
| 8991 : | @} | ||
| 8992 : | else | ||
| 8993 : | @{ | ||
| 8994 : | echo "Greetings everyone, this page will be in English<p>"; | ||
| 8995 : | @} | ||
| 8996 : | |||
| 8997 : | echo "</table> "; | ||
| 8998 : | |||
| 8999 : | ### | ||
| 9000 : | |||
| 9001 : | echo ("</blockquote>\n"); | ||
| 9002 : | echo ("</body>\n"); | ||
| 9003 : | echo ("</html>\n"); | ||
| 9004 : | ?> | ||
| 9005 : | |||
| 9006 : | |||
| 9007 : | @end smallexample | ||
| 9008 : | |||
| 9009 : | @c ********************************************************************** | ||
| 9010 : | @c CHAPTER | ||
| 9011 : | @c ********************************************************************** | ||
| 9012 : | |||
| 9013 : | @node C programming, Network programming, WWW and CGI programming, Top | ||
| 9014 : | @chapter C programming | ||
| 9015 : | |||
| 9016 : | @emph{This section is not meant to teach you C. It is a guide to using C | ||
| 9017 : | in UNIX and it is assumed that you have a working knowledge of the | ||
| 9018 : | language. See the GNU C-Tutorial for an introduction to basics.} | ||
| 9019 : | |||
| 9020 : | @c ----------------------------------------------------------------------- | ||
| 9021 : | @c SECTION | ||
| 9022 : | @c ----------------------------------------------------------------------- | ||
| 9023 : | |||
| 9024 : | @menu | ||
| 9025 : | * Shell or C?:: | ||
| 9026 : | * C program structure:: | ||
| 9027 : | * UNIX calls and POSIX:: | ||
| 9028 : | * Compiling C:: | ||
| 9029 : | * Make:: | ||
| 9030 : | * argv argc envp:: | ||
| 9031 : | * Environment variables in C:: | ||
| 9032 : | * C files and dirs:: | ||
| 9033 : | * File test macros:: | ||
| 9034 : | * Process control:: | ||
| 9035 : | * A more secure popen:: | ||
| 9036 : | * Traps and signals:: | ||
| 9037 : | * Regular expressions in C:: | ||
| 9038 : | * DES encryption:: | ||
| 9039 : | * ioctl:: | ||
| 9040 : | * Database example in C:: | ||
| 9041 : | * lex and yacc:: | ||
| 9042 : | * Ex 6:: | ||
| 9043 : | @end menu | ||
| 9044 : | |||
| 9045 : | @node Shell or C?, C program structure, C programming, C programming | ||
| 9046 : | @section Shell or C? | ||
| 9047 : | |||
| 9048 : | @cindex C programming | ||
| 9049 : | In the preceding chapters we have been looking at ways to get simple | ||
| 9050 : | programming tasks done. The immediateness of the script languages is a | ||
| 9051 : | great advantage when we just want to get a job done as quickly as | ||
| 9052 : | possible. Scripts lend themselves to simple system administration tasks | ||
| 9053 : | like file processing, but they do not easily lend themselves to more | ||
| 9054 : | serious programs. | ||
| 9055 : | |||
| 9056 : | @cindex Wrappers | ||
| 9057 : | Although some system administrators have grown to the idea that shell | ||
| 9058 : | programming is easier, I would argue that this is not really true. | ||
| 9059 : | First of all, most of the UNIX shell commands are just wrapper programs | ||
| 9060 : | for C function calls. Why use the wrapper when you can use the real | ||
| 9061 : | thing? Secondly, the C function calls return data in pointers and | ||
| 9062 : | structures which are very easy to manipulate, whereas piping the output | ||
| 9063 : | of shell programs into others can be a very messy and awkward way of | ||
| 9064 : | working. Here are some of the reasons why we also need a more | ||
| 9065 : | traditional programming language like C. | ||
| 9066 : | |||
| 9067 : | @enumerate | ||
| 9068 : | |||
| 9069 : | @item | ||
| 9070 : | The shell languages do not allow us to create an acceptable | ||
| 9071 : | user-interface, like X-windows, or the curses (cursor manipulation) | ||
| 9072 : | library. They are mainly intended for file-processing. (Though | ||
| 9073 : | recently the @emph{Tk} library has provided a way of creating | ||
| 9074 : | user interfaces in Tcl and Perl.) | ||
| 9075 : | @cindex Curses | ||
| 9076 : | @cindex X windows | ||
| 9077 : | @cindex Tk library | ||
| 9078 : | |||
| 9079 : | @item | ||
| 9080 : | Shell commands read their input line-by-line. Not all input | ||
| 9081 : | is generated in this simple way -- we also need to be able to read | ||
| 9082 : | through lines i.e. the concept of a @emph{data stream}. | ||
| 9083 : | |||
| 9084 : | @item | ||
| 9085 : | More advanced data structures are needed for most applications, such | ||
| 9086 : | as linked lists and binary trees, acyclic graphs etc. | ||
| 9087 : | |||
| 9088 : | @item | ||
| 9089 : | Compilers help to sort out simple typographical and logical errors | ||
| 9090 : | by compile-time checking source code. | ||
| 9091 : | |||
| 9092 : | @item | ||
| 9093 : | Compiled code is faster than interpreted code. | ||
| 9094 : | |||
| 9095 : | @item | ||
| 9096 : | Many tools have been written to help in the programming of C code | ||
| 9097 : | (dbx, lex, yacc etc.). | ||
| 9098 : | @cindex @samp{lex} | ||
| 9099 : | @cindex @samp{yacc} | ||
| 9100 : | |||
| 9101 : | @end enumerate | ||
| 9102 : | |||
| 9103 : | @c ----------------------------------------------------------------------- | ||
| 9104 : | @c SECTION | ||
| 9105 : | @c ----------------------------------------------------------------------- | ||
| 9106 : | |||
| 9107 : | @node C program structure, UNIX calls and POSIX, Shell or C?, C programming | ||
| 9108 : | @section C program structure | ||
| 9109 : | |||
| 9110 : | @c ..................................................... | ||
| 9111 : | @c SUBSECTION | ||
| 9112 : | @c ..................................................... | ||
| 9113 : | |||
| 9114 : | @menu | ||
| 9115 : | * C structure:: | ||
| 9116 : | * Macros and declarations:: | ||
| 9117 : | * Several files:: | ||
| 9118 : | @end menu | ||
| 9119 : | |||
| 9120 : | @node C structure, Macros and declarations, C program structure, C program structure | ||
| 9121 : | @subsection The form of a C program | ||
| 9122 : | |||
| 9123 : | A C program consists of a set of function, beginning | ||
| 9124 : | with the main program: | ||
| 9125 : | |||
| 9126 : | |||
| 9127 : | @smallexample | ||
| 9128 : | |||
| 9129 : | main () /* This is a comment */ | ||
| 9130 : | |||
| 9131 : | @{ | ||
| 9132 : | |||
| 9133 : | Commands ... | ||
| 9134 : | |||
| 9135 : | |||
| 9136 : | @} | ||
| 9137 : | |||
| 9138 : | @end smallexample | ||
| 9139 : | |||
| 9140 : | The source code of a C program can be divided into several text files. | ||
| 9141 : | C compiles all functions separately; the linker @code{ld} joins them all | ||
| 9142 : | up at the end. This means that we can plan out a strategy for writing | ||
| 9143 : | large programs in a clear and efficient manner. | ||
| 9144 : | |||
| 9145 : | NOTE: C++ style comments @samp{//...} are not allowed by most | ||
| 9146 : | C compilers. | ||
| 9147 : | |||
| 9148 : | @c ..................................................... | ||
| 9149 : | @c SUBSECTION | ||
| 9150 : | @c ..................................................... | ||
| 9151 : | |||
| 9152 : | @node Macros and declarations, Several files, C structure, C program structure | ||
| 9153 : | @subsection Macros and declarations | ||
| 9154 : | |||
| 9155 : | Most Unix systems now have ANSI C compatible compilers, but this has not | ||
| 9156 : | always been the case. Most UNIX programs written in a version | ||
| 9157 : | of C which is older than the ANSI standard, so you will need an | ||
| 9158 : | appreciation of old Kernighan and Ritchie C conventions for C | ||
| 9159 : | programming. See for example my C book. | ||
| 9160 : | |||
| 9161 : | An obvious difference between ANSI C and K&R C is that the C++ | ||
| 9162 : | additions to the language are not included. Here are some useful | ||
| 9163 : | points to remember. | ||
| 9164 : | @cindex ANSI C | ||
| 9165 : | @cindex Kernighan and Ritchie C | ||
| 9166 : | |||
| 9167 : | @itemize @bullet | ||
| 9168 : | @item | ||
| 9169 : | K&R C does not allow @samp{const} data, it uses the C preprocessor with | ||
| 9170 : | @samp{#define} instead. i.e. intead of | ||
| 9171 : | @smallexample | ||
| 9172 : | |||
| 9173 : | const int blah = 1; | ||
| 9174 : | |||
| 9175 : | @end smallexample | ||
| 9176 : | @noindent | ||
| 9177 : | use | ||
| 9178 : | @smallexample | ||
| 9179 : | #define blah 1 | ||
| 9180 : | @end smallexample | ||
| 9181 : | |||
| 9182 : | @noindent | ||
| 9183 : | Remember that the hash symbol @samp{#} must be the first character on | ||
| 9184 : | a line under UNIX. | ||
| 9185 : | @item | ||
| 9186 : | K&R C doesn't use function prototypes or declarations of the form: | ||
| 9187 : | @smallexample | ||
| 9188 : | |||
| 9189 : | void function (char *string, int a, int b) | ||
| 9190 : | |||
| 9191 : | @{ | ||
| 9192 : | @} | ||
| 9193 : | |||
| 9194 : | @end smallexample | ||
| 9195 : | @noindent | ||
| 9196 : | Instead one writes: | ||
| 9197 : | @smallexample | ||
| 9198 : | |||
| 9199 : | void function (string, a, b) | ||
| 9200 : | |||
| 9201 : | char *string; | ||
| 9202 : | int a,b; | ||
| 9203 : | |||
| 9204 : | @{ | ||
| 9205 : | @} | ||
| 9206 : | |||
| 9207 : | @end smallexample | ||
| 9208 : | @end itemize | ||
| 9209 : | |||
| 9210 : | @c ..................................................... | ||
| 9211 : | @c SUBSECTION | ||
| 9212 : | @c ..................................................... | ||
| 9213 : | |||
| 9214 : | @node Several files, , Macros and declarations, C program structure | ||
| 9215 : | @subsection Several files | ||
| 9216 : | |||
| 9217 : | Most unix programs are very large and are split up into many files. | ||
| 9218 : | Remember, when you split up programs into several files, you must | ||
| 9219 : | declare variables as @samp{extern} in file A if they are really declared | ||
| 9220 : | in file B. in which you want to use them. This tells the compiler that | ||
| 9221 : | it should not try to create local storage for the variable, because this was | ||
| 9222 : | already done in another file. | ||
| 9223 : | |||
| 9224 : | @cindex Splitting C into many files. | ||
| 9225 : | @cindex @code{extern} variables | ||
| 9226 : | |||
| 9227 : | @c ----------------------------------------------------------------------- | ||
| 9228 : | @c SECTION | ||
| 9229 : | @c ----------------------------------------------------------------------- | ||
| 9230 : | |||
| 9231 : | @node UNIX calls and POSIX, Compiling C, C program structure, C programming | ||
| 9232 : | @section A note about UNIX system calls and standards | ||
| 9233 : | |||
| 9234 : | @cindex POSIX standard | ||
| 9235 : | Most of the system calls in UNIX return data in the form of @samp{struct} | ||
| 9236 : | variables. Sometimes these are structures used by the operating system | ||
| 9237 : | itself -- in other cases they are just put together so that programmers | ||
| 9238 : | can handle a packet of data in a convenient way. | ||
| 9239 : | |||
| 9240 : | If in doubt, you can find the definitions of these structures in the | ||
| 9241 : | relevant include files under @file{/usr/include}. | ||
| 9242 : | |||
| 9243 : | Since UNIX comes in many flavours the system calls are not always | ||
| 9244 : | compatible and may have different options and arguments. Because | ||
| 9245 : | of this there is a number of standardizing organizations for UNIX. | ||
| 9246 : | One of them is POSIX which is an organization run by the | ||
| 9247 : | major UNIX vendors. Programs written for UNIX are now | ||
| 9248 : | expected to be POSIX compliant. This is not something you need to | ||
| 9249 : | think about at the level of this course, but you should certainly | ||
| 9250 : | remember that there exist programming standards and that these should | ||
| 9251 : | be adhered to. The aim is to work towards a single standard UNIX. | ||
| 9252 : | |||
| 9253 : | @c ----------------------------------------------------------------------- | ||
| 9254 : | @c SECTION | ||
| 9255 : | @c ----------------------------------------------------------------------- | ||
| 9256 : | |||
| 9257 : | @node Compiling C, Make, UNIX calls and POSIX, C programming | ||
| 9258 : | @section Compiling: @samp{cc}, @samp{ld} and @file{a.out} | ||
| 9259 : | |||
| 9260 : | The C compiler on the unix system is traditionally called @samp{cc} and | ||
| 9261 : | has always been a traditional part of every Unix environment. Recently | ||
| 9262 : | several Unix vendors have stopped including the C compiler as a part of | ||
| 9263 : | their operating systems and instead sell a compiler separately. | ||
| 9264 : | Fortunately there is a public domain Free Software version of the | ||
| 9265 : | compiler called @samp{gcc} (the GNU C compiler). We shall use this in | ||
| 9266 : | all the examples. | ||
| 9267 : | |||
| 9268 : | To compile a program consisting of several files of code, | ||
| 9269 : | we first compile all of the separate pieces without trying to link | ||
| 9270 : | them. There are therefore two stages: first we turn @samp{.c} | ||
| 9271 : | files into @samp{.o} files. This compiles code but does not | ||
| 9272 : | fix any address references. Then we link all @samp{.o} | ||
| 9273 : | files into the final executable, including any libraries | ||
| 9274 : | which are used. | ||
| 9275 : | |||
| 9276 : | @cindex Compiling programs | ||
| 9277 : | @cindex Multiple C files, compiling | ||
| 9278 : | Let's suppose we have files @file{a.c}, @file{b.c} and @file{c.c}. | ||
| 9279 : | We write: | ||
| 9280 : | @smallexample | ||
| 9281 : | |||
| 9282 : | gcc -c a.c b.c c.c | ||
| 9283 : | |||
| 9284 : | @end smallexample | ||
| 9285 : | This creates files @samp{a.o}, @samp{b.o} and @samp{c.o}. | ||
| 9286 : | Next we link them into one file called `myprog'. | ||
| 9287 : | @smallexample | ||
| 9288 : | |||
| 9289 : | gcc -o myprog a.o b.o c.o | ||
| 9290 : | |||
| 9291 : | @end smallexample | ||
| 9292 : | |||
| 9293 : | @noindent | ||
| 9294 : | If the naming option @samp{-o myprog} is not used, the link @samp{ld} | ||
| 9295 : | uses the default name @emph{a.out} for the executable file. | ||
| 9296 : | @cindex @file{a.out} | ||
| 9297 : | |||
| 9298 : | @c ..................................................... | ||
| 9299 : | @c SUBSECTION | ||
| 9300 : | @c ..................................................... | ||
| 9301 : | |||
| 9302 : | @menu | ||
| 9303 : | * Libraries and LD_LIBRARY_PATH:: | ||
| 9304 : | * Include files:: | ||
| 9305 : | * Shared and static libraries:: | ||
| 9306 : | * Important paths:: | ||
| 9307 : | @end menu | ||
| 9308 : | |||
| 9309 : | @node Libraries and LD_LIBRARY_PATH, Include files, Compiling C, Compiling C | ||
| 9310 : | @subsection Libraries and @samp{LD_LIBRARY_PATH} | ||
| 9311 : | |||
| 9312 : | @vindex @samp{LD_LIBRARY_PATH} | ||
| 9313 : | @cindex libc | ||
| 9314 : | @cindex libm | ||
| 9315 : | @cindex libcurses | ||
| 9316 : | @cindex Library path for C loader | ||
| 9317 : | @cindex @samp{-L} option to @code{cc} | ||
| 9318 : | The resulting file is called @samp{myprog} and includes references only | ||
| 9319 : | to the standard library @samp{libc}. If we wish to link in the math | ||
| 9320 : | library @samp{libm} or the cursor movement library @samp{libcurses} -- | ||
| 9321 : | or in general, a library called @samp{libBLAH} , we need to use the | ||
| 9322 : | @samp{-l} directive. | ||
| 9323 : | |||
| 9324 : | @smallexample | ||
| 9325 : | |||
| 9326 : | gcc -o myprog files.o -lm -lcurses -lBLAH | ||
| 9327 : | |||
| 9328 : | @end smallexample | ||
| 9329 : | |||
| 9330 : | @noindent | ||
| 9331 : | The compiler looks for a suitable library in all of the directories | ||
| 9332 : | listed in the environment variable @samp{LD_LIBRARY_PATH}. Alternatively | ||
| 9333 : | we can add a directory to the search path by using the @samp{-L}. | ||
| 9334 : | option: | ||
| 9335 : | @smallexample | ||
| 9336 : | |||
| 9337 : | gcc -o myprog files.o -L/usr/local/lib -lm -lcurses -lBLAH | ||
| 9338 : | |||
| 9339 : | @end smallexample | ||
| 9340 : | |||
| 9341 : | @c ..................................................... | ||
| 9342 : | @c SUBSECTION | ||
| 9343 : | @c ..................................................... | ||
| 9344 : | |||
| 9345 : | @node Include files, Shared and static libraries, Libraries and LD_LIBRARY_PATH, Compiling C | ||
| 9346 : | @subsection Include files | ||
| 9347 : | |||
| 9348 : | @cindex Include files | ||
| 9349 : | Normally the compiler looks for include files only in the | ||
| 9350 : | directory @file{/usr/include}. We can add further paths to search | ||
| 9351 : | using the @samp{-I} option. | ||
| 9352 : | @smallexample | ||
| 9353 : | |||
| 9354 : | gcc -o myprog file.c -I/usr/local/include -I/usr/local/X11/include | ||
| 9355 : | |||
| 9356 : | @end smallexample | ||
| 9357 : | @cindex @samp{-I} option to @code{cc} | ||
| 9358 : | @cindex Include file search path | ||
| 9359 : | |||
| 9360 : | Previously, Unix libraries have been in @file{a.out} code format, but | ||
| 9361 : | recent releases of unix have gone over to a more efficient and flexible | ||
| 9362 : | format called ELF (executable and linking format). | ||
| 9363 : | |||
| 9364 : | @c ..................................................... | ||
| 9365 : | @c SUBSECTION | ||
| 9366 : | @c ..................................................... | ||
| 9367 : | |||
| 9368 : | @node Shared and static libraries, Important paths, Include files, Compiling C | ||
| 9369 : | @subsection Shared and static libraries | ||
| 9370 : | |||
| 9371 : | |||
| 9372 : | @cindex Static linking | ||
| 9373 : | @cindex Shared libraries | ||
| 9374 : | Libraries are collections of C functions which the operating system | ||
| 9375 : | creators have written for our convenience. The source code for such a | ||
| 9376 : | library is just the source for a collection of functions -- there is no | ||
| 9377 : | @code{main} program. | ||
| 9378 : | |||
| 9379 : | There are two kinds of library used by modern operating systems: | ||
| 9380 : | @emph{archive libraries} or static libraries | ||
| 9381 : | and @code{shared libraries} or dynamical libraries. An archive | ||
| 9382 : | library has a name of the form | ||
| 9383 : | @smallexample | ||
| 9384 : | |||
| 9385 : | lib@var{name}.a | ||
| 9386 : | |||
| 9387 : | @end smallexample | ||
| 9388 : | @noindent | ||
| 9389 : | When an archive library is linked to a program, it is appended | ||
| 9390 : | lock, stock and barrel to the program code. This uses a lot | ||
| 9391 : | of disk space and makes the size of the compiled program very large. | ||
| 9392 : | Shared libraries (shared objects @samp{so} or shared archives @samp{sa} | ||
| 9393 : | generally have names of the form) | ||
| 9394 : | @smallexample | ||
| 9395 : | |||
| 9396 : | lib@var{name}.so | ||
| 9397 : | lib@var{name}.sa | ||
| 9398 : | |||
| 9399 : | @end smallexample | ||
| 9400 : | @noindent | ||
| 9401 : | often with version numbers appended. When a program is | ||
| 9402 : | linked with a shared library the code is not appended | ||
| 9403 : | to the program. Instead pointers to the shared objects | ||
| 9404 : | are created and the library is loaded at runtime, | ||
| 9405 : | thus avoiding the problem of having to store the library | ||
| 9406 : | effectively multiple times on the disk. | ||
| 9407 : | |||
| 9408 : | To make an archive library we compile all of | ||
| 9409 : | the functions we wish to include in the library | ||
| 9410 : | |||
| 9411 : | @smallexample | ||
| 9412 : | |||
| 9413 : | gcc -c function1.c function2.c ... | ||
| 9414 : | |||
| 9415 : | @end smallexample | ||
| 9416 : | |||
| 9417 : | @noindent | ||
| 9418 : | and then join the files using the @samp{ar} command. | ||
| 9419 : | |||
| 9420 : | @smallexample | ||
| 9421 : | |||
| 9422 : | ar rcv libMYLIB.a function1.o | ||
| 9423 : | ar rcv libMYLIB.a function2.o | ||
| 9424 : | |||
| 9425 : | @end smallexample | ||
| 9426 : | |||
| 9427 : | @noindent | ||
| 9428 : | To make a shared library one provides an option to the linker | ||
| 9429 : | program. The exact method is different in different operating systems, | ||
| 9430 : | so you should look at the manual page for @code{ld} on your system. | ||
| 9431 : | Under SunOS 4 we take the object files @samp{*.o} and run | ||
| 9432 : | @smallexample | ||
| 9433 : | |||
| 9434 : | ld -o libMYLIB.so.1.1 -assert pure-text *.o | ||
| 9435 : | |||
| 9436 : | @end smallexample | ||
| 9437 : | Under HPUX, we write | ||
| 9438 : | @smallexample | ||
| 9439 : | |||
| 9440 : | ld -b -o libMYLIB.so.1.1 *.o | ||
| 9441 : | |||
| 9442 : | @end smallexample | ||
| 9443 : | With the GNU linker, you write | ||
| 9444 : | @smallexample | ||
| 9445 : | |||
| 9446 : | ld -shared -o libMYLIB.so.1.1 *.o | ||
| 9447 : | |||
| 9448 : | @end smallexample | ||
| 9449 : | |||
| 9450 : | NOTE: when you add a shared library to the system under SunOS or | ||
| 9451 : | GNU/Linux you must run the command @samp{ldconfig}, making sure that the | ||
| 9452 : | path to the library is included in @samp{LD_LIBRARY_PATH}. SunOS and | ||
| 9453 : | GNU/Linux use a cache file @file{/etc/ld.so.cache} to keep current | ||
| 9454 : | versions of libraries. GNU/Linux also uses a configuration file called | ||
| 9455 : | @file{/etc/ld.so.conf}. | ||
| 9456 : | @cindex @file{ld.so.cache} | ||
| 9457 : | @cindex @file{ldconfig} | ||
| 9458 : | |||
| 9459 : | @c ..................................................... | ||
| 9460 : | @c SUBSECTION | ||
| 9461 : | @c ..................................................... | ||
| 9462 : | |||
| 9463 : | @node Important paths, , Shared and static libraries, Compiling C | ||
| 9464 : | @subsection Knowing about important paths: directory structure | ||
| 9465 : | |||
| 9466 : | It is important to understand how the C compiler finds the files it needs. | ||
| 9467 : | We have already mentioned the @samp{-I} and @samp{-L} options to the | ||
| 9468 : | compilation command line. In general, all system include files can be | ||
| 9469 : | found in the directory @file{/usr/include} and subdirectories of this | ||
| 9470 : | directory. All system libraries can be found in @file{/usr/lib}. | ||
| 9471 : | |||
| 9472 : | Many packages build their own libraries and keep the relevant files | ||
| 9473 : | in separate directories so that if the system gets reinstalled, they | ||
| 9474 : | do not get deleted. This is true for example of the X-windows system. | ||
| 9475 : | The include and library files for this are typically kept in | ||
| 9476 : | directories which look something like @file{/usr/local/X11R5/include} | ||
| 9477 : | and @file{/usr/X11R6/lib}. That means that we need to give all of | ||
| 9478 : | this information to the compiler. Compiling a program becomes | ||
| 9479 : | a complicated task in many cases so we need some kind of script | ||
| 9480 : | to help us perform the task. The Unix tool @code{make} was designed | ||
| 9481 : | for this purpose. | ||
| 9482 : | |||
| 9483 : | @c ----------------------------------------------------------------------- | ||
| 9484 : | @c SECTION | ||
| 9485 : | @c ----------------------------------------------------------------------- | ||
| 9486 : | |||
| 9487 : | @node Make, argv argc envp, Compiling C, C programming | ||
| 9488 : | @section Make | ||
| 9489 : | |||
| 9490 : | Nowadays compilers are often sold with fancy user environments driven by | ||
| 9491 : | menus which make it easier to compile programs. Unix has similar | ||
| 9492 : | environments but all of them use shell-based command line compilation | ||
| 9493 : | beneath the surface. That is because UNIX programmers are used to | ||
| 9494 : | writing large and complex programs which occupy many directories and | ||
| 9495 : | subdirectories. Each directory has to be adapted or configured to fit the | ||
| 9496 : | particular flavour of Unix system it is being compiled upon. Interactive | ||
| 9497 : | user environments are very poor at performing this kind of service. UNIX | ||
| 9498 : | solves the problem of compiling enormous @emph{trees} of software (such | ||
| 9499 : | as the unix system itself!) by using a compilation language called | ||
| 9500 : | @samp{make}. Such language files can be generated automatically by | ||
| 9501 : | scripts, allowing very complex programs to configure and compile | ||
| 9502 : | themselves from a single control script. | ||
| 9503 : | @cindex Compiling huge programs | ||
| 9504 : | |||
| 9505 : | @c ..................................................... | ||
| 9506 : | @c SUBSECTION | ||
| 9507 : | @c ..................................................... | ||
| 9508 : | |||
| 9509 : | @menu | ||
| 9510 : | * Compiling large programs:: | ||
| 9511 : | * Makefiles:: | ||
| 9512 : | * Suffix rules for C++:: | ||
| 9513 : | @end menu | ||
| 9514 : | |||
| 9515 : | @node Compiling large programs, Makefiles, Make, Make | ||
| 9516 : | @subsection Compiling large projects | ||
| 9517 : | |||
| 9518 : | Typing lines like | ||
| 9519 : | @smallexample | ||
| 9520 : | |||
| 9521 : | cc -c file1.c file2.c ... | ||
| 9522 : | cc -o target file1.o .... | ||
| 9523 : | |||
| 9524 : | @end smallexample | ||
| 9525 : | @noindent | ||
| 9526 : | |||
| 9527 : | repeatedly to compile a complicated program can be a real nuisance. One | ||
| 9528 : | possibility would therefore be to keep all the commands in a script. | ||
| 9529 : | This could waste a lot of time though. Suppose you are working on a big | ||
| 9530 : | project which consists of many lines of source code -- but are editing | ||
| 9531 : | only one file. You really only want to recompile the file you are | ||
| 9532 : | working on and then relink the resulting object file with all of the | ||
| 9533 : | other object files. Recompiling the other files which hadn't changed | ||
| 9534 : | would be a waste of time. But that would mean that you would have to | ||
| 9535 : | change the script each time you change what you need to compile. | ||
| 9536 : | |||
| 9537 : | A better solution is to use the @samp{make} command. @samp{make} was | ||
| 9538 : | designed for precisely this purpose. To use @samp{make}, we create | ||
| 9539 : | a file called @file{Makefile} in the same directory as our program. | ||
| 9540 : | @samp{make} is a quite general program for building software. It is | ||
| 9541 : | not specifically tied to the C programming language--- | ||
| 9542 : | it can be used in any programming language. | ||
| 9543 : | |||
| 9544 : | A @samp{make} configuration file, called a @file{Makefile}, contains | ||
| 9545 : | rules which describe how to compile or build all of the pieces of | ||
| 9546 : | a program. For example, even without telling it specifically, | ||
| 9547 : | @code{make} knows that in order to go from @samp{prog.c} to | ||
| 9548 : | @samp{prog.o} the command @samp{cc -c prog.c} must be executed. A | ||
| 9549 : | Makefile works by making such associations. The Makefile contains a | ||
| 9550 : | list of all of the files which compose the program and rules as to how | ||
| 9551 : | to get to the finished product from the source. | ||
| 9552 : | |||
| 9553 : | The idea is that, to compile a program, we just have to type @kbd{make}. | ||
| 9554 : | @samp{make} then reads the Makefile and compiles all of the parts which | ||
| 9555 : | need compiling. It does not recompile files which have not changed since | ||
| 9556 : | the last compilation! How does it do this? @samp{make} works by | ||
| 9557 : | comparing the time-stamp on the file it needs to create with the | ||
| 9558 : | time-stamp on the file which is to be compiled. If the compiled version | ||
| 9559 : | exists and is newer than its source then the source does not need to be | ||
| 9560 : | recompiled. | ||
| 9561 : | |||
| 9562 : | To make this idea work in practice, @samp{make} has to know how to | ||
| 9563 : | go through the steps of compiling a program. Some default rules are | ||
| 9564 : | defined in a global configuration file, e.g. | ||
| 9565 : | @smallexample | ||
| 9566 : | |||
| 9567 : | /usr/include/make/default.mk | ||
| 9568 : | |||
| 9569 : | @end smallexample | ||
| 9570 : | |||
| 9571 : | @noindent | ||
| 9572 : | Let's consider an example of what happens for the the three files | ||
| 9573 : | @file{a.c}, @file{b.c} and @file{c.c} in the example above -- and | ||
| 9574 : | let's not worry about what the Makefile looks like yet. | ||
| 9575 : | |||
| 9576 : | The first time we compile, only the `.c' files exist. When we type | ||
| 9577 : | @samp{make}, the program looks at its rules and finds that it | ||
| 9578 : | has to make a file called `myprog'. To make this | ||
| 9579 : | it needs to execute the command | ||
| 9580 : | @smallexample | ||
| 9581 : | |||
| 9582 : | gcc -o myprog a.o b.o c.o | ||
| 9583 : | |||
| 9584 : | @end smallexample | ||
| 9585 : | |||
| 9586 : | @noindent | ||
| 9587 : | So it looks for `a.o' etc and doesn't find them. It now goes to a kind | ||
| 9588 : | of subroutine and looks to see if it has any rules for making files | ||
| 9589 : | called `.o' and it discovers that these are made by compiling with the | ||
| 9590 : | @samp{gcc -c} option. Since the files do not exist, it does this. Now | ||
| 9591 : | the files `a.o b.o c.o' exist and it jumps back to the original problem | ||
| 9592 : | of trying to make `myprog'. All the files it needs now exist and so it | ||
| 9593 : | executes the command and builds `myprog'. | ||
| 9594 : | |||
| 9595 : | If we now edit `a.c', and type @samp{make} once again -- it goes | ||
| 9596 : | through the same procedure as before but now it finds all of the | ||
| 9597 : | files. So it compares the dates on the files -- if the source | ||
| 9598 : | is newer than the result, it recompiles. | ||
| 9599 : | |||
| 9600 : | By using this recursive method, @samp{make} only compiles those | ||
| 9601 : | parts of a program which need compiling. | ||
| 9602 : | |||
| 9603 : | @c ..................................................... | ||
| 9604 : | @c SUBSECTION | ||
| 9605 : | @c ..................................................... | ||
| 9606 : | |||
| 9607 : | @node Makefiles, Suffix rules for C++, Compiling large programs, Make | ||
| 9608 : | @subsection Makefiles | ||
| 9609 : | |||
| 9610 : | @cindex Suffix rules in Makefiles | ||
| 9611 : | @cindex Dependencies in Makefiles | ||
| 9612 : | |||
| 9613 : | To write a Makefile, we have to tell @samp{make} about @emph{dependencies}. | ||
| 9614 : | The dependencies of a file are all of those files which are required | ||
| 9615 : | to build it. Thus, the dependencies of `myprog' are `a.o', `b.o' | ||
| 9616 : | and `c.o'. The dependencies of `a.o' are simply `a.c', | ||
| 9617 : | the dependencies of `b.o' are `b.c' and so on. | ||
| 9618 : | |||
| 9619 : | A Makefile consists of rules of the form: | ||
| 9620 : | |||
| 9621 : | @smallexample | ||
| 9622 : | target : dependencies | ||
| 9623 : | @key{TAB} rule; | ||
| 9624 : | |||
| 9625 : | @end smallexample | ||
| 9626 : | |||
| 9627 : | @noindent | ||
| 9628 : | The target is the thing we want to build, the dependenices are | ||
| 9629 : | like subroutines to be executed first if they do not exist. Finally | ||
| 9630 : | the rule is to be executed if all if the dependenices exist; it takes | ||
| 9631 : | the dependencies and turns them into the target. | ||
| 9632 : | There are two important things to remember: | ||
| 9633 : | |||
| 9634 : | @itemize @bullet | ||
| 9635 : | @item | ||
| 9636 : | The file names must start on the first character of | ||
| 9637 : | a line. | ||
| 9638 : | @item | ||
| 9639 : | There must be a @key{TAB} character at the beginning | ||
| 9640 : | of every rule or action. If there are spaces instead of tabs, or no | ||
| 9641 : | tab at all, @samp{make} will signal an error. This bizarre feature | ||
| 9642 : | can cause a lot of confusion. | ||
| 9643 : | @end itemize | ||
| 9644 : | |||
| 9645 : | @noindent | ||
| 9646 : | Let's look at an example Makefile for a program which consists of two | ||
| 9647 : | course files @file{main.c} and @file{other.c} and which makes use of a | ||
| 9648 : | library called @file{libdb} which lies in the directory @file{/usr/local/lib}. | ||
| 9649 : | Our aim is to build a program called @code{database}: | ||
| 9650 : | |||
| 9651 : | @smallexample | ||
| 9652 : | |||
| 9653 : | # | ||
| 9654 : | # Simple Makefile for `database' | ||
| 9655 : | # | ||
| 9656 : | |||
| 9657 : | # First define a macro | ||
| 9658 : | |||
| 9659 : | OBJ = main.o other.o | ||
| 9660 : | |||
| 9661 : | CC = gcc | ||
| 9662 : | CFLAGS = -I/usr/local/include | ||
| 9663 : | LDFLAGS = -L/usr/local/lib -ldb | ||
| 9664 : | INSTALLDIR = /usr/local/bin | ||
| 9665 : | |||
| 9666 : | # | ||
| 9667 : | # Rules start here. Note that the $@@ variable becomes the name of the | ||
| 9668 : | # executable file. In this case it is taken from the $@{OBJ@} variable | ||
| 9669 : | # | ||
| 9670 : | |||
| 9671 : | database: $@{OBJ@} | ||
| 9672 : | $@{CC@} -o $@@ $@{OBJ@} $@{LDFLAGS@} | ||
| 9673 : | |||
| 9674 : | # | ||
| 9675 : | # If a header file changes, normally we need to recompile everything. | ||
| 9676 : | # There is no way that make can know this unless we write a rule which | ||
| 9677 : | # forces it to rebuild all .o files if the header file changes... | ||
| 9678 : | # | ||
| 9679 : | |||
| 9680 : | $@{OBJ@}: $@{HEADERS@} | ||
| 9681 : | |||
| 9682 : | # | ||
| 9683 : | # As well as special rules for special files we can also define a | ||
| 9684 : | # "suffix rule". This is a rule which tells us how to build all files | ||
| 9685 : | # of a certain type. Here is a rule to get .o files from .c files. | ||
| 9686 : | # The $< variable is like $? but is only used in suffix rules. | ||
| 9687 : | # | ||
| 9688 : | |||
| 9689 : | .c.o: | ||
| 9690 : | $@{CC@} -c $@{CFLAGS@} $< | ||
| 9691 : | |||
| 9692 : | |||
| 9693 : | ####################################################################### | ||
| 9694 : | # Clean up | ||
| 9695 : | ####################################################################### | ||
| 9696 : | |||
| 9697 : | # | ||
| 9698 : | # Make can also perform ordinary shell command jobs | ||
| 9699 : | # "make tidy" here performs a cleanup operation | ||
| 9700 : | # | ||
| 9701 : | |||
| 9702 : | clean: | ||
| 9703 : | rm -f $@{OBJ@} | ||
| 9704 : | rm -f y.tab.c lex.yy.c y.tab.h | ||
| 9705 : | rm -f y.tab lex.yy | ||
| 9706 : | rm -f *% *~ *.o | ||
| 9707 : | rm -f mconfig.tab.c mconfig.tab.h a.out | ||
| 9708 : | rm -f man.dvi man.aux man.log man.toc | ||
| 9709 : | rm -f cfengine.tar.gz cfengine.tar cfengine.tar.Z | ||
| 9710 : | make tidy | ||
| 9711 : | rm -f cfengine | ||
| 9712 : | |||
| 9713 : | install: $@{INSTALLDIR@}/database | ||
| 9714 : | cp database $@{INSTALLDIR@}/database | ||
| 9715 : | |||
| 9716 : | @end smallexample | ||
| 9717 : | |||
| 9718 : | @noindent | ||
| 9719 : | The Makefile above can be invoked in several ways. | ||
| 9720 : | @smallexample | ||
| 9721 : | |||
| 9722 : | make | ||
| 9723 : | make database | ||
| 9724 : | make clean | ||
| 9725 : | make install | ||
| 9726 : | |||
| 9727 : | @end smallexample | ||
| 9728 : | |||
| 9729 : | @noindent | ||
| 9730 : | If we simple type @samp{make} i.e. the first of these choices, @samp{make} | ||
| 9731 : | takes the first of the rules it finds as the object to build. In this | ||
| 9732 : | case the rule is `database', so the first two forms above are equivalent. | ||
| 9733 : | |||
| 9734 : | On the other hand, if we type | ||
| 9735 : | @smallexample | ||
| 9736 : | make clean | ||
| 9737 : | @end smallexample | ||
| 9738 : | |||
| 9739 : | @noindent | ||
| 9740 : | then execution starts at the rule for `clean', which is normally used | ||
| 9741 : | to remove all files except the original source code. Make `install' | ||
| 9742 : | causes the compiled program to be installed at its intended destination. | ||
| 9743 : | |||
| 9744 : | @samp{make} uses some special variables (which resemble the special | ||
| 9745 : | variables used in Perl -- but don't confuse them). The most useful one | ||
| 9746 : | is @samp{$@@} which represents the current @emph{target} -- or the | ||
| 9747 : | object which @samp{make} would like to compile. i.e. as @samp{make} | ||
| 9748 : | checks each file it would like to compile, @samp{$@@} is set to the | ||
| 9749 : | current filename. | ||
| 9750 : | |||
| 9751 : | @table @code | ||
| 9752 : | |||
| 9753 : | @item $@@ | ||
| 9754 : | This evaluates to the current target i.e. the name of the object | ||
| 9755 : | you are currently trying to build. It is normal to use this as the | ||
| 9756 : | final name of the program when compiling | ||
| 9757 : | |||
| 9758 : | @item $? | ||
| 9759 : | This is used only outside of suffix rules and means the name of all the | ||
| 9760 : | files which must be compiled in order to build the current target. | ||
| 9761 : | @smallexample | ||
| 9762 : | target: file1.o file2.o | ||
| 9763 : | @key{TAB} cc -o $@@ $? | ||
| 9764 : | @end smallexample | ||
| 9765 : | |||
| 9766 : | @item $< | ||
| 9767 : | This is only used in suffix rules. It has the same meaning as @samp{$?} | ||
| 9768 : | but only in suffix rules. It stands for the pre-requisite, or the file | ||
| 9769 : | which must be compiled in order to make a given object. | ||
| 9770 : | |||
| 9771 : | |||
| 9772 : | @vindex $@@ in make | ||
| 9773 : | @vindex $? in make | ||
| 9774 : | @vindex $< in make | ||
| 9775 : | |||
| 9776 : | @end table | ||
| 9777 : | |||
| 9778 : | Note that, because @samp{make} has some default rules defined in its | ||
| 9779 : | configuration file, a single-file C program can be compiled | ||
| 9780 : | very easily by typing | ||
| 9781 : | @smallexample | ||
| 9782 : | make filename.c | ||
| 9783 : | @end smallexample | ||
| 9784 : | |||
| 9785 : | @noindent | ||
| 9786 : | This is equivalent to | ||
| 9787 : | @smallexample | ||
| 9788 : | cc -c filename.c | ||
| 9789 : | cc -o filename filename.o | ||
| 9790 : | @end smallexample | ||
| 9791 : | |||
| 9792 : | @c ..................................................... | ||
| 9793 : | @c SUBSECTION | ||
| 9794 : | @c ..................................................... | ||
| 9795 : | |||
| 9796 : | @node Suffix rules for C++, , Makefiles, Make | ||
| 9797 : | @subsection New suffix rules for C++ | ||
| 9798 : | |||
| 9799 : | Standard rules for C++ are not often built into UNIX systems at the | ||
| 9800 : | time of writing, but we can create them in our own Makefiles very easily. | ||
| 9801 : | Here we shall use the GNU compiler g++'s conventions for | ||
| 9802 : | C++ files. Here is a sample Makefile for using C++. Note | ||
| 9803 : | that the @samp{.SUFFIXES} command must be used to declare new endings | ||
| 9804 : | or file extensions. | ||
| 9805 : | @cindex C++ suffix rules | ||
| 9806 : | @cindex Make rules for C++ | ||
| 9807 : | |||
| 9808 : | @smallexample | ||
| 9809 : | ################################################################## | ||
| 9810 : | # | ||
| 9811 : | # This is the Makefile for g++ | ||
| 9812 : | # | ||
| 9813 : | ################################################################## | ||
| 9814 : | |||
| 9815 : | OBJ = cpp-prog.o X.o Y.o Z.o | ||
| 9816 : | |||
| 9817 : | CCPLUS = g++ | ||
| 9818 : | |||
| 9819 : | .SUFFIXES: .C .o .h | ||
| 9820 : | |||
| 9821 : | # | ||
| 9822 : | # Program Rules | ||
| 9823 : | # | ||
| 9824 : | |||
| 9825 : | |||
| 9826 : | filesys: $@{OBJ@} | ||
| 9827 : | $(CCPLUS) -o filesys $(OBJ) | ||
| 9828 : | |||
| 9829 : | # | ||
| 9830 : | # Extra dependencies on the header file | ||
| 9831 : | # (if the header file changes, we need to rebuild *.o) | ||
| 9832 : | # | ||
| 9833 : | |||
| 9834 : | cpp-prog.o: filesys.h | ||
| 9835 : | X.o: filesys.h | ||
| 9836 : | Y.o: filesys.h | ||
| 9837 : | Z.o: filesys.h | ||
| 9838 : | |||
| 9839 : | # | ||
| 9840 : | # Suffix rules | ||
| 9841 : | # | ||
| 9842 : | |||
| 9843 : | .C.o: | ||
| 9844 : | $(CCPLUS) -c $< | ||
| 9845 : | |||
| 9846 : | |||
| 9847 : | @end smallexample | ||
| 9848 : | |||
| 9849 : | The general rule here tells @code{make} that a @file{.o} file | ||
| 9850 : | can be created from a @file{.C} file by executing the | ||
| 9851 : | command @samp{$(CCPLUS) -c}. (This is identical to the | ||
| 9852 : | C case, exept for the name of the compiler). The extra | ||
| 9853 : | dependencies tell @code{make} that, if we change the header | ||
| 9854 : | file @file{filesys.h}, then we must recompile all the files | ||
| 9855 : | which read in @file{filesys.h}, since this could affect all of | ||
| 9856 : | these. Finally, the highest level rule says that to make | ||
| 9857 : | @file{filesys} from the @file{.o} files, we have to run | ||
| 9858 : | @samp{$(CCPLUS) -o filesys *.o}. | ||
| 9859 : | |||
| 9860 : | @c ----------------------------------------------------------------------- | ||
| 9861 : | @c SECTION | ||
| 9862 : | @c ----------------------------------------------------------------------- | ||
| 9863 : | |||
| 9864 : | @node argv argc envp, Environment variables in C, Make, C programming | ||
| 9865 : | @section The @code{argv}, @code{argc} and @code{envp} paramters | ||
| 9866 : | |||
| 9867 : | When we write C programs which reads command line arguments, they are | ||
| 9868 : | fed to us as an array of strings called the argument vector. The | ||
| 9869 : | mechanisms for the C-shell and Perl are derived from the C argument | ||
| 9870 : | vector. To read in the command line, we write | ||
| 9871 : | @cindex The arguement vector in C | ||
| 9872 : | @cindex Command line arguments in C | ||
| 9873 : | @vindex @code{argv} in C | ||
| 9874 : | @vindex @code{argc} in C | ||
| 9875 : | @cindex @code{envp} in C | ||
| 9876 : | @cindex Environment variables in C | ||
| 9877 : | |||
| 9878 : | @smallexample | ||
| 9879 : | |||
| 9880 : | main (argc,argv,envp) | ||
| 9881 : | |||
| 9882 : | int argc; | ||
| 9883 : | char *argv[], *envp[]; | ||
| 9884 : | |||
| 9885 : | @{ | ||
| 9886 : | printf ("The first argument was %s\n",argv[1]); | ||
| 9887 : | @} | ||
| 9888 : | @end smallexample | ||
| 9889 : | |||
| 9890 : | @noindent | ||
| 9891 : | Argument zero is the name of the program itself and @samp{argv[argc-1]} | ||
| 9892 : | is the last argument. The above definitions are in Kernighan and Ritchie | ||
| 9893 : | C style. In ANSI C, the arguments can be declared using prototype: | ||
| 9894 : | |||
| 9895 : | @smallexample | ||
| 9896 : | main (int argc, char **argv) | ||
| 9897 : | |||
| 9898 : | @{ | ||
| 9899 : | |||
| 9900 : | @} | ||
| 9901 : | @end smallexample | ||
| 9902 : | |||
| 9903 : | @noindent | ||
| 9904 : | The array of strings @samp{envp[]} is a list of values of the | ||
| 9905 : | @emph{environment variables} of the system, formatted by | ||
| 9906 : | @smallexample | ||
| 9907 : | NAME=value | ||
| 9908 : | @end smallexample | ||
| 9909 : | |||
| 9910 : | @noindent | ||
| 9911 : | This gives C programmers access to the shell's global environment. | ||
| 9912 : | |||
| 9913 : | @c ----------------------------------------------------------------------- | ||
| 9914 : | @c SECTION | ||
| 9915 : | @c ----------------------------------------------------------------------- | ||
| 9916 : | |||
| 9917 : | @node Environment variables in C, C files and dirs, argv argc envp, C programming | ||
| 9918 : | @section Environment variables in C | ||
| 9919 : | |||
| 9920 : | @cindex Environment variables in C | ||
| 9921 : | @cindex @code{getenv() function} | ||
| 9922 : | @vindex @code{getenv()} | ||
| 9923 : | |||
| 9924 : | In addition to the @samp{envp} vector, it is possible to access the | ||
| 9925 : | environment variables through the call @samp{getenv()}. This is used as | ||
| 9926 : | follows; suppose we want to access the shell environment variable @samp{$HOME}. | ||
| 9927 : | @smallexample | ||
| 9928 : | char *string; | ||
| 9929 : | |||
| 9930 : | string = getenv("HOME"); | ||
| 9931 : | @end smallexample | ||
| 9932 : | |||
| 9933 : | @noindent | ||
| 9934 : | @samp{string} is now a pointer to static but public data. You should not | ||
| 9935 : | use @samp{string} as if it were you're own property because it will be | ||
| 9936 : | used again by the system. Copy it's contents to another string before | ||
| 9937 : | using the data. | ||
| 9938 : | @smallexample | ||
| 9939 : | char buffer[500]; | ||
| 9940 : | |||
| 9941 : | strcpy (buffer,string); | ||
| 9942 : | @end smallexample | ||
| 9943 : | |||
| 9944 : | |||
| 9945 : | @c ----------------------------------------------------------------------- | ||
| 9946 : | @c SECTION | ||
| 9947 : | @c ----------------------------------------------------------------------- | ||
| 9948 : | |||
| 9949 : | @node C files and dirs, File test macros, Environment variables in C, C programming | ||
| 9950 : | @section Files and directories | ||
| 9951 : | |||
| 9952 : | All of the regular C functions from the standard library are available | ||
| 9953 : | to Unix programmers. The standard functions only address the issue | ||
| 9954 : | of reading and writing to files however, they do not deal with operating | ||
| 9955 : | system specific attributes such as file permissions and file types. | ||
| 9956 : | Nor is there a mechanisms for obtaining lists of files within a | ||
| 9957 : | directory. The reason for these omissions is that they are operating | ||
| 9958 : | system dependent. To find out about these other attributes POSIX describes | ||
| 9959 : | some standard Unix system calls. | ||
| 9960 : | |||
| 9961 : | @c ..................................................... | ||
| 9962 : | @c SUBSECTION | ||
| 9963 : | @c ..................................................... | ||
| 9964 : | |||
| 9965 : | @menu | ||
| 9966 : | * opendir and readir:: | ||
| 9967 : | * stat:: | ||
| 9968 : | * lstat and readlink:: | ||
| 9969 : | @end menu | ||
| 9970 : | |||
| 9971 : | @node opendir and readir, stat, C files and dirs, C files and dirs | ||
| 9972 : | @subsection opendir, readdir | ||
| 9973 : | |||
| 9974 : | @cindex @code{opendir} command | ||
| 9975 : | @cindex @code{closedir} command | ||
| 9976 : | @cindex @code{readdir} command | ||
| 9977 : | @cindex dirent directory interface | ||
| 9978 : | |||
| 9979 : | Files and directories are handled by functions defined in the header | ||
| 9980 : | file @file{dirent.h}. In earlier UNIX systems the file @file{dir.h} was | ||
| 9981 : | used -- and the definitions were slightly different, but not much. To | ||
| 9982 : | get a list of files in a directory we must open the directory and read | ||
| 9983 : | from it -- just like a file. (A directory is just a file which contains | ||
| 9984 : | data on its entries). The commands are | ||
| 9985 : | @smallexample | ||
| 9986 : | opendir | ||
| 9987 : | closedir | ||
| 9988 : | readdir | ||
| 9989 : | @end smallexample | ||
| 9990 : | |||
| 9991 : | @noindent | ||
| 9992 : | See the manual pages for dirent. These functions return pointers to a | ||
| 9993 : | @code{dirent} structure which is defined in the file | ||
| 9994 : | @file{/usr/include/dirent.h}. Here is an example @code{ls} command | ||
| 9995 : | which lists the contents of the directory @file{/etc}. This header | ||
| 9996 : | defines a structure | ||
| 9997 : | |||
| 9998 : | @smallexample | ||
| 9999 : | |||
| 10000 : | struct dirent | ||
| 10001 : | @{ | ||
| 10002 : | off_t d_off; /* offset of next disk dir entry */ | ||
| 10003 : | unsigned long d_fileno; /* file number of entry */ | ||
| 10004 : | unsigned short d_reclen; /* length of this record */ | ||
| 10005 : | unsigned short d_namlen; /* length of string in d_name */ | ||
| 10006 : | char d_name[255+1]; /* name (up to MAXNAMLEN + 1) */ | ||
| 10007 : | @}; | ||
| 10008 : | |||
| 10009 : | @end smallexample | ||
| 10010 : | @noindent | ||
| 10011 : | which can be used to obtain information from the directory nodes. | ||
| 10012 : | |||
| 10013 : | @smallexample | ||
| 10014 : | |||
| 10015 : | #include <stdio.h> | ||
| 10016 : | #include <dirent.h> | ||
| 10017 : | |||
| 10018 : | main () | ||
| 10019 : | |||
| 10020 : | @{ DIR *dirh; | ||
| 10021 : | struct dirent *dirp; | ||
| 10022 : | static char mydir[20] = "/etc"; | ||
| 10023 : | |||
| 10024 : | if ((dirh = opendir(mydir)) == NULL) | ||
| 10025 : | @{ | ||
| 10026 : | perror("opendir"); | ||
| 10027 : | return; | ||
| 10028 : | @} | ||
| 10029 : | |||
| 10030 : | for (dirp = readdir(dirh); dirp != NULL; dirp = readdir(dirh)) | ||
| 10031 : | @{ | ||
| 10032 : | printf("Got dir entry: %s\n",dirp->d_name); | ||
| 10033 : | @} | ||
| 10034 : | |||
| 10035 : | closedir(dirh); | ||
| 10036 : | @} | ||
| 10037 : | |||
| 10038 : | @end smallexample | ||
| 10039 : | @noindent | ||
| 10040 : | Notice that reading from a directory is like reading from a file | ||
| 10041 : | with @code{fgets()}, | ||
| 10042 : | but the entries are filenames rather than lines of text. | ||
| 10043 : | |||
| 10044 : | @c ..................................................... | ||
| 10045 : | @c SUBSECTION | ||
| 10046 : | @c ..................................................... | ||
| 10047 : | |||
| 10048 : | @node stat, lstat and readlink, opendir and readir, C files and dirs | ||
| 10049 : | @subsection @code{stat()} | ||
| 10050 : | |||
| 10051 : | |||
| 10052 : | @cindex Information about file properties | ||
| 10053 : | @cindex Statistics about a file | ||
| 10054 : | @cindex @code{stat()} | ||
| 10055 : | @cindex @code{lstat()} | ||
| 10056 : | |||
| 10057 : | To determine the file properties or @emph{statistics} we use the | ||
| 10058 : | function call @samp{stat()} or its corollory @samp{lstat()}. Both these | ||
| 10059 : | functions find out information about files (permissions, owner, filetype | ||
| 10060 : | etc). The only difference between them is the way in which they treat | ||
| 10061 : | symbolic links. If @samp{stat} is used on a symbolic link, it stats the | ||
| 10062 : | file the link points to rather than the link itself. If @samp{lstat} is | ||
| 10063 : | used, the data refer to the link. Thus, to detect a link, we must use | ||
| 10064 : | @samp{lstat}, @xref{lstat and readlink}. | ||
| 10065 : | |||
| 10066 : | The data in the `stat' structure are defined in the file | ||
| 10067 : | @file{/usr/include/sys/stat.h}. Here are the most important structures. | ||
| 10068 : | |||
| 10069 : | @smallexample | ||
| 10070 : | |||
| 10071 : | struct stat | ||
| 10072 : | @{ | ||
| 10073 : | dev_t st_dev; /* device number*/ | ||
| 10074 : | ino_t st_ino; /* file inode */ | ||
| 10075 : | mode_t st_mode; /* permission */ | ||
| 10076 : | short st_nlink; /* Number of hardlinks to file */ | ||
| 10077 : | uid_t st_uid; /* user id */ | ||
| 10078 : | gid_t st_gid; /* group id */ | ||
| 10079 : | dev_t st_rdev; | ||
| 10080 : | off_t st_size; /* size in bytes */ | ||
| 10081 : | time_t st_atime; /* time file last accessed */ | ||
| 10082 : | time_t st_mtime; /* time file contents last modified */ | ||
| 10083 : | time_t st_ctime; /* time last attribute change */ | ||
| 10084 : | long st_blksize; | ||
| 10085 : | long st_blocks; | ||
| 10086 : | @}; | ||
| 10087 : | |||
| 10088 : | @end smallexample | ||
| 10089 : | |||
| 10090 : | |||
| 10091 : | @c ..................................................... | ||
| 10092 : | @c SUBSECTION | ||
| 10093 : | @c ..................................................... | ||
| 10094 : | |||
| 10095 : | @node lstat and readlink, , stat, C files and dirs | ||
| 10096 : | @subsection lstat and readlink | ||
| 10097 : | |||
| 10098 : | @cindex @code{readlink()} | ||
| 10099 : | @cindex Links, where do they point? | ||
| 10100 : | @cindex Links in C | ||
| 10101 : | |||
| 10102 : | The function @samp{stat()} treats symbolic links as though they | ||
| 10103 : | were the files they point to. In other words, if we use @samp{stat()} | ||
| 10104 : | to read a symbolic link, we end up reading the file the link points | ||
| 10105 : | to and not the link itself--- | ||
| 10106 : | we never see symbolic links. To avoid this problem, there is a different | ||
| 10107 : | version of the stat function called @samp{lstat()} which is identical | ||
| 10108 : | to @samp{stat()} except that it treats links as links and @emph{not} as | ||
| 10109 : | the files they point to. This means that we can test whether a file is a | ||
| 10110 : | symbolic link, only if we use @samp{lstat()}. (See the next paragraph.) | ||
| 10111 : | |||
| 10112 : | Once we have identified a file to be a symbolic link, we use the | ||
| 10113 : | @samp{readlink()} function to obtain the name of the file the | ||
| 10114 : | link points to. | ||
| 10115 : | @smallexample | ||
| 10116 : | |||
| 10117 : | #define bufsize 512 | ||
| 10118 : | char buffer[bufsize]; | ||
| 10119 : | |||
| 10120 : | readlink("/path/to/file",buffer,bufsize); | ||
| 10121 : | |||
| 10122 : | @end smallexample | ||
| 10123 : | |||
| 10124 : | @noindent | ||
| 10125 : | The result is returned in the string buffer. | ||
| 10126 : | |||
| 10127 : | @c ----------------------------------------------------------------------- | ||
| 10128 : | @c SECTION | ||
| 10129 : | @c ----------------------------------------------------------------------- | ||
| 10130 : | |||
| 10131 : | @node File test macros, Process control, C files and dirs, C programming | ||
| 10132 : | @section @code{stat()} test macros | ||
| 10133 : | |||
| 10134 : | @cindex Macros for stat | ||
| 10135 : | @cindex Permissions, determining in C | ||
| 10136 : | @cindex File type, determining in C | ||
| 10137 : | |||
| 10138 : | As we have already mentioned, the Unix mode bits contain not only | ||
| 10139 : | information about what permissions a file has, but also bits describing the | ||
| 10140 : | type of file -- whether it is a directory or a link etc. There are macros | ||
| 10141 : | defined in UNIX to extract this information from the @samp{st_mode} | ||
| 10142 : | member of the @samp{stat} structure. They are defined in the @samp{stat.h} | ||
| 10143 : | headerfile. Here are some examples. | ||
| 10144 : | |||
| 10145 : | @smallexample | ||
| 10146 : | #define S_ISBLK(m) /* is block device */ | ||
| 10147 : | #define S_ISCHR(m) /* is character device */ | ||
| 10148 : | #define S_ISDIR(m) /* is directory */ | ||
| 10149 : | #define S_ISFIFO(m) /* is fifo pipe/socket */ | ||
| 10150 : | #define S_ISREG(m) /* is regular (normal) file */ | ||
| 10151 : | |||
| 10152 : | #define S_ISLNK(m) /* is symbolic link */ /* Not POSIX */ | ||
| 10153 : | #define S_ISSOCK(m) /* is a lock */ | ||
| 10154 : | |||
| 10155 : | |||
| 10156 : | #define S_IRWXU /* rwx, owner */ | ||
| 10157 : | #define S_IRUSR /* read permission, owner */ | ||
| 10158 : | #define S_IWUSR /* write permission, owner */ | ||
| 10159 : | #define S_IXUSR /* execute/search permission, owner */ | ||
| 10160 : | #define S_IRWXG /* rwx, group */ | ||
| 10161 : | #define S_IRGRP /* read permission, group */ | ||
| 10162 : | #define S_IWGRP /* write permission, grougroup */ | ||
| 10163 : | #define S_IXGRP /* execute/search permission, group */ | ||
| 10164 : | #define S_IRWXO /* rwx, other */ | ||
| 10165 : | #define S_IROTH /* read permission, other */ | ||
| 10166 : | #define S_IWOTH /* write permission, other */ | ||
| 10167 : | #define S_IXOTH /* execute/search permission, other */ | ||
| 10168 : | |||
| 10169 : | @end smallexample | ||
| 10170 : | These return true or false when acting on the mode member. | ||
| 10171 : | Here is an example @xref{readdir example}. | ||
| 10172 : | @smallexample | ||
| 10173 : | |||
| 10174 : | struct stat statvar; | ||
| 10175 : | |||
| 10176 : | stat("file",&statvar); | ||
| 10177 : | |||
| 10178 : | /* test return values */ | ||
| 10179 : | |||
| 10180 : | if (S_ISDIR(statvar.st_mode)) | ||
| 10181 : | @{ | ||
| 10182 : | printf("Is a directory!"); | ||
| 10183 : | @} | ||
| 10184 : | |||
| 10185 : | @end smallexample | ||
| 10186 : | |||
| 10187 : | |||
| 10188 : | @c ..................................................... | ||
| 10189 : | @c SUBSECTION | ||
| 10190 : | @c ..................................................... | ||
| 10191 : | |||
| 10192 : | @menu | ||
| 10193 : | * readdir example:: | ||
| 10194 : | @end menu | ||
| 10195 : | |||
| 10196 : | @node readdir example, , File test macros, File test macros | ||
| 10197 : | @subsection Example filing program | ||
| 10198 : | |||
| 10199 : | The following example program demonstrates the use of the directory | ||
| 10200 : | functions in @code{dirent} and the @code{stat} function call. | ||
| 10201 : | |||
| 10202 : | @smallexample | ||
| 10203 : | /********************************************************************/ | ||
| 10204 : | /* */ | ||
| 10205 : | /* Reading directories and `statting' files */ | ||
| 10206 : | /* */ | ||
| 10207 : | /********************************************************************/ | ||
| 10208 : | |||
| 10209 : | #include <stdio.h> | ||
| 10210 : | #include <dirent.h> | ||
| 10211 : | #include <sys/types.h> | ||
| 10212 : | #include <sys/stat.h> | ||
| 10213 : | |||
| 10214 : | |||
| 10215 : | #define DIRNAME "/." | ||
| 10216 : | #define bufsize 255 | ||
| 10217 : | |||
| 10218 : | /********************************************************************/ | ||
| 10219 : | |||
| 10220 : | main () | ||
| 10221 : | |||
| 10222 : | |||
| 10223 : | @{ DIR *dirh; | ||
| 10224 : | struct dirent *dirp; | ||
| 10225 : | struct stat statbuf; | ||
| 10226 : | char *pathname[bufsize]; | ||
| 10227 : | char *linkname[bufsize]; | ||
| 10228 : | |||
| 10229 : | if ((dirh = opendir(DIRNAME)) == NULL) | ||
| 10230 : | @{ | ||
| 10231 : | perror("opendir"); | ||
| 10232 : | exit(1); | ||
| 10233 : | @} | ||
| 10234 : | |||
| 10235 : | for (dirp = readdir(dirh); dirp != NULL; dirp = readdir(dirh)) | ||
| 10236 : | @{ | ||
| 10237 : | if (strcmp(".",dirp->d_name) == 0 || strcmp("..",dirp->d_name) == 0) | ||
| 10238 : | @{ | ||
| 10239 : | continue; | ||
| 10240 : | @} | ||
| 10241 : | |||
| 10242 : | if (strcmp("lost+found",dirp->d_name) == 0) | ||
| 10243 : | @{ | ||
| 10244 : | continue; | ||
| 10245 : | @} | ||
| 10246 : | |||
| 10247 : | sprintf(pathname,"%s/%s",DIRNAME,dirp->d_name); | ||
| 10248 : | |||
| 10249 : | if (lstat(pathname,&statbuf) == -1) /* see man stat */ | ||
| 10250 : | @{ | ||
| 10251 : | perror("stat"); | ||
| 10252 : | continue; | ||
| 10253 : | @} | ||
| 10254 : | |||
| 10255 : | if (S_ISREG(statbuf.st_mode)) | ||
| 10256 : | @{ | ||
| 10257 : | printf("%s is a regular file\n",pathname); | ||
| 10258 : | @}; | ||
| 10259 : | |||
| 10260 : | if (S_ISDIR(statbuf.st_mode)) | ||
| 10261 : | @{ | ||
| 10262 : | printf("%s is a directory\n",pathname); | ||
| 10263 : | @} | ||
| 10264 : | |||
| 10265 : | if (S_ISLNK(statbuf.st_mode)) | ||
| 10266 : | @{ | ||
| 10267 : | bzero(linkname,bufsize); /* clear string */ | ||
| 10268 : | readlink(pathname,linkname,bufsize); | ||
| 10269 : | printf("%s is a link to %s\n",pathname,linkname); | ||
| 10270 : | @} | ||
| 10271 : | |||
| 10272 : | printf("The mode of %s is %o\n\n",pathname,statbuf.st_mode & 07777); | ||
| 10273 : | @} | ||
| 10274 : | |||
| 10275 : | closedir(dirh); | ||
| 10276 : | @} | ||
| 10277 : | |||
| 10278 : | @end smallexample | ||
| 10279 : | |||
| 10280 : | |||
| 10281 : | @c ----------------------------------------------------------------------- | ||
| 10282 : | @c SECTION | ||
| 10283 : | @c ----------------------------------------------------------------------- | ||
| 10284 : | |||
| 10285 : | @node Process control, A more secure popen, File test macros, C programming | ||
| 10286 : | @section Process control, @code{fork()}, @code{exec()}, @code{popen()} and system | ||
| 10287 : | |||
| 10288 : | There is a number of ways in which processes can interact with one | ||
| 10289 : | another and in which we can control their behaviour. We shall not go | ||
| 10290 : | into great detail in this course, only provide examples for | ||
| 10291 : | reference. | ||
| 10292 : | |||
| 10293 : | The UNIX @samp{fork()} function is used to create child processes. | ||
| 10294 : | This is the basis of all `heavyweight' multitasking under unix. | ||
| 10295 : | Here is a simple example of fork in which we start a child process | ||
| 10296 : | from within a program and wait for it to finish. Note that | ||
| 10297 : | the code for the parent and the child is is the same file. The | ||
| 10298 : | only thing that distinguishes parent from child is the value | ||
| 10299 : | returned by the fork function. | ||
| 10300 : | |||
| 10301 : | When @samp{fork()} is called, it duplicates the entire current | ||
| 10302 : | process so that two parallel processes are then running. The only | ||
| 10303 : | difference between these is that the child process (the copy) | ||
| 10304 : | gets a return value of zero from @samp{fork()}, whereas the | ||
| 10305 : | parent gets a return value equal to the process identifier | ||
| 10306 : | (pid) of the child. This value can be used by the parent | ||
| 10307 : | to send messages or to wait for the child. Here we show a | ||
| 10308 : | simple example in which the @samp{wait(NULL)} command is used | ||
| 10309 : | to wait for the last child spawned by the parent. | ||
| 10310 : | |||
| 10311 : | @smallexample | ||
| 10312 : | /**************************************************************/ | ||
| 10313 : | /* */ | ||
| 10314 : | /* A brief demo of the UNIX process duplicator fork(). */ | ||
| 10315 : | /* */ | ||
| 10316 : | /**************************************************************/ | ||
| 10317 : | |||
| 10318 : | #include <stdio.h> | ||
| 10319 : | |||
| 10320 : | |||
| 10321 : | /***************************************************************/ | ||
| 10322 : | |||
| 10323 : | main () | ||
| 10324 : | |||
| 10325 : | @{ int pid, cid; | ||
| 10326 : | |||
| 10327 : | pid = getpid(); | ||
| 10328 : | |||
| 10329 : | printf ("Fork demo! I am the parent (pid = %d)\n",pid); | ||
| 10330 : | |||
| 10331 : | if (! fork()) | ||
| 10332 : | @{ | ||
| 10333 : | cid = getpid(); | ||
| 10334 : | printf ("I am the child (cid = %d) of (pid=%d)\n",cid,pid); | ||
| 10335 : | ChildProcess(); | ||
| 10336 : | exit(0); | ||
| 10337 : | @} | ||
| 10338 : | |||
| 10339 : | |||
| 10340 : | printf("Parent waiting here for the child...\n"); | ||
| 10341 : | |||
| 10342 : | wait(NULL); | ||
| 10343 : | |||
| 10344 : | printf("Child finished, parent quitting too!\n"); | ||
| 10345 : | @} | ||
| 10346 : | |||
| 10347 : | /**************************************************************/ | ||
| 10348 : | |||
| 10349 : | ChildProcess() | ||
| 10350 : | |||
| 10351 : | @{ int i; | ||
| 10352 : | |||
| 10353 : | for (i = 0; i < 10; i++) | ||
| 10354 : | @{ | ||
| 10355 : | printf ("%d...\n",i); | ||
| 10356 : | sleep(1); | ||
| 10357 : | @} | ||
| 10358 : | @} | ||
| 10359 : | |||
| 10360 : | @end smallexample | ||
| 10361 : | |||
| 10362 : | Another possibility is that we might want to execute a program and | ||
| 10363 : | wait to find out what the result of the program is before | ||
| 10364 : | continuing. There are two ways to do this. The first is a variation | ||
| 10365 : | on the theme above and uses @code{fork()}. | ||
| 10366 : | |||
| 10367 : | Let's create a function which runs a shell command from within | ||
| 10368 : | a C program, and determines its return value. We make the | ||
| 10369 : | result a boolean (integer) value, so that the function returns | ||
| 10370 : | `true' if the shell command exits normally, @xref{Return codes}. | ||
| 10371 : | |||
| 10372 : | @smallexample | ||
| 10373 : | if (ShellCommandReturnsZero(@var{shell-command})) | ||
| 10374 : | @{ | ||
| 10375 : | printf ("Command %s went ok\n",@var{shell-command}); | ||
| 10376 : | @} | ||
| 10377 : | |||
| 10378 : | @end smallexample | ||
| 10379 : | |||
| 10380 : | @noindent | ||
| 10381 : | To do this we first have to fork a new process and then | ||
| 10382 : | use one of the @code{exec} commands to load a new | ||
| 10383 : | code image on top of the new process. | ||
| 10384 : | @cindex Starting | ||
| 10385 : | shell commands from C This sounds complicated, but it is necessary | ||
| 10386 : | because of the way unix handles processes. If we had no use for the | ||
| 10387 : | return value, we could simply execute a shell command using the | ||
| 10388 : | @code{system("shell command")} function, (which does all this for us) | ||
| 10389 : | but when @code{system()} exits, we can only tell if the command was | ||
| 10390 : | executed successfully or unsuccessfully---we learn nothing about what | ||
| 10391 : | actually failed (the shell or command which was executed under the | ||
| 10392 : | shell?) If we require detailed information about what happened to the | ||
| 10393 : | child process then we need to do the following. | ||
| 10394 : | |||
| 10395 : | @smallexample | ||
| 10396 : | #include <sys/types.h> | ||
| 10397 : | #include <sys/wait.h> | ||
| 10398 : | |||
| 10399 : | /* Send complete command as a string */ | ||
| 10400 : | /* including all arguments */ | ||
| 10401 : | |||
| 10402 : | ShellCommandReturnsZero(comm) | ||
| 10403 : | |||
| 10404 : | char *comm; | ||
| 10405 : | |||
| 10406 : | @{ int status, i, argc; | ||
| 10407 : | pid_t pid; | ||
| 10408 : | char arg[maxshellargs][bufsize]; | ||
| 10409 : | char **argv; | ||
| 10410 : | |||
| 10411 : | /* Build argument array for execv call*/ | ||
| 10412 : | |||
| 10413 : | for (i = 0; i < maxshellargs; i++) | ||
| 10414 : | @{ | ||
| 10415 : | bzero (arg[i],bufsize); | ||
| 10416 : | @} | ||
| 10417 : | |||
| 10418 : | argc = SplitCommand(comm,arg); | ||
| 10419 : | |||
| 10420 : | if ((pid = fork()) < 0) | ||
| 10421 : | @{ | ||
| 10422 : | FatalError("Failed to fork new process"); | ||
| 10423 : | @} | ||
| 10424 : | else if (pid == 0) /* child */ | ||
| 10425 : | @{ | ||
| 10426 : | argv = malloc((argc+1)*sizeof(char *)); | ||
| 10427 : | |||
| 10428 : | for (i = 0; i < argc; i++) | ||
| 10429 : | @{ | ||
| 10430 : | argv[i] = arg[i]; | ||
| 10431 : | @} | ||
| 10432 : | |||
| 10433 : | argv[i] = (char *) NULL; | ||
| 10434 : | |||
| 10435 : | if (execv(arg[0],argv) == -1) | ||
| 10436 : | @{ | ||
| 10437 : | yyerror("script failed"); | ||
| 10438 : | perror("execvp"); | ||
| 10439 : | exit(1); | ||
| 10440 : | @} | ||
| 10441 : | @} | ||
| 10442 : | else /* parent */ | ||
| 10443 : | @{ | ||
| 10444 : | if (wait(&status) != pid) | ||
| 10445 : | @{ | ||
| 10446 : | printf("Wait for child failed\n"); | ||
| 10447 : | perror("wait"); | ||
| 10448 : | return false; | ||
| 10449 : | @} | ||
| 10450 : | else | ||
| 10451 : | @{ | ||
| 10452 : | if (WIFSIGNALED(status)) | ||
| 10453 : | @{ | ||
| 10454 : | printf("Script %s returned: %s\n",comm,WTERMSIG(status)); | ||
| 10455 : | return false; | ||
| 10456 : | @} | ||
| 10457 : | |||
| 10458 : | if (! WIFEXITED(status)) | ||
| 10459 : | @{ | ||
| 10460 : | return false; | ||
| 10461 : | @} | ||
| 10462 : | |||
| 10463 : | if (WEXITSTATUS(status) == 0) | ||
| 10464 : | @{ | ||
| 10465 : | return true; | ||
| 10466 : | @} | ||
| 10467 : | else | ||
| 10468 : | @{ | ||
| 10469 : | return false; | ||
| 10470 : | @} | ||
| 10471 : | @} | ||
| 10472 : | @} | ||
| 10473 : | |||
| 10474 : | @} | ||
| 10475 : | |||
| 10476 : | /*******************************************************************/ | ||
| 10477 : | |||
| 10478 : | SplitCommand(comm,arg) | ||
| 10479 : | |||
| 10480 : | char *comm, arg[maxshellargs][bufsize]; | ||
| 10481 : | |||
| 10482 : | @{ char *sp; | ||
| 10483 : | int i = 0, j; | ||
| 10484 : | char buff[bufsize]; | ||
| 10485 : | |||
| 10486 : | for (sp = comm; *sp != NULL; sp++) | ||
| 10487 : | @{ | ||
| 10488 : | bzero(buff,bufsize); | ||
| 10489 : | |||
| 10490 : | if (i >= maxshellargs-1) | ||
| 10491 : | @{ | ||
| 10492 : | yyerror("Too many arguments in embedded script"); | ||
| 10493 : | FatalError("Use a wrapper"); | ||
| 10494 : | @} | ||
| 10495 : | |||
| 10496 : | while (*sp == ' ' || *sp == '\t') | ||
| 10497 : | @{ | ||
| 10498 : | sp++; | ||
| 10499 : | @} | ||
| 10500 : | |||
| 10501 : | switch (*sp) | ||
| 10502 : | @{ | ||
| 10503 : | case '\"': sscanf (++sp,"%[^\"]",buff); | ||
| 10504 : | break; | ||
| 10505 : | case '\'': sscanf (++sp,"%[^\']",buff); | ||
| 10506 : | break; | ||
| 10507 : | default: sscanf (sp,"%s",buff); | ||
| 10508 : | break; | ||
| 10509 : | @} | ||
| 10510 : | |||
| 10511 : | for (j = 0; j < bufsize; j++) | ||
| 10512 : | @{ | ||
| 10513 : | arg[i][j] = buff[j]; | ||
| 10514 : | @} | ||
| 10515 : | |||
| 10516 : | sp += strlen(arg[i]); | ||
| 10517 : | i++; | ||
| 10518 : | @} | ||
| 10519 : | return (i); | ||
| 10520 : | @} | ||
| 10521 : | |||
| 10522 : | @end smallexample | ||
| 10523 : | |||
| 10524 : | @noindent | ||
| 10525 : | In this example, the script waits for the exit signal from the child | ||
| 10526 : | process before continuing. The return value from the child is | ||
| 10527 : | available from the wait function with the help of a set of macros | ||
| 10528 : | defined in @file{/usr/include/sys/wait.h}. The value is | ||
| 10529 : | given by @code{WTERMSIG(status)}. | ||
| 10530 : | @cindex Waiting for child processes | ||
| 10531 : | @cindex @file{wait.h} | ||
| 10532 : | @cindex @code{WTERMSIG(status)} | ||
| 10533 : | |||
| 10534 : | In the final example, we can open a pipe to a | ||
| 10535 : | process directly in a C program | ||
| 10536 : | as though it were a file, by using the function @code{popen()}. | ||
| 10537 : | @cindex @code{popen()} | ||
| 10538 : | @cindex Pipes in C | ||
| 10539 : | @cindex Opening a pipe in C | ||
| 10540 : | Pipes may be opened for reading or for writing, in exactly the same | ||
| 10541 : | way as a file is opened. The child process is automatically | ||
| 10542 : | synchronized with the parent using this method. Here is a | ||
| 10543 : | program which opens a unix command for reading (both stdout and | ||
| 10544 : | stderr) from the child process are piped into the program. | ||
| 10545 : | Notice that the syntax used in this call is that used by | ||
| 10546 : | the Bourne shell, since this is build deeply into the unix | ||
| 10547 : | execution design. | ||
| 10548 : | |||
| 10549 : | @smallexample | ||
| 10550 : | |||
| 10551 : | #define bufsize 1024 | ||
| 10552 : | |||
| 10553 : | FILE *pp; | ||
| 10554 : | char VBUFF[bufsize]; | ||
| 10555 : | |||
| 10556 : | ... | ||
| 10557 : | |||
| 10558 : | if ((pp = popen( "/sbin/mount -va 2<&1","r")) == NULL) | ||
| 10559 : | @{ | ||
| 10560 : | printf("Failed to open pipe\n"); | ||
| 10561 : | return errorcode; | ||
| 10562 : | @} | ||
| 10563 : | |||
| 10564 : | while (!feof(pp)) | ||
| 10565 : | @{ | ||
| 10566 : | fgets(VBUFF,bufsize,pp); | ||
| 10567 : | |||
| 10568 : | /* Just write the output to stdout */ | ||
| 10569 : | |||
| 10570 : | printf ("Pipe read: %s\n",VBUFF); | ||
| 10571 : | @} | ||
| 10572 : | |||
| 10573 : | pclose(pp); | ||
| 10574 : | |||
| 10575 : | |||
| 10576 : | @end smallexample | ||
| 10577 : | |||
| 10578 : | |||
| 10579 : | @c ----------------------------------------------------------------------- | ||
| 10580 : | @c SECTION | ||
| 10581 : | @c ----------------------------------------------------------------------- | ||
| 10582 : | |||
| 10583 : | @node A more secure popen, Traps and signals, Process control, C programming | ||
| 10584 : | @section A more secure @code{popen()} | ||
| 10585 : | |||
| 10586 : | One problem with the @code{popen()} system call is that it uses a | ||
| 10587 : | shell to execute the command it obtains a pipe to. In the past this | ||
| 10588 : | has been used to allow Unix security breaches, using a so-called | ||
| 10589 : | @code{IFS} attack which can trick the shell into executing a program with | ||
| 10590 : | the name of the first node in the directory of the executable. For instance,if the pipe was to open the program @file{/bin/ps}, this coudl be tricked | ||
| 10591 : | into executing a program in the current working directory of the process | ||
| 10592 : | called @file{bin} with argument @samp{ps}. | ||
| 10593 : | |||
| 10594 : | The solution is not to use a shell at all, but to replace @code{popen()} | ||
| 10595 : | with a version which calls @code{exec()} directly. Here is a safe | ||
| 10596 : | version from the source code of cfengine: | ||
| 10597 : | |||
| 10598 : | @smallexample | ||
| 10599 : | |||
| 10600 : | #define bufsize 4096 | ||
| 10601 : | #define maxshellargs 20 | ||
| 10602 : | |||
| 10603 : | pid_t *CHILD; | ||
| 10604 : | int MAXFD = 20; /* Max number of simultaneous pipes */ | ||
| 10605 : | |||
| 10606 : | /***************************************************************/ | ||
| 10607 : | |||
| 10608 : | FILE *cfpopen(command, type) | ||
| 10609 : | |||
| 10610 : | char *command, *type; | ||
| 10611 : | |||
| 10612 : | @{ char arg[maxshellargs][bufsize]; | ||
| 10613 : | int i, argc, pd[2]; | ||
| 10614 : | char **argv; | ||
| 10615 : | pid_t pid; | ||
| 10616 : | FILE *pp = NULL; | ||
| 10617 : | |||
| 10618 : | if ((*type != 'r' && *type != 'w') || (type[1] != '\0')) | ||
| 10619 : | @{ | ||
| 10620 : | errno = EINVAL; | ||
| 10621 : | return NULL; | ||
| 10622 : | @} | ||
| 10623 : | |||
| 10624 : | if (CHILD == NULL) /* first time */ | ||
| 10625 : | @{ | ||
| 10626 : | if ((CHILD = calloc(MAXFD,sizeof(pid_t))) == NULL) | ||
| 10627 : | @{ | ||
| 10628 : | return NULL; | ||
| 10629 : | @} | ||
| 10630 : | @} | ||
| 10631 : | |||
| 10632 : | if (pipe(pd) < 0) /* Create a pair of descriptors to this process */ | ||
| 10633 : | @{ | ||
| 10634 : | return NULL; | ||
| 10635 : | @} | ||
| 10636 : | |||
| 10637 : | if ((pid = fork()) == -1) | ||
| 10638 : | @{ | ||
| 10639 : | return NULL; | ||
| 10640 : | @} | ||
| 10641 : | |||
| 10642 : | if (pid == 0) | ||
| 10643 : | @{ | ||
| 10644 : | switch (*type) | ||
| 10645 : | @{ | ||
| 10646 : | case 'r': | ||
| 10647 : | |||
| 10648 : | close(pd[0]); /* Don't need output from parent */ | ||
| 10649 : | |||
| 10650 : | if (pd[1] != 1) | ||
| 10651 : | @{ | ||
| 10652 : | dup2(pd[1],1); /* Attach pp=pd[1] to our stdout */ | ||
| 10653 : | dup2(pd[1],2); /* Merge stdout/stderr */ | ||
| 10654 : | close(pd[1]); | ||
| 10655 : | @} | ||
| 10656 : | |||
| 10657 : | break; | ||
| 10658 : | |||
| 10659 : | case 'w': | ||
| 10660 : | |||
| 10661 : | close(pd[1]); | ||
| 10662 : | |||
| 10663 : | if (pd[0] != 0) | ||
| 10664 : | @{ | ||
| 10665 : | dup2(pd[0],0); | ||
| 10666 : | close(pd[0]); | ||
| 10667 : | @} | ||
| 10668 : | @} | ||
| 10669 : | |||
| 10670 : | for (i = 0; i < MAXFD; i++) | ||
| 10671 : | @{ | ||
| 10672 : | if (CHILD[i] > 0) | ||
| 10673 : | @{ | ||
| 10674 : | close(CHILD[i]); | ||
| 10675 : | @} | ||
| 10676 : | |||
| 10677 : | argc = SplitCommand(command,arg); | ||
| 10678 : | argv = (char **) malloc((argc+1)*sizeof(char *)); | ||
| 10679 : | |||
| 10680 : | if (argv == NULL) | ||
| 10681 : | @{ | ||
| 10682 : | FatalError("Out of memory"); | ||
| 10683 : | @} | ||
| 10684 : | |||
| 10685 : | for (i = 0; i < argc; i++) | ||
| 10686 : | @{ | ||
| 10687 : | argv[i] = arg[i]; | ||
| 10688 : | @} | ||
| 10689 : | |||
| 10690 : | argv[i] = (char *) NULL; | ||
| 10691 : | |||
| 10692 : | if (execv(arg[0],argv) == -1) | ||
| 10693 : | @{ | ||
| 10694 : | sprintf(OUTPUT,"Couldn't run %s",arg[0]); | ||
| 10695 : | CfLog(cferror,OUTPUT,"execv"); | ||
| 10696 : | @} | ||
| 10697 : | |||
| 10698 : | _exit(1); | ||
| 10699 : | @} | ||
| 10700 : | @} | ||
| 10701 : | else | ||
| 10702 : | @{ | ||
| 10703 : | switch (*type) | ||
| 10704 : | @{ | ||
| 10705 : | case 'r': | ||
| 10706 : | |||
| 10707 : | close(pd[1]); | ||
| 10708 : | |||
| 10709 : | if ((pp = fdopen(pd[0],type)) == NULL) | ||
| 10710 : | @{ | ||
| 10711 : | return NULL; | ||
| 10712 : | @} | ||
| 10713 : | break; | ||
| 10714 : | |||
| 10715 : | case 'w': | ||
| 10716 : | |||
| 10717 : | close(pd[0]); | ||
| 10718 : | |||
| 10719 : | if ((pp = fdopen(pd[1],type)) == NULL) | ||
| 10720 : | @{ | ||
| 10721 : | return NULL; | ||
| 10722 : | @} | ||
| 10723 : | @} | ||
| 10724 : | |||
| 10725 : | CHILD[fileno(pp)] = pid; | ||
| 10726 : | return pp; | ||
| 10727 : | @} | ||
| 10728 : | @} | ||
| 10729 : | |||
| 10730 : | |||
| 10731 : | /***************************************************************/ | ||
| 10732 : | |||
| 10733 : | cfpclose(pp) | ||
| 10734 : | |||
| 10735 : | FILE *pp; | ||
| 10736 : | |||
| 10737 : | @{ int fd, status; | ||
| 10738 : | pid_t pid; | ||
| 10739 : | |||
| 10740 : | Debug("cfpclose(pp)\n"); | ||
| 10741 : | |||
| 10742 : | if (CHILD == NULL) /* popen hasn't been called */ | ||
| 10743 : | @{ | ||
| 10744 : | return -1; | ||
| 10745 : | @} | ||
| 10746 : | |||
| 10747 : | fd = fileno(pp); | ||
| 10748 : | |||
| 10749 : | if ((pid = CHILD[fd]) == 0) | ||
| 10750 : | @{ | ||
| 10751 : | return -1; | ||
| 10752 : | @} | ||
| 10753 : | |||
| 10754 : | CHILD[fd] = 0; | ||
| 10755 : | |||
| 10756 : | if (fclose(pp) == EOF) | ||
| 10757 : | @{ | ||
| 10758 : | return -1; | ||
| 10759 : | @} | ||
| 10760 : | |||
| 10761 : | Debug("cfpopen - Waiting for process %d\n",pid); | ||
| 10762 : | |||
| 10763 : | #ifdef HAVE_WAITPID | ||
| 10764 : | |||
| 10765 : | while(waitpid(pid,&status,0) < 0) | ||
| 10766 : | @{ | ||
| 10767 : | if (errno != EINTR) | ||
| 10768 : | @{ | ||
| 10769 : | return -1; | ||
| 10770 : | @} | ||
| 10771 : | @} | ||
| 10772 : | |||
| 10773 : | return status; | ||
| 10774 : | |||
| 10775 : | #else | ||
| 10776 : | |||
| 10777 : | if (wait(&status) != pid) | ||
| 10778 : | @{ | ||
| 10779 : | return -1; | ||
| 10780 : | @} | ||
| 10781 : | else | ||
| 10782 : | @{ | ||
| 10783 : | if (WIFSIGNALED(status)) | ||
| 10784 : | @{ | ||
| 10785 : | return -1; | ||
| 10786 : | @} | ||
| 10787 : | |||
| 10788 : | if (! WIFEXITED(status)) | ||
| 10789 : | @{ | ||
| 10790 : | return -1; | ||
| 10791 : | @} | ||
| 10792 : | |||
| 10793 : | return (WEXITSTATUS(status)); | ||
| 10794 : | @} | ||
| 10795 : | #endif | ||
| 10796 : | @} | ||
| 10797 : | |||
| 10798 : | /*******************************************************************/ | ||
| 10799 : | /* Command exec aids */ | ||
| 10800 : | /*******************************************************************/ | ||
| 10801 : | |||
| 10802 : | SplitCommand(comm,arg) | ||
| 10803 : | |||
| 10804 : | char *comm, arg[maxshellargs][bufsize]; | ||
| 10805 : | |||
| 10806 : | @{ char *sp; | ||
| 10807 : | int i = 0, j; | ||
| 10808 : | char buff[bufsize]; | ||
| 10809 : | |||
| 10810 : | for (sp = comm; sp < comm+strlen(comm); sp++) | ||
| 10811 : | @{ | ||
| 10812 : | bzero(buff,bufsize); | ||
| 10813 : | |||
| 10814 : | if (i >= maxshellargs-1) | ||
| 10815 : | @{ | ||
| 10816 : | CfLog(cferror,"Too many arguments in embedded script",""); | ||
| 10817 : | FatalError("Use a wrapper"); | ||
| 10818 : | @} | ||
| 10819 : | |||
| 10820 : | while (*sp == ' ' || *sp == '\t') | ||
| 10821 : | @{ | ||
| 10822 : | sp++; | ||
| 10823 : | @} | ||
| 10824 : | |||
| 10825 : | switch (*sp) | ||
| 10826 : | @{ | ||
| 10827 : | case '\0': return(i-1); | ||
| 10828 : | |||
| 10829 : | case '\"': sscanf (++sp,"%[^\"]",arg[i]); | ||
| 10830 : | break; | ||
| 10831 : | case '\'': sscanf (++sp,"%[^\']",arg[i]); | ||
| 10832 : | break; | ||
| 10833 : | case '`': sscanf (++sp,"%[^`]",arg[i]); | ||
| 10834 : | break; | ||
| 10835 : | default: sscanf (sp,"%s",arg[i]); | ||
| 10836 : | break; | ||
| 10837 : | @} | ||
| 10838 : | |||
| 10839 : | sp += strlen(arg[i]); | ||
| 10840 : | i++; | ||
| 10841 : | @} | ||
| 10842 : | |||
| 10843 : | return (i); | ||
| 10844 : | @} | ||
| 10845 : | |||
| 10846 : | @end smallexample | ||
| 10847 : | |||
| 10848 : | @c ----------------------------------------------------------------------- | ||
| 10849 : | @c SECTION | ||
| 10850 : | @c ----------------------------------------------------------------------- | ||
| 10851 : | |||
| 10852 : | @node Traps and signals, Regular expressions in C, A more secure popen, C programming | ||
| 10853 : | @section Traps and signals | ||
| 10854 : | |||
| 10855 : | Processes can receive signals from the UNIX kernel at any time. | ||
| 10856 : | Some of these signals terminate the execution of the program. | ||
| 10857 : | This can cause problems if the program is in the middle of critical | ||
| 10858 : | activity such as writing to a file. For that reason we can trap | ||
| 10859 : | signals and provide our own routine for handling them in a special way. | ||
| 10860 : | |||
| 10861 : | A signal handler is made by calling the function @samp{signal()} for | ||
| 10862 : | each signal and by specifying a pointer to a function which will be | ||
| 10863 : | called in the event of a signal. For example: | ||
| 10864 : | @smallexample | ||
| 10865 : | |||
| 10866 : | main () | ||
| 10867 : | |||
| 10868 : | @{ int HandleSignal(); | ||
| 10869 : | |||
| 10870 : | signal(SIGTERM,HandleSignal); | ||
| 10871 : | @} | ||
| 10872 : | |||
| 10873 : | |||
| 10874 : | HandleSignal() | ||
| 10875 : | |||
| 10876 : | @{ | ||
| 10877 : | /* Tidy up and exit cleanly */ | ||
| 10878 : | |||
| 10879 : | exit(0); | ||
| 10880 : | @} | ||
| 10881 : | |||
| 10882 : | @end smallexample | ||
| 10883 : | @samp{SIGTERM} is the usual signal sent by the command @samp{kill}. There are | ||
| 10884 : | many other signals which can be sent to programs. Here is list. | ||
| 10885 : | You have to decide for yourself whether or not you want to | ||
| 10886 : | provide your own signal handling function. | ||
| 10887 : | To ignore a signal, you write | ||
| 10888 : | @smallexample | ||
| 10889 : | |||
| 10890 : | signal(SIG@var{type},SIG_IGN); | ||
| 10891 : | |||
| 10892 : | @end smallexample | ||
| 10893 : | @noindent | ||
| 10894 : | To remove a signal handler and re-activate a signal, you write | ||
| 10895 : | @smallexample | ||
| 10896 : | |||
| 10897 : | signal(SIG@var{type},SIG_DFL); | ||
| 10898 : | |||
| 10899 : | @end smallexample | ||
| 10900 : | |||
| 10901 : | |||
| 10902 : | @c ----------------------------------------------------------------------- | ||
| 10903 : | @c SECTION | ||
| 10904 : | @c ----------------------------------------------------------------------- | ||
| 10905 : | |||
| 10906 : | @node Regular expressions in C, DES encryption, Traps and signals, C programming | ||
| 10907 : | @section Regular expressions | ||
| 10908 : | |||
| 10909 : | A regular expression is a pattern for matching strings of text. | ||
| 10910 : | We have met regular expressions earlier in connection with the | ||
| 10911 : | shell and Perl. Naturally these earlier encounters have their | ||
| 10912 : | roots in C functions for handling expressions. A regular | ||
| 10913 : | expression is used by first `compiling' it into a convenient | ||
| 10914 : | data structure. Then a matching function is used to compare the | ||
| 10915 : | expression with a test string. In this example program we show | ||
| 10916 : | how a regular expression typed in as an argument to the program | ||
| 10917 : | is found within strings of input entered on the keyboard. | ||
| 10918 : | |||
| 10919 : | |||
| 10920 : | @smallexample | ||
| 10921 : | |||
| 10922 : | #include <stdio.h> | ||
| 10923 : | #include <regex.h> | ||
| 10924 : | |||
| 10925 : | main (argc,argv) | ||
| 10926 : | |||
| 10927 : | int argc; | ||
| 10928 : | char **argv; | ||
| 10929 : | |||
| 10930 : | @{ | ||
| 10931 : | char buffer[1024]; | ||
| 10932 : | regex_t rx; | ||
| 10933 : | regmatch_t match; | ||
| 10934 : | size_t nmatch = 1; | ||
| 10935 : | |||
| 10936 : | if (regcomp(&rx, argv[1], REG_EXTENDED) != 0) | ||
| 10937 : | @{ | ||
| 10938 : | perror("regcomp"); | ||
| 10939 : | return; | ||
| 10940 : | @} | ||
| 10941 : | |||
| 10942 : | while (!feof(stdin)) | ||
| 10943 : | @{ | ||
| 10944 : | fgets(buffer,1024,stdin); | ||
| 10945 : | |||
| 10946 : | if (regexec(&rx,buffer,1,&match,0) == 0) | ||
| 10947 : | @{ | ||
| 10948 : | printf("Matched:(%s) at %d to %d",buffer,match.rm_so,match.rm_eo); | ||
| 10949 : | @} | ||
| 10950 : | |||
| 10951 : | @} | ||
| 10952 : | |||
| 10953 : | regfree(&rx); | ||
| 10954 : | @} | ||
| 10955 : | |||
| 10956 : | @end smallexample | ||
| 10957 : | |||
| 10958 : | Here is an example of its use. The | ||
| 10959 : | output of the program is in @emph{italics} | ||
| 10960 : | |||
| 10961 : | @smallexample | ||
| 10962 : | |||
| 10963 : | % a.out xyz | ||
| 10964 : | this is a string | ||
| 10965 : | another string | ||
| 10966 : | an xyz string | ||
| 10967 : | @emph{Matched: (an xyz string | ||
| 10968 : | ) at 3 to 6} | ||
| 10969 : | another xyz zyxxyz string | ||
| 10970 : | @emph{Matched: (another xyz xyz string | ||
| 10971 : | ) at 8 to 11} | ||
| 10972 : | |||
| 10973 : | % a.out 'xyz|abc' | ||
| 10974 : | This is a string | ||
| 10975 : | An abc string | ||
| 10976 : | @emph{Matched: (An abc string | ||
| 10977 : | ) at 3 to 6} | ||
| 10978 : | Or an xyz string | ||
| 10979 : | @emph{Matched: (Or an xyz string | ||
| 10980 : | ) at 6 to 9} | ||
| 10981 : | |||
| 10982 : | @end smallexample | ||
| 10983 : | If you don't want the match data set @code{&pm} to @code{NULL}. To get | ||
| 10984 : | an exact match rather than a substring check that the bounds are 0 and | ||
| 10985 : | @code{strlen(argv[1])-1}. | ||
| 10986 : | |||
| 10987 : | @c ----------------------------------------------------------------------- | ||
| 10988 : | @c SECTION | ||
| 10989 : | @c ----------------------------------------------------------------------- | ||
| 10990 : | |||
| 10991 : | @node DES encryption, ioctl, Regular expressions in C, C programming | ||
| 10992 : | @section DES encryption | ||
| 10993 : | |||
| 10994 : | Encryption with the SSLeay library, compile with command | ||
| 10995 : | |||
| 10996 : | @smallexample | ||
| 10997 : | |||
| 10998 : | gcc crypto.c -I/usr/local/ssl/include -L/usr/local/ssl/lib -lcrypto | ||
| 10999 : | |||
| 11000 : | @end smallexample | ||
| 11001 : | Example of normal triple DES encryption which works only on an 8-byte | ||
| 11002 : | buffer: | ||
| 11003 : | @smallexample | ||
| 11004 : | |||
| 11005 : | /*****************************************************************************/ | ||
| 11006 : | /* */ | ||
| 11007 : | /* File: crypto.c */ | ||
| 11008 : | /* */ | ||
| 11009 : | /* Compile with: gcc program.c -lcrypto (SSLeay) */ | ||
| 11010 : | /* */ | ||
| 11011 : | /*****************************************************************************/ | ||
| 11012 : | |||
| 11013 : | #include <stdio.h> | ||
| 11014 : | #include <des.h> | ||
| 11015 : | |||
| 11016 : | #define bufsize 1024 | ||
| 11017 : | |||
| 11018 : | /* Note how this truncates to 8 characters */ | ||
| 11019 : | |||
| 11020 : | main () | ||
| 11021 : | |||
| 11022 : | @{ char in[bufsize],out[bufsize],back[bufsize]; | ||
| 11023 : | des_cblock key1,key2,key3,seed = @{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10@}; | ||
| 11024 : | des_key_schedule ks1,ks2,ks3; | ||
| 11025 : | |||
| 11026 : | strcpy(in,"1 2 3 4 5 6 7 8 9 a b c d e f g h i j k"); | ||
| 11027 : | |||
| 11028 : | des_random_seed(seed); | ||
| 11029 : | |||
| 11030 : | des_random_key(key1); | ||
| 11031 : | des_random_key(key2); | ||
| 11032 : | des_random_key(key3); | ||
| 11033 : | |||
| 11034 : | des_set_key((C_Block *)key1,ks1); | ||
| 11035 : | des_set_key((C_Block *)key2,ks2); | ||
| 11036 : | des_set_key((C_Block *)key3,ks3); | ||
| 11037 : | des_ecb3_encrypt((C_Block *)in,(C_Block *)out,ks1,ks2,ks3,DES_ENCRYPT); | ||
| 11038 : | |||
| 11039 : | printf("Encrypted [%s] into [%s]\n",in,out); | ||
| 11040 : | |||
| 11041 : | des_ecb3_encrypt((C_Block *)out,(C_Block *)back,ks1,ks2,ks3,DES_DECRYPT); | ||
| 11042 : | |||
| 11043 : | printf("and back to.. [%s]\n",back); | ||
| 11044 : | @} | ||
| 11045 : | |||
| 11046 : | @end smallexample | ||
| 11047 : | Triple DES, chaining mode, for longer strings (which must be a multiple of | ||
| 11048 : | 8 bytes): | ||
| 11049 : | @smallexample | ||
| 11050 : | |||
| 11051 : | /*****************************************************************************/ | ||
| 11052 : | /* */ | ||
| 11053 : | /* File: crypto.c */ | ||
| 11054 : | /* */ | ||
| 11055 : | /* Compile with: gcc program.c -lcrypto (SSLeay) */ | ||
| 11056 : | /* */ | ||
| 11057 : | /*****************************************************************************/ | ||
| 11058 : | |||
| 11059 : | #include <stdio.h> | ||
| 11060 : | #include <des.h> | ||
| 11061 : | |||
| 11062 : | #define bufsize 1024 | ||
| 11063 : | |||
| 11064 : | /* This can be used on arbitrary length buffers */ | ||
| 11065 : | |||
| 11066 : | main () | ||
| 11067 : | |||
| 11068 : | @{ char in[bufsize],out[bufsize],back[bufsize],workvec[bufsize]; | ||
| 11069 : | des_cblock key1,key2,key3,seed = @{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10@}; | ||
| 11070 : | des_key_schedule ks1,ks2,ks3; | ||
| 11071 : | |||
| 11072 : | strcpy(in,"1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z"); | ||
| 11073 : | |||
| 11074 : | des_random_seed(seed); | ||
| 11075 : | |||
| 11076 : | des_random_key(key1); | ||
| 11077 : | des_random_key(key2); | ||
| 11078 : | des_random_key(key3); | ||
| 11079 : | |||
| 11080 : | des_set_key((C_Block *)key1,ks1); | ||
| 11081 : | des_set_key((C_Block *)key2,ks2); | ||
| 11082 : | des_set_key((C_Block *)key3,ks3); | ||
| 11083 : | |||
| 11084 : | /* This work vector can be intialized t anything ...*/ | ||
| 11085 : | |||
| 11086 : | memset(workvec,0,bufsize); | ||
| 11087 : | |||
| 11088 : | des_ede3_cbc_encrypt((C_Block *)in,(C_Block *)out,(long)strlen(in), | ||
| 11089 : | ks1,ks2,ks3,(C_Block *)workvec,DES_ENCRYPT); | ||
| 11090 : | |||
| 11091 : | printf("Encypted [%s] into [something]\n",in); | ||
| 11092 : | |||
| 11093 : | /* .. but this must be initialized the same as above */ | ||
| 11094 : | |||
| 11095 : | memset(workvec,0,bufsize); | ||
| 11096 : | |||
| 11097 : | /* Note that the length is the original length, not strlen(out) */ | ||
| 11098 : | |||
| 11099 : | des_ede3_cbc_encrypt((C_Block *)out,(C_Block *)back,(long)strlen(in), | ||
| 11100 : | ks1,ks2,ks3,(C_Block *)workvec,DES_DECRYPT); | ||
| 11101 : | |||
| 11102 : | printf("and back to.. [%s]\n",back); | ||
| 11103 : | @} | ||
| 11104 : | |||
| 11105 : | |||
| 11106 : | |||
| 11107 : | |||
| 11108 : | |||
| 11109 : | @end smallexample | ||
| 11110 : | |||
| 11111 : | |||
| 11112 : | @c ----------------------------------------------------------------------- | ||
| 11113 : | @c SECTION | ||
| 11114 : | @c ----------------------------------------------------------------------- | ||
| 11115 : | |||
| 11116 : | @node ioctl, Database example in C, DES encryption, C programming | ||
| 11117 : | @section Device control: ioctl | ||
| 11118 : | @cindex @code{ioctl()} | ||
| 11119 : | @vindex ioctl() | ||
| 11120 : | |||
| 11121 : | The C function @samp{ioctl} (I/O control) is used to send special | ||
| 11122 : | control commands to devices like the disk and the network interface. | ||
| 11123 : | The syntax of the function is | ||
| 11124 : | @smallexample | ||
| 11125 : | int ioctl(fd, request, arg) | ||
| 11126 : | int fd, request; | ||
| 11127 : | long arg; | ||
| 11128 : | @end smallexample | ||
| 11129 : | |||
| 11130 : | @noindent | ||
| 11131 : | The first parameter is normally as device handle or socket descriptor. | ||
| 11132 : | The second is a control parameter. Lists of valid control parameters are | ||
| 11133 : | normally defined in the system `include' files for a particular | ||
| 11134 : | device. They are device and system dependent so you need a local manual | ||
| 11135 : | and som detective work to find out what they are. | ||
| 11136 : | The final parameter is a pointer to a variable which | ||
| 11137 : | receives return data from the device. | ||
| 11138 : | |||
| 11139 : | @samp{ioctl} commands are device specific, by their nature. The commands | ||
| 11140 : | for the ethernet interface device are only partially standardized, for | ||
| 11141 : | example. We could read the ethernet device (which is called `le0' on a | ||
| 11142 : | Sun workstation), using the following command: | ||
| 11143 : | @smallexample | ||
| 11144 : | |||
| 11145 : | # include <sys/socket.h> /* Typical includes for internet */ | ||
| 11146 : | # include <sys/ioctl.h> | ||
| 11147 : | # include <net/if.h> | ||
| 11148 : | # include <netinet/in.h> | ||
| 11149 : | # include <arpa/inet.h> | ||
| 11150 : | # include <netdb.h> | ||
| 11151 : | # include <sys/protosw.h> | ||
| 11152 : | # include <net/route.h> | ||
| 11153 : | |||
| 11154 : | struct ifreq IFR; | ||
| 11155 : | int sk; | ||
| 11156 : | struct sockaddr_in sin; | ||
| 11157 : | |||
| 11158 : | strcpy(IFR.ifr_name,"le0"); | ||
| 11159 : | IFR.ifr_addr.sa_family = AF_INET; | ||
| 11160 : | |||
| 11161 : | if ((sk = socket(AF_INET,SOCK_DGRAM,IPPROTO_IP)) == -1) | ||
| 11162 : | @{ | ||
| 11163 : | perror("socket"); | ||
| 11164 : | exit(1); | ||
| 11165 : | @} | ||
| 11166 : | |||
| 11167 : | if (ioctl(sk,SIOCGIFFLAGS, (caddr_t) &IFR) == -1) | ||
| 11168 : | @{ | ||
| 11169 : | perror ("ioctl"); | ||
| 11170 : | exit(1); | ||
| 11171 : | @} | ||
| 11172 : | @end smallexample | ||
| 11173 : | |||
| 11174 : | We shall not go into the further details of @samp{ioctl}, but simply note | ||
| 11175 : | its role in system programming. | ||
| 11176 : | |||
| 11177 : | |||
| 11178 : | |||
| 11179 : | @c ----------------------------------------------------------------------- | ||
| 11180 : | @c SECTION | ||
| 11181 : | @c ----------------------------------------------------------------------- | ||
| 11182 : | |||
| 11183 : | @node Database example in C, lex and yacc, ioctl, C programming | ||
| 11184 : | @section Database example (Berkeley db) | ||
| 11185 : | |||
| 11186 : | @smallexample | ||
| 11187 : | |||
| 11188 : | DBT key,value; | ||
| 11189 : | DB *dbp; | ||
| 11190 : | DBC *dbcp; | ||
| 11191 : | db_recno_t recno; | ||
| 11192 : | |||
| 11193 : | if ((errno = db_open(CHECKSUMDB,DB_BTREE, DB_CREATE, 0664, NULL, NULL, &dbp)) != 0) | ||
| 11194 : | @{ | ||
| 11195 : | sprintf(OUTPUT,"cfd: couldn't open checksum database %s\n",CHECKSUMDB); | ||
| 11196 : | CfLog(cferror,OUTPUT,"db_open"); | ||
| 11197 : | return false; | ||
| 11198 : | @} | ||
| 11199 : | |||
| 11200 : | bzero(&value,sizeof(value)); | ||
| 11201 : | bzero(&key,sizeof(key)); | ||
| 11202 : | |||
| 11203 : | key.data = filename; | ||
| 11204 : | key.size = strlen(filename)+1; | ||
| 11205 : | value.data = dbvalue; | ||
| 11206 : | value.size = sizeof(dbvalue); | ||
| 11207 : | |||
| 11208 : | if ((errno = dbp->del(dbp,NULL,&key,0)) != 0) | ||
| 11209 : | @{ | ||
| 11210 : | CfLog(cferror,"","db_store"); | ||
| 11211 : | @} | ||
| 11212 : | |||
| 11213 : | key.data = filename; | ||
| 11214 : | key.size = strlen(filename)+1; | ||
| 11215 : | |||
| 11216 : | if ((errno = dbp->put(dbp,NULL,&key,&value,0)) != 0) | ||
| 11217 : | @{ | ||
| 11218 : | CfLog(cferror,"put failed","db->put"); | ||
| 11219 : | @} | ||
| 11220 : | |||
| 11221 : | if ((errno = dbp->get(dbp,NULL,&key,&value,0)) == 0) | ||
| 11222 : | @{ | ||
| 11223 : | /* Not found ... */ | ||
| 11224 : | return; | ||
| 11225 : | @} | ||
| 11226 : | |||
| 11227 : | dbp->close(dbp,0); | ||
| 11228 : | |||
| 11229 : | @end smallexample | ||
| 11230 : | |||
| 11231 : | @c ----------------------------------------------------------------------- | ||
| 11232 : | @c SECTION | ||
| 11233 : | @c ----------------------------------------------------------------------- | ||
| 11234 : | |||
| 11235 : | @node lex and yacc, Ex 6, Database example in C, C programming | ||
| 11236 : | @section Text parsing tools: @samp{lex} and @samp{yacc} | ||
| 11237 : | |||
| 11238 : | @cindex Lexer | ||
| 11239 : | @cindex Parser | ||
| 11240 : | @cindex @samp{yacc} | ||
| 11241 : | |||
| 11242 : | @emph{This section is a taster only. You only need to know what lex and | ||
| 11243 : | yacc are, not how they work.} | ||
| 11244 : | |||
| 11245 : | @samp{lex} and @samp{yacc} are two tools for the C programmer who wishes | ||
| 11246 : | to make a text parser. A text parser is a program which reads a text file | ||
| 11247 : | and interprets the symbols in it. Every programming language must | ||
| 11248 : | include a text parser, for instance. | ||
| 11249 : | |||
| 11250 : | The @samp{yacc} (yet another compiler compiler) program generates C | ||
| 11251 : | code which parses a textfile, given a description of the syntax | ||
| 11252 : | rules for the file. In other words, we define the logical structure | ||
| 11253 : | of the text file, according to the way we wish to interpret it | ||
| 11254 : | and give the rules to @samp{yacc}. @samp{yacc} produces C code | ||
| 11255 : | from this which does the job. | ||
| 11256 : | |||
| 11257 : | @samp{lex} is a `lexer'. It is normally used together with @samp{yacc}. | ||
| 11258 : | @samp{lex} @emph{tokenizes} or identifies symbols in | ||
| 11259 : | a file. What that means is that it reads in a file and matches | ||
| 11260 : | @emph{types} of string in the file which are defined in terms of | ||
| 11261 : | regular expressions by the programmer, and returns symbolic | ||
| 11262 : | values for those strings. | ||
| 11263 : | |||
| 11264 : | Although @samp{lex} can be used by independently of @samp{yacc}, it | ||
| 11265 : | is normally used to identify the different @emph{types} of string which | ||
| 11266 : | define the syntax of a file. For example, suppose @samp{yacc} | ||
| 11267 : | was parsing a C program. On the beginning of a line, it | ||
| 11268 : | might expect to find either a variable name or a preprocessor symbol. | ||
| 11269 : | A variable name is just a string consisting of characters from | ||
| 11270 : | the set @samp{0-9a-Z_}, whereas a preprocessor command always | ||
| 11271 : | starts with the character @samp{#}. @samp{yacc} passes control to @samp{lex} | ||
| 11272 : | which reads the file and matches the first object on the line. | ||
| 11273 : | If it finds a variable, it returns to @samp{yacc} a @emph{token} | ||
| 11274 : | which is a number or value | ||
| 11275 : | corresponding to `variable'. Similarly, if it finds a preprocessor | ||
| 11276 : | command, it returns a token for that. If it doesn't match either | ||
| 11277 : | type it returns something else and @samp{yacc} signals a syntax error. | ||
| 11278 : | |||
| 11279 : | Here is a @samp{yacc} file which parses a file | ||
| 11280 : | consisting of lines of the form | ||
| 11281 : | a+b, where $a$ and $b$ are numbers -- | ||
| 11282 : | any other syntax is incorrect. | ||
| 11283 : | We could have used this later in the example | ||
| 11284 : | program for the client-server example, @xref{Sockets}. | ||
| 11285 : | |||
| 11286 : | You can learn more about lex and yacc in @emph{"Lex and Yacc", J. Levine, | ||
| 11287 : | T. Mason and D. Brown, O'Reilly and Assoc.} | ||
| 11288 : | |||
| 11289 : | @smallexample | ||
| 11290 : | %@{ | ||
| 11291 : | /*******************************************************************/ | ||
| 11292 : | /* */ | ||
| 11293 : | /* PARSER for a + b protocol */ | ||
| 11294 : | /* */ | ||
| 11295 : | /* The section between the single %'s gets copied verbatim into */ | ||
| 11296 : | /* the resulting C code yacc generates -- including this comment! */ | ||
| 11297 : | /* */ | ||
| 11298 : | /*******************************************************************/ | ||
| 11299 : | |||
| 11300 : | #include <stdio.h> | ||
| 11301 : | |||
| 11302 : | extern char *yytext; | ||
| 11303 : | |||
| 11304 : | %@} | ||
| 11305 : | |||
| 11306 : | %token NUMBER PLUS | ||
| 11307 : | |||
| 11308 : | %% | ||
| 11309 : | |||
| 11310 : | specification: @{ yyerror("Warning: invalid statement");@} | ||
| 11311 : | | statement; | ||
| 11312 : | |||
| 11313 : | statement: NUMBER PLUS NUMBER; | ||
| 11314 : | |||
| 11315 : | @end smallexample | ||
| 11316 : | |||
| 11317 : | @noindent | ||
| 11318 : | The lexer to go with this parser generates the tokens NUMBER and PLUS | ||
| 11319 : | used by @samp{yacc}: | ||
| 11320 : | |||
| 11321 : | @smallexample | ||
| 11322 : | %@{ | ||
| 11323 : | /*******************************************************************/ | ||
| 11324 : | /* */ | ||
| 11325 : | /* LEXER for a + b protocol */ | ||
| 11326 : | /* */ | ||
| 11327 : | /* Returns token types NUMBER and PLUS to yacc, one at a time */ | ||
| 11328 : | /* */ | ||
| 11329 : | /*******************************************************************/ | ||
| 11330 : | |||
| 11331 : | |||
| 11332 : | #include "y.tab.h" /* yacc produces this -- need this line! */ | ||
| 11333 : | |||
| 11334 : | |||
| 11335 : | %@} | ||
| 11336 : | |||
| 11337 : | |||
| 11338 : | number [0-9]+ | ||
| 11339 : | plus [+] | ||
| 11340 : | |||
| 11341 : | %% | ||
| 11342 : | |||
| 11343 : | |||
| 11344 : | number @{ | ||
| 11345 : | return NUMBER; | ||
| 11346 : | @} | ||
| 11347 : | |||
| 11348 : | plus @{ | ||
| 11349 : | return PLUS; | ||
| 11350 : | @} | ||
| 11351 : | |||
| 11352 : | . @{ | ||
| 11353 : | return yytext[0]; | ||
| 11354 : | @} | ||
| 11355 : | |||
| 11356 : | %% | ||
| 11357 : | |||
| 11358 : | /* EOF */ | ||
| 11359 : | |||
| 11360 : | @end smallexample | ||
| 11361 : | |||
| 11362 : | The main program which uses @samp{yacc} and @samp{lex} looks like this: | ||
| 11363 : | |||
| 11364 : | @smallexample | ||
| 11365 : | |||
| 11366 : | extern FILE *yyin; | ||
| 11367 : | |||
| 11368 : | main () | ||
| 11369 : | |||
| 11370 : | @{ | ||
| 11371 : | |||
| 11372 : | if ((yyin = fopen("My_Input_File","r")) == NULL) /* Open file */ | ||
| 11373 : | @{ | ||
| 11374 : | printf("Can't open file\n"); | ||
| 11375 : | exit (1); | ||
| 11376 : | @} | ||
| 11377 : | |||
| 11378 : | while (!feof(yyin)) | ||
| 11379 : | @{ | ||
| 11380 : | yyparse(); | ||
| 11381 : | @} | ||
| 11382 : | |||
| 11383 : | fclose (yyin); | ||
| 11384 : | @} | ||
| 11385 : | @end smallexample | ||
| 11386 : | |||
| 11387 : | |||
| 11388 : | |||
| 11389 : | |||
| 11390 : | @c ----------------------------------------------------------------------- | ||
| 11391 : | @c SECTION | ||
| 11392 : | @c ----------------------------------------------------------------------- | ||
| 11393 : | |||
| 11394 : | @node Ex 6, , lex and yacc, C programming | ||
| 11395 : | @section Exercises | ||
| 11396 : | |||
| 11397 : | @enumerate | ||
| 11398 : | |||
| 11399 : | @item | ||
| 11400 : | Write a daemon program with a signal handler which makes a log | ||
| 11401 : | of the heaviest (maximum cpu) process running, every five minutes. The | ||
| 11402 : | program should exit if the log file becomes greater than 5-kbytes. | ||
| 11403 : | |||
| 11404 : | @item | ||
| 11405 : | Rewrite in C the perl program which lists all the files in | ||
| 11406 : | the current directory containing a certain string. | ||
| 11407 : | |||
| 11408 : | @item | ||
| 11409 : | Write a version of `more' which prints control characters safely. | ||
| 11410 : | See the @samp{cat -e} command. | ||
| 11411 : | |||
| 11412 : | @item | ||
| 11413 : | Write a Makefile to create a shared library from a number of object files. | ||
| 11414 : | |||
| 11415 : | @end enumerate | ||
| 11416 : | |||
| 11417 : | @c ********************************************************************** | ||
| 11418 : | @c CHAPTER | ||
| 11419 : | @c ********************************************************************** | ||
| 11420 : | |||
| 11421 : | @node Network programming, Programming idioms, C programming, Top | ||
| 11422 : | @chapter Network Programming | ||
| 11423 : | |||
| 11424 : | Client-server communication is the basis of modern operating system | ||
| 11425 : | technology. The Unix socket mechanism makes stream-based communication | ||
| 11426 : | virtually transparent. | ||
| 11427 : | |||
| 11428 : | @c ----------------------------------------------------------------------- | ||
| 11429 : | @c SECTION | ||
| 11430 : | @c ----------------------------------------------------------------------- | ||
| 11431 : | |||
| 11432 : | @menu | ||
| 11433 : | * Sockets:: | ||
| 11434 : | * Multithreading a server:: | ||
| 11435 : | * System databases:: | ||
| 11436 : | * DNS:: | ||
| 11437 : | * C and NFS:: | ||
| 11438 : | * Ex 7:: | ||
| 11439 : | @end menu | ||
| 11440 : | |||
| 11441 : | @node Sockets, Multithreading a server, Network programming, Network programming | ||
| 11442 : | @section Socket streams | ||
| 11443 : | |||
| 11444 : | Analogous to filestreams are @emph{sockets} or TCP/IP @emph{network | ||
| 11445 : | connections}. A socket is a two-way (read/write) pseudo-file node. An | ||
| 11446 : | open socket stream is like an open file-descriptor. Berkeley sockets | ||
| 11447 : | are part of the standard C library. | ||
| 11448 : | |||
| 11449 : | There are two main kinds of socket: TCP/IP sockets and Unix domain | ||
| 11450 : | sockets. Unix sockets can be used to provide local interprocess | ||
| 11451 : | communication using a filestream communication protocol. TCP/IP sockets | ||
| 11452 : | open file descriptors across the network. | ||
| 11453 : | @cindex Sockets | ||
| 11454 : | @cindex TCP/IP | ||
| 11455 : | @cindex @code{INADDR_ANY} | ||
| 11456 : | A TCP/IP socket is | ||
| 11457 : | a file stream associated with an IP address and a port number. | ||
| 11458 : | We write to a socket descriptor just as with a file descriptor, either | ||
| 11459 : | with @code{write()} or using @code{send()}. | ||
| 11460 : | |||
| 11461 : | When sending binary data over a network we have to be careful about | ||
| 11462 : | machine level representations of data. | ||
| 11463 : | Operating systems (actually the hardware they run on) fall into | ||
| 11464 : | two categories known as @emph{big endian} and @emph{little endian}. The | ||
| 11465 : | names refer to the @emph{byte-order} of numerical representations. | ||
| 11466 : | @cindex Byte order | ||
| 11467 : | @cindex Network byte order | ||
| 11468 : | @cindex Big endian | ||
| 11469 : | @cindex Little endian | ||
| 11470 : | The names indicate how large integers (which require say 32 bits or more) | ||
| 11471 : | are stored in memory. Little endian systems store the least significant byte | ||
| 11472 : | first, while big endian systems store the most significant byte first. | ||
| 11473 : | For example, the representation of the number 34,677,374 has either of | ||
| 11474 : | these forms. | ||
| 11475 : | |||
| 11476 : | @smallexample | ||
| 11477 : | |||
| 11478 : | ----------------------------------- | ||
| 11479 : | Big | 2 | 17 | 34 | 126 | | ||
| 11480 : | ----------------------------------- | ||
| 11481 : | |||
| 11482 : | ----------------------------------- | ||
| 11483 : | Little | 126 | 34 | 17 | 2 | | ||
| 11484 : | ----------------------------------- | ||
| 11485 : | |||
| 11486 : | @end smallexample | ||
| 11487 : | |||
| 11488 : | Obviously if we are transferring data from one host to another, both | ||
| 11489 : | hosts have to agree on the data representation otherwise there would be | ||
| 11490 : | disastrous consequences. This means that there has to be a common | ||
| 11491 : | standard of @emph{network byte ordering}. For example, Solaris (SPARC | ||
| 11492 : | hardware) uses network byte ordering (big endian), while GNU/Linux | ||
| 11493 : | (Intel hardware) uses the opposite (little endian). This means that | ||
| 11494 : | Intel systems have to convert the format every time something is | ||
| 11495 : | transmitted over the network. Unix systems provide generic functions | ||
| 11496 : | for converting between host-byteorder and network-byteorder for small | ||
| 11497 : | and long integer data: | ||
| 11498 : | @smallexample | ||
| 11499 : | |||
| 11500 : | htonl, htons, ntohl, ntohs | ||
| 11501 : | |||
| 11502 : | @end smallexample | ||
| 11503 : | @noindent | ||
| 11504 : | Here we list two example programs which show how to make a client-server | ||
| 11505 : | pair. The server enters a loop, and listens for connections from any | ||
| 11506 : | clients (the generic address @samp{INADDR_ANY} is a wildcard for any | ||
| 11507 : | address on the current local network segment). The client program sends | ||
| 11508 : | requests to the server as a protocol in the form of a string of the type | ||
| 11509 : | @samp{a + b}. Normally @samp{a} and @samp{b} are numbers, in which case | ||
| 11510 : | the server returns their sum to the client. If the message has the | ||
| 11511 : | special form @samp{halt + *}, where the star is arbitrary, then the | ||
| 11512 : | server shuts down. Any other form of message results in an error, which | ||
| 11513 : | the server signals to the client. | ||
| 11514 : | |||
| 11515 : | The basic structure of the client-server components in terms of | ||
| 11516 : | system calls is this: | ||
| 11517 : | |||
| 11518 : | @smallexample | ||
| 11519 : | |||
| 11520 : | Client: | ||
| 11521 : | |||
| 11522 : | socket() @var{Create a socket} | ||
| 11523 : | connect() @var{Contact a server socket (IP + port)} | ||
| 11524 : | |||
| 11525 : | while (?) | ||
| 11526 : | @{ | ||
| 11527 : | send() @var{Send to server} | ||
| 11528 : | recv() @var{Receive from server} | ||
| 11529 : | @} | ||
| 11530 : | |||
| 11531 : | Server: | ||
| 11532 : | |||
| 11533 : | socket() @var{Create a socket} | ||
| 11534 : | bind() @var{Associates the socket with a fixed address} | ||
| 11535 : | listen() @var{Create a listen queue} | ||
| 11536 : | |||
| 11537 : | while() | ||
| 11538 : | @{ | ||
| 11539 : | reply=accept() @var{Accept a connection request} | ||
| 11540 : | recv() @var{Receive from client} | ||
| 11541 : | send() @var{Send to client} | ||
| 11542 : | @} | ||
| 11543 : | |||
| 11544 : | @end smallexample | ||
| 11545 : | |||
| 11546 : | @smallexample | ||
| 11547 : | /**********************************************************************/ | ||
| 11548 : | /* */ | ||
| 11549 : | /* The client part of a client-server pair. This simply takes two */ | ||
| 11550 : | /* numbers and adds them together, returning the result to the client */ | ||
| 11551 : | /* */ | ||
| 11552 : | /* Compiled with: */ | ||
| 11553 : | /* cc server.c */ | ||
| 11554 : | /* */ | ||
| 11555 : | /* User types: */ | ||
| 11556 : | /* 3 + 5 */ | ||
| 11557 : | /* a + b */ | ||
| 11558 : | /* halt + server */ | ||
| 11559 : | /**********************************************************************/ | ||
| 11560 : | |||
| 11561 : | #include <stdio.h> | ||
| 11562 : | #include <sys/types.h> | ||
| 11563 : | #include <sys/socket.h> | ||
| 11564 : | #include <netinet/in.h> | ||
| 11565 : | #include <netdb.h> | ||
| 11566 : | |||
| 11567 : | |||
| 11568 : | #define PORT 9000 /* Arbitrary non-reserved port */ | ||
| 11569 : | #define HOST "nexus.iu.hioslo.no" | ||
| 11570 : | #define bufsize 20 | ||
| 11571 : | |||
| 11572 : | /**********************************************************************/ | ||
| 11573 : | /* Main */ | ||
| 11574 : | /**********************************************************************/ | ||
| 11575 : | |||
| 11576 : | main (argc,argv) | ||
| 11577 : | |||
| 11578 : | int argc; | ||
| 11579 : | char *argv[]; | ||
| 11580 : | |||
| 11581 : | @{ struct sockaddr_in cin; | ||
| 11582 : | struct hostent *hp; | ||
| 11583 : | char buffer[bufsize]; | ||
| 11584 : | int sd; | ||
| 11585 : | |||
| 11586 : | if (argc != 4) | ||
| 11587 : | @{ | ||
| 11588 : | printf("syntax: client a + b\n"); | ||
| 11589 : | exit(1); | ||
| 11590 : | @} | ||
| 11591 : | |||
| 11592 : | @cindex @code{gethostbyname()} | ||
| 11593 : | if ((hp = gethostbyname(HOST)) == NULL) | ||
| 11594 : | @{ | ||
| 11595 : | perror("gethostbyname: "); | ||
| 11596 : | exit(1); | ||
| 11597 : | @} | ||
| 11598 : | |||
| 11599 : | memset(&cin,0,sizeof(cin)); /* Another way to zero memory */ | ||
| 11600 : | |||
| 11601 : | cin.sin_family = AF_INET; | ||
| 11602 : | cin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr; | ||
| 11603 : | cin.sin_port = htons(PORT); | ||
| 11604 : | |||
| 11605 : | printf("Trying to connect to %s = %s\n",HOST,inet_ntoa(cin.sin_addr)); | ||
| 11606 : | |||
| 11607 : | @cindex @code{socket()} | ||
| 11608 : | if ((sd = socket(AF_INET,SOCK_STREAM,0)) == -1) | ||
| 11609 : | @{ | ||
| 11610 : | perror("socket"); | ||
| 11611 : | exit(1); | ||
| 11612 : | @} | ||
| 11613 : | |||
| 11614 : | @cindex @code{connect()} | ||
| 11615 : | if (connect(sd,&cin,sizeof(cin)) == -1) | ||
| 11616 : | @{ | ||
| 11617 : | perror("connect"); | ||
| 11618 : | exit(1); | ||
| 11619 : | @} | ||
| 11620 : | |||
| 11621 : | sprintf(buffer,"%s + %s",argv[1],argv[3]); | ||
| 11622 : | |||
| 11623 : | @cindex @code{send()} | ||
| 11624 : | if (send(sd,buffer,strlen(buffer),0) == -1) | ||
| 11625 : | @{ | ||
| 11626 : | perror ("send"); | ||
| 11627 : | exit(1); | ||
| 11628 : | @} | ||
| 11629 : | |||
| 11630 : | @cindex @code{recv()} | ||
| 11631 : | if (recv(sd,buffer,bufsize,0) == -1) | ||
| 11632 : | @{ | ||
| 11633 : | perror("recv"); | ||
| 11634 : | exit (1); | ||
| 11635 : | @} | ||
| 11636 : | |||
| 11637 : | printf ("Server responded with %s\n",buffer); | ||
| 11638 : | |||
| 11639 : | close (sd); | ||
| 11640 : | unlink("./socket"); | ||
| 11641 : | @} | ||
| 11642 : | |||
| 11643 : | @end smallexample | ||
| 11644 : | |||
| 11645 : | |||
| 11646 : | |||
| 11647 : | |||
| 11648 : | |||
| 11649 : | |||
| 11650 : | @smallexample | ||
| 11651 : | /**********************************************************************/ | ||
| 11652 : | /* */ | ||
| 11653 : | /* The server part of a client-server pair. This simply takes two */ | ||
| 11654 : | /* numbers and adds them together, returning the result to the client */ | ||
| 11655 : | /* */ | ||
| 11656 : | /* Compiled with: */ | ||
| 11657 : | /* cc server.c */ | ||
| 11658 : | /* */ | ||
| 11659 : | /**********************************************************************/ | ||
| 11660 : | |||
| 11661 : | #include <stdio.h> | ||
| 11662 : | #include <sys/types.h> | ||
| 11663 : | #include <sys/socket.h> | ||
| 11664 : | #include <netinet/in.h> | ||
| 11665 : | #include <netdb.h> | ||
| 11666 : | |||
| 11667 : | |||
| 11668 : | #define PORT 9000 | ||
| 11669 : | #define bufsize 20 | ||
| 11670 : | #define queuesize 5 | ||
| 11671 : | #define true 1 | ||
| 11672 : | #define false 0 | ||
| 11673 : | |||
| 11674 : | /**********************************************************************/ | ||
| 11675 : | /* Main */ | ||
| 11676 : | /**********************************************************************/ | ||
| 11677 : | |||
| 11678 : | main () | ||
| 11679 : | |||
| 11680 : | @{ struct sockaddr_in cin; | ||
| 11681 : | struct sockaddr_in sin; | ||
| 11682 : | struct hostent *hp; | ||
| 11683 : | char buffer[bufsize]; | ||
| 11684 : | int sd, sd_client, addrlen; | ||
| 11685 : | |||
| 11686 : | |||
| 11687 : | memset(&sin,0,sizeof(sin)); /* Another way to zero memory */ | ||
| 11688 : | sin.sin_family = AF_INET; | ||
| 11689 : | sin.sin_addr.s_addr = INADDR_ANY; /* Broadcast address */ | ||
| 11690 : | sin.sin_port = htons(PORT); | ||
| 11691 : | |||
| 11692 : | |||
| 11693 : | if ((sd = socket(AF_INET,SOCK_STREAM,0)) == -1) | ||
| 11694 : | @{ | ||
| 11695 : | perror("socket"); | ||
| 11696 : | exit(1); | ||
| 11697 : | @} | ||
| 11698 : | |||
| 11699 : | @cindex @code{bind()} | ||
| 11700 : | if (bind(sd,&sin,sizeof(sin)) == -1) /* Must have this on server */ | ||
| 11701 : | @{ | ||
| 11702 : | perror("bind"); | ||
| 11703 : | exit(1); | ||
| 11704 : | @} | ||
| 11705 : | |||
| 11706 : | @cindex @code{listen()} | ||
| 11707 : | if (listen(sd,queuesize) == -1) | ||
| 11708 : | @{ | ||
| 11709 : | perror("listen"); | ||
| 11710 : | exit(1); | ||
| 11711 : | @} | ||
| 11712 : | |||
| 11713 : | @cindex @code{accept()} | ||
| 11714 : | while (true) | ||
| 11715 : | @{ | ||
| 11716 : | if ((sd_client = accept(sd,&cin,&addrlen)) == -1) | ||
| 11717 : | @{ | ||
| 11718 : | perror("accept"); | ||
| 11719 : | exit(1); | ||
| 11720 : | @} | ||
| 11721 : | |||
| 11722 : | if (recv(sd_client,buffer,sizeof(buffer),0) == -1) | ||
| 11723 : | @{ | ||
| 11724 : | perror("recv"); | ||
| 11725 : | exit(1); | ||
| 11726 : | @} | ||
| 11727 : | |||
| 11728 : | if (!DoService(buffer)) | ||
| 11729 : | @{ | ||
| 11730 : | break; | ||
| 11731 : | @} | ||
| 11732 : | |||
| 11733 : | if (send(sd_client,buffer,strlen(buffer),0) == -1) | ||
| 11734 : | @{ | ||
| 11735 : | perror("send"); | ||
| 11736 : | exit(1); | ||
| 11737 : | @} | ||
| 11738 : | |||
| 11739 : | close (sd_client); | ||
| 11740 : | @} | ||
| 11741 : | |||
| 11742 : | close (sd); | ||
| 11743 : | printf("Server closing down...\n"); | ||
| 11744 : | @} | ||
| 11745 : | |||
| 11746 : | |||
| 11747 : | /**************************************************************/ | ||
| 11748 : | |||
| 11749 : | DoService(buffer) | ||
| 11750 : | |||
| 11751 : | char *buffer; | ||
| 11752 : | |||
| 11753 : | /* This is the protocol section. Here we must */ | ||
| 11754 : | /* check that the incoming data are sensible */ | ||
| 11755 : | |||
| 11756 : | @{ int a=0,b=0; | ||
| 11757 : | |||
| 11758 : | printf("Received: %s\n",buffer); | ||
| 11759 : | sscanf(buffer,"%d + %d\n",&a,&b); | ||
| 11760 : | |||
| 11761 : | if (a > 0 && b> 0) | ||
| 11762 : | @{ | ||
| 11763 : | sprintf(buffer,"%d + %d = %d",a,b,a+b); | ||
| 11764 : | return true; | ||
| 11765 : | @} | ||
| 11766 : | else | ||
| 11767 : | @{ | ||
| 11768 : | if (strncmp("halt",buffer,4) == 0) | ||
| 11769 : | @{ | ||
| 11770 : | sprintf(buffer,"Server closing down!"); | ||
| 11771 : | return false; | ||
| 11772 : | @} | ||
| 11773 : | else | ||
| 11774 : | @{ | ||
| 11775 : | sprintf(buffer,"Invalid protocol"); | ||
| 11776 : | return true; | ||
| 11777 : | @} | ||
| 11778 : | @} | ||
| 11779 : | @} | ||
| 11780 : | |||
| 11781 : | @end smallexample | ||
| 11782 : | |||
| 11783 : | @noindent | ||
| 11784 : | In the example we use `streams' to implement a typical input/output | ||
| 11785 : | behaviour for C. A stream interface is a so-called reliable protocol. | ||
| 11786 : | @cindex Reliable socket protocol | ||
| 11787 : | There are other kinds of sockets too, called @emph{unrealiable}, or UDP | ||
| 11788 : | sockets. Features to notice on the server are that we must bind to a | ||
| 11789 : | specific address. The client is always implicitly bound to an address | ||
| 11790 : | since a socket connection always originates from the machine on which | ||
| 11791 : | the client is running. On the server however we want to know which | ||
| 11792 : | addresses we shall be receiving requests from. In the above example we | ||
| 11793 : | use the generic wildcard address @samp{INADDR_ANY} which means that any | ||
| 11794 : | host can connect to the server. Had we been more specific, we could have | ||
| 11795 : | limited communication to two machines only. | ||
| 11796 : | |||
| 11797 : | By calling @samp{listen()} we set up a queue for incoming connections. | ||
| 11798 : | Rather than forking a separate process to handle each request we | ||
| 11799 : | set up a queue of a certain depth. If we exceed this depth then | ||
| 11800 : | new clients rtying to connect will be refused connection. | ||
| 11801 : | |||
| 11802 : | The @samp{accept} call is the mechanism which extracts a `reply handle' | ||
| 11803 : | from the socket. Using the handle obtained from this call we can reply | ||
| 11804 : | to the client without having to open a special socket explicitly. | ||
| 11805 : | |||
| 11806 : | An improved server side connection can be setup, reading the | ||
| 11807 : | service name from @file{/etc/services} and setting reusable | ||
| 11808 : | socket options to avoid busy signals, like this: | ||
| 11809 : | @smallexample | ||
| 11810 : | |||
| 11811 : | struct sockaddr_in cin, sin; | ||
| 11812 : | struct servent *server; | ||
| 11813 : | int sd, addrlen = sizeof(cin); | ||
| 11814 : | int portnumber, yes=1; | ||
| 11815 : | |||
| 11816 : | if ((server = getservbyname(@var{service-name},"tcp")) == NULL) | ||
| 11817 : | @{ | ||
| 11818 : | CfLog(cferror,"Couldn't get cfengine service","getservbyname"); | ||
| 11819 : | exit (1); | ||
| 11820 : | @} | ||
| 11821 : | |||
| 11822 : | bzero(&cin,sizeof(cin)); | ||
| 11823 : | |||
| 11824 : | /* Service returns network byte order */ | ||
| 11825 : | |||
| 11826 : | sin.sin_port = (unsigned short)(server->s_port); | ||
| 11827 : | sin.sin_addr.s_addr = INADDR_ANY; | ||
| 11828 : | sin.sin_family = AF_INET; | ||
| 11829 : | |||
| 11830 : | if ((sd = socket(AF_INET,SOCK_STREAM,0)) == -1) | ||
| 11831 : | @{ | ||
| 11832 : | CfLog(cferror,"Couldn't open socket","socket"); | ||
| 11833 : | exit (1); | ||
| 11834 : | @} | ||
| 11835 : | |||
| 11836 : | if (setsockopt (sd, SOL_SOCKET, SO_REUSEADDR, | ||
| 11837 : | (char *) &yes, sizeof (int)) == -1) | ||
| 11838 : | @{ | ||
| 11839 : | CfLog(cferror,"Couldn't set socket options","sockopt"); | ||
| 11840 : | exit (1); | ||
| 11841 : | @} | ||
| 11842 : | |||
| 11843 : | |||
| 11844 : | if (bind(sd,(struct sockaddr *)&sin,sizeof(sin)) == -1) | ||
| 11845 : | @{ | ||
| 11846 : | |||
| 11847 : | @} | ||
| 11848 : | |||
| 11849 : | /* etc */ | ||
| 11850 : | |||
| 11851 : | @end smallexample | ||
| 11852 : | |||
| 11853 : | @c ----------------------------------------------------------------------- | ||
| 11854 : | @c SECTION | ||
| 11855 : | @c ----------------------------------------------------------------------- | ||
| 11856 : | |||
| 11857 : | @node Multithreading a server, System databases, Sockets, Network programming | ||
| 11858 : | @section Multithreading a server | ||
| 11859 : | |||
| 11860 : | All the arguments must be collected into a struct, since only | ||
| 11861 : | one argument pointer can be sent to the pthread functions. | ||
| 11862 : | |||
| 11863 : | @smallexample | ||
| 11864 : | |||
| 11865 : | #include <pthread.h> | ||
| 11866 : | |||
| 11867 : | |||
| 11868 : | SpawnCfGetFile(args) | ||
| 11869 : | |||
| 11870 : | struct cfd_thread_arg *args; | ||
| 11871 : | |||
| 11872 : | @{ pthread_t tid; | ||
| 11873 : | void *CfGetFile(); | ||
| 11874 : | |||
| 11875 : | pthread_attr_init(&PTHREADDEFAULTS); | ||
| 11876 : | pthread_attr_setdetachstate(&PTHREADDEFAULTS,PTHREAD_CREATE_DETACHED); | ||
| 11877 : | |||
| 11878 : | if (pthread_create(&tid,&PTHREADDEFAULTS,CfGetFile,args) != 0) | ||
| 11879 : | @{ | ||
| 11880 : | CfLog(cferror,"pthread_create failed","create"); | ||
| 11881 : | CfGetFile(args); | ||
| 11882 : | @} | ||
| 11883 : | |||
| 11884 : | pthread_attr_destroy(&PTHREADDEFAULTS); | ||
| 11885 : | @} | ||
| 11886 : | |||
| 11887 : | /***************************************************************/ | ||
| 11888 : | |||
| 11889 : | void *CfGetFile(args) | ||
| 11890 : | |||
| 11891 : | struct cfd_thread_arg *args; | ||
| 11892 : | |||
| 11893 : | @{ pthread_mutex_t mutex; | ||
| 11894 : | |||
| 11895 : | if (pthread_mutex_lock(&mutex) != 0) | ||
| 11896 : | @{ | ||
| 11897 : | CfLog(cferror,"pthread_mutex_lock failed","pthread_mutex_lock"); | ||
| 11898 : | free(args->replyfile); /* from strdup in each thread */ | ||
| 11899 : | DeleteConn(args->connect); | ||
| 11900 : | free((char *)args); | ||
| 11901 : | return NULL; | ||
| 11902 : | @} | ||
| 11903 : | |||
| 11904 : | ACTIVE_THREADS++; /* Global variable */ | ||
| 11905 : | |||
| 11906 : | if (pthread_mutex_unlock(&mutex) != 0) | ||
| 11907 : | @{ | ||
| 11908 : | CfLog(cferror,"pthread_mutex_unlock failed","unlock"); | ||
| 11909 : | @} | ||
| 11910 : | |||
| 11911 : | |||
| 11912 : | /* send data */ | ||
| 11913 : | |||
| 11914 : | if (pthread_mutex_lock(&mutex) != 0) | ||
| 11915 : | @{ | ||
| 11916 : | CfLog(cferror,"pthread_mutex_lock failed","pthread_mutex_lock"); | ||
| 11917 : | return; | ||
| 11918 : | @} | ||
| 11919 : | |||
| 11920 : | ACTIVE_THREADS--; | ||
| 11921 : | |||
| 11922 : | if (pthread_mutex_unlock(&mutex) != 0) | ||
| 11923 : | @{ | ||
| 11924 : | CfLog(cferror,"pthread_mutex_unlock failed","unlock"); | ||
| 11925 : | @} | ||
| 11926 : | |||
| 11927 : | #endif | ||
| 11928 : | |||
| 11929 : | return NULL; | ||
| 11930 : | @} | ||
| 11931 : | |||
| 11932 : | @end smallexample | ||
| 11933 : | |||
| 11934 : | @c ----------------------------------------------------------------------- | ||
| 11935 : | @c SECTION | ||
| 11936 : | @c ----------------------------------------------------------------------- | ||
| 11937 : | |||
| 11938 : | @node System databases, DNS, Multithreading a server, Network programming | ||
| 11939 : | @section System databases | ||
| 11940 : | |||
| 11941 : | @cindex NIS | ||
| 11942 : | @cindex Network information service | ||
| 11943 : | @cindex Network databases | ||
| 11944 : | @cindex Database maps | ||
| 11945 : | |||
| 11946 : | |||
| 11947 : | The C library calls which query the databases are, amongst others, | ||
| 11948 : | @smallexample | ||
| 11949 : | getpwnam @var{get password data by name} | ||
| 11950 : | getpwuid @var{get password data by uid} | ||
| 11951 : | getgrnam @var{get group data by name} | ||
| 11952 : | gethostent @var{get entry in hosts database} | ||
| 11953 : | getnetgrent @var{get entry in netgroups database} | ||
| 11954 : | getservbyname @var{get servive by name} | ||
| 11955 : | getservbyport @var{get service by port} | ||
| 11956 : | get protobyname @var{get protocol by name} | ||
| 11957 : | @end smallexample | ||
| 11958 : | |||
| 11959 : | @noindent | ||
| 11960 : | For a complete list and how to use these, see the UNIX manual. | ||
| 11961 : | @cindex @code{getpwnam()} | ||
| 11962 : | @cindex @code{getpwuid()} | ||
| 11963 : | @cindex @code{getgrnam()} | ||
| 11964 : | @cindex @code{gethostent()} | ||
| 11965 : | @cindex @code{getnetgrent()} | ||
| 11966 : | @cindex @code{getservbyname()} | ||
| 11967 : | @cindex @code{getservbyport()} | ||
| 11968 : | |||
| 11969 : | The following example shows how to read the password file of the | ||
| 11970 : | system. The functions used here can be used regardless of whether | ||
| 11971 : | the network information service (NIS) is in use. The data are | ||
| 11972 : | returned in a structure which is defined in @samp{/usr/include/pwd.h}. | ||
| 11973 : | |||
| 11974 : | |||
| 11975 : | @smallexample | ||
| 11976 : | /******************************************************************/ | ||
| 11977 : | /* */ | ||
| 11978 : | /* Read the passwd file by name and sequentially */ | ||
| 11979 : | /* */ | ||
| 11980 : | /******************************************************************/ | ||
| 11981 : | |||
| 11982 : | #include <unistd.h> | ||
| 11983 : | #include <pwd.h> | ||
| 11984 : | |||
| 11985 : | main () | ||
| 11986 : | |||
| 11987 : | @{ uid_t uid; | ||
| 11988 : | struct passwd *pw; | ||
| 11989 : | |||
| 11990 : | uid = getuid(); | ||
| 11991 : | |||
| 11992 : | pw = getpwuid(uid); | ||
| 11993 : | |||
| 11994 : | printf ("Your login name is %s\n",pw->pw_name); | ||
| 11995 : | |||
| 11996 : | printf ("Now here comes the whole file!\n\n"); | ||
| 11997 : | |||
| 11998 : | setpwent(); | ||
| 11999 : | |||
| 12000 : | while (getpwent()) | ||
| 12001 : | @{ | ||
| 12002 : | printf ("%s:%s:%s\n",pw->pw_name,pw->pw_gecos,pw->pw_dir); | ||
| 12003 : | @} | ||
| 12004 : | |||
| 12005 : | endpwent(); | ||
| 12006 : | @} | ||
| 12007 : | |||
| 12008 : | |||
| 12009 : | @end smallexample | ||
| 12010 : | |||
| 12011 : | @c ----------------------------------------------------------------------- | ||
| 12012 : | @c SECTION | ||
| 12013 : | @c ----------------------------------------------------------------------- | ||
| 12014 : | |||
| 12015 : | @node DNS, C and NFS, System databases, Network programming | ||
| 12016 : | @section DNS - The Domain Name Service | ||
| 12017 : | |||
| 12018 : | @cindex DNS | ||
| 12019 : | @cindex The domain name service | ||
| 12020 : | @cindex BIND | ||
| 12021 : | @cindex Berkeley Internet Name Domain (BIND) | ||
| 12022 : | The second network database service is that which converts host and | ||
| 12023 : | domain names into IP numbers and vice versa. This is the domain | ||
| 12024 : | name service, usually implemented by the BIND | ||
| 12025 : | (Berkeley Internet Name Domain) software. | ||
| 12026 : | The information here concerns version 4.9 of this software. | ||
| 12027 : | |||
| 12028 : | @c ..................................................... | ||
| 12029 : | @c SUBSECTION | ||
| 12030 : | @c ..................................................... | ||
| 12031 : | |||
| 12032 : | @menu | ||
| 12033 : | * gethostbyname:: | ||
| 12034 : | @end menu | ||
| 12035 : | |||
| 12036 : | @node gethostbyname, , DNS, DNS | ||
| 12037 : | @subsection gethostbyname() | ||
| 12038 : | |||
| 12039 : | This is perhaps the most important function form hostname | ||
| 12040 : | lookup. @samp{gethostbyname()} gets its information either from files, | ||
| 12041 : | NIS or DNS. Its behaviour is configured by the files mentioned above, | ||
| 12042 : | @xref{DNS}. It is used to look up the IP address of a named host | ||
| 12043 : | (including domain name if DNS is used). On the configurable systems | ||
| 12044 : | described above, the full list of servers is queried until a reply is | ||
| 12045 : | obtained. The order in which the different services are queried is | ||
| 12046 : | important here since DNS returns a @emph{fully qualified name} | ||
| 12047 : | @cindex Fully qualified name | ||
| 12048 : | (host name plus domain name) whereas NIS and the @file{/etc/hosts} file | ||
| 12049 : | database return only a hostname. | ||
| 12050 : | |||
| 12051 : | gethostbyname returns data in the form of a pointer to a static | ||
| 12052 : | data structure. The syntax is | ||
| 12053 : | @smallexample | ||
| 12054 : | #include <netdb.h> | ||
| 12055 : | |||
| 12056 : | @cindex @code{gethostbyname()} | ||
| 12057 : | struct hostent *hp; | ||
| 12058 : | |||
| 12059 : | hp = gethostbyname("myhost.domain.country") | ||
| 12060 : | @end smallexample | ||
| 12061 : | |||
| 12062 : | @noindent | ||
| 12063 : | The resulting structure varies on different implementations | ||
| 12064 : | of UNIX, but the `old BSD standard' is of the form: | ||
| 12065 : | @smallexample | ||
| 12066 : | |||
| 12067 : | struct hostent | ||
| 12068 : | @{ | ||
| 12069 : | char *h_name; /* official name of host */ | ||
| 12070 : | char **h_aliases; /* alias list */ | ||
| 12071 : | int h_addrtype; /* host address type */ | ||
| 12072 : | int h_length; /* length of address */ | ||
| 12073 : | char **h_addr_list; /* list of addresses from name server */ | ||
| 12074 : | @}; | ||
| 12075 : | |||
| 12076 : | #define h_addr h_addr_list[0] /* address, for backward compatiblity */ | ||
| 12077 : | |||
| 12078 : | @end smallexample | ||
| 12079 : | |||
| 12080 : | @noindent | ||
| 12081 : | The structure contains a list of addresses and or aliases from the | ||
| 12082 : | nameserver. The interesting quantity is usually extracted by means | ||
| 12083 : | of the macro @samp{h_addr} | ||
| 12084 : | whcih gives the first value in the address list, | ||
| 12085 : | though officially one should examine the whole list now. | ||
| 12086 : | |||
| 12087 : | This value is a pointer which can be converted into a text form | ||
| 12088 : | by the following hideous type transformation: | ||
| 12089 : | @smallexample | ||
| 12090 : | |||
| 12091 : | #include <sys/types.h> | ||
| 12092 : | #include <sys/socket.h> | ||
| 12093 : | #include <netinet/in.h> | ||
| 12094 : | |||
| 12095 : | struct sockaddr_in sin; | ||
| 12096 : | |||
| 12097 : | cin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr; | ||
| 12098 : | |||
| 12099 : | printf("IP address = %s\n",inet_ntoa(cin.sin_addr)); | ||
| 12100 : | |||
| 12101 : | @end smallexample | ||
| 12102 : | |||
| 12103 : | See the client program in the first section of this chapter for an | ||
| 12104 : | example of its use. | ||
| 12105 : | |||
| 12106 : | |||
| 12107 : | @c ----------------------------------------------------------------------- | ||
| 12108 : | @c SECTION | ||
| 12109 : | @c ----------------------------------------------------------------------- | ||
| 12110 : | |||
| 12111 : | @node C and NFS, Ex 7, DNS, Network programming | ||
| 12112 : | @section C support for NFS | ||
| 12113 : | |||
| 12114 : | The support for NFS mounting in the standard C library is through | ||
| 12115 : | two sources. NFS is based on the Sun's RPC system, so the basic | ||
| 12116 : | calls are only instances of standard RPC protocols. | ||
| 12117 : | |||
| 12118 : | @cindex NFS and C support | ||
| 12119 : | The C functions in the standard input/output library can be used to | ||
| 12120 : | access NFS filesystems. Since NFS imitates the UNIX filesystem as | ||
| 12121 : | closely as possible, NFS filesystems can be mounted in exactly the same | ||
| 12122 : | way as ordinary filesystems. Unfortunately, the C functions which | ||
| 12123 : | perform the mount operation in UNIX and depressingly non-standard. They | ||
| 12124 : | differ on almost every implementation of UNIX. | ||
| 12125 : | |||
| 12126 : | The basic function which mounts a filesystem, in @samp{mount} (see | ||
| 12127 : | @kbd{man (2) mount}). The mount table is stored in a file | ||
| 12128 : | @emph{/etc/mtab} on BSD systems (again the name varies wildly from UNIX | ||
| 12129 : | to UNIX, mnttab on HPUX for instance). The file @emph{/etc/rmtab} on an | ||
| 12130 : | NFS server contains a list of remote-mounted filesystems which are | ||
| 12131 : | mounted by remote clients. C functions exist which can read the | ||
| 12132 : | filesystem tables and place the resulting data in C struct types. Alas, | ||
| 12133 : | these struct defintions are also quite different on different | ||
| 12134 : | systems. See @file{/usr/include/sys/mount.h}, so the user wishing to | ||
| 12135 : | write system-independent code is confounded at the lowest level. | ||
| 12136 : | |||
| 12137 : | @c ----------------------------------------------------------------------- | ||
| 12138 : | @c SECTION | ||
| 12139 : | @c ----------------------------------------------------------------------- | ||
| 12140 : | |||
| 12141 : | @node Ex 7, , C and NFS, Network programming | ||
| 12142 : | @section Exercises | ||
| 12143 : | |||
| 12144 : | @enumerate | ||
| 12145 : | @item | ||
| 12146 : | Use @samp{gethostbyname()} to make a simple program like @samp{nslookup} | ||
| 12147 : | which gives the internet address of a named host. | ||
| 12148 : | |||
| 12149 : | @item | ||
| 12150 : | Modify the client server example above to make a `remote ls' | ||
| 12151 : | command called @samp{rls}. You should be able to use the syntax | ||
| 12152 : | @smallexample | ||
| 12153 : | rls (options) hostname:/path/to/file | ||
| 12154 : | @end smallexample | ||
| 12155 : | @end enumerate | ||
| 12156 : | |||
| 12157 : | |||
| 12158 : | @c ********************************************************************** | ||
| 12159 : | @c APPENDIX | ||
| 12160 : | @c ********************************************************************** | ||
| 12161 : | |||
| 12162 : | @node Programming idioms, Variable Index, Network programming, Top | ||
| 12163 : | @appendix Summary of programming idioms. | ||
| 12164 : | |||
| 12165 : | @table @emph | ||
| 12166 : | |||
| 12167 : | @item True and false | ||
| 12168 : | |||
| 12169 : | @smallexample | ||
| 12170 : | |||
| 12171 : | # C shell | ||
| 12172 : | |||
| 12173 : | True - non-zero/non-empty value | ||
| 12174 : | False - zero or null string | ||
| 12175 : | |||
| 12176 : | # Bourne shell | ||
| 12177 : | |||
| 12178 : | True - 0 returned by shell command | ||
| 12179 : | False - non-zero returned by shell command | ||
| 12180 : | |||
| 12181 : | ( Note that "test" converts from C shell style to Bourne shell) | ||
| 12182 : | |||
| 12183 : | # Perl | ||
| 12184 : | |||
| 12185 : | True - non-zero/non-empty value | ||
| 12186 : | False - zero or null string | ||
| 12187 : | |||
| 12188 : | /* C */ | ||
| 12189 : | |||
| 12190 : | True - non zero integer | ||
| 12191 : | False - zero integer | ||
| 12192 : | @end smallexample | ||
| 12193 : | |||
| 12194 : | @item Input from tty | ||
| 12195 : | |||
| 12196 : | @smallexample | ||
| 12197 : | # C shell | ||
| 12198 : | |||
| 12199 : | $< | ||
| 12200 : | |||
| 12201 : | # Bourne shell | ||
| 12202 : | |||
| 12203 : | line | ||
| 12204 : | read | ||
| 12205 : | |||
| 12206 : | # Perl | ||
| 12207 : | |||
| 12208 : | <STDIN> | ||
| 12209 : | |||
| 12210 : | /* C */ | ||
| 12211 : | |||
| 12212 : | scanf | ||
| 12213 : | |||
| 12214 : | @end smallexample | ||
| 12215 : | |||
| 12216 : | @item Redirection of I/O | ||
| 12217 : | |||
| 12218 : | @smallexample | ||
| 12219 : | |||
| 12220 : | # C shell | ||
| 12221 : | |||
| 12222 : | @var{command} > file | ||
| 12223 : | @var{command} >& file | ||
| 12224 : | @var{command} >> file | ||
| 12225 : | @var{command1} | @var{command2} | ||
| 12226 : | |||
| 12227 : | # Bourne shell | ||
| 12228 : | |||
| 12229 : | @var{command} > file | ||
| 12230 : | @var{command} > file 2>&1 | ||
| 12231 : | @var{command} >> file | ||
| 12232 : | @var{command1} | @var{command2} | ||
| 12233 : | |||
| 12234 : | # Perl | ||
| 12235 : | |||
| 12236 : | open (HANDLE,">file") | ||
| 12237 : | open (HANDLE,">file 2>&1") | ||
| 12238 : | open (HANDLE,">>file") | ||
| 12239 : | open (HANDLE,"command1 |") | ||
| 12240 : | open (HANDLE,"| command2") | ||
| 12241 : | |||
| 12242 : | /* C */ | ||
| 12243 : | |||
| 12244 : | fopen ("file","w"); printf(..) | ||
| 12245 : | fopen ("file","w"); printf(..); fprintf(stderr,..) | ||
| 12246 : | fopen ("file","a"); printf(..) | ||
| 12247 : | popen ("@var{command1}","r") | ||
| 12248 : | popen ("@var{command2}","w") | ||
| 12249 : | |||
| 12250 : | @end smallexample | ||
| 12251 : | |||
| 12252 : | @item Loops and tests | ||
| 12253 : | |||
| 12254 : | @smallexample | ||
| 12255 : | |||
| 12256 : | /* C */ Shell | ||
| 12257 : | |||
| 12258 : | foreach end if then else endif | ||
| 12259 : | while end switch case breaksw endsw | ||
| 12260 : | repeat | ||
| 12261 : | |||
| 12262 : | # Bourne shell | ||
| 12263 : | |||
| 12264 : | while do done if then else fi | ||
| 12265 : | until do done case in esac | ||
| 12266 : | for in do done | ||
| 12267 : | |||
| 12268 : | # Perl | ||
| 12269 : | |||
| 12270 : | while if then else | ||
| 12271 : | for unless else | ||
| 12272 : | foreach | ||
| 12273 : | until | ||
| 12274 : | do while | ||
| 12275 : | do until | ||
| 12276 : | |||
| 12277 : | /* C */ | ||
| 12278 : | |||
| 12279 : | while if then else | ||
| 12280 : | do while switch case | ||
| 12281 : | for | ||
| 12282 : | |||
| 12283 : | @end smallexample | ||
| 12284 : | |||
| 12285 : | @item Arguments from command line | ||
| 12286 : | |||
| 12287 : | @smallexample | ||
| 12288 : | # C shell | ||
| 12289 : | |||
| 12290 : | $argv[] | ||
| 12291 : | $#argv | ||
| 12292 : | |||
| 12293 : | # Bourne Shell | ||
| 12294 : | |||
| 12295 : | $1, $2, $3... $* | ||
| 12296 : | $# | ||
| 12297 : | |||
| 12298 : | # Perl | ||
| 12299 : | |||
| 12300 : | $ARGV[] | ||
| 12301 : | $#ARGV | ||
| 12302 : | |||
| 12303 : | /* C */ | ||
| 12304 : | |||
| 12305 : | char argv[][] | ||
| 12306 : | int argc | ||
| 12307 : | @end smallexample | ||
| 12308 : | |||
| 12309 : | @item Arithmetic | ||
| 12310 : | @smallexample | ||
| 12311 : | # C shell | ||
| 12312 : | |||
| 12313 : | @ a = $b + $c | ||
| 12314 : | |||
| 12315 : | # Bourne shell | ||
| 12316 : | |||
| 12317 : | a = `expr $b + $c` | ||
| 12318 : | |||
| 12319 : | # Perl | ||
| 12320 : | |||
| 12321 : | $a = $b + $c; | ||
| 12322 : | |||
| 12323 : | /* C */ | ||
| 12324 : | |||
| 12325 : | a = b + c; | ||
| 12326 : | @end smallexample | ||
| 12327 : | |||
| 12328 : | @item Numerical comparison | ||
| 12329 : | @smallexample | ||
| 12330 : | # C shell | ||
| 12331 : | |||
| 12332 : | if ( $x == $y ) then | ||
| 12333 : | endif | ||
| 12334 : | |||
| 12335 : | # Bourne shell | ||
| 12336 : | |||
| 12337 : | if [ $x -eq $y ]; then | ||
| 12338 : | fi | ||
| 12339 : | |||
| 12340 : | # Perl | ||
| 12341 : | |||
| 12342 : | if ( $x == $y ) | ||
| 12343 : | @{ | ||
| 12344 : | @} | ||
| 12345 : | |||
| 12346 : | /* C */ | ||
| 12347 : | |||
| 12348 : | if ( x == y ) | ||
| 12349 : | @{ | ||
| 12350 : | @} | ||
| 12351 : | @end smallexample | ||
| 12352 : | |||
| 12353 : | @item String comparison | ||
| 12354 : | @smallexample | ||
| 12355 : | |||
| 12356 : | # C shell | ||
| 12357 : | |||
| 12358 : | if ( $x == $y ) then | ||
| 12359 : | endif | ||
| 12360 : | |||
| 12361 : | # Bourne shell | ||
| 12362 : | |||
| 12363 : | if [ $x = $y ]; then | ||
| 12364 : | fi | ||
| 12365 : | |||
| 12366 : | # Perl | ||
| 12367 : | |||
| 12368 : | if ( $x eq $y ) then | ||
| 12369 : | @{ | ||
| 12370 : | @} | ||
| 12371 : | |||
| 12372 : | /* C */ | ||
| 12373 : | |||
| 12374 : | if (strcmp(x,y) == 0) | ||
| 12375 : | @{ | ||
| 12376 : | @} | ||
| 12377 : | |||
| 12378 : | @end smallexample | ||
| 12379 : | |||
| 12380 : | @item Opening a file | ||
| 12381 : | @smallexample | ||
| 12382 : | |||
| 12383 : | # C shell, Bourne shell - cannot be done (pipes only) | ||
| 12384 : | |||
| 12385 : | # Perl | ||
| 12386 : | |||
| 12387 : | open (READ_HANDLE,"filename"); | ||
| 12388 : | open (WRITE_HANDLE,"> filename"); | ||
| 12389 : | open (APPEND_HANDLE,">> filename"); | ||
| 12390 : | |||
| 12391 : | /* C */ | ||
| 12392 : | |||
| 12393 : | FILE *fp; | ||
| 12394 : | |||
| 12395 : | fp = fopen ("file","r"); | ||
| 12396 : | fp = fopen ("file","w"); | ||
| 12397 : | fp = fopen ("file","a"); | ||
| 12398 : | |||
| 12399 : | @end smallexample | ||
| 12400 : | |||
| 12401 : | @item Opening a directory | ||
| 12402 : | @smallexample | ||
| 12403 : | |||
| 12404 : | # C shell | ||
| 12405 : | |||
| 12406 : | foreach dir ( @var{directory}/* ) | ||
| 12407 : | ... | ||
| 12408 : | end | ||
| 12409 : | |||
| 12410 : | # Bourne shell | ||
| 12411 : | |||
| 12412 : | for dir in @var{directory}/* ; | ||
| 12413 : | do | ||
| 12414 : | ... | ||
| 12415 : | done | ||
| 12416 : | |||
| 12417 : | # Perl | ||
| 12418 : | |||
| 12419 : | opendir (HANDLE,"@var{directory}") || die; | ||
| 12420 : | |||
| 12421 : | while ($entry = readdir(HANDLE)) | ||
| 12422 : | @{ | ||
| 12423 : | @} | ||
| 12424 : | |||
| 12425 : | closedir(HANDLE); | ||
| 12426 : | |||
| 12427 : | # C | ||
| 12428 : | |||
| 12429 : | #include <dirent.h> | ||
| 12430 : | DIR *dirh; | ||
| 12431 : | struct dirent *dirp; | ||
| 12432 : | |||
| 12433 : | if ((dirh = opendir(name)) == NULL) | ||
| 12434 : | @{ | ||
| 12435 : | perror("opendir") | ||
| 12436 : | exit(1); | ||
| 12437 : | @} | ||
| 12438 : | |||
| 12439 : | for (dirp = readdir(dirh); dirp != NULL; dirp = readdir(dirh)) | ||
| 12440 : | @{ | ||
| 12441 : | ... /* dirp->d_name points to child */ | ||
| 12442 : | @} | ||
| 12443 : | |||
| 12444 : | closedir(dirh); | ||
| 12445 : | |||
| 12446 : | |||
| 12447 : | @end smallexample | ||
| 12448 : | |||
| 12449 : | @item Testing file types | ||
| 12450 : | @smallexample | ||
| 12451 : | |||
| 12452 : | # C shell | ||
| 12453 : | |||
| 12454 : | if ( -f file ) # plain file | ||
| 12455 : | if ( -d file ) # directory | ||
| 12456 : | |||
| 12457 : | # Bourne shell | ||
| 12458 : | |||
| 12459 : | if [ -f file ] # plain file | ||
| 12460 : | if [ -d file ] # directory | ||
| 12461 : | |||
| 12462 : | # Perl | ||
| 12463 : | |||
| 12464 : | if ( -f file ) # plain file | ||
| 12465 : | if ( -d file ) # directory | ||
| 12466 : | if ( -l file ) # symbolic link | ||
| 12467 : | |||
| 12468 : | /* C */ | ||
| 12469 : | |||
| 12470 : | #include <sys/stat.h> | ||
| 12471 : | |||
| 12472 : | struct stat statvar; | ||
| 12473 : | |||
| 12474 : | stat("file", &statvar); | ||
| 12475 : | |||
| 12476 : | if (S_ISREG(statvar.mode)) /* plain file */ | ||
| 12477 : | if (S_ISDIR(statvar.mode)) /* directory */ | ||
| 12478 : | |||
| 12479 : | lstat("file", &statvar); | ||
| 12480 : | |||
| 12481 : | if (S_ISLNK(statvar.mode)) /* symbolic link */ | ||
| 12482 : | |||
| 12483 : | @end smallexample | ||
| 12484 : | |||
| 12485 : | |||
| 12486 : | @end table | ||
| 12487 : | |||
| 12488 : | @c ********************************************************************** | ||
| 12489 : | @c INDEX | ||
| 12490 : | @c ********************************************************************** | ||
| 12491 : | |||
| 12492 : | @node Variable Index, Concept Index, Programming idioms, Top | ||
| 12493 : | @unnumbered Command and Variable Index | ||
| 12494 : | |||
| 12495 : | @printindex vr | ||
| 12496 : | |||
| 12497 : | @node Concept Index, , Variable Index, Top | ||
| 12498 : | @unnumbered Concept Index | ||
| 12499 : | |||
| 12500 : | @printindex cp | ||
| 12501 : | |||
| 12502 : | @contents | ||
| 12503 : | |||
| 12504 : | @bye | ||
| 12505 : | |||
| 12506 : | |||
| 12507 : |
| Administrator | ViewVC Help |
| Powered by ViewVC 1.0.3 |