#!/usr/bin/env python
# climagic tribute: the 140 best climagic tricks
# v. 0.1

# 2010 openuniverse (license: http://creativecommons.org/licenses/by/3.0/)

# multiline data string copyright 2009-2010 climagic: http://identi.ca/climagic
# multiline data string license: http://creativecommons.org/licenses/by/3.0/

# this program offers all 4 freedoms. if you change the code, please- make note
# this program comes with no warranty; please use with care

from os import system
from time import sleep
from random import shuffle

# giant multiline data string:

q = r"""[[[bcaldemo]]]echo "scale=20; 610976535/1024" | bc # Show the result of 610976535 divded by 1024 with accuracy to 20 decimal places.

[[[trnd]]]for i in {1..1000} ; do echo $(( $RANDOM % 2 )) ; done | awk '{sum+=$1;c++} END {print sum/c;}' # Test $RANDOM 's randomness. Should be ~0.5

[[[showenvnfn]]]declare # This will show your shell environment including any functions that are set. Ubuntu has a surprising number of functions.

[[[tarbssh]]]tar pjcv directory | ssh user@remotehost 'cat > file.tar.bz2' # You have data you want to transfer compressed, but not make tarfile prior.

[[[andgurus]]]ls --help # Even if you're a "guru", you should read/reread the help and man pages sometimes to find new options added in.

[[[filesxnl]]]for i in $( ls -1a ) ; do echo ${#i} $i ; done | sort -n # Print filenames in PWD by their name length sorted in ascending order.

[[[pathper]]]tr : '\n' <<<$PATH # Show the directories in your path one per line. By foob4r on commandlinefu.

[[[calcalcal]]]cal -3 # Show a 3 month (before, current, after) view in cal. Sorry I made a typo.

[[[cmp2dirs]]]comm -3 <(ls -1) <(cd /dir2 ; ls -1) # Compare the contents of two directories. Show only 2 columns, 1 for files unique to each directory

[[[32bitor64]]]getconf LONG_BIT # Is the host 32-bit or 64-bit. This is based on the OS installed, not the physical CPU capabilities. ie.

[[[varlogrpm]]]rpm -qa --filesbypkg | grep " /var/log/" # List all rpm packaged files in /var/log by what rpm they belong to.

[[[list404s]]]awk '{ if ($9 ~ /^404$/) { print $7 } }' access_log | sort | uniq # Generate a list of 404 not found URIs from your web log.

[[[login20usr]]]last -da -10 jsmith # Show the last 20 login sessions on the system for user jsmith, putting the remote host in the last column.

[[[fullpsrs]]]ps auxw --sort rss # Full ps output, sorting process table by memory usage.

[[[funfacts]]]elinks -dump randomfunfacts.com | sed -n '/^| /p' # Get a random fact. Idea inspired by others at http://www.commandlinefu.com/

[[[blinken]]]telnet towel.blinkenlights.nl # An oldie, but goodie. Try it with IPv6.

[[[graydient]]]yes "$(seq 232 255;seq 254 -1 233)" | while read i; do printf "\x1b[48;5;${i}m\n"; sleep .01; done # A GRAYdient. Haha. Still on vacation

[[[rainbow]]]yes "$(seq 1 255)" | while read i; do printf "\x1b[48;5;${i}m\n"; sleep .05; done # A rainbow in your shell.

[[[folderdemo]]]ls -ld /var/log # List the information about the directory var/log itself (-d flag), not the files inside of it.

[[[ansicols]]]for fg in {30..37};do for bg in {40..47};do echo -ne "\e[${bg}m\e[${fg}m$fg on $bg\e[0m";done;echo;done # Generate ANSI color chart

[[[findnotgz]]]find . \! -name '*.gz' -type f # Find all the files in the subdirectory or below that do not have the extension .gz

[[[bottles]]]x="bottles of beer";for b in {99..1} ; do echo "$b $x on the wall, $b $x. Take one down pass it around, $(( $b - 1 )) $x on the wall" ; done

[[[nowp1946]]]date -d 'now + 1946 days' # The -d option to date lets you specify a date to display, you can use it to calculate a date using "delta days"
 
[[[pcmddemo]]]PROMPT_COMMAND=uptime # You can set this variable to something to run prior to each bash prompt. This one uses the output from uptime.

[[[wbooted]]]date -d @$(grep ^btime /proc/stat | cut -d" " -f 2) # On Linux, show the exact time/date the system was last booted.

[[[sleepi]]]sleep $(echo "scale=50; 4*a(1)" | bc -l) # Sleep for pi seconds. bc formula for pi from the bc man page. By request of .@jwildeboer

[[[sleeppt5]]]sleep 0.5 # Newer versions of GNU sleep now can accept floating point delay values. Just in case you didn't realize this was fixed.

[[[nltabls]]]iptables -nL # View the linux firewall without doing the dns lookups for the IPs.

[[[wshellid]]]echo $$ # Display the process id of the shell you are in.

[[[cmpmany]]]ls -1 | xargs -n 2 diff # Diff each file against the file after it in the directory listing.

[[[listpq]]]lpq -a # List the jobs currently in your local print queue.

[[[comnetorgetc]]]for i in com net org eu co.uk co.za co.nz; do ping -c 1 google.$i > /dev/null 2>&1 || echo $i is not responding ; done # Sug. by .@andgodsed

[[[wherealias]]]alias whereami='echo "$( hostname --fqdn )($(hostname -i)):$( pwd )"' # Complement to whoami command. For .@karlpro

[[[tailgrep]]]tail -n 5000 bigfile | grep pattern # With very large files (log file), if you want to search near the end, tail|grep is much more efficient

[[[nstats]]]netstat -s # The -s option produces some easier to parse output about host network activity, but its for the whole system network stack.

[[[nsetstrt]]]chkconfig --list | grep -v :on # Display any service that is not setup to start on boot at all.

[[[epochhuman]]]date -d @1236605323 # Turn unix epoch time back into a human readable date. This is a new (& not widely documented) feature of date command

[[[ckconflist]]]chkconfig --list | grep 3:on # Check what services are setup to start up in run level 3 on a Red Hat based system.

[[[cpuptime]]]uptime # Show the system uptime, number of logged in users and 1, 5 and 15 minute system load averages.

[[[manls]]]man ls # View the (man)ual page for the ls command. Manual pages exist for almost every command and you should check them b4 program use.

[[[viewlsl]]]ls -l | less # Pipe the output from ls -l (long list) to less so that you can move about the output with arrow keys/pgup/pgdown and search

[[[viewfile]]]less file # less is used to view a file or output. arrowkeys/pgup/pgdown move you around. Press / and enter a pattern to search. q to quit

[[[lslsrh]]]ls -lSrh # List files long (-l), ordered by size (-S) from smallest to largest (-r) and display their size in human readable form (-h).

[[[pwfwnof]]]ls -1 /home | grep -v -f- /etc/passwd | grep /home # Show the lines of /etc/passwd for which there is no home directory in /home

[[[add2cli]]]curl http://identi.ca/climagic | html2text | sed '/ Notices /,/Pagination/ !d' # CLI way of displaying the last 20 updates on identi.ca

[[[greppstdin]]]grep -f- file # grep through a file, taking patterns one per line from stdin. '-' can often be used to mean "take data from stdin".

[[[iowaiting]]]ps auxw | grep " D " # Show processes that are waiting for IO (uninteruptable sleep).

[[[lslart]]]ls -lart # List files in the current dir by the last time they were modified. (-l = long, -a = all, -r = reverse, -t = order by mod time)

[[[wakeupogg]]]sleep $((`date -d 'tomorrow 5:30 am' +%s`-`date +%s`)) && mplayer something_to_wake_up.ogg # !cli

[[[tryonpiday]]]date +"Today is %_m.%d" # The date command allows you to specify a format for the date using different sequences. Happy Pi Day!

[[[typea]]]type -a ls # Show all the ways in which the command ls might be interpreted. Good way to see if you're using a builtin, an alias, etc.

[[[ccletpe1]]]let COFFEECOUNT+=1 # Same as let COFFEECOUNT=$COFFEECOUNT+1, just a nice shorthand similar to other programming languages. nice aroma too;

[[[digtheip]]]dig +short -x 141.59.26.5 # Do a reverse lookup on an IP and only show the reverse name. If there isn't one, it returns nothing.

[[[helpwcd]]]help cd # This shows the help for the bash internal command cd. Several commands/functions you run in bash are actually builtins.

[[[tblrot13]]]echo {a..z} ; echo {n..z} {a..m} # Make a quick rot13 translation table.

[[[trlikepython]]]echo ${val:0:1} # Print out the first character of $val. The syntax is ${variable:start:length}. Omitting length value gives rest of string.

[[[freqwrds]]]cat file|tr -s '[:space:]' '\n' |tr '[:upper:]' '[:lower:]'|sort|uniq -c|sort -n|tail -10 # Find most freq words in file. By tlrobinson.net

[[[followmsgsb]]]tail -f /var/log/messages & # Run tail on /var/log/messages and continuously print out new updates. The & backgrounds this.

[[[printa2z]]]echo {a..z} # Print out a list of letters from a to z. This is available in bash 3.0+ and zsh.

[[[top30]]]top -d 30 # Show an auto updating display of the top CPU hogging processes. Update every 30 seconds. Note: Top can use lots of CPU itself

[[[disparch]]]uname -m # Display the processor architecture of the host. On Intel compatible hardware i[3456]86 is usually 32-bit and x86_64 is 64-bit.

[[[hellowww]]]find /var/www -not -type l -a \( -perm 666 -o -perm 777 \) # Find world writable files or directories in the /var/www directory subtree.

[[[freem]]]free -m # Show free, used and cached memory on a host in megabytes. On Linux, the right num in the -/+ row is what most people care about.

[[[findbloat]]]ps aux | awk '/firefox/ {sum += $6} END { printf "%dMB\n", sum/1024 }' # Show the total memory used by firefox processes. Thanks .@jc00ke

[[[echolsp]]]!ls:p # Putting : and p together at the end of a ! line for calling the last instance of ls will simply echo it out. Thanks .@Mikoangelo

[[[thosewho]]]HISTIGNORE="clear:bg:fg:cd" # Colon seperated list of exact commands to ignore for storing in history. Thanks .@bvankuik, that's a good one.

[[[routablen]]]route -n # Show the routing table in Linux without doing DNS lookups. If you aren't root, try /sbin/route -n

[[[enhancedecho]]]echo -e "I want a break here\nand another one here\nAnd here\tI want a tab" # The -e option to echo allows you to specify special characters

[[[demoecho]]]echo -n "The file testfile has this many lines: " ; wc -l testfile # Using -n option to echo omits the newline. Very useful in loops.

[[[howlongjohnny]]]echo -n "measure the length of this text" | wc -c #Print out the number of characters in a string. The -n option omits the default newline.

[[[tiparis]]]TZ=Europe/Paris date # Show the current time in Paris, France. Unfortunately, not every city has a timezone file. Check /usr/share/zoneinfo

[[[tophosts]]]awk {'print $1'} access_log | sort | uniq -c | sort -rn | head -100 # Display top requesting hosts to website.

[[[datzpst]]]TZ=PST date # Display the current date, but force the use of Pacific Standard Time time zone.

[[[revipwsl]]]awk {'print $1'} access_log | xargs -n 1 dig +short -x # Lookup reverse IPs for all remote hosts in web server log without for loop.

[[[onlyf]]]ls -l | grep -v ^d # List out files in the current directory, but exclude the entries for directories.

[[[lldir]]]ls -ld */ # Show a long listing (-l) of directories only (put / at end of wildcard) and list only the directories, not the contents (-d)

[[[digmail]]]dig +short MX example.com # Show the mail servers that are designated to receive e-mail addressed to example.com.

[[[dfstype]]]df -T # Normal df output, but also show the type of filesystem that the partition is using.

[[[cgrepfile]]]grep --color=auto pattern file # grep for pattern in file and highlight the matches using a different color.

[[[lslines]]]ls -1 # Using the -1 argument to ls will list files in a plain format one per line. Can be useful alone or in pipes to other commands.

[[[cron5]]]man 5 crontab # Go directly to the crontab man page that is in chapter 5 of the unix manual pages. Some topics have multiple man pages.

[[[basedemo]]]basename /var/www/html/images/logo.png .png # basename strips the directory prefix and in this case the .png suffix. outputing just "logo"

[[[flowblok]]]echo test | rev | cut -c 2- | rev # Use rev twice to get around limitation of cut not being able to truncate end of a string. For .@flowblok

[[[f20to40]]]cut -c 20-40 file # Read in a file and print out only the 20th through 40th character columns in the text.

[[[dushc]]]du -shc */ # Show space usage of directories only, and sum up the total space for all these directories at the end in human readable form.

[[[sillyrube]]]sudo echo "Meow" | nice cat | tail | strings | grep -v Mouse | more # Complete sillyness. Like a CLI Rube Goldberg machine

[[[whattty]]]tty # Find out what tty/pts device you are on. For instance, you can send data to a TTY with echo Hello > `tty`

[[[dispnode]]]df -i # On Linux and others, display the inodes used per filesystem. Useful for determining how long it takes to backup or search the fs.

[[[countree]]]for i in */ ; do echo -n "$i " ; find $i | wc -l ; done # Display the number of files located in each subdirectory tree.

[[[sdpkg]]]dpkg -S /usr/bin/xxd # Debian/Ubuntu and apt based systems. Use dpkg to find out what package owns /usr/bin/xxd.

[[[qfrpm]]]rpm -qf /usr/bin/xxd # Redhat/rpm based systems. Use rpm to find out what package owns /usr/bin/xxd. Can be used with any packaged file.

[[[lutnetstat]]]netstat -lut # On Linux, show all the tcp and udp ports that a system is listening on. As root, use the -p option to get program names.

[[[recvnet]]]while true ; do X=$( ifconfig eth0|grep "RX by"|sed 's/^.*RX bytes:\([0-9]\+\).*/\1/' );Z=$(( $X-$Y ));Y=$X;echo $Z;sleep 1;done # net recv

[[[dflnnet]]]df -l # Print out the local partitions, no network ones. Useful if you have an network share acting up.

[[[calc25000]]]python -c "print 2**5000" # Other than a language, python makes a nice fast arbitrary precision calcuator.

[[[dig12356]]]dig +short -x 198.182.196.56 # Lookup the reverse DNS name for the IP 198.182.196.56 using dig. +short is optional, makes less output.

[[[whichls]]]which ls # Display the path or location from which the command ls is being run. Important to check sometimes if you suspect something.

[[[mansound]]]man -k sound # Search the man pages for any description containing the word sound. Requires that man pages are indexed first.

[[[lddphp]]]ldd /usr/bin/php # On Linux, show the dynamic libraries that an executable (like php) was compiled against. Helpful when program no workie.

[[[longgrep2]]]grep -R "pattern" * 2> /dev/null # Grep through all files and subdirectories, but send errors to /dev/null using 2> stderr redirect.

[[[helloworld]]]find / -perm -o+w -a -not -type l -ls # Find files and directories on the system that are world writable. Exclude symbolic links.

[[[progread]]]head -2 program.pl | hexdump -c # Look at the two first lines of file program.pl and print each character including newlines, tabs, etc.

[[[rndfile]]]nl -ba file | sort -R | sed 's/.*[0-9]\t//' # Add line numbers to make each line unique, then random sort, then remove the line number.

[[[numlines]]]nl -ba file # Number all lines of a file, including blank ones. By default, nl doesn't number blank lines. -ba stands for body all

[[[ezrndfile]]]sort -R file # Randomly order the lines of a file. Only works if the lines of the file are unique, otherwise it puts same lines sequentially

[[[login20]]]last -da -20 # Show the last 20 login sessions on the system. -da is good to use if you care about the remote host column.

[[[csvnf]]]awk -F, {'print NF'} file.csv # Print the number of fields per line in a CSV file. -F could be any seperator of course.

[[[0131]]]seq -w 1 31 #Generate numbers 1 to 31 and use leading zeros for 1 through 9 (-w option). Useful when using output for use in grepping logs.

[[[imgaccess]]]egrep -e "GET /[^\ ]*.(jpg|png|gif) " access_log | awk '{sum+=$10} END {print sum}' #Dipslay total bytes transfered for images on website

[[[12letter]]]awk {'if (length($0) >= 12) {print}'} /usr/share/dict/words #Show all words in your local words list that are 12 characters or longer.

[[[oddlines]]]awk 'NR % 2 == 1' data #Print the odd numbered lines of the file data. line 1, line 3, line 5, etc. if you don't know what odd means.

[[[evenlines]]]awk 'NR % 2' data #Print the even numbered lines of the file called data. line 2, line 4, line 6, etc. if you don't know what even means.

[[[uniqhosts]]]netstat -t | grep ESTABLISHED | awk {'print $5'} | awk -F: {'print $1'} | sort | uniq #show unique hosts you are currently connected to.

[[[rtreeproc]]]pstree #Similar to ps auxwf, but this is a different program with different options.

[[[treeproc]]]ps auxwf # Display the process table in a nice tree view so that you can easily see what the parent processes are.

[[[pricron]]]crontab -e #On systems that allow users to have a crontab, the -e option lets you edit it.

[[[followmsg]]]tail -f /var/log/messages #Display the last few lines of the system messages fail and continue to update the output in real time.

[[[whatshel]]]echo $SHLVL # This variable will be greater than 1 if you are in a shell within a shell or within a chroot environment that you created.

[[[longgrep]]]grep -r -l "what you searching for" . #Show the filenames of files in the current directory and below containing "what you searching for"

[[[wclength]]]echo -n "measure the length of this text" | wc -c #Print out the number of characters in a string. The -n option omits the default newline.

[[[commatogether]]]cat file | tr "\n" "," | sed 's/,$/\n/' #Turn multiple lines of a file into 1 line seperated by commas and fix the trailing comma.

[[[golowercase]]]echo DOMAINNAME.COM | tr A-Z a-z #translate the letters in DOMAINNAME.COM from uppercase to lowercase. Can be used for any string of course.

[[[commdemo]]]comm -12 <(sort file1) <(sort file2) #Determine what lines two different files have in common. The comm program requires sorted files.

[[[newyears]]]while V=$((`date +%s -d "10-01-01"`-`date +%s`));do if [ $V == 0 ];then figlet 'Happy New Year!!';break;else figlet $V;sleep 1;clear;fi;done

[[[countnewyears]]]while true ; do figlet $(( $( date +%s -d 2010-01-01 ) - $( date +%s ) )) ; sleep 1 ; clear ; done #asciiart countdown to new years. !linux

[[[cupcount]]]alias coffee='VALUE=$( cat ~/.cupsocoffee ) ; VALUE=$(( $VALUE + 1 )); echo $VALUE > ~/.cupsocoffee ; echo $VALUE' #make your own counter

[[[ncdemo]]]nc -q1 -lvp 1234 < file.txt #poor man's fileserve. Use nc remotehostname 1234 > output.txt to retreive file from remote host.

[[[20largest]]]find ~/ -mindepth 2 -type f -ls | sort -n -r -k 7 | head -20 #show the 20 largest files located in subdirectories and lower of your homedir.

[[[whynoteject]]]lsof /media/cdrom #Show which programs are using the cd-rom drive mountpoint. Useful when you can't eject it due to it being "busy".

[[[snows]]]while true ; do NUM=$(( $RANDOM % 80 )) ; for i in $( seq 1 $NUM ) ; do echo -n " " ; done ; echo \* ; done #snow storm in your terminal

[[[shajp]]]shasum *.jpg | awk {'print $1'} | sort | uniq -c | grep -v " 1 " #Find out if any duplicate image files exist in the current directory.

[[[dfpo]]]df -P #Use the -P option when you don't want long devicenames to break the partition info across two lines.

[[[gugnews]]]echo -e "GET / HTTP/1.0\nHost: news.google.com\n" | nc news.google.com 80 | html2text #GET news without browser. extra \n at end required

[[[nonal]]]\ls #run the non-aliased version of ls. Putting a \ in front of a command name will bypass any aliases of the same name.

[[[gmtclock]]]TZ=GMT xclock #display the time in xclock, but use the GMT timezone. This works for almost any program and timezone, not just xclock and GMT

[[[vconfhttpd]]]egrep -v "^#|^$" httpd.conf #display the httpd.conf file contents and exclude blank lines and lines that start with comment character.

[[[file80]]]cat file | cut -c 1-80 #trim output data width to 80 characters per line.

[[[scanachosts]]]for i in `seq 1 254` ; do ping -W1 -c 1 10.0.0.$i > /dev/null && echo 10.0.0.$i ; done #scan network 10.0.0.0 for active hosts

[[[soflist]]]ls -ltraSh | grep -v ^d #size ordered listing of files, excluding directory entries

[[[suds]]]du -sh */ #space usage of directories only

"""[3:] # completes giant multiline data string and removes first "[[["

