Saturday, November 18, 2006

Sanctuaries

Ok, it all started with my friend Chetan letting this out yesterday:

"Windows will never be virus-free. Those anti-virus companies need to survive, don't they?"

Hmmm. That one reminded me of this one:

"World will never be rid of wars. The weapons industry needs them!"

The mention of war led to remind me of this one:

"Not everything man does is evil to nature. After all, some of us DO try and help and preserve animals. There ARE sanctuaries."

Right. Like there would be a need for sanctuaries if man hadn't threatened their existence in the first place!

This led to Vika remembering someone saying this:

"Americans didn't massacre the Indians. They're helping them preserve their culture.."

Like Vika says... nifty!

Friday, November 10, 2006

Running Faith


This is Amanda.

I started doing this one on 5th November and finished it on 10th November. Took nearly 8 hours.

Pencils used: HB, 2B, 4B, 6B, 8B, 2H, 4h, 6H.

I used the eraser quite a bit for highlighting.

Wednesday, November 08, 2006

A bash script to post on pastebin(s)

OK, ed-209 referred me to this script by zer0python, located here: http://www.alpadesign.com/shpost

I ended up adding features to it and in the process, making it ugly :-/. Anyway, here it is:


#!/bin/bash
# A Script that automates pasting to pastebin(s)..
# Thanks to ed-209 for this wonderful idea.. you can see his version
# which is located at http://www.alpadesign.com/shpost .. :>
#
# Author: floyd_n_milan
# Date: 08th November 2006
# Comments: Added features to the original script by zer0python
#
# Changelog:
# 08/11/06: Removed an unnecessary [ and added timeout to curl
#
# Usage: shpost.sh [-n nick] [-t type] [-s service] [-d description] \
# [-f source] [-h|--help|help]
######################################################################

function showusage
{
cat 1>&2 << EOF

nopaste: Automatic posting to pastebin(s).

Usage:
$0 [-n nick] [-t type] [-s service] [-d description] [-f source] [-h|--help|help]

Default nick is randomized.

type is one of the following:

"C89", "C", "C++", "C#"
"Java", "Pascal", "Perl"
"PHP", "PL/I", "Python"
"Ruby", "SQL", "VB"
"Plain Text"

BE SURE TO USE THE QUOTES FOR AT LEAST "Plain Text"

Default is Plain Text.

service can be one of the following:

rafb - http://rafb.net/post
sh - http://sh.nu/p/

Default is rafb.

Description must be quoted (""), if more than one word.

Default source is read from the keyboard. :-)

-h or --help or help shows this usage summery.

Mail comments, suggestions, bugs etc to
mrugeshkarnik@gmail.com
EOF
}

nick=""
lang=""
service=""
desc=""
input=""
url=""

if grep help <<<"$@"; then
showusage
exit 0
elif [[ ! $1 ]]; then
input="$(</dev/stdin)"
nick="shpostuser${$}"
lang="Plain Text"
service="rafb"
desc="shpost Post"
fi

while getopts ":n:t:s:d:f:h" opt; do
case $opt in
n )
nick="${OPTARG:=nopasteuser$$}"
;;

t )
lang="${OPTARG:="Plain Text"}"
;;

s )
service="${OPTARG:=rafb}"
;;

d )
desc="${OPTARG:="shpost Post"}"
;;

f )
input="$(<"${OPTARG:=/dev/stdin}")"
;;

h )
showusage
exit 0;;

? )
showusage
exit 64 #E_WRONGARGS (What's that?)
esac
done

input="${input:="$(</dev/stdin)"}"
nick="${nick:="shpostuser${$}"}"
lang="${lang:="Plain Text"}"
service="${service:="rafb"}"
desc="${desc:="shpost Post"}"

