A Common Hades

iPhone and Linux

Monday, September 6, 2010

Over 100 million language files deleted?

Over at xsellize.com, the user lll2for3lll, who posted the language file script there and zipped it for download, reported that the long version has been downloaded 2,834 times and the short version 3,421 times, for a total of 6,255 downloads from the xsellize forum alone. I think that only counts the latest version that was uploaded there in March.

I've also had 15,000 hits to that one page on this blog. Then there are people who have gotten it from other forums, the two or three places where it's been translated into other languages and the people who tell me they've ran it on 30 phones.

So I'll add a conservative 5,000 people who have downloaded and used the script through means other than xsellize.

Users usually report that the script deletes 4,000 to 5,000 language directories, but I'll use a more conservative figure of 3,500 because I never had a lot of apps installed and that's what it deleted on mine.

So from those stats, I'm going to go out on a limb and say that I'm responsible for deleting over 40 million directories from iPhones all over the world.

If I remember correctly, there are usually anywhere from two to five or more files in those directories. If we assume a conservative 2.5 files per directory, that's 100 million files.

I'm like a virus.

In reality, I just wrote a script that a few thousand people used, which isn't a big deal, but it's kind of humbling to think I did 100 million of anything. If I had a dollar for every file deleted...

Sunday, April 11, 2010

N1 Blog

For anyone who may be interested, I've finally started a blog for the Nexus One called A More Common Hades.

Friday, March 19, 2010

Nexus One

I did it. I bought a Nexus One. I've only had a few minutes to play with it so far and my initial impression of the interface is that it makes the iPhone feel clunky and boring. I don't know if it will be an iPhone killer, but there's a lot to like about this phone.

I plan to continue this blog because I enjoy hacking around on the iPhone. I'll probably start a different blog for the N1.

Taken with my iPhone. I'm going to go out on a limb and say the N1's 5MP camera with flash could probably have done better than my old 3G.

Thursday, March 18, 2010

Script for looking up language codes

Shhh, don't tell anyone but I've made a secret post. It's a simple script to look up language codes, but it's 1100 lines long. The script is one simple grep command, the other 1100 lines are just languages and codes.

I made the post date Jan 1 2009 so it would go straight to the archive and not take up the front page. It can be found here.

It may be useful to anyone running my iPhone language deleting script who runs across an unknown language code.

Wednesday, March 3, 2010


Another simple script to replace the missing whereis command on the iPhone.
#! /bin/sh
ls /usr/bin/$1 2>/dev/null
then echo >/dev/null
ls /usr/local/bin/$1 2>/dev/null
then echo >/dev/null
ls /usr/sbin/$1 2>/dev/null
then echo >/dev/null
ls /sbin/$1 2>/dev/null
then echo >/dev/null
ls /bin/$1 2>/dev/null
then echo >/dev/null
echo "$1 not found in /bin /sbin /usr/bin /usr/sbin /usr/local/bin"
Too bad an if statement needs a then statement to go with it. Since ls has it's own output, there's no reason to duplicate it so it's easier to use the ls output and do an empty then command. The result works, but it just looks dumb. Here's a shorter version. It will list all the files. If any are not found, the error goes to /dev/null.
#! /bin/sh
ls /usr/bin/$1 /usr/local/bin/$1 /usr/sbin/$1 /sbin/$1 /bin/$1 2>/dev/null
But that won't give you a "not found" message. So let's take that and put it in a variable. If the variable is not empty, it will echo the variable, which is the non-error output from the ls command. If it ends up empty, the -n test will fail so the && command is skipped and the || command executes.
#! /bin/sh
test=$(ls /usr/bin/$1 /usr/local/bin/$1 /usr/sbin/$1 /sbin/$1 /bin/$1 2>/dev/null)
[ -n "$test" ] && echo $test || echo "$1 not found in /bin /sbin /usr/bin /usr/sbin /usr/local/bin"

Sunday, February 28, 2010

Whatis it, man?

The "man" command is used to read UNIX manual pages and "whatis" gives you a brief description of a command taken from the NAME field of the man page. The iPhone lacks both commands, but these work ok.

