home *** CD-ROM | disk | FTP | other *** search
- From: tmatimar@morse.waterloo.edu
- Newsgroups: comp.unix.questions,news.answers
- Subject: Welcome to comp.unix.questions [Monthly posting]
- Date: 4 May 92 05:00:27 GMT
- Followup-To: comp.unix.questions
-
- Archive-name: unix-faq/unix-intro
- Version: $Id: unix-intro,v 1.5 1992/04/26 20:17:15 tmatimar Exp $
-
- Comp.unix.questions is one of the most popular and highest volume
- newsgroups on Usenet. This article is a monthly attempt to remind
- potential posters about what is appropriate for this newsgroup.
- If you would like to make any suggestions about the content of
- this article, please contact its maintainer at
- tmatimar@nff.ncl.omron.co.jp.
-
- Companion articles include the answers to some Frequently
- Asked Questions. You may save yourself a lot of time by reading
- those articles before posting a question to the net.
-
- If you have not already read the overall Usenet introductory material
- posted to "news.announce.newusers", please do. Much of this article
- overlaps with the common sense guidelines posted there.
-
- Should I Post My Unix Question to the Net?
-
- Often the answer is "No, you can get an answer a lot faster without
- posting a question." Before you post, you should try -
-
- o Reading the manual for your system. Some day you may encounter
- the phrase "RTFM", which stands for "Read the Fine Manual"
- (except 'F' doesn't really stand for "Fine"). If you ask
- someone a question and they tell you to RTFM, it's an
- indication that you haven't done your homework. For instance,
- if you are having trouble removing a file whose name begins
- with a "-", check the man page for "rm". It might tell
- you what you need to know.
-
- When people use terminology like "read(2)", they are referring
- to the "read" man page in section 2 of the manual (which you
- would see by using "man 2 read").
-
- o Finding a knowledgeable user at your site. Many sites have
- at least a few Unix experts who will be happy to help you
- figure out how to remove a file whose name begins with "-".
- Many larger sites, particularly universities, may even have
- paid consultants whose job is to help you with Unix problems.
- Check with them first.
-
- o Find a good introductory book on Unix. There are plenty of
- such books available, and you will save yourself a lot
- of trouble by having one handy and consulting it frequently.
- (Question 1.5 in the companion articles will let you know
- where you can find a list of good Unix and C books.)
-
- Please remember that the comp.unix.* newsgroups are read by over 80,000
- people around the world, and that posting a question to this group will
- cost a lot of time and money by the time your article is distributed to
- Asia, Australia, Europe (west and east), Africa, the middle east,
- and all corners of North, South and Central America.
-
- Also, some people receive these newsgroups as part of a mailing list
- rather than a newsgroup. If you're one of these people, please don't
- send a "Remove me from this list" or "UNSUBSCRIBE" message to the
- wrong place. Take the time to figure out where you're getting this
- stuff from, and send your request to the mailing list maintainer, *not*
- to the list or newsgroup itself! Ask your local postmaster for help.
- (One of the answers in the companion articles deals with the details of
- the mailing list.)
-
- To Which Newsgroup Should I Post My Question?
-
- The choice of newsgroup is harder than it used to be. In the old days,
- you just had to choose between "comp.unix.questions" and
- "comp.unix.wizards". Now there are a variety of more specific groups.
- Choose one of the following groups carefully. If you aren't sure where
- your question belongs or if your question is not specific to some
- particular version of Unix, try "comp.unix.questions". Many
- knowledgeable Unix wizards read that group and will be able to help you.
-
- Here are the capsule descriptions of various groups you might consider
- (extracted from a monthly posting to "news.announce.newusers")
-
- comp.unix.questions General questions from UNIX users and sys admins.
- If your question isn't a really good match for one of
- the groups below, post it here.
-
- news.answers Repository for periodic USENET articles. (Moderated)
- This article is crossposted here.
- Do not try to post here unless you're posting a FAQ.
-
- comp.unix.shell Using and programming any UNIX shell.
-
- comp.lang.c Discussion about C.
-
- comp.sources.unix Postings of complete, UNIX-oriented sources. (Moderated)
- comp.std.unix Discussion for the P1003 committee on UNIX. (Moderated)
- comp.unix Discussion of UNIX* features and bugs. (Moderated)
- comp.unix.admin Administering a Unix-based system.
- comp.unix.aix IBM's version of UNIX.
- comp.unix.amiga Unix on the Commodore Amiga
- comp.unix.aux The version of UNIX for Apple Macintosh II computers.
- comp.unix.bsd Discussions relating to BSD UNIX.
- comp.unix.internals Discussions on hacking UNIX internals.
- comp.unix.large UNIX on mainframes and in large networks.
- comp.unix.misc Various topics that don't fit other groups.
- comp.unix.msdos MS-DOS running under UNIX by whatever means.
- comp.unix.programmer Q&A for people programming under Unix.
- comp.unix.sysv286 UNIX System V (not XENIX) on the '286.
- comp.unix.sysv386 Versions of Unix (not Xenix) on Intel 80386-based boxes.
- comp.unix.ultrix Discussions about DEC's Ultrix.
- comp.unix.xenix.misc General discussions regarding XENIX (except SCO).
- comp.unix.xenix.sco XENIX versions from the Santa Cruz Operation.
-
- comp.unix.wizards In-depth discussions of advanced unix topics.
- People should not post to this group unless they
- have used unix as a user, sysadmin and know details
- of the kernel, and how different unix kernels differ.
- In other words, don't post to comp.unix.wizards.
-
- What Information Should I Include?
-
- It's hard to include too much information. There are hundreds of
- different Unix systems out there, and they all have less in common
- than you might think. If you have a problem and are posting an
- article, please be sure to mention:
-
- o A descriptive subject line. Many people will decide whether
- to read your article solely on the basis of the subject line,
- so it should be a good statement of your problem.
-
- NOT GOOD GOOD
-
- "Help" "How do I sort a file by line length?"
- "Csh question" "csh dumps core when I use '$<'"
-
- o What computer you are using, and what specific version
- of the operating system it uses. For instance,
-
- SunOS 4.0.1, Sun 3/50
- 4.3BSD-tahoe, Vax 11/780
- SVR3.2, 3b2
-
- o If possible, the *exact* text of any error message you
- may have encountered.
-
- WRONG RIGHT
-
- "I can't print this file" "When I type 'lpr Filename', I get
- lpr: Filename: File too ugly to print
- What does this mean? It isn't in
- the man page. This is using
- Mueslix 9.3 on a Fax 68086502"
-
- It's a good idea to post unrelated questions in separate articles,
- so that people can keep different discussions separate. It's also
- a *very* good idea to include a line or two like this:
-
- "Please mail your answers to me and I'll summarize what I get
- and post the results to comp.unix.questions."
-
- This prevents many identical responses from different users to the
- same question from clogging up the newsgroup. And make sure
- you really summarize what you get - don't just concatenate
- all the mail you've received.
-
- It's also a good idea to read comp.unix.questions for at least a couple
- of weeks after you post your article to see what followup articles
- are posted.
-
- Should I Post an Answer to a Question?
-
- It's very tempting to post an answer to a question you read on the net,
- especially when you think "Aha, finally - a question I can answer!"
- Consider though that when a simple question is asked, such as the
- sort about to be answered below, many other people around the
- world already know the answer and may be posting their own reply.
- In order to avoid dozens of replies to simple questions, please
- wait a day or so and see if anyone else has already answered
- the question. If you have something special to contribute, please
- do so, but make sure you're not duplicating something someone else has
- already done.
-
- You should feel free to reply to any question >by email<. Even if
- the user gets 200 responses to his question, at least the load on the
- rest of the net is minimized.
-
- What About Posting Source Code?
-
- Posting small amounts of example code is fine (use comp.sources.unix to
- distribute complete programs) - but please make sure that your code
- runs (or at least compiles) properly. Don't just type it in while
- editing your posting and hope it will work, no matter how sure you are
- that it will. We all make mistakes.
-
- What About Those People
- Who Continue to Ask Stupid or Frequently Asked Questions
- In Spite of The Frequently Asked Questions Document?
-
- Just send them a polite mail message, possibly referring them to this document.
- There is no need to flame them on the net - it's busy enough as it is.
- --
- Ted Timar - tmatimar@nff.ncl.omron.co.jp
- Omron Corporation, Shimokaiinji, Nagaokakyo-city, Kyoto 617, Japan
-
-
- ..
- Hope you know what you're doing ...
- Data directory is /big/gd
- Port is 70
- Logging to File /usr/adm/gopherd.l
-
- >From news.cso.uiuc.edu!ux1.cso.uiuc.edu!uwm.edu!wupost!cs.utexas.edu!sun-barr!olivea!uunet!snorkelwacker.mit.edu!bloom-picayune.mit.edu!news Mon Jul 6 13:59:30 CDT 1992
- Article: 2042 of news.answers
- Xref: news.cso.uiuc.edu comp.unix.questions:27745 comp.unix.shell:6135 news.answers:2042
- Path: news.cso.uiuc.edu!ux1.cso.uiuc.edu!uwm.edu!wupost!cs.utexas.edu!sun-barr!olivea!uunet!snorkelwacker.mit.edu!bloom-picayune.mit.edu!news
- >From: tmatimar@morse.waterloo.edu
- Newsgroups: comp.unix.questions,comp.unix.shell,news.answers
- Subject: Frequently Asked Questions about Unix (1/4) [Monthly posting]
- Message-ID: <unix-faq/part1_710139620@athena.mit.edu>
- Date: 3 Jul 92 05:01:17 GMT
- Expires: Sun, 16 Aug 1992 05:00:20 GMT
- Sender: news@athena.mit.edu (News system)
- Followup-To: comp.unix.questions
- Organization: Omron Corporation
- Lines: 306
- Approved: news-answers-request@MIT.Edu
- Supersedes: <unix-faq/part1_707547611@athena.mit.edu>
- X-Last-Updated: 1992/05/04
- Nntp-Posting-Host: pit-manager.mit.edu
- Status: RO
-
- Archive-name: unix-faq/part1
- Version: $Id: part1,v 1.5 1992/04/26 20:14:45 tmatimar Exp $
-
- These four articles contain the answers to some Frequently Asked
- Questions often seen in comp.unix.questions and comp.unix.shell.
- Please don't ask these questions again, they've been answered plenty
- of times already - and please don't flame someone just because they may
- not have read this particular posting. Thank you.
-
- These articles are divided approximately as follows:
-
- 1.*) General questions.
- 2.*) Relatively basic questions, likely to be asked by beginners.
- 3.*) Intermediate questions.
- 4.*) Advanced questions, likely to be asked by people who thought
- they already knew all of the answers.
-
- This article includes answers to:
-
- 1.1) Who helped you put this list together?
- 1.2) When someone refers to 'rn(1)' or 'ctime(3)', what does
- the number in parentheses mean?
- 1.3) What does {some strange unix command name} stand for?
- 1.4) How does the gateway between "comp.unix.questions" and the
- "info-unix" mailing list work?
- 1.5) What are some useful Unix or C books?
- 1.6) What happened to the pronunciation list that used to be
- part of this document?
-
- If you're looking for the answer to, say, question 1.5, and want to skip
- everything else, you can search ahead for the regular expression "^5)".
-
- While these are all legitimate questions, they seem to crop up in
- comp.unix.questions on an annual basis, usually followed by plenty
- of replies (only some of which are correct) and then a period of
- griping about how the same questions keep coming up. You may also like
- to read the monthly article "Answers to Frequently Asked Questions"
- in the newsgroup "news.announce.newusers", which will tell you what
- "UNIX" stands for.
-
- With the variety of Unix systems in the world, it's hard to guarantee
- that these answers will work everywhere. Read your local manual pages
- before trying anything suggested here. If you have suggestions or
- corrections for any of these answers, please send them to to
- tmatimar@nff.ncl.omron.co.jp.
-
- 1) Who helped you put this list together?
-
- I have just taken over the maintenance of this list. Almost all of
- the work (and the credit) for generating this compilation was done
- by Steve Hayman.
-
- We also owe a great deal of thanks to dozens of Usenet readers who
- submitted questions, answers, corrections and suggestions for this
- list. Special thanks go to Maarten Litmaath, Guy Harris and
- Jonathan Kamens, who have all made many especially valuable
- contributions.
-
- 2) When someone refers to 'rn(1)' or 'ctime(3)', what does
- the number in parentheses mean?
-
- It looks like some sort of function call, but it isn't.
- These numbers refer to the section of the "Unix manual" where
- the appropriate documentation can be found. You could type
- "man 3 ctime" to look up the manual page for "ctime" in section 3
- of the manual.
-
- The traditional manual sections are:
-
- 1 User-level commands
- 2 System calls
- 3 Library functions
- 4 Devices and device drivers
- 5 File formats
- 6 Games
- 7 Various miscellaneous stuff - macro packages etc.
- 8 System maintenance and operation commands
-
- Some Unix versions use non-numeric section names. For instance,
- Xenix uses "C" for commands and "S" for functions.
-
- Each section has an introduction, which you can read with "man # intro"
- where # is the section number.
-
- Sometimes the number is necessary to differentiate between a
- command and a library routine or system call of the same name. For
- instance, your system may have "time(1)", a manual page about the
- 'time' command for timing programs, and also "time(3)", a manual
- page about the 'time' subroutine for determining the current time.
- You can use "man 1 time" or "man 3 time" to specify which "time"
- man page you're interested in.
-
- You'll often find other sections for local programs or
- even subsections of the sections above - Ultrix has
- sections 3m, 3n, 3x and 3yp among others.
-
- 3) What does {some strange unix command name} stand for?
-
- awk = "Aho Weinberger and Kernighan"
-
- This language was named by its authors, Al Aho, Peter Weinberger and
- Brian Kernighan.
-
- grep = "Global Regular Expression Print"
-
- grep comes from the ed command to print all lines matching a
- certain pattern
-
- g/re/p
-
- where "re" is a "regular expression".
-
- fgrep = "Fixed GREP".
-
- fgrep searches for fixed strings only. The "f" does not
- stand for "fast" - in fact, "fgrep foobar *.c" is usually slower
- than "egrep foobar *.c" (Yes, this is kind of surprising. Try it.)
-
- Fgrep still has its uses though, and may be useful when searching
- a file for a larger number of strings than egrep can handle.
-
- egrep = "Extended GREP"
-
- egrep uses fancier regular expressions than grep.
- Many people use egrep all the time, since it has some more
- sophisticated internal algorithms than grep or fgrep,
- and is usually the fastest of the three programs.
-
- cat = "CATenate"
-
- catenate is an obscure word meaning "to connect in a series",
- which is what the "cat" command does to one or more files.
- Not to be confused with C/A/T, the Computer Aided Typesetter.
-
- gecos = "General Electric Comprehensive Operating System"
-
- When GE's large systems division was sold to Honeywell,
- Honeywell dropped the "E" from "GECOS".
-
- Unix's password file has a "pw_gecos" field. The name is
- a real holdover from the early days. Dennis Ritchie
- has reported:
-
- "Sometimes we sent printer output or batch jobs
- to the GCOS machine. The gcos field in the
- password file was a place to stash the information
- for the $IDENT card. Not elegant."
-
- nroff = "New ROFF"
- troff = "Typesetter new ROFF"
-
- These are descendants of "roff", which was a re-implementation
- of the Multics "runoff" program (a program that you'd use to
- "run off" a good copy of a document).
-
- tee = T
-
- From plumbing terminology for a T-shaped pipe splitter.
-
- bss = "Block Started by Symbol"
-
- Dennis Ritchie says:
-
- Actually the acronym (in the sense we took it up; it may
- have other credible etymologies) is "Block Started by Symbol."
- It was a pseudo-op in FAP (Fortran Assembly [-er?] Program), an
- assembler for the IBM 704-709-7090-7094 machines. It defined
- its label and set aside space for a given number of words.
- There was another pseudo-op, BES, "Block Ended by Symbol"
- that did the same except that the label was defined by
- the last assigned word + 1. (On these machines Fortran
- arrays were stored backwards in storage and were 1-origin.)
-
- The usage is reasonably appropriate, because just as with
- standard Unix loaders, the space assigned didn't have to
- be punched literally into the object deck but was represented
- by a count somewhere.
-
- biff = "BIFF"
-
- This command, which turns on asynchronous mail notification,
- was actually named after a dog at Berkeley.
-
- I can confirm the origin of biff, if you're interested. Biff
- was Heidi Stettner's dog, back when Heidi (and I, and Bill Joy)
- were all grad students at U.C. Berkeley and the early versions
- of BSD were being developed. Biff was popular among the
- residents of Evans Hall, and was known for barking at the
- mailman, hence the name of the command.
-
- Confirmation courtesy of Eric Cooper, Carnegie Mellon
- University
-
- rc (as in ".cshrc" or "/etc/rc") = "RunCom"
-
- "rc" derives from "runcom", from the MIT CTSS system, ca. 1965.
-
- 'There was a facility that would execute a bunch of commands
- stored in a file; it was called "runcom" for "run commands",
- and the file began to be called "a runcom."
-
- "rc" in Unix is a fossil from that usage.'
-
- Brian Kernighan & Dennis Ritchie, as told to Vicki Brown
-
- "rc" is also the name of the shell from the new Plan 9
- operating system.
-
- Perl = "Practical Extraction and Report Language"
-
- The Perl language is Larry Wall's highly popular
- freely-available completely portable text, process, and file
- manipulation tool that bridges the gap between shell and C
- programming (or between doing it on the command line and
- pulling your hair out). For further information, see the
- Usenet newsgroup comp.lang.perl.
-
- Don Libes' book "Life with Unix" contains lots more of these
- tidbits.
-
- 4) How does the gateway between "comp.unix.questions" and the
- "info-unix" mailing list work?
-
- "Info-Unix" and "Unix-Wizards" are mailing list versions of
- comp.unix.questions and comp.unix.wizards respectively.
- There should be no difference in content between the
- mailing list and the newsgroup.
-
- To get on or off either of these lists, send mail to
- Info-Unix-Request@brl.mil or Unix-Wizards-Request@brl.mil .
- Be sure to use the '-Request'. Don't expect an immediate response.
-
- Here are the gory details, courtesy of the list's maintainer, Bob Reschly.
-
- ==== postings to info-UNIX and UNIX-wizards lists ====
-
- Anything submitted to the list is posted; I do not moderate incoming
- traffic -- BRL functions as a reflector. Postings submitted by Internet
- subscribers should be addressed to the list address (info-UNIX or UNIX-
- wizards); the '-request' addresses are for correspondence with the list
- maintainer [me]. Postings submitted by USENET readers should be
- addressed to the appropriate news group (comp.unix.questions or
- comp.unix.wizards).
-
- For Internet subscribers, received traffic will be of two types;
- individual messages, and digests. Traffic which comes to BRL from the
- Internet and BITNET (via the BITNET-Internet gateway) is immediately
- resent to all addressees on the mailing list. Traffic originating on
- USENET is gathered up into digests which are sent to all list members
- daily.
-
- BITNET traffic is much like Internet traffic. The main difference is
- that I maintain only one address for traffic destined to all BITNET
- subscribers. That address points to a list exploder which then sends
- copies to individual BITNET subscribers. This way only one copy of a
- given message has to cross the BITNET-Internet gateway in either
- direction.
-
- USENET subscribers see only individual messages. All messages
- originating on the Internet side are forwarded to our USENET machine.
- They are then posted to the appropriate newsgroup. Unfortunately,
- for gatewayed messages, the sender becomes "news@brl-adm". This is
- currently an unavoidable side-effect of the software which performs the
- gateway function.
-
- As for readership, USENET has an extremely large readership - I would
- guess several thousand hosts and tens of thousands of readers. The
- master list maintained here at BRL runs about two hundred fifty entries
- with roughly ten percent of those being local redistribution lists.
- I don't have a good feel for the size of the BITNET redistribution, but
- I would guess it is roughly the same size and composition as the master
- list. Traffic runs 150K to 400K bytes per list per week on average.
-
- 5) What are some useful Unix or C books?
-
- Mitch Wright (mitch@cirrus.com) maintains a useful list of Unix and
- C books, with descriptions and some mini-reviews. There are currently
- 77 titles on his list.
-
- You can obtain a copy of this list by anonymous ftp from
- ftp.wg.omron.co.jp (133.210.4.4), where it's
- "pub/unix-faq/Unix-C-Booklist".
- If you can't use anonymous ftp, email the line "help" to
- "mailserv@iuvax.cs.indiana.edu" for instructions on
- retrieving things via email.
-
- Send additions or suggestions to mitch@cirrus.com.
-
- 6) What happened to the pronunciation list that used to be part of this
- document?
-
- From its inception in 1989, this FAQ document included a comprehensive
- pronunciation list maintained by Maarten Litmaath (thanks, Maarten!).
- (Does anyone know who *created* it?)
-
- It has been retired, since it is not really relevant to the topic of
- "Unix questions". You can still find it as part of the
- widely-distributed "Jargon" file (maintained by Eric S. Raymond,
- eric@snark.thyrsus.com) which seems like a much more appropriate
- forum for the topic of "How do you pronounce /* ?"
-
- If you'd like a copy, you can ftp one from ftp.wg.omron.co.jp
- (133.210.4.4), it's "pub/unix-faq/Pronunciation-Guide".
- --
- Ted Timar - tmatimar@nff.ncl.omron.co.jp
- Omron Corporation, Shimokaiinji, Nagaokakyo-city, Kyoto 617, Japan
-
-
- ..
- Hope you know what you're doing ...
- Data directory is /big/gd
- Port is 70
- Logging to File /usr/adm/gopherd.l
-
- >From news.cso.uiuc.edu!ux1.cso.uiuc.edu!uwm.edu!cs.utexas.edu!sun-barr!olivea!uunet!snorkelwacker.mit.edu!bloom-picayune.mit.edu!news Mon Jul 6 13:59:33 CDT 1992
- Article: 2043 of news.answers
- Xref: news.cso.uiuc.edu comp.unix.questions:27746 comp.unix.shell:6136 news.answers:2043
- Path: news.cso.uiuc.edu!ux1.cso.uiuc.edu!uwm.edu!cs.utexas.edu!sun-barr!olivea!uunet!snorkelwacker.mit.edu!bloom-picayune.mit.edu!news
- >From: tmatimar@morse.waterloo.edu
- Newsgroups: comp.unix.questions,comp.unix.shell,news.answers
- Subject: Frequently Asked Questions about Unix (2/4) [Monthly posting]
- Message-ID: <unix-faq/part2_710139620@athena.mit.edu>
- Date: 3 Jul 92 05:01:38 GMT
- References: <unix-faq/part1_710139620@athena.mit.edu>
- Sender: news@athena.mit.edu (News system)
- Followup-To: comp.unix.questions
- Organization: Omron Corporation
- Lines: 828
- Approved: news-answers-request@MIT.Edu
- Supersedes: <unix-faq/part2_707547611@athena.mit.edu>
- X-Last-Updated: 1992/05/04
- Nntp-Posting-Host: pit-manager.mit.edu
- Status: RO
-
- Archive-name: unix-faq/part2
- Version: $Id: part2,v 1.5 1992/04/26 20:14:45 tmatimar Exp $
-
- These four articles contain the answers to some Frequently Asked
- Questions often seen in comp.unix.questions and comp.unix.shell.
- Please don't ask these questions again, they've been answered plenty
- of times already - and please don't flame someone just because they may
- not have read this particular posting. Thank you.
-
- These articles are divided approximately as follows:
-
- 1.*) General questions.
- 2.*) Relatively basic questions, likely to be asked by beginners.
- 3.*) Intermediate questions.
- 4.*) Advanced questions, likely to be asked by people who thought
- they already knew all of the answers.
-
- This article includes answers to:
-
- 2.1) How do I remove a file whose name begins with a "-" ?
- 2.2) How do I remove a file with funny characters in the filename ?
- 2.3) How do I get a recursive directory listing?
- 2.4) How do I get the current directory into my prompt?
- 2.5) How do I read characters from the terminal in a shell script?
- 2.6) How do I rename "*.foo" to "*.bar", or change file names
- to lowercase?
- 2.7) Why do I get [some strange error message] when I
- "rsh host command" ?
- 2.8) How do I {set an environment variable, change directory} inside a
- program or shell script and have that change affect my
- current shell?
- 2.9) How do I redirect stdout and stderr separately in csh?
- 2.10) How do I tell inside .cshrc if I'm a login shell?
- 2.11) How do I construct a shell glob-pattern that matches all files
- except "." and ".." ?
- 2.12) How do I find the last argument in a Bourne shell script?
- 2.13) What's wrong with having '.' in your $PATH ?
-
- If you're looking for the answer to, say, question 2.5, and want to skip
- everything else, you can search ahead for the regular expression "^5)".
-
- While these are all legitimate questions, they seem to crop up in
- comp.unix.questions on an annual basis, usually followed by plenty
- of replies (only some of which are correct) and then a period of
- griping about how the same questions keep coming up. You may also like
- to read the monthly article "Answers to Frequently Asked Questions"
- in the newsgroup "news.announce.newusers", which will tell you what
- "UNIX" stands for.
-
- With the variety of Unix systems in the world, it's hard to guarantee
- that these answers will work everywhere. Read your local manual pages
- before trying anything suggested here. If you have suggestions or
- corrections for any of these answers, please send them to to
- tmatimar@nff.ncl.omron.co.jp.
-
- 1) How do I remove a file whose name begins with a "-" ?
-
- Figure out some way to name the file so that it doesn't
- begin with a dash. The simplest answer is to use
-
- rm ./-filename
-
- (assuming "-filename" is in the current directory, of course.)
- This method of avoiding the interpretation of the "-" works
- with other commands too.
-
- Many commands, particularly those that have been written to use
- the "getopt(3)" argument parsing routine, accept a "--" argument
- which means "this is the last option, anything after this is not
- an option", so your version of rm might handle "rm -- -filename".
- Some versions of rm that don't use getopt() treat a single "-"
- in the same way, so you can also try "rm - -filename".
-
- 2) How do I remove a file with funny characters in the filename ?
-
- If the 'funny character' is a '/', skip to the last part of
- this answer. If the funny character is something else,
- such as a ' ' or control character or character with
- the 8th bit set, keep reading.
-
- The classic answers are
-
- rm -i some*pattern*that*matches*only*the*file*you*want
-
- which asks you whether you want to remove each file matching
- the indicated pattern; depending on your shell, this may
- not work if the filename has a character with the 8th bit set
- (the shell may strip that off);
-
- and
-
- rm -ri .
-
- which asks you whether to remove each file in the directory.
- Answer "y" to the problem file and "n" to everything else.
- Unfortunately this doesn't work with many versions of rm.
- Also unfortunately, this will walk through every subdirectory
- of ".", so you might want to "chmod a-x" those directories
- temporarily to make them unsearchable.
-
- Always take a deep breath and think about what you're doing
- and double check what you typed when you use rm's "-r" flag
- or a wildcard on the command line;
-
- and
-
- find . -type f ... -ok rm '{}' \;
-
- where "..." is a group of predicates that uniquely identify the
- file. One possibility is to figure out the inode number
- of the problem file (use "ls -i .") and then use
-
- find . -inum 12345 -ok rm '{}' \;
-
- or
- find . -inum 12345 -ok mv '{}' new-file-name \;
-
- "-ok" is a safety check - it will prompt you for confirmation of the
- command it's about to execute. You can use "-exec" instead to avoid
- the prompting, if you want to live dangerously, or if you suspect
- that the filename may contain a funny character sequence that will mess
- up your screen when printed.
-
- What if the filename has a '/' in it?
-
- These files really are special cases, and can only be created
- by buggy kernel code (typically by implementations of NFS
- that don't filter out illegal characters in file names from
- remote machines.) The first thing to do is to try to
- understand exactly why this problem is so strange.
-
- Recall that Unix directories are simply pairs of
- filenames and inode numbers. A directory essentially
- contains information like this:
-
- filename inode
-
- file1 12345
- file2.c 12349
- file3 12347
-
- Theoretically, '/' and '\0' are the only two characters that
- cannot appear in a filename - '/' because it's used to separate
- directories and files, and '\0' because it terminates a filename.
-
- Unfortunately some implementations of NFS will blithely create
- filenames with embedded slashes in response to requests from remote
- machines. For instance, this could happen when someone on a Mac or
- other non-Unix machine decides to create a remote NFS file on
- your Unix machine with the date in the filename. Your Unix
- directory then has this in it:
-
- filename inode
-
- 91/02/07 12357
-
- No amount of messing around with 'find' or 'rm' as described above
- will delete this file, since those utilities and all other Unix
- programs, are forced to interpret the '/' in the normal way.
-
- Any ordinary program will eventually try to do unlink("91/02/07"),
- which as far as the kernel is concerned means "unlink the file 07
- in the subdirectory 02 of directory 91", but that's not what we
- have - we have a *FILE* named "91/02/07" in the current directory.
- This is a subtle but crucial distinction.
-
- What can you do in this case?
- The first thing to try is to return to the Mac that created this
- crummy entry, and see if you can convince it and your local NFS
- daemon to rename the file to something without slashes.
-
- If that doesn't work or isn't possible, you'll need help from your
- system manager, who will have to try the one of the following.
- Use "ls -i" to find the inode number of this bogus file, then
- unmount the file system and use "clri" to clear the inode, and
- "fsck" the file system with your fingers crossed. This destroys
- the information in the file. If you want to keep it, you can try:
-
- create a new directory in the same parent directory as the one
- containing the bad file name;
-
- move everything you can (i.e. everything but the file with
- the bad name) from the old directory to the new one;
-
- do "ls -id" on the directory containing the file with the
- bad name to get its inumber;
-
- umount the file system;
-
- "clri" the directory containing the file with the bad name;
-
- "fsck" the file system.
-
- Then, to find the file,
-
- remount the file system;
-
- rename the directory you created to have the name of
- the old directory (since the old directory should have
- been blown away by "fsck")
-
- move the file out of "lost+found" into the directory
- with a better name.
-
- Alternatively, you can patch the directory the hard way
- by crawling around in the raw file system.
- Use "fsdb", if you have it.
-
- 3) How do I get a recursive directory listing?
-
- One of the following may do what you want:
-
- ls -R (not all versions of "ls" have -R)
- find . -print (should work everywhere)
- du -a . (shows you both the name and size)
-
- If you're looking for a wildcard pattern that will match
- all ".c" files in this directory and below, you won't find one,
- but you can use
-
- % some-command `find . -name '*.c' -print`
-
- "find" is a powerful program. Learn about it.
-
- 4) How do I get the current directory into my prompt?
-
- It depends which shell you are using. It's easy with some shells,
- hard or impossible with others.
-
- C Shell (csh):
- Put this in your .cshrc - customize the prompt variable
- the way you want.
-
- alias setprompt 'set prompt="${cwd}% "'
- setprompt # to set the initial prompt
- alias cd 'chdir \!* && setprompt'
-
- If you use pushd and popd, you'll also need
-
- alias pushd 'pushd \!* && setprompt'
- alias popd 'popd \!* && setprompt'
-
- Some C shells don't keep a $cwd variable - you can use
- `pwd` instead.
-
- If you just want the last component of the current directory
- in your prompt ("mail% " instead of "/usr/spool/mail% ")
- you can use
-
- alias setprompt 'set prompt="$cwd:t% "'
-
- Some older csh's get the meaning of && and || reversed.
- Try doing:
-
- false && echo bug
-
- If it prints "bug", you need to switch && and || (and get
- a better version of csh.)
-
- Bourne Shell (sh):
-
- If you have a newer version of the Bourne Shell (SVR2 or newer)
- you can use a shell function to make your own command, "xcd" say:
-
- xcd() { cd $* ; PS1="`pwd` $ "; }
-
- If you have an older Bourne shell, it's complicated but not impossible.
- Here's one way. Add this to your .profile file:
-
- LOGIN_SHELL=$$ export LOGIN_SHELL
- CMDFILE=/tmp/cd.$$ export CMDFILE
- # 16 is SIGURG, pick some signal that isn't likely to be used
- PROMPTSIG=16 export PROMPTSIG
- trap '. $CMDFILE' $PROMPTSIG
-
- and then put this executable script (without the indentation!),
- let's call it "xcd", somewhere in your PATH
-
- : xcd directory - change directory and set prompt
- : by signalling the login shell to read a command file
- cat >${CMDFILE?"not set"} <<EOF
- cd $1
- PS1="\`pwd\`$ "
- EOF
- kill -${PROMPTSIG?"not set"} ${LOGIN_SHELL?"not set"}
-
- Now change directories with "xcd /some/dir".
-
- Korn Shell (ksh):
-
- Put this in your .profile file:
- PS1='$PWD $ '
-
- If you just want the last component of the directory, use
- PS1='${PWD##*/} $ '
-
- T C shell (tcsh)
-
- Tcsh is a popular enhanced version of csh with some extra
- builtin variables (and many other features):
-
- %~ the current directory, using ~ for $HOME
- %d or %/ the full pathname of the current directory
- %c or %. the trailing component of the current directory
-
- so you can do
-
- set prompt='%~ '
-
- BASH (FSF's "Bourne Again SHell")
-
- \w in $PS1 gives the full pathname of the current directory,
- with ~ expansion for $HOME; \W gives the basename of
- the current directory. So, in addition to the above sh and
- ksh solutions, you could use
-
- PS1='\w $ '
- or
- PS1='\W $ '
-
- 5) How do I read characters from the terminal in a shell script?
-
- In sh, use read. It is most common to use a loop like
-
- while read line
- do
- ...
- done
-
- In csh, use $< like this:
-
- while ( 1 )
- set line = "$<"
- if ( "$line" == "" ) break
- ...
- end
-
- Unfortunately csh has no way of distinguishing between
- a blank line and an end-of-file.
-
- If you're using sh and want to read a *single* character from
- the terminal, you can try something like
-
- echo -n "Enter a character: "
- stty cbreak # or stty raw
- readchar=`dd if=/dev/tty bs=1 count=1 2>/dev/null`
- stty -cbreak
-
- echo "Thank you for typing a $readchar ."
-
- 6) How do I rename "*.foo" to "*.bar", or change file names to lowercase?
-
- Why doesn't "mv *.foo *.bar" work? Think about how the shell
- expands wildcards. "*.foo" and "*.bar" are expanded before the mv
- command ever sees the arguments. Depending on your shell, this
- can fail in a couple of ways. CSH prints "No match." because
- it can't match "*.bar". SH executes "mv a.foo b.foo c.foo *.bar",
- which will only succeed if you happen to have a single
- directory named "*.bar", which is very unlikely and almost
- certainly not what you had in mind.
-
- Depending on your shell, you can do it with a loop to "mv" each
- file individually. If your system has "basename", you can use:
-
- C Shell:
- foreach f ( *.foo )
- set base=`basename $f .foo`
- mv $f $base.bar
- end
-
- Bourne Shell:
- for f in *.foo; do
- base=`basename $f .foo`
- mv $f $base.bar
- done
-
- Some shells have their own variable substitution features, so instead
- of using "basename", you can use simpler loops like:
-
- C Shell:
-
- foreach f ( *.foo )
- mv $f $f:r.bar
- end
-
- Korn Shell:
-
- for f in *.foo; do
- mv $f ${f%foo}bar
- done
-
- If you don't have "basename" or want to do something like
- renaming foo.* to bar.*, you can use something like "sed" to
- strip apart the original file name in other ways, but
- the general looping idea is the same. You can also convert
- file names into "mv" commands with 'sed', and hand the commands
- off to "sh" for execution. Try
-
- ls -d *.foo | sed -e 's/.*/mv & &/' -e 's/foo$/bar/' | sh
-
- A program by Vladimir Lanin called "mmv" that does this job nicely
- was posted to comp.sources.unix (Volume 21, issues 87 and 88) in
- April 1990. It lets you use
-
- mmv '*.foo' '=1.bar'
-
- Shell loops like the above can also be used to translate
- file names from upper to lower case or vice versa. You could use
- something like this to rename uppercase files to lowercase:
-
- C Shell:
- foreach f ( * )
- mv $f `echo $f | tr '[A-Z]' '[a-z]'`
- end
- Bourne Shell:
- for f in *; do
- mv $f `echo $f | tr '[A-Z]' '[a-z]'`
- done
- Korn Shell:
- typeset -l l
- for f in *; do
- l="$f"
- mv $f $l
- done
-
- If you wanted to be really thorough and handle files with
- `funny' names (embedded blanks or whatever) you'd need to use
-
- Bourne Shell:
-
- for f in *; do
- g=`expr "xxx$f" : 'xxx\(.*\)' | tr '[A-Z]' '[a-z]'`
- mv "$f" "$g"
- done
-
- The `expr' command will always print the filename, even if it equals
- `-n' or if it contains a System V escape sequence like `\c'.
-
- Some versions of "tr" require the [ and ], some don't. It happens
- to be harmless to include them in this particular example; versions of
- tr that don't want the [] will conveniently think they are supposed
- to translate '[' to '[' and ']' to ']'.
-
- If you have the "perl" language installed, you may find this rename
- script by Larry Wall very useful. It can be used to accomplish a
- wide variety of filename changes.
-
- #!/usr/bin/perl
- #
- # rename script examples from lwall:
- # rename 's/\.orig$//' *.orig
- # rename 'y/A-Z/a-z/ unless /^Make/' *
- # rename '$_ .= ".bad"' *.f
- # rename 'print "$_: "; s/foo/bar/ if <stdin> =~ /^y/i' *
-
- $op = shift;
- for (@ARGV) {
- $was = $_;
- eval $op;
- die $@ if $@;
- rename($was,$_) unless $was eq $_;
- }
-
- 7) Why do I get [some strange error message] when I "rsh host command" ?
-
- (We're talking about the remote shell program "rsh" or sometimes "remsh";
- on some machines, there is a restricted shell called "rsh", which
- is a different thing.)
-
- If your remote account uses the C shell, the remote host will
- fire up a C shell to execute 'command' for you, and that shell
- will read your remote .cshrc file. Perhaps your .cshrc contains
- a "stty", "biff" or some other command that isn't appropriate
- for a non-interactive shell. The unexpected output or error
- message from these commands can screw up your rsh in odd ways.
-
- Here's an example. Suppose you have
-
- stty erase ^H
- biff y
-
- in your .cshrc file. You'll get some odd messages like this.
-
- % rsh some-machine date
- stty: : Can't assign requested address
- Where are you?
- Tue Oct 1 09:24:45 EST 1991
-
- You might also get similar errors when running certain "at" or
- "cron" jobs that also read your .cshrc file.
-
- Fortunately, the fix is simple. There are, quite possibly, a whole
- *bunch* of operations in your ".cshrc" (e.g., "set history=N") that are
- simply not worth doing except in interactive shells. What you do is
- surround them in your ".cshrc" with:
-
- if ( $?prompt ) then
- operations....
- endif
-
- and, since in a non-interactive shell "prompt" won't be set, the
- operations in question will only be done in interactive shells.
-
- You may also wish to move some commands to your .login file; if
- those commands only need to be done when a login session starts up
- (checking for new mail, unread news and so on) it's better
- to have them in the .login file.
-
- 8) How do I {set an environment variable, change directory} inside a
- program or shell script and have that change affect my
- current shell?
-
- In general, you can't, at least not without making special
- arrangements. When a child process is created, it inherits a copy
- of its parent's variables (and current directory). The child can
- change these values all it wants but the changes won't affect the
- parent shell, since the child is changing a copy of the
- original data.
-
- Some special arrangements are possible. Your child process could
- write out the changed variables, if the parent was prepared to read
- the output and interpret it as commands to set its own variables.
-
- Also, shells can arrange to run other shell scripts in the context
- of the current shell, rather than in a child process, so that
- changes will affect the original shell.
-
- For instance, if you have a C shell script named "myscript":
-
- cd /very/long/path
- setenv PATH /something:/something-else
-
- or the equivalent Bourne or Korn shell script
-
- cd /very/long/path
- PATH=/something:/something-else export PATH
-
- and try to run "myscript" from your shell, your shell will fork and run
- the shell script in a subprocess. The subprocess is also
- running the shell; when it sees the "cd" command it changes
- *its* current directory, and when it sees the "setenv" command
- it changes *its* environment, but neither has any effect on the current
- directory of the shell at which you're typing (your login shell,
- let's say).
-
- In order to get your login shell to execute the script (without forking)
- you have to use the "." command (for the Bourne or Korn shells)
- or the "source" command (for the C shell). I.e. you type
-
- . myscript
-
- to the Bourne or Korn shells, or
-
- source myscript
-
- to the C shell.
-
- If all you are trying to do is change directory or set an
- environment variable, it will probably be simpler to use a
- C shell alias or Bourne/Korn shell function. See the "how do
- I get the current directory into my prompt" section
- of this article for some examples.
-
- 9) How do I redirect stdout and stderr separately in csh?
-
- In csh, you can redirect stdout with ">", or stdout and stderr
- together with ">&" but there is no direct way to redirect
- stderr only. The best you can do is
-
- ( command >stdout_file ) >&stderr_file
-
- which runs "command" in a subshell; stdout is redirected inside
- the subshell to stdout_file, and both stdout and stderr from the
- subshell are redirected to stderr_file, but by this point stdout
- has already been redirected so only stderr actually winds up in
- stderr_file.
-
- Sometimes it's easier to let sh do the work for you.
-
- sh -c 'command >stdout_file 2>stderr_file'
-
- 10) How do I tell inside .cshrc if I'm a login shell?
-
- When people ask this, they usually mean either
-
- How can I tell if it's an interactive shell? or
- How can I tell if it's a top-level shell?
-
- You could perhaps determine if your shell truly is a login shell
- (i.e. is going to source ".login" after it is done with ".cshrc")
- by fooling around with "ps" and "$$". Login shells generally have
- names that begin with a '-'. If you're really interested in the
- other two questions, here's one way you can organize your .cshrc to
- find out.
-
- if (! $?CSHLEVEL) then
- #
- # This is a "top-level" shell,
- # perhaps a login shell, perhaps a shell started up by
- # 'rsh machine some-command'
- # This is where we should set PATH and anything else we
- # want to apply to every one of our shells.
- #
- setenv CSHLEVEL 0
- set home = ~username # just to be sure
- source ~/.env # environment stuff we always want
- else
- #
- # This shell is a child of one of our other shells so
- # we don't need to set all the environment variables again.
- #
- set tmp = $CSHLEVEL
- @ tmp++
- setenv CSHLEVEL $tmp
- endif
-
- # Exit from .cshrc if not interactive, e.g. under rsh
- if (! $?prompt) exit
-
- # Here we could set the prompt or aliases that would be useful
- # for interactive shells only.
-
- source ~/.aliases
-
- 11) How do I construct a shell glob-pattern that matches all files
- except "." and ".." ?
-
- You'd think this would be easy.
-
- * Matches all files that don't begin with a ".";
-
- .* Matches all files that do begin with a ".", but
- this includes the special entries "." and "..",
- which often you don't want;
-
- .[!.]* (Newer shells only; some shells use a "^" instead of
- the "!"; POSIX shells must accept the "!", but may
- accept a "^" as well; all portable applications shall
- not use an unquoted "^" immediately following the "[")
-
- Matches all files that begin with a "." and are
- followed by a non-"."; unfortunately this will miss
- "..foo";
-
- .??* Matches files that begin with a "." and which are
- at least 3 characters long. This neatly avoids
- "." and "..", but also misses ".a" .
-
- So to match all files except "." and ".." safely you have to use
- 3 patterns (if you don't have filenames like ".a" you can leave out
- the first):
-
- .[!.]* .??* *
-
- Alternatively you could employ an external program or two and use
- backquote substitution. This is pretty good:
-
- `ls -a | sed -e '/^\.$/d' -e '/^\.\.$/d'`
-
- (or `ls -A` in some Unix versions)
-
- but even it will mess up on files with newlines, IFS characters
- or wildcards in their names.
-
- 12) How do I find the last argument in a Bourne shell script?
-
- Answer by:
- Martin Weitzel <@mikros.systemware.de:martin@mwtech.uucp>
- Maarten Litmaath <maart@nat.vu.nl>
-
- If you are sure the number of arguments is at most 9, you can use:
-
- eval last=\${$#}
-
- In POSIX-compatible shells it works for ANY number of arguments.
- The following works always too:
-
- for last
- do
- :
- done
-
- This can be generalized as follows:
-
- for i
- do
- third_last=$second_last
- second_last=$last
- last=$i
- done
-
- Now suppose you want to REMOVE the last argument from the list,
- or REVERSE the argument list, or ACCESS the N-th argument directly,
- whatever N may be. Here is a basis of how to do it, using only
- built-in shell constructs, without creating subprocesses:
-
- t0= u0= rest='1 2 3 4 5 6 7 8 9' argv=
-
- for h in '' $rest
- do
- for t in "$t0" $rest
- do
- for u in $u0 $rest
- do
- case $# in
- 0)
- break 3
- esac
- eval argv$h$t$u=\$1
- argv="$argv \"\$argv$h$t$u\"" # (1)
- shift
- done
- u0=0
- done
- t0=0
- done
-
- # now restore the arguments
- eval set x "$argv" # (2)
- shift
-
- This example works for the first 999 arguments. Enough?
- Take a good look at the lines marked (1) and (2) and convince yourself
- that the original arguments are restored indeed, no matter what funny
- characters they contain!
-
- To find the N-th argument now you can use this:
-
- eval argN=\$argv$N
-
- To reverse the arguments the line marked (1) must be changed to:
-
- argv="\"\$argv$h$t$u\" $argv"
-
- How to remove the last argument is left as an exercise.
-
- If you allow subprocesses as well, possibly executing nonbuilt-in
- commands, the `argvN' variables can be set up more easily:
-
- N=1
-
- for i
- do
- eval argv$N=\$i
- N=`expr $N + 1`
- done
-
- To reverse the arguments there is still a simpler method, that even does
- not create subprocesses. This approach can also be taken if you want
- to delete e.g. the last argument, but in that case you cannot refer
- directly to the N-th argument any more, because the `argvN' variables are
- set up in reverse order:
-
- argv=
-
- for i
- do
- eval argv$#=\$i
- argv="\"\$argv$#\" $argv"
- shift
- done
-
- eval set x "$argv"
- shift
-
- 13) What's wrong with having '.' in your $PATH ?
-
- A bit of background: the PATH environment variable is a list of
- directories separated by colons. When you type a command name
- without giving an explicit path (e.g. you type "ls", rather than
- "/bin/ls") your shell searches each directory in the PATH list in
- order, looking for an executable file by that name, and the
- shell will run the first matching program it finds.
-
- One of the directories in the PATH list can be the
- current directory "." . It is also permissible to use
- an empty directory name in the PATH list to indicate
- the current directory. Both of these are equivalent
-
- for csh users:
-
- setenv PATH :/usr/ucb:/bin:/usr/bin
- setenv PATH .:/usr/ucb:/bin:/usr/bin
-
- for sh or ksh users
-
- PATH=:/usr/ucb:/bin:/usr/bin export PATH
- PATH=.:/usr/ucb:/bin:/usr/bin export PATH
-
- Having "." somewhere in the PATH is convenient - you can type
- "a.out" instead of "./a.out" to run programs in the current
- directory. But there's a catch.
-
- Consider what happens in the case where "." is the
- first entry in the PATH. Suppose your current directory is a
- publically-writable one, such as "/tmp". If there just happens to
- be a program named "/tmp/ls" left there by some other user, and you
- type "ls" (intending, of course, to run the normal "/bin/ls"
- program), your shell will instead run "./ls", the other
- user's program. Needless to say, the results of running
- an unknown program like this might surprise you.
-
- It's slightly better to have "." at the end of the PATH:
-
- setenv PATH /usr/ucb:/bin:/usr/bin:.
-
- Now if you're in /tmp and you type "ls", the shell will
- search /usr/ucb, /bin and /usr/bin for a program named
- "ls" before it gets around to looking in ".", and there
- is less risk of inadvertently running some other user's
- "ls" program. This isn't 100% secure though - if you're
- a clumsy typist and some day type "sl -l" instead of "ls -l",
- you run the risk of running "./sl", if there is one.
- Some "clever" programmer could anticipate common typing
- mistakes and leave programs by those names scattered
- throughout public directories. Beware.
-
- Many seasoned Unix users get by just fine without having
- "." in the PATH at all:
-
- setenv PATH /usr/ucb:/bin:/usr/bin
-
- If you do this, you'll need to type "./program" instead
- of "program" to run programs in the current directory, but
- the increase in security is probably worth it.
- --
- Ted Timar - tmatimar@nff.ncl.omron.co.jp
- Omron Corporation, Shimokaiinji, Nagaokakyo-city, Kyoto 617, Japan
-
-
- ..
- Hope you know what you're doing ...
- Data directory is /big/gd
- Port is 70
- Logging to File /usr/adm/gopherd.l
-
- >From news.cso.uiuc.edu!ux1.cso.uiuc.edu!uwm.edu!cs.utexas.edu!sun-barr!olivea!uunet!snorkelwacker.mit.edu!bloom-picayune.mit.edu!news Mon Jul 6 13:59:36 CDT 1992
- Article: 2044 of news.answers
- Xref: news.cso.uiuc.edu comp.unix.questions:27747 comp.unix.shell:6137 news.answers:2044
- Path: news.cso.uiuc.edu!ux1.cso.uiuc.edu!uwm.edu!cs.utexas.edu!sun-barr!olivea!uunet!snorkelwacker.mit.edu!bloom-picayune.mit.edu!news
- >From: tmatimar@morse.waterloo.edu
- Newsgroups: comp.unix.questions,comp.unix.shell,news.answers
- Subject: Frequently Asked Questions about Unix (3/4) [Monthly posting]
- Message-ID: <unix-faq/part3_710139620@athena.mit.edu>
- Date: 3 Jul 92 05:01:58 GMT
- References: <unix-faq/part1_710139620@athena.mit.edu>
- Sender: news@athena.mit.edu (News system)
- Followup-To: comp.unix.questions
- Organization: Omron Corporation
- Lines: 612
- Approved: news-answers-request@MIT.Edu
- Supersedes: <unix-faq/part3_707547611@athena.mit.edu>
- X-Last-Updated: 1992/05/04
- Nntp-Posting-Host: pit-manager.mit.edu
- Status: RO
-
- Archive-name: unix-faq/part3
- Version: $Id: part3,v 1.5 1992/04/26 20:14:45 tmatimar Exp $
-
- These four articles contain the answers to some Frequently Asked
- Questions often seen in comp.unix.questions and comp.unix.shell.
- Please don't ask these questions again, they've been answered plenty
- of times already - and please don't flame someone just because they may
- not have read this particular posting. Thank you.
-
- These articles are divided approximately as follows:
-
- 1.*) General questions.
- 2.*) Relatively basic questions, likely to be asked by beginners.
- 3.*) Intermediate questions.
- 4.*) Advanced questions, likely to be asked by people who thought
- they already knew all of the answers.
-
- This article includes answers to:
-
- 3.1) How do I find out the creation time of a file?
- 3.2) How do I use "rsh" without having the rsh hang around
- until the remote command has completed?
- 3.3) How do I truncate a file?
- 3.4) Why doesn't find's "{}" symbol do what I want?
- 3.5) How do I set the permissions on a symbolic link?
- 3.6) How do I "undelete" a file?
- 3.7) How can a process detect if it's running in the background?
- 3.8) Why doesn't redirecting a loop work as intended? (Bourne shell)
- 3.9) How do I run 'passwd', 'ftp', 'telnet', 'tip' and other interactive
- programs from a shell script or in the background?
- 3.10) How do I find out the process ID of a program with a particular
- name from inside a shell script or C program?
- 3.11) How do I check the exit status of a remote command
- executed via "rsh" ?
- 3.12) Is it possible to pass shell variable settings into an awk program?
- 3.13) How do I get rid of zombie processes that persevere?
- 3.14) How do I get lines from a pipe as they are written instead of
- only in larger blocks.
-
- If you're looking for the answer to, say, question 3.5, and want to skip
- everything else, you can search ahead for the regular expression "^5)".
-
- While these are all legitimate questions, they seem to crop up in
- comp.unix.questions on an annual basis, usually followed by plenty
- of replies (only some of which are correct) and then a period of
- griping about how the same questions keep coming up. You may also like
- to read the monthly article "Answers to Frequently Asked Questions"
- in the newsgroup "news.announce.newusers", which will tell you what
- "UNIX" stands for.
-
- With the variety of Unix systems in the world, it's hard to guarantee
- that these answers will work everywhere. Read your local manual pages
- before trying anything suggested here. If you have suggestions or
- corrections for any of these answers, please send them to to
- tmatimar@nff.ncl.omron.co.jp.
-
- 1) How do I find out the creation time of a file?
-
- You can't - it isn't stored anywhere. Files have a last-modified
- time (shown by "ls -l"), a last-accessed time (shown by "ls -lu")
- and an inode change time (shown by "ls -lc"). The latter is often
- referred to as the "creation time" - even in some man pages - but
- that's wrong; it's also set by such operations as mv, ln,
- chmod, chown and chgrp.
-
- The man page for "stat(2)" discusses this.
-
- 2) How do I use "rsh" without having the rsh hang around until the
- remote command has completed?
-
- (See note in question 2.7 about what "rsh" we're talking about.)
-
- The obvious answers fail:
- rsh machine command &
- or rsh machine 'command &'
-
- For instance, try doing rsh machine 'sleep 60 &'
- and you'll see that the 'rsh' won't exit right away.
- It will wait 60 seconds until the remote 'sleep' command
- finishes, even though that command was started in the
- background on the remote machine. So how do you get
- the 'rsh' to exit immediately after the 'sleep' is started?
-
- The solution - if you use csh on the remote machine:
-
- rsh machine -n 'command >&/dev/null </dev/null &'
-
- If you use sh on the remote machine:
-
- rsh machine -n 'command >/dev/null 2>&1 </dev/null &'
-
- Why? "-n" attaches rsh's stdin to /dev/null so you could run the
- complete rsh command in the background on the LOCAL machine.
- Thus "-n" is equivalent to another specific "< /dev/null".
- Furthermore, the input/output redirections on the REMOTE machine
- (inside the single quotes) ensure that rsh thinks the session can
- be terminated (there's no data flow any more.)
-
- Note: The file that you redirect to/from on the remote machine
- doesn't have to be /dev/null; any ordinary file will do.
-
- In many cases, various parts of these complicated commands
- aren't necessary.
-
- 3) How do I truncate a file?
-
- The BSD function ftruncate() sets the length of a file. Xenix -
- and therefore SysV r3.2 and later - has the chsize() system call.
- For other systems, the only kind of truncation you can do is
- truncation to length zero with creat() or open(..., O_TRUNC).
-
- 4) Why doesn't find's "{}" symbol do what I want?
-
- "find" has a -exec option that will execute a particular
- command on all the selected files. Find will replace any "{}"
- it sees with the name of the file currently under consideration.
-
- So, some day you might try to use "find" to run a command on every
- file, one directory at a time. You might try this:
-
- find /path -type d -exec command {}/\* \;
-
- hoping that find will execute, in turn
-
- command directory1/*
- command directory2/*
- ...
-
- Unfortunately, find only expands the "{}" token when it appears
- by itself. Find will leave anything else like "{}/*" alone, so
- instead of doing what you want, it will do
-
- command {}/*
- command {}/*
- ...
-
- once for each directory. This might be a bug, it might be a feature,
- but we're stuck with the current behaviour.
-
- So how do you get around this? One way would be to write a
- trivial little shell script, let's say "./doit", that
- consists of
-
- command "$1"/*
-
- You could then use
-
- find /path -type d -exec ./doit {} \;
-
- Or if you want to avoid the "./doit" shell script, you can use
-
- find /path -type d -exec sh -c 'command $0/*' {} \;
-
- (This works because within the 'command' of "sh -c 'command' A B C ...",
- $0 expands to A, $1 to B, and so on.)
-
- or you can use the construct-a-command-with-sed trick
-
- find /path -type d -print | sed 's:.*:command &/*:' | sh
-
- If all you're trying to do is cut down on the number of times
- that "command" is executed, you should see if your system
- has the "xargs" command. Xargs reads arguments one line at a time
- from the standard input and assembles as many of them as will fit into
- one command line. You could use
-
- find /path -print | xargs command
-
- which would result in one or more executions of
-
- command file1 file2 file3 file4 dir1/file1 dir1/file2
-
- Unfortunately this is not a perfectly robust or secure solution.
- Xargs expects its input lines to be terminated with newlines, so it
- will be confused by files with odd characters such as newlines
- in their names.
-
- 5) How do I set the permissions on a symbolic link?
-
- Permissions on a symbolic link don't really mean anything. The
- only permissions that count are the permissions on the file that
- the link points to.
-
- 6) How do I "undelete" a file?
-
- Someday, you are going to accidentally type something like "rm * .foo",
- and find you just deleted "*" instead of "*.foo". Consider it a rite
- of passage.
-
- Of course, any decent systems administrator should be doing regular
- backups. Check with your sysadmin to see if a recent backup copy
- of your file is available. But if it isn't, read on.
-
- For all intents and purposes, when you delete a file with "rm" it is
- gone. Once you "rm" a file, the system totally forgets which blocks
- scattered around the disk comprised your file. Even worse, the blocks
- from the file you just deleted are going to be the first ones taken
- and scribbled upon when the system needs more disk space. However,
- never say never. It is theoretically possible *if* you shut down
- the system immediately after the "rm" to recover portions of the data.
- However, you had better have a very wizardly type person at hand with
- hours or days to spare to get it all back.
-
- Your first reaction when you "rm" a file by mistake is why not make
- a shell alias or procedure which changes "rm" to move files into a
- trash bin rather than delete them? That way you can recover them if
- you make a mistake, and periodically clean out your trash bin. Two
- points: first, this is generally accepted as a *bad* idea. You will
- become dependent upon this behaviour of "rm", and you will find
- yourself someday on a normal system where "rm" is really "rm", and
- you will get yourself in trouble. Second, you will eventually find
- that the hassle of dealing with the disk space and time involved in
- maintaining the trash bin, it might be easier just to be a bit more
- careful with "rm". For starters, you should look up the "-i" option
- to "rm" in your manual.
-
- If you are still undaunted, then here is a possible simple answer. You
- can create yourself a "can" command which moves files into a
- trashcan directory. In csh(1) you can place the following commands
- in the ".login" file in your home directory:
-
- alias can 'mv \!* ~/.trashcan' # junk file(s) to trashcan
- alias mtcan 'rm -f ~/.trashcan/*' # irretrievably empty trash
- if ( ! -d ~/.trashcan ) mkdir ~/.trashcan # ensure trashcan exists
-
- You might also want to put a:
-
- rm -f ~/.trashcan/*
-
- in the ".logout" file in your home directory to automatically empty
- the trash when you log out. (sh and ksh versions are left as an
- exercise for the reader.)
-
- MIT's Project Athena has produced a comprehensive
- delete/undelete/expunge/purge package, which can serve as a
- complete replacement for rm which allows file recovery. This
- package was posted to comp.sources.misc (volume 17, issue 023-026)
-
- 7) How can a process detect if it's running in the background?
-
- First of all: do you want to know if you're running in the background,
- or if you're running interactively? If you're deciding whether or
- not you should print prompts and the like, that's probably a better
- criterion. Check if standard input is a terminal:
-
- sh: if [ -t 0 ]; then ... fi
- C: if(isatty(0)) { ... }
-
- In general, you can't tell if you're running in the background.
- The fundamental problem is that different shells and different
- versions of UNIX have different notions of what "foreground" and
- "background" mean - and on the most common type of system with a
- better-defined notion of what they mean, programs can be moved
- arbitrarily between foreground and background!
-
- UNIX systems without job control typically put a process into the
- background by ignoring SIGINT and SIGQUIT and redirecting the standard
- input to "/dev/null"; this is done by the shell.
-
- Shells that support job control, on UNIX systems that support job
- control, put a process into the background by giving it a process group
- ID different from the process group to which the terminal belongs. They
- move it back into the foreground by setting the terminal's process group
- ID to that of the process. Shells that do *not* support job control, on
- UNIX systems that support job control, typically do what shells do on
- systems that don't support job control.
-
- 8) Why doesn't redirecting a loop work as intended? (Bourne shell)
-
- Take the following example:
-
- foo=bar
-
- while read line
- do
- # do something with $line
- foo=bletch
- done < /etc/passwd
-
- echo "foo is now: $foo"
-
- Despite the assignment ``foo=bletch'' this will print ``foo is now: bar''
- in many implementations of the Bourne shell. Why?
- Because of the following, often undocumented, feature of historic
- Bourne shells: redirecting a control structure (such as a loop, or an
- ``if'' statement) causes a subshell to be created, in which the structure
- is executed; variables set in that subshell (like the ``foo=bletch''
- assignment) don't affect the current shell, of course.
-
- The POSIX 1003.2 Shell and Tools Interface standardization committee
- forbids the behaviour described above, i.e. in P1003.2 conformant
- Bourne shells the example will print ``foo is now: bletch''.
-
- In historic (and P1003.2 conformant) implementations you can use the
- following `trick' to get around the redirection problem:
-
- foo=bar
-
- # make file descriptor 9 a duplicate of file descriptor 0 (stdin);
- # then connect stdin to /etc/passwd; the original stdin is now
- # `remembered' in file descriptor 9; see dup(2) and sh(1)
- exec 9<&0 < /etc/passwd
-
- while read line
- do
- # do something with $line
- foo=bletch
- done
-
- # make stdin a duplicate of file descriptor 9, i.e. reconnect it to
- # the original stdin; then close file descriptor 9
- exec 0<&9 9<&-
-
- echo "foo is now: $foo"
-
- This should always print ``foo is now: bletch''.
- Right, take the next example:
-
- foo=bar
-
- echo bletch | read foo
-
- echo "foo is now: $foo"
-
- This will print ``foo is now: bar'' in many implementations,
- ``foo is now: bletch'' in some others. Why?
- Generally each part of a pipeline is run in a different subshell;
- in some implementations though, the last command in the pipeline is
- made an exception: if it is a builtin command like ``read'', the current
- shell will execute it, else another subshell is created.
-
- POSIX 1003.2 allows both behaviours so portable scripts cannot depend
- on any of them.
-
- 9) How do I run 'passwd', 'ftp', 'telnet', 'tip' and other interactive
- programs from a shell script or in the background?
-
- These programs expect a terminal interface. Shells makes no special
- provisions to provide one. Hence, such programs cannot be automated
- in shell scripts.
-
- The 'expect' program provides a programmable terminal interface for
- automating interaction with such programs. The following expect
- script is an example of a non-interactive version of passwd(1).
-
- # username is passed as 1st arg, password as 2nd
- set password [index $argv 2]
- spawn passwd [index $argv 1]
- expect "*password:"
- send "$password\r"
- expect "*password:"
- send "$password\r"
- expect eof
-
- expect can partially automate interaction which is especially
- useful for telnet, rlogin, debuggers or other programs that have no
- built-in command language. The distribution provides an example
- script to rerun rogue until a good starting configuration appears.
- Then, control is given back to the user to enjoy the game.
-
- Fortunately some programs have been written to manage the connection
- to a pseudo-tty so that you can run these sorts of programs in a script.
-
- To get expect, email "send pub/expect/expect.shar.Z" to
- library@cme.nist.gov or anonymous ftp same from durer.cme.nist.gov.
-
- Another solution is provided by the pty 4.0 program, which runs a
- program under a pseudo-tty session and was posted to comp.sources.unix,
- volume 25. A pty-based solution using named pipes to do the same as
- the above might look like this:
-
- #!/bin/sh
- /etc/mknod out.$$ p; exec 2>&1
- ( exec 4<out.$$; rm -f out.$$
- <&4 waitfor 'password:'
- echo "$2"
- <&4 waitfor 'password:'
- echo "$2"
- <&4 cat >/dev/null
- ) | ( pty passwd "$1" >out.$$ )
-
- Here, 'waitfor' is a simple C program that searches for
- its argument in the input, character by character.
-
- A simpler pty solution (which has the drawback of not
- synchronizing properly with the passwd program) is
-
- #!/bin/sh
- ( sleep 5; echo "$2"; sleep 5; echo "$2") | pty passwd "$1"
-
- 10) How do I find out the process ID of a program with a particular
- name from inside a shell script or C program?
-
- In a shell script:
-
- There is no utility specifically designed to map between program names
- and process IDs. Furthermore, such mappings are often unreliable,
- since it's possible for more than one process to have the same name,
- and since it's possible for a process to change its name once it
- starts running. However, a pipeline like this can often be used to
- get a list of processes (owned by you) with a particular name:
-
- ps ux | awk '/name/ && !/awk/ {print $2}'
-
- You replace "name" with the name of the process for which you are
- searching.
-
- The general idea is to parse the output of ps, using awk or grep or
- other utilities, to search for the lines with the specified name on
- them, and print the PID's for those lines. Note that the "!/awk/"
- above prevents the awk process for being listed.
-
- You may have to change the arguments to ps, depending on what kind of
- Unix you are using.
-
- In a C program:
-
- Just as there is no utility specifically designed to map between
- program names and process IDs, there are no (portable) C library
- functions to do it either.
-
- However, some vendors provide functions for reading Kernel memory; for
- example, Sun provides the "kvm_" functions, and Data General provides
- the "dg_" functions. It may be possible for any user to use these, or
- they may only be useable by the super-user (or a user in group "kmem")
- if read-access to kernel memory on your system is restricted.
- Furthermore, these functions are often not documented or documented
- badly, and might change from release to release.
-
- Some vendors provide a "/proc" filesystem, which appears as a
- directory with a bunch of filenames in it. Each filename is a number,
- corresponding to a process ID, and you can open the file and read it
- to get information about the process. Once again, access to this may
- be restricted, and the interface to it may change from system to
- system.
-
- If you can't use vendor-specific library functions, and you don't have
- /proc, and you still want to do this completely in C, you are going to
- have to do the grovelling through kernel memory yourself. For a good
- example of how to do this on many systems, see the sources to
- "ofiles", available in the comp.sources.unix archives.
- (A package named "kstuff" to help with kernel grovelling was posted
- to alt.sources in May 1991 and is also available via anonymous ftp as
- usenet/alt.sources/articles/{329{6,7,8,9},330{0,1}}.Z from
- wuarchive.wustl.edu.)
-
- 11) How do I check the exit status of a remote command
- executed via "rsh" ?
-
- This doesn't work:
-
- rsh some-machine some-crummy-command || echo "Command failed"
-
- The exit status of 'rsh' is 0 (success) if the rsh program
- itself completed successfully, which probably isn't what
- you wanted.
-
- If you want to check on the exit status of the remote program, you
- can try using Maarten Litmaath's 'ersh' script, which was posted to
- alt.sources in January, 1991. ersh is a shell script that
- calls rsh, arranges for the remote machine to echo the status
- of the command after it completes, and exits with that status.
-
- 12) Is it possible to pass shell variable settings into an awk program?
-
- There are two different ways to do this. The first involves simply
- expanding the variable where it is needed in the program. For
- example, to get a list of all ttys you're using:
-
- who | awk '/^'"$USER"'/ { print $2 }' (1)
-
- Single quotes are usually used to enclose awk programs because the
- character '$' is often used in them, and '$' will be interpreted by
- the shell if enclosed inside double quotes, but not if enclosed
- inside single quotes. In this case, we *want* the '$' in "$USER"
- to be interpreted by the shell, so we close the single quotes and
- then put the "$USER" inside double quotes. Note that there are no
- spaces in any of that, so the shell will see it all as one
- argument. Note, further, that the double quotes probably aren't
- necessary in this particular case (i.e. we could have done
-
- who | awk '/^'$USER'/ { print $2 }' (2)
-
- ), but they should be included nevertheless because they are
- necessary when the shell variable in question contains special
- characters or spaces.
-
- The second way to pass variable settings into awk is to use an
- often undocumented feature of awk which allows variable settings to
- be specified as "fake file names" on the command line. For
- example:
-
- who | awk '$1 == user { print $2 }' user="$USER" - (3)
-
- Variable settings take effect when they are encountered on the
- command line, so, for example, you could instruct awk on how to
- behave for different files using this technique. For example:
-
- awk '{ program that depends on s }' s=1 file1 s=0 file2 (4)
-
- Note that some versions of awk will cause variable settings
- encountered before any real filenames to take effect before the
- BEGIN block is executed, but some won't so neither way should be
- relied upon.
-
- Note, further, that when you specify a variable setting, awk won't
- automatically read from stdin if no real files are specified, so
- you need to add a "-" argument to the end of your command, as I did
- at (3) above.
-
- 13) How do I get rid of zombie processes that persevere?
-
- From: jik@pit-manager.MIT.Edu (Jonathan I. Kamens)
- Date: Fri, 17 Jan 92 14:40:09 -0500
-
- Unfortunately, it's impossible to generalize how the death of child
- processes should behave, because the exact mechanism varies over
- the various flavors of Unix.
-
- First of all, by default, you have to do a wait() for child
- processes under ALL flavors of Unix. That is, there is no flavor
- of Unix that I know of that will automatically flush child
- processes that exit, even if you don't do anything to tell it to do
- so.
-
- Second, under some SysV-derived systems, if you do "signal(SIGCHLD,
- SIG_IGN)" (well, actually, it may be SIGCLD instead of SIGCHLD, but
- most of the newer SysV systems have "#define SIGCHLD SIGCLD" in the
- header files), then child processes will be cleaned up
- automatically, with no further effort in your part. The best way
- to find out if it works at your site is to try it, although if you
- are trying to write portable code, it's a bad idea to rely on this
- in any case. Unfortunately, POSIX doesn't allow you to do this;
- the behavior of setting the SIGCHLD to SIG_IGN under POSIX is
- undefined, so you can't do it if your program is supposed to be
- POSIX-compliant.
-
- If you can't use SIG_IGN to force automatic clean-up, then you've
- got to write a signal handler to do it. It isn't easy at all to
- write a signal handler that does things right on all flavors of
- Unix, because of the following inconsistencies:
-
- On some flavors of Unix, the SIGCHLD signal handler is called if
- one *or more* children have died. This means that if your signal
- handler only does one wait() call, then it won't clean up all of
- the children. Fortunately, I believe that all Unix flavors for
- which this is the case have available to the programmer the wait3()
- call, which allows the WNOHANG option to check whether or not there
- are any children waiting to be cleaned up. Therefore, on any
- system that has wait3(), your signal handler should call wait3()
- over and over again with the WNOHANG option until there are no
- children left to clean up.
-
- On SysV-derived systems, SIGCHLD signals are regenerated if there
- are child processes still waiting to be cleaned up after you exit
- the SIGCHLD signal handler. Therefore, it's safe on most SysV
- systems to assume when the signal handler gets called that you only
- have to clean up one signal, and assume that the handler will get
- called again if there are more to clean up after it exits.
-
- On older systems, signal handlers are automatically reset to
- SIG_DFL when the signal handler gets called. On such systems, you
- have to put "signal(SIGCHILD, catcher_func)" (where "catcher_func"
- is the name of the handler function) as the first thing in the
- signal handler, so that it gets reset. Unfortunately, there is a
- race condition which may cause you to get a SIGCHLD signal and have
- it ignored between the time your handler gets called and the time
- you reset the signal. Fortunately, newer implementations of
- signal() don't reset the handler to SIG_DFL when the handler
- function is called. To get around this problem, on systems that do
- not have wait3() but do have SIGCLD, you need to reset the signal
- handler with a call to signal() after doing at least one wait()
- within the handler, each time it is called.
-
- The summary of all this is that on systems that have wait3(), you
- should use that and your signal handler should loop, and on systems
- that don't, you should have one call to wait() per invocation of
- the signal handler.
-
- One more thing -- if you don't want to go through all of this
- trouble, there is a portable way to avoid this problem, although it
- is somewhat less efficient. Your parent process should fork, and
- then wait right there and then for the child process to terminate.
- The child process then forks again, giving you a child and a
- grandchild. The child exits immediately (and hence the parent
- waiting for it notices its death and continues to work), and the
- grandchild does whatever the child was originally supposed to.
- Since its parent died, it is inherited by init, which will do
- whatever waiting is needed. This method is inefficient because it
- requires an extra fork, but is pretty much completely portable.
-
- 14) How do I get lines from a pipe as they are written instead of only in
- larger blocks.
-
- From: jik@pit-manager.MIT.Edu (Jonathan I. Kamens)
- Date: Sun, 16 Feb 92 20:59:28 -0500
-
- The stdio library does buffering differently depending on whether
- it thinks it's running on a tty. If it thinks it's on a tty, it
- does buffering on a per-line basis; if not, it uses a larger buffer
- than one line.
-
- If you have the source code to the client whose buffering you want
- to disable, you can use setbuf() or setvbuf() to change the
- buffering.
-
- If not, the best you can do is try to convince the program that
- it's running on a tty by running it under a pty, e.g. by using the
- "pty" program mentioned in question 3.9.
- --
- Ted Timar - tmatimar@nff.ncl.omron.co.jp
- Omron Corporation, Shimokaiinji, Nagaokakyo-city, Kyoto 617, Japan
-
-
- ..
- Hope you know what you're doing ...
- Data directory is /big/gd
- Port is 70
- Logging to File /usr/adm/gopherd.l
-
- .
-