Showing posts with label crash. Show all posts
Showing posts with label crash. Show all posts

Thursday, April 30, 2009

The Tiny Unix And Linux Shell Crash Course For Beginners

Hey there,

Today's been a long day, filled with fun and gainful employment. Unfortunately, nothing I did today was the least bit interesting to write about ;)

So, in the mean time - in between time - I came up with a little something to help a few new guys get used to the shell (bash in this instance, but most of this will work in any shell... except the c shell - nothing is compatible with the c shell except tcsh and ...the c shell ;)

The setup is simple for this crash course, and (we'll consider ourselves the teachers) you should let the student know that they're in for a fun little piece of problem solving. Maybe, if I had the time to give this some more thought, it could be a pretty decent (although probably unusually cruel ;) interview tactic. If you have the time (and the stomach) to do that to some poor bastard that's looking to make a buck; go for it. I'm a pretty harsh interview, but I don't know if this is something I'd do to someone who didn't already know that their future employment was ensured (pending the outcome of drug testing, of course. Quite frankly, if you don't have what it takes to do your job while you're loaded to the gills, I don't think you'll not be able to see right through my fragile mask of sanity ;)

Anyway. Load up your mark's .profile (or .bashrc, etc) with this little collection of shell aliases and see how long it takes them to break out and get a normal shell back. Plenty of folks can do it without thinking. Anyone who can't will learn a little something.

And, please remember, this isn't about judgement; it's about pushing someone (even yourself) to think outside the box (or whatever object they're figuratively trapped in ;). We all need to be able to think in that abstract space every once in a while. Why not make it fun :)

Cheers,

PS1="youAreHere/ "
export PS1
alias --='-'
alias ash='echo youAreHere/ '
alias bash='echo youAreHere/ '
alias cat='perl -l'
alias cd='cd .'
alias cp='echo cp'
alias csh='echo youAreHere/ '
alias df='echo /dev/dump 100% 100% 0% /tmp/jailfs/hoosegow/you'
alias echo='echo '
alias emacs='ed'
alias env='vmstat'
alias ex='ed'
alias exec='echo cannot fork'
alias exit='echo are you sure?'
alias id='echo user\(me\) group\(sadly the same\)'
alias joe='ed'
alias jsh='echo youAreHere/ '
alias kill='echo all dead'
alias ksh='echo youAreHere/ '
alias less='more ---x'
alias logout='echo are you sure?'
alias ls='echo .'
alias mkdir='echo making directory'
alias more='less </dev/null'
alias mv='echo stay'
alias netstat='cat /dev/random'
alias ping='ping /dev/null'
alias prompt='echo youAreHere/'
alias ps='echo you 501 501 0 Apr 1 ? 0:00 /usr/bin/vicks -vaporub'
alias pwd='echo you are here'
alias rm='echo can\'\''t find'
alias rmdir='removing directory'
alias set='iostat'
alias sh='echo youAreHere/ '
alias su='echo cannot su to'
alias sudo='exec'
alias touch='echo please don\'\''t touch'
alias unalias='echo no aliases found named'
alias vi='ed'
alias vim='ed'
alias w='echo x, y and z'
alias who='echo what?'
alias zsh='echo youAreHere/ '
# alias alias="sleep 5"

# Uncommenting that last line is optional ;)

, Mike




Discover the Free Ebook that shows you how to make 100% commissions on ClickBank!



Please note that this blog accepts comments via email only. See our Mission And Policy Statement for further details.

Wednesday, April 1, 2009

Top 10 Linux Crashes - And Pictures Of them

Hey there,

Once again work interferes with my plans for world domination and I have to splash around outside the local watering hole to find material ;)

As today's title suggests, I went out and found some interesting pictures in an online post called the "Linux Crash Top 10 Pictures." It's apparently an answer to some sort of backlash of Windows users who take their Operating System so seriously that they actually managed to come together and whine in unison; in numbers so staggering that someone felt the need to listen and respond ;) Actually it's a pretty interesting and low-key post. Check it out for the rest of the pictures. I've included my favorites below.

You may note that most of them aren't really "crashes." But, each one does link back to the original site (if those two things can be directly related ?? ;)