#! /bin/sh
links -dump http://unixhelp.ed.ac.uk/CGI/man-cgi?${1} | grep -A 1000 NAME | sed 's/^[ \t]*//'
I actually like that because it's easier to grep the output, but adding a pipe to "less" more accurately approximates the real command. You could probably roll the grep into the sed command, but that's one of those things where I don't mind spending an extra one-thousandth of a second execution time to keep from having to craft a better sed one-liner.

#! /bin/sh
links -dump http://unixhelp.ed.ac.uk/CGI/man-cgi?${1} | grep "\- " | head -1 | sed 's/^[ \t]*//'
Let's test it.
# whatis ifconfig
ifconfig [] (8) - configure a network interface
# ./my_whatis ifconfig
ifconfig - configure a network interface
Close enough.

Wednesday, February 24, 2010

How pretty

I've never fooled around with colors in the shell before.

#! /bin/sh
echo "Colors:"
tput setaf 0; echo "Black = tput setaf 0 $(tput sgr0) <--- that was black (tput setaf 0)"
tput bold ; tput setaf 0; echo "DarkGrey = tput bold ; tput setaf 0" ; tput sgr0
tput setaf 7; echo "LightGrey = tput setaf 7" ; tput sgr0
tput bold ; tput setaf 7 ; echo "White = tput bold ; tput setaf 7" ; tput sgr0
tput setaf 1 ; echo "Red = tput setaf 1" ; tput sgr0
tput bold ; tput setaf 1 ; echo "LightRed = tput bold ; tput setaf 1" ; tput sgr0
tput setaf 2 ; echo "Green = tput setaf 2" ; tput sgr0
tput bold ; tput setaf 2 ; echo "LightGreen = tput bold ; tput setaf 2" ; tput sgr0
tput setaf 3 ; echo "Brown = tput setaf 3" ; tput sgr0
tput bold ; tput setaf 3 ; echo "Yellow = tput bold ; tput setaf 3" ; tput sgr0
tput setaf 4 ; echo "Blue = tput setaf 4" ; tput sgr0
tput bold ; tput setaf 4 ; echo "LightBlue = tput bold ; tput setaf 4" ; tput sgr0
tput setaf 5 ; echo "Purple = tput setaf 5" ; tput sgr0
tput bold ; tput setaf 5 ; echo "Pink = tput bold ; tput setaf 5" ; tput sgr0
tput setaf 6 ; echo "Cyan = tput setaf 6" ; tput sgr0
tput bold ; tput setaf 6 ; echo "LightCyan = tput bold ; tput setaf 6" ; tput sgr0
tput sgr0 ; echo "Normal = tput sgr0" ; tput sgr0
echo "Backgrounds:"
tput setab 0 ; echo -n "BlackBG = tput setab 0" ; tput setab 0 ; echo
tput setab 7 ; tput setaf 0; echo -n "LightGreyBG = tput setab 7" ; tput sgr0 ; tput setab 0 ; echo # used black text
tput setab 1 ; echo -n "RedBG = tput setab 1" ; tput setab 0 ; echo
tput setaf 0 # switch to black text for these
tput setab 2 ; echo -n "GreenBG = tput setab 2" ; tput setab 0 ; echo
tput setab 3 ; echo -n "BrownBG = tput setab 3" ; tput setab 0 ; echo
tput setab 4 ; echo -n "BlueBG = tput setab 4" ; tput setab 0 ; echo
tput setab 5 ; echo -n "PurpleBG = tput setab 5" ; tput setab 0 ; echo
tput setab 6 ; echo -n "CyanBG = tput setab 6" ; tput setab 0 ; echo
tput sgr0 # back to normal text

Monday, February 22, 2010

Final script for deleting iPhone language packs

This will probably be the final script for deleting language packs on the iPhone. As I have said before, it is a pain to keep up with the ever-changing languages. This started out as a script I threw together in an hour or two just because I was curious if I could write a self-referential script that listed the languages and allowed people to pick the ones to remove, but has become something popular that needs maintaining, and the developers who create the language packs don't seem to have any guidelines for naming them. As the languages changed, the older script got longer and asked the user more and more questions. This one changes that and makes it easier for me to maintain.