if [[ $service = rafb ]]; then
url=$(\
curl -i --connect-timeout 10\
-F "lang=$lang" \
-F "nick=$nick" \
-F "desc=$desc" \
-F "cvt_tabs=2" \
-F "text=$input" \
http://rafb.net/paste/paste.php 2>/dev/null | grep -i location)
echo "Your paste can be seen here: http://rafb.net${url:10}"
exit 0
elif [[ $service = sh ]]; then
curl --connect-timeout 10 -F "code=$input" -F "poster=$nick" http://sh.nu/p/
exit 0
fi

exit 0

Tuesday, November 07, 2006

bash Quoting

I thought I'd compile a list for bash's quoting rules for my own easy reference. I guess it might help others as well. Here goes then..

Escape Character (\)

Backslash (\) is used to remove the special meaning of the following character.
For example, \$ prints a $ instead of it being interpreted to signify a parameter.

An exception to the above statement is \. In the case of this sequence, bash looks for line continuation. Essentially, the character is removed completely.

Single Quotes ('')

Single quotes ('') are strong quotes. They bypass all the expansions. Everything inside single quotes is untouched.

You cannot have single quotes inside single quotes. Not even when backslash escaped. Use '\'' instead.

Double Quotes ("")

Double quotes allow parameter expansion, command substitution and arithmetic exansion. In short, all the expansions associated with $.

` is the archaic way of command substitution and is allowed inside double quotes.

\ inside double quotes is allowed only when used for \, `, $ and . In short, all the special characters which retain their special meaning inside double quotes.

Double quotes inside double quotes are allowed with used with a \. That is, \"

If history expansion is enabled, it'll be performed when ! is encountered inside double quotes. This can be bypassed with \!. The backslash preceding the ! is NOT removed.

Note: This can be annoying in your interactive shell when you get an error about history expansion when doing something like echo "Hello world!". The way to bypass this is to do "Hello world"\! or 'Hello world!' or Hello world\!

Examples:

Expression Value

$testvar hello
\$testvar $testvar
'$testvar' $testvar
"$testvar" hello
"'$testvar'" 'hello'
""$testvar"" hello
"\"$testvar\"" "hello"
~mrugesh /home/mrugesh
"~mrugesh" ~mrugesh
'~mrugesh' ~mrugesh

$' and $"

$'string' expands the string and the backslash escaped characters are replaced by the ANSI C standards. The expanded result is equivalent to being single quoted, as if $ is not present. Here are the characters expanded:

\a alert (bell)
\b backspace
\e an escape character
\f form feed
\n new line
\r carriage return
\t horizontal tab
\v vertical tab
\\ backslash
\' single quote
\nnn the eight-bit character whose value is the octal value nnn (one to three digits)
\xHH the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)
\cx a control-x character

As an example:
$ echo -e 'Hello\nworld'
Hello
world

$ echo $'Hello\nworld'
Hello
world

$" translates the quoted string according to the current locale. For C and POSIX locales, the $ sign is ignored. If translated and replaced, the replacement is double quoted.

$* and $@

These two special variables are used in terms of positional parameters. They produce the same output when unquoted. When double quoted however, "$*" produces one word with all the positional parameters separated by the first IFS character; while "$@" produces different words, separated by spaces.

To elaborate, if "$*" is fed as an argument to a command, it is just one single argument ($# will show you 1). If "$@" is fed as an argument, it is several different arguments($# will show you N, where N equals the number of positional parameters provided.).

Most times, you'd want to use "$@".

When unquoted, the output of both is grounds for word splitting.

For example,

$ set -- "first argument" "second argument" "third argument"

$ for i in "$@"; do echo ">${i}<"; done
>first argument<
>second argument<
>third argument<

$ for i in "$*"; do echo ">${i}<"; done
>first argument second argument third argument<

$ for i in $@; do echo ">${i}<"; done
>first<
>argument<
>second<
>argument<
>third<
>argument<

$ for i in $*; do echo ">${i}<"; done
>first<
>argument<
>second<
>argument<
>third<
>argument<

This post is for a quick reference. Look here for a proper explanation: http://www.grymoire.com/Unix/Quote.html. This document is not restricted to just bash.

Saturday, November 04, 2006

Two Birds with One Stone!

I had this problem with KDM while I was using amd64 on this Sempron64 machine. KDM would work fine for a while and then would become very slow on startup. By slow, I mean nearly 20 seconds. The NVIDIA logo would show up, followed by a blank screen with a busy mouse pointer in the middle. Normally, this screen would last only for a couple of seconds and KDM would show up. But here, it would keep showing for all of those 20 seconds. After that KDM would appear. During the blank screen period, there would a lot of disk activity.

The problem was very irritating. But I never bothered to solve it on that system.

I replaced the amd64 system with x86 last month. KDM had been fine till the start of this week. Then came the same problem. 20 seconds to start up. Very frustating. Today, I actually went on about investigating it. So here's how it went.

First of all, I needed to check the 'span' of the problem. I had had an X server crash today (Beryl and NVIDIA beta.. "Shit happens" ;-)). I noticed that after the crash, KDM started up normally, in no time at all. I logged out and the same thing happened. It started up normally. So apparently, the problem was only with the initial startup.

