Last updated: 716 day(s) ago (Sun Feb 24 15:01:33 2008)
Tue Feb 9 05:07:49 2010
Stupid Unix Tricks
Many years ago late night talk show host David Letterman used to offer his show Late Night With David Letterman a bit called Stupid Pet Tricks. Well over the years I have collected what I call Stupid Unix tricks.
Definitions:
ICMP - Internet Control Message Protocol is provided within IP which generates error
messages to help in diagnosing IP delivery problems.
TTL - Time to live can be viewed as a hop counter. A datagram starts with 30 hops, if it
doesn't reach its destination by 30 hops, the sending node gets notified that the node or
Host is Unreachable.
Tracert - Windows/NT built-in traceroute utility which is run in the dos window.
Traceroute Utility - From sled you can type traceroute (ip address or fully qualified node
name)
Fundamentals of Internet Communications:
To understand traceroute, you must understand something fundamental about the nature of
Internet communications. As you may know, the Internet gets data from one place to another
by formatting it as a "packet," which is simply a chunk of data along with some routing
information and a few other things attached in a specific format. The pieces of extra
information pertinent to this discussion are the source IP address, destination IP
address, and Time-To-Live (TTL), which is simply a number specifying how many "hops" the
packet is allowed to take during its journey across the Internet. All data is passed
across the network in the form of packets, and it is the job of the Internet's many
"routers" to decide how to get packets from one place to another. The way it works is best
illustrated with a step-by-step walk-through: When one computer has some information to
send (a web page, perhaps), it puts it in a packet (or multiple packets), and sets the TTL
to some initial value (typically 30). The computer then sends the packet to a router
(Router A) which is directly connected, whether it be by Ethernet, PPP (dialup), or some
other form of network. Router A would be called the "default gateway" for that computer.
Generally, all routers will be connected in some form to one or more OTHER routers. Router
A will examine the packet to determine the destination IP address and will, based on that
address, choose one of these other routers which will get the packet closer to the
destination. This new router (Router B) is referred to as the "Next Hop". There are many
ways that the router might be able to choose the most appropriate Next Hop intelligently,
but a discussion of "routing protocols" is beyond the scope of this article. At any rate,
Router A will then decrement the TTL by one, and forward the packet to the new router,
Router B.
This process of "hopping" repeats indefinitely, with Router B choosing a new Next Hop,
decrementing the TTL, and forwarding the packet, etc. until one of two things happens: 1)
The packet reaches its destination, or 2) the TTL decrements to zero, or "times out." It's
this last bit that allows traceroute to do its magic. We are now at a point where we can
explain just what it is that traceroute is supposed to do.
Traceroute's Mission:
Traceroute's mission in life is to show you the path a packet sent from your machine to
some other machine on the network takes as it hops from router to router. It will show you
the IP address (and the actual name, usually) of each router, line-by-line.
It's time for an example: The time you'd want to use traceroute is when you can't reach
some remote site. For example, after a bit of searching, we've found that I can't
currently reach 207.13.21.254, and I want to know why. Using Windows 95/NT's built-in
traceroute utility (called "tracert"), we can see the following output:
C:\>tracert 207.13.21.254
traceroute to 207.13.21.254 (207.13.21.254), 30 hops max, 40 byte packets
1 rtr-cne-e.gsfc.nasa.gov (128.183.50.1) 2 ms 1 ms 1 ms
2 rtr-wan1-cf.gsfc.nasa.gov (128.183.251.1) 2 ms 1 ms 1 ms
3 rtr-internet-ef.gsfc.nasa.gov (192.43.240.36) 6 ms 4 ms 4 ms
4 sl-mae-e-f0-0.sprintlink.net (192.41.177.241) 7 ms 25 ms 18 ms
5 sl-bb5-dc-6-1-0.sprintlink.net (144.232.8.25) 41 ms 47 ms *
6 sl-bb3-dc-4-0-0-155M.sprintlink.net (144.232.0.6) 29 ms * 48 ms
7 144.232.8.113 (144.232.8.113) 51 ms 43 ms 40 ms
8 sl-bb1-atl-4-0-0-155M.sprintlink.net (144.232.1.198) 40 ms * 61 ms
9 sl-bb5-fw-1-0-0.sprintlink.net (144.232.8.98) 86 ms 84 ms 79 ms
10 sl-bb1-fw-4-0-0-155M.sprintlink.net (144.232.1.150) 86 ms 85 ms *
11 * * sl-gw13-fw-0-0.sprintlink.net (144.228.30.17) 87 ms
12 sl-comp-3-0.sprintlink.net (144.228.137.14) 91 ms 90 ms *
13 cisco3640-1.cmpu.net (204.96.11.48) 95 ms 88 ms 90 ms
14 cisco7505-1.cmpu.net (204.96.11.1) 149 ms * *
15 cisco3640-1.cmpu.net (204.96.11.48) 113 ms 114 ms 113 ms
.
.
28 cisco7505-1.cmpu.net (204.96.11.1) 149 ms * *
29 cisco3640-1.cmpu.net (204.96.11.48) 113 ms 114 ms 113 ms
30 * cisco7505-1.cmpu.net (204.96.11.1) 111 ms * Trace complete.
First of all, please note that we edited out lines 16 through 27. As you can see, for each
hop, tracert shows us the hop number, three "round-trip" times, the name of the router (if
available), and the router's IP address. Let's skip the round-trip times for a moment and
examine the other things tracert is telling us.
It shows us that the first hop my packet takes from my desktop computer is to
rtr-cne-e.gsfc.nasa.gov (which is one of CNE's routers). Tracert then tells us that for
this particular destination (207.13.21.254), our router determines that the best Next Hop
is rtr-wan1-cf.gsfc.nasa.gov. That router passes the packet to
rtr-internet-ef.gsfc.nasa.gov, then it traverses to Sprintnet,
where it reaches hop 13, cisco3640-1.cmpu.net (204.96.11.48) , which immediately forwards
it to cisco7505-1.cmpu.net (204.96.11.1) , and THIS is where we start to see problems:
cisco7505-1.cmpu.net (204.96.11.1) passes it BACK to cisco3640-1.cmpu.net (204.96.11.48)
and again, and again ...! This circular routing continues until the end of the traceroute
(30 hops), clearly showing us the location of the routing failure (in
cisco7505-1.cmpu.net), and why the packet is never reaching its destination.
Unfortunately, there's nothing we at CNE can do to fix this problem, as it is external to
our network. Internal, yes, we can contact the owner of the offending router.
HOW DOES IT WORK???
Just a couple more important things about traceroute: First, HOW DOES IT WORK??? You may
recall ICMP (Internet Control Message Protocol), and also that we said that traceroute
relies on packet time-outs. To determine the first hop, traceroute simply sends a packet
to the destination, but instead of setting the TTL to 30, as usual, it sets the TTL to 1,
meaning the packet is only allowed to take one hop. It takes that hop, arriving at the
"hop 1" router, which faithfully decrements the TTL and notices that it is now zero.
Whenever a router sees the TTL go to zero, it does two things: it 1) drops the packet (NOT
forwarding it at all), and 2) sends an ICMP packet BACK to the source IP address of the
dropped packet. This ICMP message says that the "TTL Expired in Transit." The source IP
address of the ICMP message IS the address of the router itself, so traceroute can now see
the IP address of the router at hop 1. Windows 95/NT's tracert (like most) performs this
little test three times for each hop (by default), also keeping track of how long it takes
for each error message to return. This is how it gets the round-trip times (in
milliseconds), which, like ping, can be used to gauge which routers may be slowing things
down. These numbers should be taken with a grain of salt, because many routers assign a
low priority to the ICMP reply, which can cause a short delay. Note also that these times
are cumulative, so it's really the differences between the average for each router that's
important. Incidentally, the "*" in hop 5 indicates a packet which received no ICMP
response at all. This is a result of normal packet-loss on the network.
Example:
So, here is how it works:
* Sends IP datagram (TTL=1) to destination host
* First router decrements TTL to 0, discards datagram, sends back ICMP "time exceeded"
message (now first router in path is identified)
* Sends IP datagram (TTL=2) to identify the second router
* Process continues until destination host reached
Since hosts do not return ICMP "time exceeded" messages, traceroute needs another method
for realizing it has reached the final destination. It sends UDP datagrams to a very high
number port (33434 by default) that is unlikely to have an application running on it. This
causes the destination host to generate an ICMP "port unreachable" error message, and
traceroute then interprets this as the signal that it has reached the destination host.
The last caveat we should mention is this: the path BACK from the remote machine to you is
NOT NECESSARILY the same! This situation is called asymmetric routing, and is usually not
an issue. In cases where it does exist though, it can make troubleshooting much more
difficult, because some problem may exist on the reverse path (preventing data from
getting back to you) which traceroute cannot show you. Some traceroute implementations
support a feature which allows to do a trick so that you CAN see this information (Hint:
take a look at tracert's "-j" option).
So, if you encounter a problem with a node on-site, run a traceroute using tracert or some
other utility. By doing a traceroute you can determine if a node is reachable, the general
throughput of the network; and if the node is not reachable, where the failure is
occurring. Additionally, if someone complains they can't get offsite try tracerouting a
node offsite like 128.8.10.14, which is one of our backup nameservers. Also, try an
external traceroute if someone complains they can't reach outside our network. Here's anurl to use when doing an external traceroute
http://nucleus.nectec.or.th/pub/info/netinfo/routing.arbiter/tools/trace.html
Possible Problems:
Strange thing 1:
Traceroute Hangs:
Quick 'n' Dirty: traceroute -n
Normally when you do a traceroute to a domain name or IP address, traceroute will try to
look up the
DNS hostnames of the IP address at each hop. If there is any problem with the DNS server,
your
traceroute will "hang". This can throw you off track.
Instead, use traceroute -n. This means "IP numbers only", and any hangs or problems that
show up in the
traceroute will be entirely due to routing -- which is what you're troubleshooting.
Here's an example:
_fairy.tlg.net[~]> traceroute -n gw1-sj-tlg
traceroute to gw1-sj-tlg.tlg.net (140.174.74.1), 30 hops max, 40 byte
packets
1 140.174.77.5 2.2 ms 2.119 ms 2.257 ms
2 140.174.178.1 7.593 ms 4.177 ms 26.672 ms
3 140.174.125.5 6.958 ms 49.766 ms 17.813 ms
4 140.174.161.2 12.194 ms * 71.78 ms
Here's what the same traceroute looks like with DNS lookups:
_fairy.tlg.net[~]> traceroute gw1-sj-tlg
traceroute to gw1-sj-tlg.tlg.net (140.174.161.2), 30 hops max, 40 byte
packets
1 gw1-ms-tlg (140.174.77.5) 2.354 ms 2.191 ms 4.617 ms
2 ln1_gw2-sf-tlg_ms (140.174.178.1) 29.144 ms 4.482 ms 4.305 ms
3 border-sf-tlg (140.174.125.5) 5.013 ms 4.663 ms 5.071 ms
4 border-sj-tlg (140.174.161.2) 13.748 ms * 12.346 ms
Notice that "border-sj-tlg" and "gw1-sj-tlg" are the same IP address. This is set up in
the DNS for that IP address.
Strange thing 2:
Note that lines 2 & 3 are the same. This is due to a buggy kernel
on the 2nd hop system that forwards packets with
a zero ttl (a bug in the distributed version of 4.3BSD).
1 helios.ee.lbl.gov (128.3.112.1) 19 ms 19 ms 0 ms
2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms
3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms
4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 39
Strange thing 3:
!H, means that the router at that hop doesn't know anything about the target address.
!N, !P, means you got a host, network or protocol unreachable, respectively.
!S or !F means the source route failed or fragmentation needed - neither of these
should ever occur and the associated gateway is busted if you see
one.
One last item:
Sometimes you will see a traceroute that display the following information:
Sometimes you will see a traceroute that display the following information:
1 rtr-cne-e.gsfc.nasa.gov (128.183.50.1) 2 ms 1 ms 1 ms
2 rtr-wan1-cf.gsfc.nasa.gov (128.183.251.1) 2 ms 1 ms 1 ms
3 rtr-internet-ef.gsfc.nasa.gov (192.43.240.36) 6 ms 4 ms 4 ms
4 sl-mae-e-f0-0.sprintlink.net (192.41.177.241) 7 ms 25 ms 18 ms
5 sl-bb5-dc-6-1-0.sprintlink.net (144.232.8.25) 41 ms 47 ms *
6 sl-bb3-dc-4-0-0-155M.sprintlink.net (144.232.0.6) 29 ms * 48 ms
7 144.232.8.113 (144.232.8.113) 51 ms 43 ms 40 ms
8 sl-bb1-atl-4-0-0-155M.sprintlink.net (144.232.1.198) 40 ms * 61 ms
9 sl-bb5-fw-1-0-0.sprintlink.net (144.232.8.98) 86 ms 84 ms 79 ms
10 sl-bb1-fw-4-0-0-155M.sprintlink.net (144.232.1.150) 86 ms 85 ms *
11 * * *
12 * * *
13 * * *
14 * * *
15 sl-comp-3-0.sprintlink.net (144.228.137.14) 91 ms 90 ms *
16 cisco3640-1.cmpu.net (204.96.11.48) 95 ms 88 ms 90 ms
So, what's happening here. For some reason, probably the machine after sl-bbl-fw, the
machine is not getting its ICMP packet back to the client requesting the traceroute. The
traceroute circumvents the problem by bumping the ttl value up 1 hop until it gets a
response or until the TTL reaches 30 hops.
Enhancing the system prompt
Daniel Robbins (drobbins@gentoo.org)
President-CEO, Gentoo Technologies, Inc.
September 2000
Why stick with the standard boring shell prompt when you can easily make it colorful and more informative? In this tip, Daniel Robbins will show you how to get your shell prompt just the way you like it, as well as how to dynamically update your X terminal's title bar.
As Linux/UNIX people, we spend a lot of time working in the shell, and in many cases, this is what we have staring back at us:
bash-2.04$
If you happen to be root, you're entitled to the "prestige" version of this beautiful prompt:
bash-2.04#
These prompts are not exactly pretty. It's no wonder that several Linux distributions have upgraded their default prompts that add color and additional information to boot. However, even if you happen to have a modern distribution that comes with a nice, colorful prompt, it may not be perfect. Maybe you'd like to add or change some colors, or add (or remove) information from the prompt itself. It isn't hard to design your own colorized, tricked-out prompt from scratch.
Prompt basics
Under bash, you can set your prompt by changing the value of the PS1 environment variable, as follows:
$ export PS1="> "
>
Changes take effect immediately, and can be made permanent by placing the "export" definition in your ~/.bashrc file. PS1 can contain any amount of plain text that you'd like:
$ export PS1="This is my super prompt > "
This is my super prompt >
While this is, um, interesting, it's not exactly useful to have a prompt that contains lots of static text. Most custom prompts contain information like the current username, working directory, or hostname. These tidbits of information can help you to navigate in your shell universe. For example, the following prompt will display your username and hostname:
$ export PS1="\u@\H > "
drobbins@freebox >
This prompt is especially handy for people who log in to various machines under various, differently-named accounts, since it acts as a reminder of what machine you're actually on and what privileges you currently have.
In the above example, we told bash to insert the username and hostname into the prompt by using special backslash-escaped character sequences that bash replaces with specific values when they appear in the PS1 variable. We used the sequences "\u" (for username) and "\H" (for the first part of the hostname). Here's a complete list of all special sequences that bash recognizes (you can find this list in the bash man page, in the "PROMPTING" section):
Sequence Description
\a The ASCII bell character (you can also type \007)
\d Date in "Wed Sep 06" format
\e ASCII escape character (you can also type \033)
\h First part of hostname (such as "mybox")
\H Full hostname (such as "mybox.mydomain.com")
\j The number of processes you've suspended in this shell by hitting ^Z
\l The name of the shell's terminal device (such as "ttyp4")
\n Newline
\r Carriage return
\s The name of the shell executable (such as "bash")
\t Time in 24-hour format (such as "23:01:01")
\T Time in 12-hour format (such as "11:01:01")
\@ Time in 12-hour format with am/pm
\u Your username
\v Version of bash (such as 2.04)
\V Bash version, including patchlevel
\w Current working directory (such as "/home/drobbins")
\W The "basename" of the current working directory (such as "drobbins")
\! Current command's position in the history buffer
\# Command number (this will count up at each prompt, as long as you type something)
\$ If you are not root, inserts a "$"; if you are root, you get a "#"
\xxx Inserts an ASCII character based on three-digit number xxx (replace unused digits with zeros, such as "\007")
\\ A backslash
\[ This sequence should appear before a sequence of characters that don't move the cursor (like color escape sequences). This allows bash to calculate word wrapping correctly.
\] This sequence should appear after a sequence of non-printing characters.
So, there you have all of bash's special backslashed escape sequences. Play around with them for a bit to get a feel for how they work. After you've done a little testing, it's time to add some color.
Colorization
Adding color is quite easy; the first step is to design a prompt without color. Then, all we need to do is add special escape sequences that'll be recognized by the terminal (rather than bash) and cause it to display certain parts of the text in color. Standard Linux terminals and X terminals allow you to set the foreground (text) color and the background color, and also enable "bold" characters if so desired. We get eight colors to choose from.
Colors are selected by adding special sequences to PS1 -- basically sandwiching numeric values between a "\e[" (escape open-bracket) and an "m". If we specify more than one numeric code, we separate each code with a semicolon. Here's an example color code:
"\e[0m"
When we specify a zero as a numeric code, it tells the terminal to reset foreground, background, and boldness settings to their default values. You'll want to use this code at the end of your prompt, so that the text that you type in is not colorized. Now, let's take a look at the color codes. Check out this screenshot:
Color chart
Color chart
To use this chart, find the color you'd like to use, and find the corresponding foreground (30-37) and background (40-47) numbers. For example, if you like green on a normal black background, the numbers are 32 and 40. Then, take your prompt definition and add the appropriate color codes. This:
export PS1="\w> "
becomes:
export PS1="\e[32;40m\w> "
So far, so good, but it's not perfect yet. After bash prints the working directory, we need to set the color back to normal with a "\e[0m" sequence:
export PS1="\e[32;40m\w> \e[0m"
This definition will give you a nice, green prompt, but we still need to add a few finishing touches. We don't need to include the background color setting of 40, since that sets the background to black which is the default color anyway. Also, the green color is quite dim; we can fix this by adding a "1" color code, which enables brighter, bold text. In addition to this change, we need to surround all non-printing characters with special bash escape sequences, "\[" and "\]". These sequences will tell bash that the enclosed characters don't take up any space on the line, which will allow word-wrapping to continue to work properly. Without them, you'll end up with a nice-looking prompt that will mess up the screen if you happen to type in a command that approaches the extreme right of the terminal. Here's our final prompt:
export PS1="\[\e[32;1m\]\w> \[\e[0m\]"
Don't be afraid to use several colors in the same prompt, like so:
export PS1="\[\e[36;1m\]\u@\[\e[32;1m\]\H> \[\e[0m\]"
Xterm fun
I've shown you how to add information and color to your prompt, but you can do even more. It's possible to add special codes to your prompt that will cause the title bar of your X terminal (such as rxvt or aterm) to be dynamically updated. All you need to do is add the following sequence to your PS1 prompt:
"\e]2;titlebar\a"
Simply replace the substring "titlebar" with the text that you'd like to have appear in your xterm's title bar, and you're all set! You don't need to use static text; you can also insert bash escape sequences into your titlebar. Check out this example, which places the username, hostname, and current working directory in the titlebar, as well as defining a short, bright green prompt:
export PS1="\[\e]2;\u@\H \w\a\e[32;1m\]>\[\e[0m\] "
This is the particular prompt that I'm using in the colortable screenshot, above. I love this prompt, because it puts all the information in the title bar rather than in the terminal where it limits how much can fit on a line. By the way, make sure you surround your titlebar sequence with "\[" and "\]", since as far as the terminal is concerned, this sequence is non-printing. The problem with putting lots of information in the title bar is that you will not be able to see info if you are using a non-graphical terminal, such as the system console. To fix this, you may want to add something like this to your .bashrc:
if [ "$TERM" = "linux" ]
then
#we're on the system console or maybe telnetting in
export PS1="\[\e[32;1m\]\u@\H > \[\e[0m\]"
else
#we're not on the console, assume an xterm
export PS1="\[\e]2;\u@\H \w\a\e[32;1m\]>\[\e[0m\] "
fi
This bash conditional statement will dynamically set your prompt based on your current terminal settings. For consistency, you'll want to configure your ~/.bash_profile so that it sources your ~/.bashrc on startup. Make sure the following line is in your ~/.bash_profile:
source ~/.bashrc
This way, you'll get the same prompt setting whether you start a login or non-login shell.
Well, there you have it. Now, have some fun and whip up some nifty colorized prompts!
Resources
* rxvt is a great little xterm that happens to have a good amount of documentation related to escape sequences tucked in the "doc" directory included in the source tarball.
* aterm is another terminal program, based on rxvt. It supports several nice visual features, like transparency and tinting.
* bashish is a theme engine for all different kinds of terminals. Check out some great screenshots of bashish in action!
About the author
Residing in Albuquerque, New Mexico, Daniel Robbins is the President/CEO of Gentoo Technologies, Inc., the creator of Gentoo Linux, an advanced Linux for the PC, and the Portage system, a next-generation ports system for Linux. He has also served as a contributing author for the Macmillan books Caldera OpenLinux Unleashed, SuSE Linux Unleashed, and Samba Unleashed. Daniel has been involved with computers in some fashion since the second grade, when he was first exposed to the Logo programming language as well as a potentially dangerous dose of Pac Man. This probably explains why he has since served as a Lead Graphic Artist at SONY Electronic Publishing/Psygnosis. Daniel enjoys spending time with his wife, Mary, and his new baby daughter, Hadassah. You can contact Daniel at drobbins@gentoo.org.
If you're going to set up a character terminal or modem with Solaris, there are two important
commands you need to learn.
1. To add a port monitor, you'll need to use the
casadm command--that is, if it isn't configured on
your machine.
2. To Define a service to be specified with the new
port monitor, you'll use the pmadm command
Date: Fri, 15 Dec 2000 21:12:58 -0800
From: Kris Kennaway
Subject: Re: /tmp topic
To: BUGTRAQ@SECURITYFOCUS.COM
--SUOF0GtieIMvvwua
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
On Thu, Dec 14, 2000 at 10:10:07PM -0800, Octavio / Super wrote:
> Is there a standard or a guide or a "HOWTO" on using tmp
> directories safely? About using mkstemp(), assigning correct
> permissions, erasing the file at program termination, etc.
Use mkstemp() for making temporary files. If you can't use mkstemp()
then make yourself a directory using mkdtemp(), which is protected
from the outside world and you can be as insecure as you like within
it. If you really have to use the insecure mktemp() then use lots of
X's - I suggest 10 (if your libc allows it) so that the filename can't
easily be guessed (using only 6 X's means that 5 are taken up by the
PID, leaving only one random character and allowing an attacker to
mount an easy race condition) [1]
Never "roll your own" temporary file creation routine. Chances are you
don't know what you're doing and will get it wrong. Use the interfaces
helpfully provided to you by your libc vendor (described above). If
they don't provide these interfaces then yell at your vendor until
they do, or port the functions from a freely available libc such as
the FreeBSD/NetBSD/OpenBSD libc. Beware of deprecated, insecure
interfaces like mktemp() or tmpnam() which should be documented as
being insecure by your vendor.
Don't ever reuse a temporary filename (i.e. remove and recreate it) -
no matter how you obtained that "secure" temporary filename in the
first place (e.g. mkstemp()). An attacker can observe the original
filename and hijack it before you recreate it the second time.
If you ever want to make a file in /tmp or a world-writable directory
(or group-writable, if you don't trust the group) and don't want to
use mk*temp() (e.g. you intend for the file to be predictably named),
then ALWAYS use the O_EXCL flag to open() and CHECK THE RETURN
VALUE. If you fail the open() call, then recover gracefully
(e.g. exit).
Always use appropriate permissions - e.g. only allow world/group
access if you need the world or a group to access the file, otherwise
keep it mode 600.
Clean up after yourself, either by using an exit handler, or making
use of UNIX filesystem semantics and unlink()ing the file immediately
after creation so the directory entry goes away but the file itself
remains accessible until the last file descriptor pointing to it is
closed. You can then continue to access it within your program by
passing around the file descriptor.
Kris
[1] FreeBSD has recently changed the mk*temp() family to get rid of
the PID component of the filename and replace the entire thing with
base-62 encoded randomness. This drastically raises the number of
possible temporary files for the "default" usage of 6 X's, meaning
that even mktemp() with 6 X's is reasonably (probabilistically) secure
against guessing, except under very frequent usage.
http://www.FreeBSD.org/cgi/cvsweb.cgi/src/lib/libc/stdio/mktemp.c.diff?r1=1.19&r2=1.20
--SUOF0GtieIMvvwua
Content-Type: application/pgp-signature
Content-Disposition: inline
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.4 (GNU/Linux)
Comment: For info see http://www.gnupg.org
iD8DBQE6OvnUWry0BWjoQKURAt2wAKC+SY7UIwt8uR3HPuhM6lIYvlR0ZQCgjr+g
a1yH9FXtYDtjGWHjoR1U+Dc=
=Ucxe
-----END PGP SIGNATURE-----
--SUOF0GtieIMvvwua--
Why use rgrep instead of more traditional Unix tools?
------------------------------------------------------
Unlike grep and egrep, rgrep has the ability to recursively descend
directories. The traditional way of performing this kind of search on Unix
systems utilizes the `find' command in conjunction with `grep'. However,
this results in very poor performance. Consider the tradional approach
where one wants to search the /usr/include directory for the string `FD_SET':
For this, one would use:
% find /usr/include -exec grep -l FD_SET \{\} \; -print
Ignoring the fact that the above expression looks complex, it failed to find
any occurence of FD_SET under the /usr/include directory of my Ultrix
system.
Now, if rgrep is used, one types:
% rgrep -lFr FD_SET /usr/include
which yielded: /usr/include/sys/types.h
The reason that `find' failed is that /usr/include/sys is a symbolic link to
/sys/h. `rgrep' was able to succeed because of the `-F' flag which telles
it to follow links. I looked in the man page for a similar option for
`find' but nothing turned up.
From: Bill Campbell
Subject: Re: how to recursively search for text string in files?
Date: Sat, 2 Feb 2002 21:47:49 GMT
References: <3c5abd57@news1.warwick.net> <3C5BD461.5080709@aplawrence.com>
--/9DWx/yDrRhgMJTb
Content-Type: text/plain; charset=us-ascii
On Sat, Feb 02, 2002 at 11:56:40AM +0000, Tony Lawrence wrote:
...
>Typically, the answer is to use find, xargs, and grep. That's horribly
>slow for a full filesystem search (John Dubois made a helpful suggestion
>on that part), and it's painfully difficult to properly construct a
>pipeline that will avoid searching binaries if you don't want to, won't
>get stuck on named pipes or blow up on funky filenames (beginning with
>-, or sometimes spaces, punctuation etc). There are ways around all
>these things, but I don't think I've ever seen anyone even attempt it.
>I'll bet a virtual round of beers that no solution posted here even
>comes close.
I have a perlscript I call ``textfiles'' that I use for many
things like this:
textfiles dirname [dirname... ] | xargs ...
Essentially it runs ``gfind @ARGV -type f'', then uses perl's -T
option on each file to determine whether it's a text file.
My textfiles script also has options to add options to the gnu
find command like -xdev, -mindepth, and -maxdepth.
Hell, it's short so I'm attaching it for anybody who wants to use
it. It does assume that the gnu version of find is in your PATH
named gfind (I make a symlink to /usr/bin/find on Linux systems
so that it works there as well).
Bill
--
INTERNET: bill@Celestial.COM Bill Campbell; Celestial Software LLC
UUCP: camco!bill PO Box 820; 6641 E. Mercer Way
FAX: (206) 232-9186 Mercer Island, WA 98040-0820; (206) 236-1676
URL: http://www.celestial.com/
``I don't care how little your country is, you got a right to run it like
you want to. When the big nations quit meddling, then the world will have
peace.''
Will Rogers
--/9DWx/yDrRhgMJTb
Content-Type: text/plain; charset=us-ascii
Content-Description: /usr/local/bin/textfiles
Content-Disposition: attachment; filename=textfiles
#!/usr/local/bin/perl
eval ' exec /usr/local/bin/perl -S $0 "$@" '
if $running_under_some_shell;
# $Header: /u/usr/cvs/lbin/textfiles,v 1.7 2000/06/22 18:29:08 bill Exp $
# $Date: 2000/06/22 18:29:08 $
# @(#) $Id: textfiles,v 1.7 2000/06/22 18:29:08 bill Exp $
#
# find text files
( $progname = $0 ) =~ s!.*/!!; # save this very early
$USAGE = "
# Find text files
#
# Usage: $progname [-v] [file [file...]]
#
# Options Argument Description
# -f Follow symlinks
# -M maxdepth maxdepth argument to gfind
# -m mindepth mindepth argument to gfind
# -x Don't cross device boundaries
# -v Verbose
#
";
sub usage {
die join("\n",@_) .
"\n$USAGE\n";
}
do "getopts.pl";
&usage("Invalid Option") unless do Getopts("fM:m:xvV");
$verbose = '-v' if $opt_v;
$suffix = $$ unless $opt_v;
$\ = "\n"; # use newlines as separators.
# use current directory if there aren't any arguments
push(@ARGV, '.') unless defined($ARGV[0]);
$args = join(" ", @ARGV);
$xdev = '-xdev' if $opt_x;
$opt_f = '-follow' if $opt_f;
$opt_m = "-mindepth $opt_m" if $opt_m;
$opt_M = "-maxdepth $opt_M" if $opt_M;
$cmd = "gfind @ARGV -type f $xdev $opt_f $opt_m $opt_M |";
print STDERR "cmd = >$cmd<" if $verbose;
open(INPUT, $cmd);
while() {
chop($name = $_);
print STDERR "testing $name..." if $verbose;
print $name if -T $name;
}
--/9DWx/yDrRhgMJTb--