Although many things look the same, this version has many changes. There are some performance improvements, although they may not be evident since it's an interactive script. It will also end itself if it doesn't find anything to delete and, overall, it just "flows" better.

The most noticeable improvement is the interaction with the user. It will only ask about the languages which it finds on the system and it will only ask once for each language. So if it finds 6 differently named Spanish directories and 2 Germans, it will only ask if you want to delete Spanish and German. The user no longer has to answer yes or no for every single code for every single language.

It has 35 languages built in because that's what Apple says the iPhone supports, but most people won't have that many installed. I've included every language code I've found over the past couple of months for those 35 languages as well as every possibility a total of 270. It will also present unrecognized languages to the user if that language is not found in those 270.

I will no longer maintain my original script as this one does everything that one did and does it in a way that is less hassle for the user.

After this is out for a week or two and I make sure there aren't any bugs in the script, I'm considering my foray into iPhone languages finished. I will update this script with new languages and it would help greatly if people send me their log files (the info is in the script) but I simply don't have the time to do anything more.

My stripped down version for deleting everything except English will never be obsolete (unless Apple changes how languages are used) and, if that's the only language you want, would be simpler to use and will remove every language except English whether it is recognized or not.

Jailbroken iPhone/iTouch OS 3.x. Or 4.x. Several users have recently used this successfully on OS 4.0.

This script uses basic BASH shell builtins and unix core utilities. Both are installed by default when you install MobileTerminal on the iPhone. It's possible that you can install them separately, I don't know, but I suggest installing MobileTerminal and also recommend using MobileTerminal to execute the script and iFile to get the script on the phone.

I would love to use more powerful tools like sed or awk and cut this script down to a fraction of the length, but I'd rather have it use minimal dependencies.

How to use.
View this page on your iPhone.

Copy everything from "#! /bin/sh" to "# end of script"

If you have Safari downloading enabled on your phone, click here and download it directly to your phone. (having trouble with mediafire, please redownload if you downloaded in the past few minutes)

Or, create a new text file on the phone with iFile. You can name it anything, but I will use langpack2.sh as an example. You can do this anywhere, but for simplicity, I suggest creating it in /var/mobile (a.k.a. /private/var/mobile)

Paste the script into the text file and save it.

Open MobileTerminal, cd to the directory where langpack2.sh is located and type chmod 755 langpack2.sh and hit enter, then type ./langpack2.sh to run it.

There are other ways to do this but I'm a Linux guy and I don't have a Mac and use Windows about twice a year so I can't recommend anything else.

Windows can screw up the formatting of the text if it isn't transferred to the phone a certain way and I'm not going to research how to do it. I've never touched a Mac, so I can't help there either. One thing we all have in common is the phone and the two iPhone apps iFile and MobileTerminal are the recommended way to run this script. Using this method, it can be downloaded and executed while you're walking down the street, no computer needed.

Linux users should have no problem saving it on their computer, ssh'ing it to the phone and running it there. I did most of the testing in a Linux terminal with ssh, but MobileTerminal is still the one foolproof way to run it.

Another method to get this script using nothing but the phone is to install lynx from Cydia then run this command:
lynx -width=500 -dump http://tinyurl.com/356wmua | grep -B 182 "end of script$" > langpack2.2.sh
That will grab the text from this page and put it in the file called langpack2.2.sh.

You may also be interested in this script for identifying unrecognized language codes.

(May 17) I've gotten some hits from a couple of sites which have translated the text of the script to German and Hungarian, which may be useful for anyone speaking those languages.

(Dec 29 2010) Several users have reported that the script fails to recognize vi.lproj. This is Vietnamese and can be deleted if you don't need Vietnamese. The script looks for vi.lproj and worked fine for months, but started missing it all of a sudden. My iPhone is a gaming device for my daughter and is still on 3.1 and I have no plans to update it to the latest firmware so I will probably never fix this problem.

