How To Adopt 10 'Good' Unix Habits
An anonymous reader writes to mention an article at the IBM site from earlier this week, which purports to offer good Unix 'habits' to learn. The ten simple suggestions may be common sense to the seasoned admin, but users with less experience may find some helpful hints here. From the article: "Quote variables with caution - Always be careful with shell expansion and variable names. It is generally a good idea to enclose variable calls in double quotation marks, unless you have a good reason not to. Similarly, if you are directly following a variable name with alphanumeric text, be sure also to enclose the variable name in square brackets ([]) to distinguish it from the surrounding text. Otherwise, the shell interprets the trailing text as part of your variable name -- and most likely returns a null value."
export POST="first"
www.isoHunt.com
An anonymous reader writes to mention an article at the IBM site from earlier this week, which purports to offer good Unix 'habits' to learn.
I seriously doubt reading this article is going to get anyone to start showering on a regular basis.
Push Button, Receive Bacon
When possible, avoid shell scripting: the language is flawed by design. Use a modern programming language, such as Python.
Gustavo J.A.M. Carneiro
Join moola.com, play games to earn money.
He's being pedantic at times with no good reason. I do cat file | grep/awk/sed/perl -pe/whatever quite frequently because it makes visualizing the pipeline easier, and handles files bigger than 2gb better than the 32-bit version of awk/sed/whatever. The only really useful piece of advice is mkdir -p...something that doesn't work with legacy UNIX systems.
The quoted paragraph from the article is incorrect -- and it is in the article too -- but the example immediately following it correctly shows the use of braces ("curly brackets"), not square brackets, for variable names in shell.
My blog: http://www.seebs.net/log/ --- My iPhone/iPad app: http://www.seebs.net/seebsfrac/
I will never stop piping cat! If I want to do so, I will!
$ cd tmp/a/b/c || mkdir -p tmp/a/b/c
If the directory exists you end up in the directory, if it does not it creates the directory but leaves you where you first started. Hence you don't know which directory you will be in after the command is executed!
There are four sorts of people in the world: fools, lunatics, idiots and morons. - Umberto Eco, Foucaut's pendulum.
(plus he didn't mention my favourite shortcut: shell history)
How about being more inclusive and expanding this to deal with security features (surely the single biggest benefit?) and the ease of working on remote boxes?
politicians are like babies' nappies: they should both be changed regularly and for the same reasons
Hey, FON, are you reading this? Sadly, even shell code in comsumer devices is often deeply flawed. Which is a good thing, if you want to install a new firmware - and a bad thing, if an attacker does it for you.
Life is just nature's way of keeping meat fresh.
...is so littered with basic errors that it really shouldn't be recommended to anybody. How is 'tar xvf -C tmp/a/b/c newarc.tar.gz' expected to work, for example? Quote variables with square brackets? Running subshell commands using ; instead of && ? No mention of 'xargs -0' ? Don't pipe from cat to grep? Does anybody actually care that people do this (primarily so that the syntax is consistent between a munged- and unmunged-grep, and also such that the order of the command-line is logical from a human point of view)? Plus, of course, it's possible that cat | grep could yield better performance than grep alone: if cat uses mmap() to efficiently read the input files, and the kernel's pipe implementation is good, then it could do better than a grep implementation alone that simply read()s the files.
What would be more useful would be things like "have your prompt include the current path" and "use a text editor to write small scripts instead of trying to type really long lines". Also perhaps "diff -u <(command 1) <(command 2)" for comparing command output, although this goes more in the "useful tricks" category (along with most of the things from the article...) rather than the "good habits" category.
Shocking. Digg is fast on news, but usually the comments will digg down anyone with even the tinest grasp of the subject matter in favour of totally incorrect information that 'feels' right. While slashdot is slow as hell to get the story up, but will usually have useful comments.
Comment removed based on user account deletion
*nix is a highly modular component-based software system with a standard interface (flat byte streams) between components, and a basic set of standard components (given in the POSIX standard) that can be relied upon to always be present.
Why the fuck would you bother to reply to the GP? Either you have a massive and debilitating lack of social skills, or you're more drunk than I am right now. If it's the latter, I'd recommend having your stomach pumped in the near future.
What is Unix? Jeebus Christ.
Digg is full of posers who think using Cygwin is the same as using a *nix.
This is in part about UNIX shell (bash alike) scripting, Tips & Tricks, and UNIX tools, not habits.
While in general useful on the commandline, these are very specific points, and some of them are quite weak. #10? come on, if you had "cat tmp/a/longfile.txt" in the command history, wouldn't appending "| grep and" be the most efficient way?
I also miss the most important and universial UNIX habit of all: do not login as root, use sudo or similiar tools when you have to.
This article seems to be driven by the need to publicize something, anything, bare of real content, like so many others at IBM devnet.
I am so glad that he showed what a difference can make, because I was *really* getting annoyed at having to wait that extra
1. Don't rm with an absolute path because you could easily
/tmp/dir
/tmp ; rm -r -f dir)
/tmp ; sudo rm -r -f dir)
/path$
#rm -r -f / tmp/dir
when "all" you wanted was
#rm -r -f
instead do this:
#(cd
or even better use sudo if you have it:
$(cd
2. When logged on as root or when using sudo on a production system think things over
at least twice before hitting enter.
3. Make sure at all times you're on the right machine, logged on as the right user in the right directory.
Set up your shell prompt to look like this user@host
I don't know whether it is complete BS, as I stopped reading after the 3rd or 4th "good habit". Maybe AIX has an exceedingly slow ''cat'', Linux does not. Maybe the other stuff is valid in some OSes, but then I have not encounterd them. By the same token, really important stuff is missing completely. This looks a bit like a Unix-noveces initial list of things he/she thought about in the first week. Really not worth your time.
Most ACs are not even worth the keystrokes to insult them. Be generically insulted by this and ignored otherwise.
The title should be 10 Good Unix Hints. Not Habits.
These things he is stating is like when an other Unix guy is looking over your shoulder and you type in a command that works perfectly fine but has to correct you to do it his way, to save the extra millisecond in CPU while wasting about 5 Seconds to retype the command.
Secondly depending what you are doing on Unix you may or may not need to use these commands often enough to remember all the parameters for every tool. like the mkdir -p, While I know mkdir could create the entire directory Tree with some parameter, I just never bothered using it, or looking it up. I may see it in a script made by someone and realizing mkdir creates paths and that I know the directory doesn't exist yet. So I figure that is what it is doing. But for myself I rarely create an entire directory tree like he stated first. I like to create a directory find what file and folder I need and put them there when I need them.
If something is so important that you feel the need to post it on the internet... It probably isn't that important.
"10 good habits that improve your UNIX command line efficiency" would probably have been a better title.
The title did however bring back fond memories of Eric Raymond's The Art of Unix Programming. The book is available online, and if you were hoping for something a bit more substantial as well, then the section Basics of the Unix Philosophy might be worth a read.
I'll dare to continue.
.o' joke is so well known... I type ... ,
4. Log out of the root session as soon as the moment's job is done.
Better type password yet again than clean the mess.
5. Never use cat to view files. There are tail (1), head (1) and less (1) (and even more) for that. Pumping zetabytes of logs over the network *is* a bad habit.
6. The good old 'rm -rf *
% ls -l
then arrow up and replace 'ls -l' with 'rm -rf'. Or even use Midnight Commander to delete files (heresy, yeah).
Also, I often use constructs like
% for i in foo bar baz; do echo somecommand $i; done
before removing the 'echo' part.
Just to see what I'm going to do.
Gonna read other people's advices now...
WYSIWIG, but what you see might not be what you need
(What is "using Unix" supposed to mean, anyway? I know people who've used Solaris desktops for years who still treat the command line as an arcane interface to be used with fear and trembling as a last resort when all GUI-based alternatives have failed.)
When I do this it doesn't include the \ continuation, and even if did, why would anyone want that on a single line?
there is this thing called a buffer cache.
we never write "(cd /tmp ; rm -r -f dir)", because the first operation might fail.
/tmp && rm -rf dir)". ;)
We write "(cd
But I guess that's different on linux, and the system actually is built to know that you didn't mean to remove anything from your current working folder in case the first operation fails...
sudo is indeed better, because it allows you to do this kind of mistake on _every_ folder. Including the important system folders.
Another advise: if you make a lot of mistakes, TYPE SLOWER. You'll save a lot in the end.
In their example with tar they did
tar xvf
without the dash. (E.g., tar -xvf)
While that does work, I prefer to add
the dash as it makes it more consistent
with the other commands. So I consider
that a bad example. tar is one of the
older commands like dd that have weird
command line syntax.
As has been pointed out, this article is riddled with errors. It's also not very interesting. So in the interest of perhaps actually providing some interesting tips:
/).
/etc/modules.autoload.d/kernel-2.6 /etc/m*a*d/*6
/etc/m* -> /etc/mail /etc/m*d -> /etc/modules.d /*/m*/*6 -> /etc/modules.autoload.d/kernel-2.6, and /etc/modules.d/i386 (not quite!)
In scripts, prefix dangersous commands with an 'echo' for a test run (So you can catch all those rm -rf
Single quotes are the best quotes for plain strings. The only reasion to use double quotes is if you need to quote a variable or a single quote.
Completion is fun, but using wildcards is more flexible (though you'll only want to use benign commans like cd, less, etc):
nano
nano
Note that the use of subpaths reduces the amount of flexibility.
cd
cd
nano
Finally, as a comment for the article, using:
test -e $DIR || mkdir -p $DIR
is much better than their suggestion and probaly faster anyway. Though I'd just do "mkdir -p $DIR" and maybe "&>/dev/null" under most circumstances anyway.
That's all I can think of at this point. Anyone else have tips?
I'll gladly trade 0.1 seconds of CPU time if it means I don't need to remember an extra command line option for the wc command.
That's why I'm of the v7 Unix philosophy. Make a tool that does one thing, and does it well.
If I later need to optimize for speed, then I'll read the man page.
GCHQ Quantum Insert installed. If only our tongues were made of glass, how much more careful we would be when we speak
i wish there was an easy way to make filenames lowercase in mass. because i transfer images from my camera and sometimes they come up as IMG_1234.JPG and sometimes as img_1234.jpg and it screws with my website scripts if they're not all the same extension (.JPG != .jpg). so often i want to make an entire directory of filenames lowercase. the only trouble is there's no clear-cut way to do this, doing it in one line is hard, and googling for it always seems to give me a bunch of shareware or a complicated .tar.gz file instead of a single line to do what i wanted. i usually end up writing a Perl script, but it seems such an overkill and it seems that it ought to be easy and simple to do as a command.
While it is not the same, it is the best thing on Windows that is close to UNIX.
Everyone is talking a different language. No wonder why nobody but nobody uses this operating system.
The article didn't mention a tip for that can prevent you from shooting yourself in the foot when you dereference a variable that isn't set (or set set to an empty string). Here's a dangerous way to clean out a directory:
$ rm -rf $FOO/*
If FOO isn't set this command will try to delete every file in your system (and network mounts).
Here's a better way to clean out a directory.
$ rm -rf ${FOO:?}/*
If FOO is unset then the shell will not execute the rm command and gives a nice error
$ rm -rf ${FOO:?}/*
-bash: FOO: parameter null or not set
According to man wget, you can use -i or --input-file options to read URLs from a file.
I once had a signature.
-- "You can lead a yak to water, but you can't teach an old dog to make a silk purse out of a pig in a poke" - Opus
Fortunately, there's an easy fix for that: Use redirected stdin rather than a filename for zcat :
zcat <arc.tar.gz | ssh user@foo 'cd tmp/a/b/c ; tar xvf -'
Some people call me a 'Grammar Nazi' for being so picky about how people use English. I get frustrated about things like commmercials that say "check us out on the web at dubya dubya dubya dot ${COMPANY} dot com backslash ${PRODUCT}", the inability to distinguish single quotes, double quotes, and backticks; or parentheses, square brackets, and curly braces. As a tech-support person, I expect non-techinical people to make that sort of mistake, but in technical writing it's inexcusable. Calling something by the wrong name is where we get VerizonMath, or crash a space probe because someone didn't convert between feet and meters.
[100% ISO 646 Compliant]
SVM, ERGO MONSTRO.
clearly there wouldn't be a arc.tar.gz.Z file
[100% ISO 646 Compliant]
SVM, ERGO MONSTRO.
Though I loath filenames with embedded spaces, his "good practices" fail to even mention the problem.
And I believe his xargs examples will not work with them.
And this:
ls -1 | xargs file
December_Report.pdf: PDF document, version 1.3
The file command will explode with the long output of ls. WTF.
The count on grep could work though.
Best practices:
Use directories; dont keep too much in one directory.
When copying to a directory: cp -av file1 file2 file3 file4 directory/. # the trailing path is a good habit
Use small shell scripts to get work done on the command line:
$ for i in images/*
> do
> convert -resize 640x480 $i 640/$i
> done
Piping cats? Is that like kitten huffing?
$ cat ~/bin/lowercase.zsh
#!/bin/zsh
for i in $@ ; do
mv $i $i:l
done
$ ls
TEST1
tEsT2
test3
$ lowercase.zsh *
$ ls
test1
test2
test3
*nix doesn't incluse linux, solaris, aix, a/ux, and many more. drop it.
finally someone has said what has annoyed the living hell out of me for years. And I've been seeing it in multiple professional articles: remove cat. How many times to you type "cat file|grep regx" for a regex and when you can just run "grep regex file".And needless to say "awk '/regex/ {print $1}' file" works wonders as well. I think there is a good point to his article... there more than one way to skin a cat, just don't make a habit of it.
It reads like "Hey! I'm so uber cool and I know a trick and you can be cool too if you act like me!"
which is utter crap.
The biggest thing to do to adopt "good" habits is to use syntax that'll work on every version of every flavor of UNIX. As the author of the article doesn't stress that, he's not a good person to use as an example.
- real hackers don't have sigs -
I think you and I are from the same school of sysadmin-dom. But you'd never catch me using mc. Wuss!
/dir filepatter\* | while read file; do echo "$file"; done
Here is a common pattern I use:
a="`echo filepattern`"
echo $a
ls -lrt $a | head
ls -lrt $a | tail
export a
su
echo $a
rm $a
^D
This is quick to type and accurate for certain VERY sensitive directories where
a) errors are unforgiveable
b) MANY files exist
c) Files DO NOT contain spaces
> % for i in foo bar baz; do echo somecommand $i; done
for i in foo bar baz; do echo somecommand "$i"; done
Quotes make this quite a bit safer, in case foo, bar, or baz have space in them. And don't forget this construct:
find
The backslash, BTW, is more important that most junior sysadmins think. But it is only used if something in your local directory matches filepatter*....
Do daemons dream of electric sleep()?
I am TheRaven on Soylent News
I mean, they're both the same if you look at them on paper-wise
XML is like violence. If it doesn't solve the problem, use more.
Don't use semicolons, use &&.
/, wanted to delete /tmp/root, and you typed cd /tm;rm -rf root. You'd be in trouble, but the && would cause the failed cd to not hose things up.
Actually, this case is a very good example of why && are better as a default over ; to delimit commands on a single line. If you were in
Still, my advice in general would be to avoid stringing commands just for the sake of being clever and run each command serially. More can go wrong than the return code will indicate that output will.
XML is like violence. If it doesn't solve the problem, use more.
Ben Hocking
Need a professional organizer?
The better I have learned how to write scripts in bash, the easier it has become for me to quickly write a "script" at the command line. I know, you can do this with Python, etc., but for some jobs it's just easier and quicker to use bash. The more tools you have, the quicker you can solve your problems.
Also, I believe that many default distros don't have Python in them. So, if you're on a strange computer you can't count on it being there. Perl or bash, however, you'll almost always find. (This is the same reason I've tried to improve my vi skills even though I'm an emacs fan. I know, I know. Yes, I said emacs.)
Ben Hocking
Need a professional organizer?
Would it be considered bad form to send this to my boss?
1. Learn about man & google. man is your friend, google is his big brother.
/somewhere &" can save you time!
/$SOMEPATH"... are you sure that $SOMEPATH is defined?
... cp -r dir dir.orig.my_name. Alternately, if you have the file in source control, use it.
2. Learn vi. It may not be the best editor, but it is everywhere.
3. Learn your shell & shell tricks. All should have history & script. Up arrow or escape - k? Use & and ; when warranted: "cp big-file
4. Don't be root unless you need to. Mistakes happen. Being root makes a mistake's potential impact larger.
5. Be very careful with rm -rf. Watch out for "rm -rf
6. Before editting a file, keep an original. Before editting a config file, cp foo_config foo_config.orig.20061219. Same goes for directories du -k dir
7. Be smart, clear & lazy when solving problems. Solutions often get attacked with brute-force ignorance instead of elegance. Be clear - exactly what problem are you trying to solve? Be lazy: stop when you have solved the problem. Also, If you can change the problem statement slightly and achieve the same results with a simpler solution, do so.
8. Expect the unexpected. When writing scripts, be defensive - check error codes, verify that variables are set and have sane values, etc...
9. Simplicity is sometimes more elegant than efficiency. If it looks like line noise and you wrote it, split it up. BAR=${${FOO:-$ZED}-y} is not as clear as using a nested if/then/else.
10. Save values or cut & paste, do not retype. Retyping is slow & error prone.
They seem to just be tips for being "clever".
;) ), edit, check, then make sure you know how to copy and paste stuff correctly ;). Only then paste the commandline to the shell... When the commandline starts to look very complex, you may wish to consider writing a script instead.
;) ). If you are typing the command to a text editor first, this is less likely to be a problem.
;). Then only use filename completion for tar -xvf <path to tar file> to untar. This way if you screw up you are less likely to mess up the wrong directories.
;).
;).
You don't need clever for Unix commandline. You need paranoid. Make backups but work so you won't need them.
Typing backslash to have extra long command lines? Don't you guys make typos?
Here are my tips:
Don't type complex commandlines into the shell directly. Copy them to a text editor first (that's what the GUI is for
Consider that many keyboards put the backslash or pipe rather close to the Enter key, this means if you slip (or someone nudges you) you could prematurely terminate the commandline. Depending on how you do things, this could be not a big problem or it could be a catastrophe ( e.g. you end up running an SQL UPDATE without a where clause
The tip about not using cat is stupid. If you use cat, it is easier to reedit the command line to repipe the file output to some other command instead. e.g. cat file | head, then up arrow replace head with grep or strings | head, or whatever.
To those who use "<", using "<" to read files is asking for trouble, because "<" and ">" are next to each other and you could be very unhappy if you used ">" instead of "<". So make it a habit of NOT using "<" at all.
Basically, when you use the Unix (or SQL) commandline, always be paranoid. Yes, don't move the tar file before untarring, but don't do it the suggested way either. Change to the directory you want to unpack the file to first, then ls -al to see if it's really the right directory
When you are using tar, always keep in mind that with the US and UK keyboard layouts the x and the c keys are next to each other and mean rather different things
Try not to do rm -rf <long path name>. cd to the directory first. Then do the rm -rf with filename completion. That way the dreaded rm -rf / is less likely to happen.
If you are using bash and you like to use ctrl-r, don't assume you'll get the command you are thinking of. Look and confirm before you press enter
I love the command line. Really. But not the Unix command line. Only a computer could ever love C, or a C shell. Humans are forever tortured by both.
Exhibit A, the tar command. Never was so inscrutable and impractical a monstrosity presented to so many grovelling supplicants. No, it does not even compress the archive. Why? Well you see unix must be modular, even when it means that every bullet gets hand-packed before being inserted in the musket. If a finger or two is lost due to a blocked chamber, so be it.
Unix, the triumph of difficulty over usability.
I come here for the love
Me too. Except I'm lazy (used to code Perl a lot, now mostly Korn shell) so I just type ^P^E|sh^M
I know it only saves a keystroke or two. However it also makes it easy to type |sudo sh instead, or
add another grep to filter out unwanted commands, etc. I guess that counts as a habit.
-Lasse
As copyright owner of this comment, I authorize everyone to defeat any technological measure which limits access to it.
I'm evaluating the tips based on them being prescriptions for things to do in interactive shell behavior, since that seems to be the theme. Writing scripts changes the situation to make some tips valuable. My number one tip as a response to these is don't try to be too clever (particularly when the biggest benefit of the approach is to say 'look how clever it is!'). Maybe it's because I don't work in a vacuum and all too many times have been called in to clean up where an administrator tried to do something too complicated for their understanding.
.01s instead of the .09s operation is a bad example. He could have set up a
mkdir -p is a convenience people should be aware of, but telling people to start getting overly creative with the shell expansion behavior is asking for mistakes/trouble. Also, having a mkdirhier script in case the example isn't supported on all shells is an indication that you shouldn't get overly cozy if you are going to be dealing with a lot of different systems/users with different default shells. The amount of time a lot of people take to figure out the 'clever' way in terms of how to phrase the expansion so the shell will expand it right is often longer than just typing the two lines more that the less thought takes. Not saying this isn't useful, but in my experience too many people mess things up too frequently or take too long to think up the expressions to tell them trying to be clever ends up taking more time than they think they are saving.
Change the path instead of the archive is not that dire to do normally, but if you avoid it, to me it's just easier to be in the target directly and use full path to the archive.
On combining commands, I second that ; can be dangerous and && as a default will make the chain more ready to break, but again I say not trying to be so clever as to put all you want on one line. Some things go wrong that aren't reflected in return codes, doing it one at a time let's you think of those. True, though, that the && never assume the first command works, while your fingers may keep moving and hit enter on next command before your brain realizes the command failed, so && may have merit, but then again taking your time may have more merit.
On the quotation thing, true enough, you must understand how quoting works to do remotely complex things, particularly nested circumstances (i.e. ssh to a system to run a command, where the output will be parsed by two shells.)
On the breaking up long lines thing, in a shell script it may be more necessary, but on an interactive command line it could also indicate you are trying too hard to do things in one chunk. I admit sometimes it does get too wide, but particularly less experienced admins should consider if there were a simpler way to do it in smaller chunks they won't screw up.
Grouping commands is important to know, and harmless (better than repeating the same pipe over and over and more powerful).
I will say xargs is way way over-rated. Too many people, particularly dealing with directory trees containing spaces, get into trouble piping the output of find into anything when IFS causes something like "/tmp/Monthly Report" to be parsed as two different files. find has a competent filtering mechanism (-type, -iname, -name, etc...) and it's own -exec. find is well aware of the state of each file. You could assign IFS to try to avoid it, but using find's built-ins where possible alleviates it.
When you are talking about interactive shell operation, picking the
much larger demonstration that would have been useful, but this just makes people mock the example. In any event, this seems like an okay thing to convey, but I dunno if it would've made my top 10.
Probably a more valid point about using awk, and a common trap I do see people stuck in.
On piping cat, that seems like more an annoyance than anything constructive. Some people use the cat | grep construct because it is so unambiguou
XML is like violence. If it doesn't solve the problem, use more.
As copyright owner of this comment, I authorize everyone to defeat any technological measure which limits access to it.
I thought that all-natural kitten huffing was PETA approved? :]
Or have they changed that recently?
No, it is not "the best thing on Windows that is close to UNIX", both Interix/Microsoft SFU (freeware) and AT&T/Bell Labs UWIN (open source) are much, much, MUCH better.
I continue to be amazed at how many people do command-line work in non-scrollable windows and don't run the command-line within an editor like emacs.
Using a non-scrollable window is simply idiotic: what are you saving - the few thousand bytes of (potentially useful) session history?
Using a scrollable window alone is only a little dumb - you've vaulted yourself into the era of teletype printing terminals: if you need to look at a previous part of the session, you can scroll backwards and search for it using your eyeballs, just like manually searching through a long piece of teletype paper. Why run in an editor which has search commands built-in? Think of the microseconds of computer time you save by wasting seconds and minutes or your own time.
People who argue that piping a single file via cat is the best method are wrong. The following method has all of the advantages you cite, but is also shorter to type, uses less system resources (no cat process, no pipe(2) object), and doesn't require you to "rething the input method" in case you want to change the grep command:
:)
$ <file.txt grep foobar
Few people know that input-redirection can be established before the command name
1. first impressions: the article is mostly simple, obvious stuff, i'm surprised to see it on IBM's developerworks site.
/home/USER/public_html -name "*.htm*" -print0 | xargs -0 chmod 644
/home/*/public_html /home/*/cgi-bin -name "*.cgi" -o -name "*.pl" -print0 | xargs -0 grep -Zzli "matt.*wright" | xargs -0 chmod a-x
2. re: xargs end-of-file warning. as of version 4.2.9, GNU xargs defaults to not having an end-of-file string - worth knowing about, but not really a problem.
3. a far more common "gotcha" with xargs is dealing with space characters (and other characters with special meaning to the shell) in file names. this is especially common if you are working on directories containing HTML (and other) files uploaded by Mac & Windows users. to deal with it, use find's "-print0" arg and xargs' "-0" arg, for null-terminated input.
e.g. to set permissions to 644 on all the html files in a user's public_html directory:
find
most of the GNU utils support null-termination for input & output - so if you need to run grep or whatever on the output of find before passing it to xargs, you can.
e.g. to find all copies of Matt Wright's scripts such as FormMail.pl in all users' web sites and disable them:
find
make your users use secure alternatives instead - such as the NMS versions of the same scripts. even Matt's Script Archive recommends the use of the NMS versions instead of his own, these days.
Is that like Kitten Huffing?
Sometimes boldness is in fashion. Sometimes only the brave will be bold.
But you can also do less == more
[100% ISO 646 Compliant]
SVM, ERGO MONSTRO.
As an absolute worst case, you can always compile and install the GNU tools (in your home 'bin' directory, if necessary), including, possibly, gcc.
If you're really worried about portability, you should also remember that -C is also a 'relatively' recent add-on to tar, so you'd be better off with ' (cd a/b/c ; tar -xf - ) < somefile '
However, once you have gnu tar and gzip installed, you can then go 'tar -C a/b/c -xzf somefile.gz'
Sometimes boldness is in fashion. Sometimes only the brave will be bold.
I'm usually writing shell scripts that invoke tools like sed/awk/grep that are built into all the flavors of Unix I have to work with. I often have to access a machine over a 9600 bps modem connection.
My most popular utility tarball weighs in at 44K (LZW) compressed, or 127K uncompressed. If I had to upload a 50K gzip binary and a 184K gnu tar just to be able to uncompress my tarball, I'd be more than doubling the time it takes to do the install. The improved compression from gzip (about 7% compared to LZH under SCO compress -H , or 25% compared to LZW from SCO/AIX compress would take a long time to pay back.
A recent project is working with much larger tarballs, so it might be a good idea to pursue getting GNU tools out to the point that they become the norm. If my employer would install them on all systems we have to support, it would be a different situation; I'd use all GNU goodness and love every minute of it. I'd also probably go back to writing utilities in perl, which is what I used to do at a prior job where I had only a handful of local systems to support instead of thousands across the whole country. But since that isn't likely to happen any time soon, I'm sticking with what is truly portable, as POSIXly correct as I can, with the absolute minimum of quirk adjustments.
[100% ISO 646 Compliant]
SVM, ERGO MONSTRO.
Great, IBM, way to ignore the dreaded "xargs" security bug! Seriously, IBM notices some kind of obscure danger about underscores, but completely ignores the fact that xargs separates arguments by newlines??
/tmp directory by a certain user for some reason: /tmp -user 1001 | xargs rm
/tmp called "haxor\n". Inside there he puts another directory "etc" and inside there he puts a file called "passwd."
/tmp/tmp43cc91 /tmp/haxor /tmp/haxor /etc/passwd
e tc/passwd"]
/tmp -user 1001 -print0 | xargs -0 rm
Let's say I'm a sysadmin and I'm running as root, trying to remove all the files in the
find
User 1001 has a directory in
Can you guess what happens?
find prints:
xargs sees: ["/tmp/tmp43cc91","/tmp/haxor","","/tmp/haxor","/
Oops!! You just hosed your system!
The correct way to use xargs is to use the -0 switch, which will separate the input by null characters, which cannot appear in filenames. find has a handy -print0 option which will output the correct output:
find
And your system is safe.
Did you ever notice that *nix doesn't even cover Linux?
Does anybody else notice these benchmarks are flawed? For an article discussing the shell, we should know that in this first benchmark, time is only counting the execution time of grep, and not wc, and is thus undercounting how much CPU time is actually used. How about a neat shell trick to correctly run that benchmark?
> ~ $ time grep and tmp/a/longfile.txt | wc -l
> 2811
>
> real 0m0.097s
> user 0m0.006s
> sys 0m0.032s
> ~ $ time grep -c and tmp/a/longfile.txt
> 2811
>
> real 0m0.013s
> user 0m0.006s
> sys 0m0.005s
> ~ $
I know it's not proprietory 'cos Debian has it
$ bash --version
GNU bash, version 3.1.17(1)-release (i486-pc-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.
While I agree with /. reader comments, I wanted to point out some other problems with the article:
Now, for my tips:
Hope this helps.
I'm a UNIX guy who's been using UNIX and derivatives for something like 2/3 of my life.
This post is bang on the money, and, in my estimation, approximately 3113.7% more useful than TFA.
Do daemons dream of electric sleep()?
> Unfortunately, in the context of Unix, there's nothing 'portable' about using gzipped files.
You're absolutely correct, but missing the mark.
The moronic FA author was trying to portably gunzip files. Given those requirements, gzcat is a reasonable prerequisite. Thus providing gzcat with arguments which would be portable to zcat is unnecessary, as zcat could not complete the task required in the first place.
BTW, I don't know what kind of machines you admin, but I have the luxury of administering primarily sparc/solaris boxen these days. This means that I can ship a Solaris 2.5.1 binary version of GNU tar and gzip with my install packages, and it will run on any of my machines, assuming they are not more than 11 years old. Sun ABI compatibility is quite good. I could even ship 2.4 binaries without issue, extending my box-age to 12 or 13 years, but that seems kind of pointless since all the boxes are less than 5 years old, with the exception of the workstation I use to build Solaris 2.5.1 binaries (an ultra 5 running 2.5.1 hardware 11-97).
I suppose I'm going to have issues at some point the future, though, as we are considering moving to Opteron machines. (If they would rip out the BMC and replace it with OpenBoot, we would have moved long ago). In that case, I'll probably have to snag gzip and tar from an old Solaris 7/x86 box I still have around.
Do daemons dream of electric sleep()?
Get a real shell, man!!
All hope abandon ye who enter here.
I replace you with a small shell script
--- I am known for the ones who want to find me on the net. Is that a privacy risk or a privilege? One might wonder..