Ten Tweetable Scripts

Today i’ve stumbled in this interesting article by Nat Friedman, on his personal Blog, it’s more than 3 years old and still awesome, check these small gems

Yesterday morning I proposed a contest to create the best one-line program that would fit inside Twitter’s 140-character buffer. To kick things off, I wrote this 105-character script which displays a small animation:

s="-<";while true;do echo -ne "$s\r";s=`sed 's/->$/-<-/;s/^/;s/-<-/;s/>-/->/;'<<<$s`;sleep 0.1;done

Arturo (or Pupi as his friends call him) wrote a 135-character morse code decoder in shell:

m=etianmsurwdkgohvf?l?pjbxcyzq;p=0;while read -sn1 c;do [ -z "$c" ]&&p=0&&echo&&continue;let p+=c;echo -ne \\b${m:$p:1};let p+=p+2;done

Press ’0′ for dot, ’1′ for dash, and hit space (or enter) as a char separator. Wow!

I learned a few tricks from Arturo’s script. First, he uses the ${} braces operator to take substrings, like so:

${var:offset:length}

This is incredibly useful! You can actually do shell arithmetic in the offset and length parameters, too. So for example,

${var:i+1:a-3}

is valid for shell variables $i and $a. And to find the length of a string, you can use:

${#str}

So str=”foobar”; echo ${#str} will print “6″. You can read more about the braces operator in the bash info page.

Another thing I learned from Arturo’s script is the versatility of the ‘read’ builtin in bash. Pupi uses the -s argument, which causes read not to echo its input (useful for inputting passwords) and -n1 which tells it to only read one character. Also, Arturo uses [ test ] && operation, which is a handy short-hand for an if statement in shell (and other languages).


Pãdraig Brady wrote this excellent screensaver:

tr -c "[:digit:]" " " < /dev/urandom | dd cbs=$COLUMNS conv=lcase,unblock | GREP_COLOR="1;32" grep --color "[^ ]"

Pãdraig makes use of the square-brace character class operator in tr(1) to filter out all the numerals, which bash also supports.

Building on what I learned from Pupi, here is one I wrote that I call paint.sh:

c=12322123;x=20;y=20;while read -sn1 p;do k=${c:(p-1)*2:2};let x+=$((k/10-2));let y+=$((k%10-2));echo -en \\033[$y\;"$x"HX;done

Use the 1 2 3 and 4 keys to move the cursor around the screen. It’s an etch-a-sketch for your terminal!

You can see that I made use of the read -sn1 trick from pupi as well as the braces operator to substring. I also used ANSI escape codes to position the cursor.

And this is one I call rockband.sh:

while read -sn1 p;do s="";for((i=0;i<$p;i++));do s=x$s;done; yes $s > /dev/audio&sleep 0.1;kill %%;done

Use the number keys to play different tones. When you’re done, hit Control-c.

The way it works is that the ASCII value of each character you send to /dev/audio specifies the excursion of the speaker diaphragm (roughly). The ‘yes’ command prints whatever string you give it, followed by a newline character (ASCII 13, pretty low), over and over again. So the longer the string of ‘x’ characters you pass to ‘yes’, and which ‘yes’ prints between newlines, the slower the oscillation of the speaker diaphragm, and the lower the tone. Neat, huh? I learned this trick from my boyhood friend Edward Loper many years ago.

And here’s the last one I wrote:

s=" #55755071317011117011117075557";for i in `seq 2 $((${#s}-1))`; do k=${s:i:1}; for b in 1 2 4; do echo -n "${s:(k&b)/b:1}"; done; echo; done

Miguel submitted this tiny function plotter:

for x in `seq -1 .05 1`; do y=`echo "s($x*8)*10+10" | bc -l`; for p in `seq 0 $y`; do echo -n " "; done; echo "*" ;done

And here’s another plot:

for x in `seq -5 .5 5`; do y=`echo "$x*$x" | bc`; for p in `seq 0 $y`; do echo -n " "; done; echo "*" ;done

Those last three scripts make use of the venerable “seq” command to generate a series of numbers. Miguel uses fractional steps, but if you only need integers you can also use braces in shell, like this:

sum=0;for i in {1..100}; do let sum+=i; done; echo $sum


Ryan Paul of ArsTechnica fame wrote this Ruby script:

proc{|f|f[proc{|x|x+1},0]}[proc{|x,y|proc{|f,z|x[proc{|w|y[f,w]},z]}} [proc{|f,x|f[f[f[f[f[f[f[x]]]]]]]},proc{|f,x|f[f[f[f[f[f[x]]]]]]}]]

Ryan is using the “proc” primitive in Ruby, which allows you to create an anonymous function (like lambda in lisp), and which I didn’t know about even though I’ve been coding Ruby off and on the last few months. He uses Church encoding to encode the numbers 7 and 6, and lambda calculus to multiply them, thus confirming that he is the most awesome IT journalist working today.

Finally, Jay Wren sent in this C program:

main(x,y){for(;x++;) for(y=2;x%y;)printf( ++y/x+"\0%d\n",x);}

of which he is not the original author (and which I suspect was an IOCCC entry), but which is a very compact way of generating all the prime numbers. The author uses the args to main to save space on variable declaration, and the leading null-terminator in the string is a really clever way to select whether or not to print the output without an if statement. Lots of cleverness in there (though the algorithm to find primes is just brute force).

There were too many good entries to declare a winner, and maybe a contest was the wrong idea anyway. But this was a lot of fun. If you want to send me a script on twitter, be sure to send a “@natfriedman” message after, so that I notice you.

Thanks to Fahim Zahid for help creating the mini screencasts.

Update: Be sure to read More Tweetable Scripts for more goodies!

About News