Creative Commons License
Langpack2 by Fubaya is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License.
Based on a work at a-common-hades.blogspot.com.
#! /bin/sh
# Apr 15 2010
# Langpack2 by Fubaya. Licensed under CC "by-nc-nd"
# more info: http://creativecommons.org/licenses/by-nc-nd/3.0/us/

##### root test #####
# won't go any farther unless you're uid=0
[ `id -u` != 0 ] && exec echo "Oops, you need to be root to run this script"

##### hello, get ready, search for languages #####
clear; echo -e "\n\n--Langpack2- by Fubaya ($(echo 'ijdqas@gqail.coq' | tr q m))--
--http://a-common-hades.blogspot.com--\n" | tee langpack.log
echo -e "Let's delete a few thousand language packs.
You will have several chances to back out
before anything is deleted but if you want
to stop at any time just type $(tput bold; tput setaf 3)q$(tput sgr0).\n
If you want to see how it runs without
making any changes, just answer no when it
asks you which languages to delete.\n
Searching for language packs. Please wait...\n"

# set interrupt to "q"
tset -Q -i q

# clear out old temp files, if any, create new
rm -f .*_fubaya; touch {.alllist,.langlist,.deletelist,.rmlist,.yeslist}_fubaya

# update database, search for lproj, grep directories,
# filter out english, filter out strange "Scanner911" app languages, put rest in alllist
updatedb && locate lproj | grep -E lproj$ | grep -v -i -E '(English|\/en|.en.l|blue.lproj|camo.lproj|classic.lproj|desert.lproj|modern.lproj)' > .alllist_fubaya

# make sure alllist isn't empty, get basename of files, grep again just to be sure they're directories
# sort and get uniq names and now we have a list of all unique languages on the phone.
[[ -s .alllist_fubaya ]] && cat .alllist_fubaya | xargs -n1 basename | grep -E lproj$ | sort | uniq > .langlist_fubaya
##### end section #####

##### core function #####
# process languages, ask user to delete
language ()
# $* is all arguments to the "language" lines. If any of those appear in langlist...
if echo $* | grep -q -i -f .langlist_fubaya

# then start a loop to require yes or no
while [[ "$choice" != 'y' ]] && [[ "$choice" != 'n' ]]

# ask "delete the first argument, yes or no?"
do read -p "Delete: $(tput bold; tput setaf 3)${1%.*}$(tput sgr0) - y or n? " choice; done

# if yes
if [ $choice = "y" ]
# put that language's formal name in yeslist
echo ${1%.*} >> .yeslist_fubaya

# put that language's whole line in rmlist, replacing spaces with newlines
echo $* | tr ' ' '\n' >> .rmlist_fubaya

# confirm the choice
echo "${1%.*} will be deleted";

# if no, echo (that language's formal name) will be kept
else echo "${1%.*} will be kept"; fi

# log the language and choice
echo "known $1: $choice" >> langpack.log

unset choice # clear the variable because I'm too lazy to use a new one
echo # spacer