global ye, gr, vi, cl
ye = "\x1b[1;33m" # yellow
gr = "\x1b[1;32m" # green
vi = "\x1b[1;35m" # violet
cl = "\x1b[0m\x1b[1;37m" # clear (reset)

def ckdirect(c, multi):
    multi=multi.split("[[[")
    for lns in range(0,len(multi)):
        title = gettitle(multi[lns])
        datas = getdatas(multi[lns])
        if title == c:
            return (datas)
    return ("echo " + "\" " + c + 
    " not found, going to next line\"")  

def about():
    print
    print gr + " climagic tribute (v. 0.1) - 2010 openuniverse" 
    print cl + " featuring commandline examples from http://identi.ca/climagic"
    print  
    print ye + " this program was going to be less interactive and more",
    print "invasive... it\n was a fun project in python, which i've been",
    print "using for less than a year,\n you know. i hope you will enjoy",
    print "either using and/or improving this\n program, and i certainly",
    print "hope @climagic will too." 
    print cl
    print " what it does" 
    print ye 
    print " what the program does is show you various bash/ash/zsh command",
    print "line\n examples, and allow you to run the examples (usually,) from",
    print "python... \n search, randomize the list, loop through, or type",
    print "the command names (it's\n not really a command interpreter...) if",
    print "you know them already. if you\n like the code, why not copy/paste", 
    print "it into bash?" + cl + "\n\n this early version (0.1,) includes",
    print "140 commandline tips. happy hacking!\n"