Enjoy!



Strange Linux Crash


Linux On Nintendo DS


Linux. Would you like fries with that?


Kernel Panic or normal boot? Does anyone in the audience know the difference?





, Mike




Discover the Free Ebook that shows you how to make 100% commissions on ClickBank!



Please note that this blog accepts comments via email only. See our Mission And Policy Statement for further details.

Tuesday, July 1, 2008

Using Strings To Safely Get Program Usage Information On Linux And Unix

Hey There,

We've posted quite a bit about the "strings" command in various past-posts running the gamut from using strings to extract RPM header information to using the basic strings construct in C to make running shells on network sockets possible. Today we're going to take a look at the "strings" command in an entirely new light.

Imagine that you were tasked with running a particular command named, for the sake of argument, BLARG. Unfortunately, in our manufactured situation, BLARG has no man page, and searches for it in Google, and other search engines turn up no useful information. Also your boss just said that you needed to run it, and left it at that, with no further instruction (he also can't be reached. What's wrong with this guy? ;) BLARG is also a compiled binary.

Your basic inclination might be to just run it without any arguments, as many commands (like "mkdir") will give you the usage information you need if you use this method, like so:

host # mkdir
usage: mkdir [-p] [-m mode] dirname ...


However, lots of other programs don't, so it's not the wisest choice. Remember that BLARG could potentially be a very harmful program. Running it without arguments may destroy things you can't afford to lose.

Other options you have, would include (but not be limited to), the following, coupled with their undesirable possible outcomes:

1. You could give the command a bogus switch line, like "BLARG -xKECVDSLdlske" : Assuming that that command line is indeed bogus, lots of programs silently ignore bogus switches and run their default instructions anyway.

2. You could cat the command : This will probably just turn your terminal output into Chinese. Even if you redirect standard error to /dev/null, odds are standard output is going to include a lot of funky characters that might cause more harm than good. You might also note that, a lot of the time, the usage message is printed to standard error and not standard output!

3. You could use eval to run the program, like "eval BLARG" : Unfortunately, even though it seems counterintuitive, eval just evaluates a condition or program's return status. Unfortunately, in order to get that, it has to run the command.

4. You could use commands like crash to get the information : This can be a great way to find out the information you need. By typing "crash -h BLARG" you should, theoretically, get a dump of all the help information you need. Unfortunately, not all distro's of Linux and Unix include it by default and not all distros' versions of crash operate the same. Some require you to be proficient in running a debugger against a dump file, afterward. Way too much hassle.

So far, we've gone through about 5 options, going from worse to better. There are probably a lot more than I'm thinking up here as I type (email them to me at eggi@comcast.net with comments if you'd like, as I'd love to do a follow-up to this post with more of that kind of information).

One way I've found that is virtually foolproof, and works in every distro I've tested, is to use the "strings" command to extract usage information. If you've ever used strings before, you know that distilling what it spits out when you run it against a command to a universally acceptable output of help information for any and/or all binaries is next to impossible. The Linux version of the crash command comes much closer to doing this, and doing it better. But, for the rest of us (even those without the privilege to run "crash"), we can still get the information we need using "strings", like so:

host # strings BLARG 2>/dev/null|egrep -i 'usage|help' <-- Note that strings generally requires the fully qualified name of the binary, like /bin/BLARG or ./BLARG
usage: %s [-abcdefGHIJKv] [file ...]

and you can even add the universal "%s" printf modifier to your egrep if you want to get all the lines that might contain useful help information, if you're not sure that the usage message is limited to a single line of output. This has the side effect of, sometimes, making the output a little messy, although (as some of you may have noted) the above usage display (while better than nothing) doesn't really help you. You'll probably be right 99% of the time if you guess the -v flag stands for verbose or version, but you never know. Using strings and grabbing all the lines with %s can provide more insight, if not a more distracting view of the binary's guts (of course, this output is from another command entirely ;)