language Albanian.lproj alb.lproj sqi.lproj sq.lproj sq-sq.lproj sq_sq.lproj sq_al.lproj sq-al.lproj
language Amharic.lproj amh.lproj am.lproj am-am.lproj am_am.lproj
language Arabic.lproj ara.lproj ar.lproj ar-ar.lproj ar_ar.lproj ar_eg.lproj ar_sa.lproj
language Armenian.lproj arm.lproj hye.lproj hy.lproj hy_hy.lproj hy-hy.lproj
language Bulgarian.lproj bul.lproj bg.lproj bg_bg.lproj bg-bg.lproj
language Catalan.lproj ca.lproj cat.lproj ca_ca.lproj ca-ca.lproj ca_es.lproj
language Chinese.lproj chi.lproj zho.lproj zh.lproj zh-zh.lproj zh_zh.lproj zh-hans.lproj zh_hans.lproj zh-hant.lproj zh_hant.lproj zh_cn.lproj zh-cn.lproj zh-hk.lproj zh_hk.lproj zh-tw.lproj zh_tw.lproj
language Croatian.lproj hrv.lproj hr.lproj hr-hr.lproj hr_hr.lproj
language Czech.lproj cze.lproj ces.lproj cs.lproj cs-cs.lproj cs_cs.lproj cs-cz.lproj cs_cz.lproj cz.lproj cz_cz.lproj cz-cz.lproj
language Danish.lproj dan.lproj da.lproj da-da.lproj da_da.lproj da_dk.lproj da-dk.lproj
language Dutch.lproj dum.lproj dut.lproj nld.lproj nl.lproj nl-nl.lproj nl_nl.lproj
language Estonian.lproj est.lproj et.lproj et_ee.lproj et-ee.lproj
language Finnish.lproj fin.lproj fi.lproj fi-fi.lproj fi_fi.lproj
language French.lproj fra.lproj fre.lproj fr.lproj fr-fr.lproj fr_fr.lproj fr_ca.lproj fr-ca.lproj fr_fr.lproj fr-fr.lproj
language German.lproj deu.lproj ger.lproj de.lproj de-de.lproj de_de.lproj
language Greek.lproj gre.lproj ell.lproj el.lproj el-el.lproj el_el.lproj el_gr.lproj el-gr.lproj gr_el.lproj gr-el.lproj
language Gujarati.lproj guj.lproj gu.lproj gu_in.lproj
language Hebrew.lproj heb.lproj he.lproj he-he.lproj he_he.lproj he_il.lproj he-il.lproj hi_in.lproj hi-in.lproj
language Hindi.lproj hin.lproj hi.lproj hi_hi.lproj hi-hi.lproj
language Hungarian.lproj hun.lproj hu.lproj hu-hu.lproj hu_hu.lproj
language Icelandic.lproj ice.lproj isl.lproj is.lproj is_is.lproj is-is.lproj
language Indonesian.lproj ind.lproj id.lproj id-id.lproj id_id.lproj
language Iranian.lproj ira.lproj fa.lproj per.lproj fa_ir.lproj fa-ir.lproj fa-fa.lproj
language Italian.lproj ita.lproj it.lproj it-it.lproj it_it.lproj
language Japanese.lproj ja.lproj ja-ja.lproj ja_ja.lproj ja_jp.lproj ja-jp.lproj jp_jp.lproj jp-jp.lproj jpn.lproj
language Korean.lproj kor.lproj ko.lproj ko-ko.lproj ko_ko.lproj
language Latvian.lproj lav.lproj lv_lv.lproj
language Lithuanian.lproj lit.lproj lt.lproj lt-lt.lproj lt_lt.lproj
language Macedonian.lproj mk.lproj mac.lproj mk_mk.lproj mk-mk.lproj
language Malay.lproj may.lproj ms.lproj ms-ms.lproj ms_ms.lproj ms_my.lproj
language Norwegian.lproj nor.lproj nob.lproj nno.lproj nn_nn.lproj nn-nn.lproj no.lproj no-no.lproj no_no.lproj nb.lproj nb_nb.lproj nb-nb.lproj no_nb.lproj no-nb.lproj nb_no.lproj nb-no.lproj nn_no.lproj nn-no.lproj nn_nb.lproj nn-nb.lproj nb_nn.lproj nb-nn.lproj
language Panjabi.lproj pa.lproj pan.lproj pa_pa.lproj pa-pa.lproj pa_in.lproj pa-in.lproj
language Polish.lproj pol.lproj pl.lproj pl-pl.lproj pl_pl.lproj
language Portuguese.lproj por.lproj pt.lproj pt-pt.lproj pt_pt.lproj pt-br.lproj pt_br.lproj
language Romanian.lproj rup.lproj rum.lproj ron.lproj ro.lproj ro-ro.lproj ro_ro.lproj
language Russian.lproj rus.lproj ru.lproj ru-ru.lproj ru_ru.lproj
language Serbian.lproj sr.lproj sr-sr.lproj sr_sr.lproj sr_rs.lproj
language Slovak.lproj slk.lproj slo.lproj sk.lproj sk-sk.lproj sk_sk.lproj
language Slovenian.lproj slv.lproj sl.lproj sl-sl.lproj sl_sl.lproj sl_si.lproj sl-si.lproj
language Spanish.lproj spa.lproj sp.lproj sp-sp.lproj sp_sp.lproj es.lproj es_es.lproj es-es.lproj es_mx.lproj es_us.lproj es_419.lproj
language Swedish.lproj swe.lproj sv.lproj sv-sv.lproj sv_sv.lproj sv-se.lproj sv_se.lproj
language Thai.lproj tha.lproj th.lproj th-th.lproj th_th.lproj
language Turkish.lproj tur.lproj tr.lproj tr-tr.lproj tr_tr.lproj
language Ukrainian.lproj ukr.lproj uk.lproj uk_uk.lproj uk-uk.lproj uk_ua.lproj uk-ua.lproj
language Vietnamese.lproj vi.lproj vn.lproj vi-vi.lproj vi_vi.lproj vn-vn.lproj vn_vn.lproj vi_vn.lproj vi-vn.lproj vn-vi.lproj vn_vi.lproj
##### end section #####