def moreinfo():
    print ye 
    print " moreinfo\t-\t" + gr + "this help section"
    print ye 
    print " [enter]\t-\t" + gr + "skip to the next trick"
    print ye 
    print " run\t\t-\t" + gr + "try out the code"
    print cl 
    print " if you know the name: \t" + ye + "just type it"
    print ye 
    print " about\t\t-\t" + gr + "about climagic tribute"
    print ye 
    print " find query\t-\t" + gr + "search tips for [query]"
    print ye 
    print " rnd\t\t-\t" + gr + "shuffle the list of tips"
    print ye 
    print " quit\t\t-\t" + gr + "quits the program immediately"
    print cl

def gestalt(title, cli, comments):
    #global ye, gr, vi, cl
    gestalt = ye # start with yellow
    gestalt += title + ":\n"
    gestalt += "\x1b[44;32m" + cli # green command
    gestalt += vi + comments + cl # violet comments, reset
    return gestalt

def gettitle(ttl):
    return ttl.split("]]]")[0]
def getdatas(dts):
    return dts.split("]]]")[1].rstrip()

def getcli(cli):
    return cli[:cli.rfind("#")]
def getcomments(cms):
    return cms[cms.rfind("#"):]

# multiline entries follow this form: [[[title]]]datas
# datas follow this form: cli #comments
# to parse, all title]]]datas lines are split: title, datas
# then cli, #comments are split from datas along rightmost "#"