I next checked if KDM was the last thing starting on bootup, just to make sure that it isn't some other init script that starts up after KDM that causes this. After a few changes using rc-update and a reboot or two, I managed to conclude that the problem was with KDM itself.

Next, I removed xdm from the runlevel. Logged in as root and tried to run xdm. No go. No X and this in Xorg.0.log:

(II) Loader running on linux
(II) LoadModule: "bitmap"
(WW) Warning, couldn't open module bitmap
(II) UnloadModule: "bitmap"
(EE) Failed to load module "bitmap" (module does not exist, 0)
(II) LoadModule: "pcidata"
(WW) Warning, couldn't open module pcidata
(II) UnloadModule: "pcidata"
(EE) Failed to load module "pcidata" (module does not exist, 0)

Fatal server error:
Unable to load required base modules, Exiting...

(WW) xf86CloseConsole: KDSETMODE failed: Bad file descriptor
(WW) xf86CloseConsole: VT_GETMODE failed: Bad file descriptor


Ok. That didn't actually come as a surprise. I was unable to start that init script manually on the amd64 system either. X wouldn't start, syslog saying that VT7 was not available. I had ignored this too, back then. Well, I decided to fix it today.

I don't know why, but I opened up /etc/conf.d/xdm file. I didn't even know it existed before this. I found this in the file:

# Tell X to always start on VT7. Otherwise it autodetects the first available
# VT, which means it has to wait until all gettys are started so it doesn't suck
# up a VT that should have had a login prompt (very slow).
# If XSTATICVT is on, the login manager will start as soon as possible during
# the boot process. If you want X to dynamically start on the first unoccupied
# VT after all gettys have started and you are using xdm, also remove the "vt7"
# from /etc/X11/xdm/Xservers.
XSTATICVT="yes"


I changed XSTATICVT to no and issued a /etc/init.d/xdm start and behold! X started up fine. But, again, KDM took a lifetime to start.

This time though, I was already logged in on tty1. I switched to it and ran top while KDM was in that blank screen phase. I could see kdm_greet eating away at the CPU all the while the blank screen was displayed. I stopped the xdm init script and launched it again. KDM startup was normal this time. So the culprit was found. kdm_greet did something on the first startup that it didn't have to do on the subsequent startups..

Here's the solution that popped up: http://www.mail-archive.com/debian-qt-kde%40lists.debian.org/msg10087.html

Nice (!). A simple fc-cache -sv and a reboot and I could see the problem solved! The title of this post justified!

You know, its nice to play Sherlock Holmes sometimes.

Btw, big thanks to SimAtWork in #kde for helping me with the KDM issue. He/she was the one that gave me the link to the solution. :-D

Friday, November 03, 2006

'bash'ing!

I love bash. I absolutely love it. It is fun. It is great fun! Take this simple script, posted by GreyCat in #bash for example:

x="hello world"; echo "$x" | read a b; echo "$a $b"; read a b <<< "$x"; echo "$a $b"

Quite simple, isn't it? Well, here's the output:


hello world

Hmm? OK. Let's try again.

hello world
hello world

What's going on?

OK. Now here's the beauty of this little script. It teaches so many fundamentals of bash.

We start off with a simple x="hello world". Next we have a pipeline. A pipe feeds the standard output of one command to the standard input of another command, as we know.

So here, we have the standard output of echo, which is 'hello world' (Well, that's written in English. In bash's terms, the output is equivalent to "hello" "world" I suppose..), being fed as the standard input of read. read stores the two words into two variables, a and b.

The pipeline finishes there and then we simply echo the values of a and b. The output, as we can see, is blank.

Now why exactly? Let's check.. Is the assignment of the variables correct? Yes. read takes the standard input by default, so a and b get assigned the values hello and world respectively. But the output of echo is still blank.

Why?

The answer is subshell. A pipeline spawns a different subshell for each process. So read a b operates in a different subshell.. different from echo "$a $b". As we know, subshells cannot propagate any information back to its parent shell. Hence, the values of a and b are blank, as they don't yet exist in the parent shell.

In the second case, we've used a form of here document - <<<. <<< expands the argument "$x" and feeds it to read a b's standard input. This time, we get a proper hello world output from echo "$a $b", because <<< doesn't spawn a subshell.

Now, if you run the same command line again, in the same session, you'll get this output:

hello world
hello world

How come?

Quite simple. The values of a and b are set by our previously run read a b <<< "$x". The values already exist in our shell, hence.

I suppose power users will find this information quite rudimentary. But, newbies would do well to understand the concepts involved. No matter how good I may become at bash, such small concepts will always be fascinating!