##### look for unrecognized languages #####
# for every entry in langlist
for i in $(cat .langlist_fubaya)
# if that lproj doesn't appear in this script
if ! cat $0 | grep -q -i $i

# start a loop to require yes or no
while [[ $choice != 'y' ]] && [[ $choice != 'n' ]]; do

# ask "delete that unrecognized language pack, yes or no?"
read -p "Delete: $(tput bold; tput setaf 3)${i}$(tput sgr0) (unrecognized) - y or n? " choice

# if yes, confirm and put it in rmlist and yeslist
if [ $choice = "y" ]; then echo "$i will be deleted"
echo $i | tee -a .rmlist_fubaya .yeslist_fubaya > /dev/null

# if no, confirm
else echo "${i} will be kept"; fi

# log language and choice
echo "unknown: $i $choice" >> langpack.log
unset choice
##### end section #####

##### finalize, confirm or quit #####
# use rmlist to extract all directories to be deleted from alllist, put them in deletelist
grep -i -f .rmlist_fubaya .alllist_fubaya > .deletelist_fubaya

# if that failed, it's because there's nothing to delete. Dump out.
[ "$?" -ne "0" ] && rm -f .*_fubaya && exec echo "
Nothing to delete. Either I didnt find
any to delete or you answered no to
everything. See ya later."

# otherwise, display all languages that are going to be deleted
echo -------------------------------------
tput bold; tput setaf 3; tr '\n' ' ' < .yeslist_fubaya
echo; tput sgr0
echo -------------------------------------
unset choice

# start a loop to require yes or no, ask to final confirmation
while [[ "$choice" != 'y' ]] && [[ "$choice" != 'n' ]]; do
echo "This is your last chance. Are you sure
you want to delete the languages listed?"
read -p "Type y or n: " choice
##### end section #####

##### delete, clean up, good-bye #####
# if yes
if [ $choice = "y" ]

# say "please wait" and loop through deletelist file, removing directories
echo -e "Please wait while I delete the chosen language packs...\n"
while read file
do rm -rf "$file"
done < .deletelist_fubaya

# count how many directories were in deletelist
num=$(grep -c ^ .deletelist_fubaya)

# remove temp files
rm -f .*_fubaya

# long goodbye
echo -e "$num language pack directories have been
deleted. A log file has been created at
My contact information is at the top of
the log file and if you encountered any
unrecognized languages, I would appreciate
you emailing me that file so that I may keep
up with the ever-changing languages.\n
The only other thing left is me, this
script located at `pwd`/`basename $0`."
read -p "Do you want me to delete myself - y or n? " choice
[ $choice = "y" ] && echo "Deleting myself...blarg.. I'm dead" && exec rm $0
echo "Phwew, Thank you! I'm too young to die. I'll be here at `pwd`/`basename $0` if you need me."
##### end section #####