def central(multi):
    # "[[[" forms the beginning of every line (except 1) of the multiline
    multi=multi.split("[[[")
    for lns in range(0,len(multi)):
        ##
        ## parse multiline
        title = gettitle(multi[lns])
        datas = getdatas(multi[lns])
        cli = getcli(datas)
        comments = getcomments(datas)
        ##
        ## user input 
        print ; print gestalt(title, cli, comments)
        message = "type: moreinfo, quit, or hit [enter] for the next trick - " 
        try:
            c = raw_input(message + ye).strip().lower()
        except KeyboardInterrupt:
            print "\x1b[0m\n\n" ; quit()
        print cl,
        ##
        ## function output
        if c.find("quit") != -1:
            print ; return (title, datas, "quit")
        elif c.find("run") != -1:
            print ; system(datas) ; system("echo -e \"\e[0m\"")       
        elif c.find("about") != -1:
            about()
        elif c.find("moreinfo") != -1:
            moreinfo()
        elif c[:4] == "find":
            return (title, datas, c)           
        elif c == "rnd":
            return (title, datas, "random")
        elif c != "":
            c = ckdirect(c, q)
            print ; system(c) ; system("echo -e \"\e[0m\"")
        else:
            print
    return (title, datas, "loop")  
    
# meta
bq = q ; rflag = 0 #to restore from search
while 1:
    (title, datas, c) = central(q) 
    if rflag == 1: q = bq ; rflag = 0 # restore q
    # data goes in as q, yields title, 1 loc, mode
    if c == "quit":
        print "\x1b[0m"
        break
    elif c[:4] == "find":
        if len(c.strip()) < 6:
            c == ""
        else:
            c = c[5:].strip()
        q=q.split("[[[") ; sr = [] # split q
        # copy each line in multi that includes query -> sr 
        for srch in q:
            if c.lower() in srch.lower(): sr += [srch] 
        q = bq.split("[[[")[:2] # make certain a list is returned
        if sr != [] : q = sr # change only if sr contains finds
        q="[[[".join(q) # rejoin finds to q 
        rflag = 1 ; sr = []
        print
    elif c == "random":
        q=q.split("[[[")
        shuffle(q)
        q="[[[".join(q)
        print
    elif c == "loop":
        print
        print " \x1b[30;47mreached end of list, returning to top\x1b[0m"
        print
    elif c.find("about") != -1:
        about()
    elif c.find("moreinfo") != -1:
        moreinfo()