host # strings BLARG 2>/dev/null|egrep -i 'usage|help|%s'
%s: %s
%s: directory causes a cycle
%s %*u %-*s %-*s
ls: %s: %s
%s/%s
usage: %s [-abcdefGHIJKv] [file ...]
%ld%s-blocks
%s: unknown blocksize
%s: minimum blocksize is 512
%s:
%s: %m
netgroup: Cycle in group `%s'
%s.%s
(%s,%s,%s)
option requires an argument -- %s
unknown option -- %s
stack overflow in function %s
%.3s %.3s%3d %2.2d:%2.2d:%2.2d %s
%H:%M:%S
%a %b %e %H:%M:%S %Z %Y
%I:%M:%S %p
%s/%s.%d
YP server for domain %s not responding, still trying
<; errno = %s
%s: %s - %s
%s/bt.XXXXXX
%s/_hash.XXXXXX


Worst case, you can just run something like:

host # strings BLARG >OUTPUT 2>&1

and safely cruise the lines of text in the OUTPUT fiel to manually find what you need. You may have to ;)

In any event, you've got a great tool at your disposal to find out what you need to know the hard way. And, sometimes, that's the only way to be absolutely sure :)

Cheers,

, Mike

Friday, April 25, 2008

Determining Signal Definitions In Linux and Unix

Greetings,

Today, we're going to take a quick look at simple return codes (or errno values) that get returned by the bash and ksh shells in Linux (and Solaris Unix). This complements a post we did a while back on trapping signals in Perl and the shell, and adds a bit more to understanding of the fork-and-exec process introduced in our post on running a login shell on a network port.

While these signals are subject to change, the POSIX standard is fairly consistent between most Unix and Linux systems. If you ever need to find out what a signal means, you have a number of options at your disposal to determine that information.

1. At the process level on Solaris, you can figure out what signals are associated with what processes by using the "psig" command. This command will list out all signals associated with a given process (assuming you know its process ID). A sample of this process-finding process would be something like:

host # ps -ef|grep "[l]pd"
daemon 2073 1 0 Mar 21 ? 0:00 /usr/local/sbin/lpd
host # psig 2073
2073: /usr/local/sbin/lpd
HUP caught sigacthandler
...
ILL default
...
PIPE ignored
...


basically, you'll get a ton of output. And none of it may make any sense to you. That's okay for now :)

2. At the process level on Linux, you can get approximately the same functionality from the "crash" command ( used interactively, if available ) or, even better, this publicly available script written specifically to emulate Solaris' psig functionality, for use on Linux. It's called psig.sh for Linux and is an excellent tool for replicating the psig experience for Linux users who are used to Solaris' proc commands.

3. On either Linux or Unix (any flavor), you can determine what signals are handled by your machine, what their names are and what their signal numbers are, by checking your system include files. On Solaris, the header file that contains this information is almost guaranteed to be named /usr/include/sys/iso/signal_iso.h (at least for Solaris 9 and 10). In Linux, it will generally be very specific to the architecture of your build system (something like: /usr/include/asm-x86_64/signal.h)

In any event, you can follow a simple process to figure out where your system's signal definitions are loaded, no matter what flavor of Unix or Linux you're running. It all comes down to derivation and, luckily, you'll always have the same starting point (I may be wrong on this, but I've never experienced it ;).

Here's a quick command line walkthrough of two different ways to figure out where your signal definitions are listed (that is, the include/header file that defines the signal numbers, their abbreviated signal names and definitions) that can be used on almost any *nix system. As a starting point, /usr/include/signal.h is probably the best, since it exists on most systems. We'll also use SIGHUP (the standard HangUp signal and signal number 1) to guide our search:

The painful way:

host # grep SIGHUP /usr/include/signal.h|grep -w 1
host # grep include /usr/include/signal.h
#include <sys/feature_tests.h>
#include <sys/types.h>
...
host # grep include /usr/include/signal.h|sed 's/^.*<\([^>]*\)>/\1/'|xargs -ivar grep SIGHUP /usr/include/var
host # grep include /usr/include/signal.h|sed 's/^.*<\([^>]*\)>/\1/'|xargs -ivar grep "^#include" /usr/include/var|grep sig
#include <sys/iso/signal_iso.h>
#include <sys/siginfo.h>
...


... and so on, and so on, until you find the right file. Basically, just follow the includes until you reach the end. This can be tedious and time consuming.

The incredibly easy way:

Solaris_9_or_10_host # find /usr/include|xargs grep SIGHUP /dev/null|grep -w 1
/usr/include/sys/iso/signal_iso.h:#define SIGHUP 1 /* hangup */
<--- This is our file :)

or

Linux_host # find /usr/include|xargs grep SIGHUP /dev/null|grep -w 1
/usr/include/bits/signum.h:#define SIGHUP 1 /* Hangup (POSIX). */
<--- Note that all 3 of these entries are valid, with this header file being the most generic. Our next command can narrow down the most "specific" correct result.
/usr/include/asm-x86_64/signal.h:#define SIGHUP 1
/usr/include/asm-i386/signal.h:#define SIGHUP 1
Linux_host # uname -pr
2.6.5-7.286-smp x86_64
<--- Now we know that, if we want to be extra sure, the "/usr/include/asm-x86_64/signal.h" is the signal definition file we should be looking at to determine our signal information.

And that's all there is to it :) As an interesting bit of trivia, if you receive an errno value from a process that's higher than 128, you can easily deduce what signal stopped that process. All you need to do is deduct 128 from the return code, like this:

host # sleep 2
host # echo $?
0
host # sleep 200
^C
host # echo $?
130


In this case, when run normally, our sleep command exited with a return code of 0 (success). When we did a control-C during the sleep command, it returned a code of 130. Of course, you won't find this signal number defined in any of your include files, but, utilizing the shell's native reporting of signal interrupts, all you need to do is subtract 128 from 130 and you now know that the sleep command was killed by a signal 2, which is defined as:

SIGINT 2 /* interrupt (rubout) */ <--- on Solaris

and

SIGINT 2 /* Interrupt (ANSI). */ <--- on the Linux box I'm using.

Both answers, although formatted differently, indicate the same signal. Nice :)

Below, I've listed the standard signals for your convenience (from a fairly generic file - signum.h) and take no credit for writing them myself ;)

Enjoy,

Some Basic signals from /usr/include/bits/signum.h on Linux (Note that I'm only listing the basic signals and not I/O polling signals, etc)

#define SIGHUP 1 /* Hangup (POSIX). */
#define SIGINT 2 /* Interrupt (ANSI). */
#define SIGQUIT 3 /* Quit (POSIX). */
#define SIGILL 4 /* Illegal instruction (ANSI). */
#define SIGTRAP 5 /* Trace trap (POSIX). */
#define SIGABRT 6 /* Abort (ANSI). */
#define SIGIOT 6 /* IOT trap (4.2 BSD). */
#define SIGBUS 7 /* BUS error (4.2 BSD). */
#define SIGFPE 8 /* Floating-point exception (ANSI). */
#define SIGKILL 9 /* Kill, unblockable (POSIX). */
#define SIGUSR1 10 /* User-defined signal 1 (POSIX). */
#define SIGSEGV 11 /* Segmentation violation (ANSI). */
#define SIGUSR2 12 /* User-defined signal 2 (POSIX). */
#define SIGPIPE 13 /* Broken pipe (POSIX). */
#define SIGALRM 14 /* Alarm clock (POSIX). */
#define SIGTERM 15 /* Termination (ANSI). */
#define SIGSTKFLT 16 /* Stack fault. */
#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */
#define SIGCHLD 17 /* Child status has changed (POSIX). */
#define SIGCONT 18 /* Continue (POSIX). */
#define SIGSTOP 19 /* Stop, unblockable (POSIX). */
#define SIGTSTP 20 /* Keyboard stop (POSIX). */
#define SIGTTIN 21 /* Background read from tty (POSIX). */
#define SIGTTOU 22 /* Background write to tty (POSIX). */
#define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */
#define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */
#define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */
#define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */
#define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */
#define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */
#define SIGPOLL SIGIO /* Pollable event occurred (System V). */
#define SIGIO 29 /* I/O now possible (4.2 BSD). */
#define SIGPWR 30 /* Power failure restart (System V). */
#define SIGSYS 31 /* Bad system call. */
#define SIGUNUSED 31
#define _NSIG 65 /* Biggest signal number + 1


, Mike