##### if DONT delete, then clean up and good-bye #####
# if user said no to final confirmation, remove temp file and exit
rm -f .*_fubaya
echo "Ok, I wont delete anything. If you made a mistake, just run me again."
##### end section #####
# end of script

Sunday, February 14, 2010

Using ssh to bypass iPhone's launch timeout on the fly

I don't think this particular method is of much use, but it may be worth knowing in a pinch.

The iPhone has a launch timeout built into the system. When an app launches, it isn't supposed to start processing data right away, it is simply supposed to load whatever it needs then make a C++ call to the system saying it finished launching. This call is aptly named applicationDidFinishLaunching. If the system doesn't get that call, it assumes the app failed to launch and kills it.

The same thing happens when you launch a shell script from a SpringBoard icon. This script will not work:
#! /bin/sh
uiopen start
sleep 10s
uiopen ten
sleep 10s
uiopen twenty
sleep 10s
uiopen thirty
This is meant to pop up a notification every ten seconds but after approximately 18 seconds, the system kills it because it did not receive the applicationDidFinishLaunching call.

Some jailbreak apps have a way around this. I emailed BigBoss a few months ago and asked if he knew of a way around the launch timeout with a script, and he pointed me to the method SBSettings uses. SBSettings does not actually launch itself, it instead uses a small shell script to launch the real SBSettings executable:
SBSettings=$(dirname "$0")
exec "${SBSettings}"/SBSettings
What this does is pretty simple. The script uses the first line to find itself on the system, the second line launches SBSettings, which it expects to find in the same directory. It launches with the exec command, which replaces the current shell with whatever exec executes.

Unfortunately, I had already tried this and could never get it to work with a shell script. I've also tried every other method I could think of to background a script such as using the standard "&" tacked on to the command or trying the disown command. These would probably work in MobileTerminal, but nothing seemed to work when launching a script from SpringBoard.

You may be able to use launchd to run a longer script, but I wanted to do it on the fly. I only had one long script I wanted to use and simply gave up on it and forgot about it until an unlikely answer came to me while working on an unrelated problem. Why not see what happens when you ssh in to localhost and run the script?

Well, you can't simply ssh in and run the command or the ssh pipe will stay open. This is a feature of OpenSSH used to avoid a race condition. To background it, you have to redirect sdtin, stdout and stderr to a file or, as I used here, to /dev/null.
slogin -i ~/.ssh/KEY localhost '/Applications/test.app/test_ </dev/null >/dev/null 2>&1 &'
To my surprise, that actually works. This command can be put in /Applications/test.app/test and launched from SpringBoard. It will then ssh to localhost and successfully launch and background test_, which can run as long as it wants.

Thursday, February 11, 2010

Forum grabber

I use various methods to visit forums. If I'm at my computer, I use a browser, obviously. On my iPhone, I use a forum app named Kaytri a lot, but I visit a couple of forums that have very low thread counts and I thought it would be nice to get a "daily digest" of all the new subjects to see if there is anything interesting.

This can be done pretty easily with links or lynx and their -dump switch, but they both split the subject line and have so much additional output, that it was simpler to start from scratch.

Starting with wget spitting out the raw html in quiet mode, I looked at the code to a couple forums and found that most use "thread_title" in their html, so it's just a matter of grepping "thread_title" and filtering out the tags with sed and (optionally) aligning the text to the left with sed also.
wget -q -O - [FORUM] | grep thread_title | sed -e 's#<[^>]*>##g' -e 's/^[ \t]*//'
One possibility for using this is to get a daily forum update by putting the output in a file, comparing it with an older version, and sending yourself only the new content.
cd /path/to/tmpfile/directory
[wget command] > .b
newcontent=$(cat .b | grep -v -f .a)
# if there is new content, do something with it
# email it to yourself, send a push notification, etc
[ -n "$newcontent" ] && [do something with $newcontent]
mv .b .a
This can be useful for both fast and slow paced forums to watch for new subjects, then you can decide whether to visit them and jump into the argument or not.

Blog Archive