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...
iPhone and Linux
Monday, September 6, 2010
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.
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.
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
whereis
Another simple script to replace the missing whereis command on the iPhone.
#! /bin/shToo 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.
if
ls /usr/bin/$1 2>/dev/null
then echo >/dev/null
elif
ls /usr/local/bin/$1 2>/dev/null
then echo >/dev/null
elif
ls /usr/sbin/$1 2>/dev/null
then echo >/dev/null
elif
ls /sbin/$1 2>/dev/null
then echo >/dev/null
elif
ls /bin/$1 2>/dev/null
then echo >/dev/null
else
echo "$1 not found in /bin /sbin /usr/bin /usr/sbin /usr/local/bin"
fi
#! /bin/shBut 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.
ls /usr/bin/$1 /usr/local/bin/$1 /usr/sbin/$1 /sbin/$1 /bin/$1 2>/dev/null
#! /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.
man:
whatis:
man:
#! /bin/shI 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.
links -dump http://unixhelp.ed.ac.uk/CGI/man-cgi?${1} | grep -A 1000 NAME | sed 's/^[ \t]*//'
whatis:
#! /bin/shLet's test it.
links -dump http://unixhelp.ed.ac.uk/CGI/man-cgi?${1} | grep "\- " | head -1 | sed 's/^[ \t]*//'
# whatis ifconfigClose enough.
ifconfig [] (8) - configure a network interface
# ./my_whatis ifconfig
ifconfig - configure a network interface
#
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
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.
Requirements.
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:
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.

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.
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.
Requirements.
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.shThat 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.
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
# 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" ]
then
# 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
fi
}
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)
do
# if that lproj doesn't appear in this script
if ! cat $0 | grep -q -i $i
then
# 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
done
# 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
fi
done
##### 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
done
##### end section #####
##### delete, clean up, good-bye #####
# if yes
if [ $choice = "y" ]
then
# 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
`pwd`/langpack.log.
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
else
rm -f .*_fubaya
echo "Ok, I wont delete anything. If you made a mistake, just run me again."
fi
##### 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:
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:
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.
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/shThis 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.
uiopen start
sleep 10s
uiopen ten
sleep 10s
uiopen twenty
sleep 10s
uiopen thirty
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")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.
exec "${SBSettings}"/SBSettings
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.
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/directoryThis 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.
[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
Sunday, February 7, 2010
Minimal video encoding for iPhone
There are countless ways of encoding video for the iPhone, but this is the command I normally use. I don't watch many videos on the phone and my goal is usually to create a video with a small size that doesn't strain the system too much to run. A lower bitrate, 20.98 framerate and 320x240 resolution (which is used on the iPod) would be terrible for watching a hi-def movie, but works great for most videos.
The only videos I routinely watch are of The Daily Show, so this little script encodes and renames them from
The.Daily.Show.2010.02.04.Rep.Anthony.Weiner.HDTV.XviD.avi to TDS-02.04.mp4
ffmpeg -i infile -f mp4 -vcodec mpeg4 -b 200k -aspect 4:3 -r 20.98 -s 320x240 -acodec libfaac -ar 48000 outfile
The only videos I routinely watch are of The Daily Show, so this little script encodes and renames them from
The.Daily.Show.2010.02.04.Rep.Anthony.Weiner.HDTV.XviD.avi to TDS-02.04.mp4
#! /bin/shIf you happen to use Prowl and want a notification when it is finished...
for i in `ls *.avi`
do
name=TDS-$(echo $i | cut -c 21-25).mp4
ffmpeg -i $i -f mp4 -vcodec mpeg4 -b 200k -aspect 4:3 -r 20.98 -s 320x240 -acodec libfaac -ar 48000 $name
done
num=$(ls | grep mp4 | wc -l)... or want to transfer them with ssh (using ssh keys):
dir=$(pwd)
url=https://prowl.weks.net/publicapi/add
app="Pod converter"
desc="Finished converting $num Daily Shows in $dir"
curl -k $url -F apikey=XXX -F application=$app -F description=$desc
mkdir mp4sTweak it a bit and you can have a basic method for encoding and automatically syncing your favorite videos while you sleep.
mv *.mp4 ./mp4s
scp -r -i ~/.ssh/SSH_FILENAME /path/to/mp4s mobile@IP:/var/mobile
Sunday, January 31, 2010
Simpler iPhone language pack deletion script
My earlier script is a pain. It works fine but I'm not happy with it because it's too much work keeping up with iPhone developers and their screwy names for the language packs.
For some reason, fr.lproj and French.lproj weren't good enough, so there's some fr_FR.lproj popping up, and not only for French, but a variety of languages. The ISO language code for Spanish is "es," so the language pack should be either "Spanish" or "es," but now I'm seeing "sp", "sp_es" and "es_ES." "Sp" isn't an recognized code for any language.
For a script that essentially greps a list of 60 languages in the old format, I don't want to have to add another 30 to deal with these new names popping up. It's easy to add them to the list, but without rewriting the script, it means the user has to be asked "yes or no" for even more languages.
I never thought it would become a project I had to maintain anyway. I will rewrite it so that it's flexible and can handle new languages on it's own, and to lessen the number of times the user has to say yes to each language, but here is a simpler script to use for the time being.
Since most people want to remove everything except English and Japanese anyway, this simple script will do that. It only asks one question "Do you want to delete everything except English and Japanese?" and if you say yes, it does it. It won't have any problem with new language codes because it gets a list of all languages, filters out English and Japanese and deletes everything that is left. Simple. Almost as simple as my very first post on the subject.
Enjoy.
For some reason, fr.lproj and French.lproj weren't good enough, so there's some fr_FR.lproj popping up, and not only for French, but a variety of languages. The ISO language code for Spanish is "es," so the language pack should be either "Spanish" or "es," but now I'm seeing "sp", "sp_es" and "es_ES." "Sp" isn't an recognized code for any language.
For a script that essentially greps a list of 60 languages in the old format, I don't want to have to add another 30 to deal with these new names popping up. It's easy to add them to the list, but without rewriting the script, it means the user has to be asked "yes or no" for even more languages.
I never thought it would become a project I had to maintain anyway. I will rewrite it so that it's flexible and can handle new languages on it's own, and to lessen the number of times the user has to say yes to each language, but here is a simpler script to use for the time being.
Since most people want to remove everything except English and Japanese anyway, this simple script will do that. It only asks one question "Do you want to delete everything except English and Japanese?" and if you say yes, it does it. It won't have any problem with new language codes because it gets a list of all languages, filters out English and Japanese and deletes everything that is left. Simple. Almost as simple as my very first post on the subject.
Enjoy.
#! /bin/sh
# Thu Feb 4 2010
if [ `id -u` != 0 ]; then echo "Oops, you need to be root to run this script"; exit 0; fi
while [[ $choice != 'y' ]] && [[ $choice != 'n' ]]
do
echo "Do you want to delete all language packs
except English and Japanese (for emoji
keyboards)?
y or n?"
read choice
done
if [[ $choice = 'y' ]]; then
echo "Please wait while I delete the chosen
language packs. This may take a minute
or two..."
updatedb && locate lproj | grep -E lproj$ | grep -v -i ja | grep -v -i English | grep -v -i \/en > .deletelist_fubaya
while read file; do rm -rf "$file"; done < .deletelist_fubaya
num=$(cat .deletelist_fubaya | wc -l)
rm .deletelist_fubaya
echo
echo "$num language pack directories deleted"
fi
[[ $choice = 'n' ]] && echo "Ok, I won't delete anything."; exit 0
# end of script
Friday, January 29, 2010
Copy and paste in MobileTerminal
I've been using this "paste" script for a long time, but put off creating anything to copy as I didn't have much of a need. I finally got interested when it came up on a forum last night. Here is the first draft of working copy and paste.
Both scripts require PasteBaordStacker because, as I have mentioned before, it stores everything as plain text and I've never gotten around to deciphering Apple's PasteBoard.
Paste also requires awk. The awk line may be familiar, it has been so useful it's probably in half the scripts on this blog. Copy uses sed, but I think sed is already installed on a jailbroken iPhone.
Edit Feb 7 2010: added the sed lines to convert the characters <, >, and & which get automatically encoded.
Paste
Copy
Usage:
Paste can be used in a variety of ways, but there are two standard methods that are most useful. 1) You can type "paste" on the command line and it will output the last thing you copied on the system. 2) You can use it in a subshell to paste an argument to another program. Example, copy a link to a file in Safari then type wget $(paste) in Terminal. Since the subshell is executed first, the resulting command that is executed is wget www.example.com/file.txt
Copy is a little rough. Since I used PasteBoardStacker, that means text isn't copied directly into the Apple PasteBoard. You have to select the text in PasteBoardStacker first, which is done by double tapping the status bar, then tapping the text you want from the pop-up list. It takes an extra step but it's still a good way to copy text from Terminal, and other than directing the output to a file, opening it and copying, it's the only way I am aware of. Copy handles piped input so if you run this command: echo "Hello world" | copy, you can then select "Hello world" in PasteBoardStacker and paste into another app.
Copy also requires you to escape some special characters with a backslash. echo "Hello world!" | copy won't work because the shell will try to interpret the exclamation point. echo "Hello world\!" | copy is what you need to use. Edit: D'oh, this was a poor example because it's normal shell behavior and not related to copy, but the sed line in copy still can't handle some characters like "<"without escaping.
Both scripts require PasteBaordStacker because, as I have mentioned before, it stores everything as plain text and I've never gotten around to deciphering Apple's PasteBoard.
Paste also requires awk. The awk line may be familiar, it has been so useful it's probably in half the scripts on this blog. Copy uses sed, but I think sed is already installed on a jailbroken iPhone.
Edit Feb 7 2010: added the sed lines to convert the characters <, >, and & which get automatically encoded.
Paste
#! /bin/sh
file=/var/mobile/Library/Preferences/com.hitoriblog.pasteboardstacker.plist
awk 'BEGIN{ RS="</string>"}{gsub(/.*<string>/,"");print;exit}' $file | sed '
s/</</g
s/>/>/g
s/&/\&/g'
Copy
#! /bin/sh
in=$(cat -)
text=$(echo '<string>'"$in"'</string>')
file=/var/mobile/Library/Preferences/com.hitoriblog.pasteboardstacker.plist
sed -i "7i\\
$text" $file
Usage:
Paste can be used in a variety of ways, but there are two standard methods that are most useful. 1) You can type "paste" on the command line and it will output the last thing you copied on the system. 2) You can use it in a subshell to paste an argument to another program. Example, copy a link to a file in Safari then type wget $(paste) in Terminal. Since the subshell is executed first, the resulting command that is executed is wget www.example.com/file.txt
Copy is a little rough. Since I used PasteBoardStacker, that means text isn't copied directly into the Apple PasteBoard. You have to select the text in PasteBoardStacker first, which is done by double tapping the status bar, then tapping the text you want from the pop-up list. It takes an extra step but it's still a good way to copy text from Terminal, and other than directing the output to a file, opening it and copying, it's the only way I am aware of. Copy handles piped input so if you run this command: echo "Hello world" | copy, you can then select "Hello world" in PasteBoardStacker and paste into another app.
Copy also requires you to escape some special characters with a backslash. echo "Hello world!" | copy won't work because the shell will try to interpret the exclamation point. echo "Hello world\!" | copy is what you need to use. Edit: D'oh, this was a poor example because it's normal shell behavior and not related to copy, but the sed line in copy still can't handle some characters like "<"without escaping.
Friday, January 22, 2010
iPhone/Linux "Network Printing"
This hack may be useful if you have a non-network printer attached to your Linux box and want to print text remotely from your iPhone.
There are actually several ways to accomplish this. You can simply create a text file and scp that file to your linux box, or pipe it over ssh then execute a print command, but neither worked right for me. The first requires you to create the text file, put something in it, save, then send to print. As for the second method, I can't get text to pipe over ssh from my phone like it should, and even if I could, I'm not certain it would work with slogin and ssh keys. Nothing seemed to work for me, so I went with tapping an icon to automatically print the clipboard contents. This way, you don't have to fool with any files, and if you do want to print a file, you can open it, copy the text, and print it.
Requirements:
On the iPhone, you need PasteBoardStacker and ssh (preferrably set up with ssh keys). PasteBoardStacker is used because it's easy to get the plain text from it and I've never gotten around to decoding the Apple pasteboard. Maybe I'll tackle that one someday.
On your Linux box, you need a to be able to print from the command line, which should already be possible as long as your printer works. In my example, I also use enscript to format the text before piping the text to the lpr print command. Enscript should be present on most systems, and I can't imagine anyone actually prints text that isn't word wrapped.
Here is the script that goes on the phone. If you want to run it by tapping an icon on SpringBoard, you need to set up ssh keys and follow these directions. If you want to run it from MobileTerminal and type your ssh password in every time, change the scp line to "scp ispool USER@IP:/PATH/TO/PUT/FILE." This script can be named anything you like. (Update: I changed the first command, which was really long, to make two shorter lines)
This goes on the Linux box and is called "iprint." If you want to name it something else, change "iprint" on the last line of the previous script to the new name. This uses enscript, but that's optional and you can change that whole line to "cat ispool | lpr" if you like.
Or, if you would like a Prowl notification of the print job...
Update: I found that piping over ssh does work as it should. I don't know why it wasn't working for me the other day, except maybe because I was figuring out this whole print thing at 2 in the morning. That's what happens when you lay in bed and think "I'd like to print this out but don't want to get up." Anyway, this script can be ran on the phone to print the contents of the clipboard. I still like the above method because it allow me to get the output via Prowl notification, but this is simpler:
There are actually several ways to accomplish this. You can simply create a text file and scp that file to your linux box, or pipe it over ssh then execute a print command, but neither worked right for me. The first requires you to create the text file, put something in it, save, then send to print. As for the second method, I can't get text to pipe over ssh from my phone like it should, and even if I could, I'm not certain it would work with slogin and ssh keys. Nothing seemed to work for me, so I went with tapping an icon to automatically print the clipboard contents. This way, you don't have to fool with any files, and if you do want to print a file, you can open it, copy the text, and print it.
Requirements:
On the iPhone, you need PasteBoardStacker and ssh (preferrably set up with ssh keys). PasteBoardStacker is used because it's easy to get the plain text from it and I've never gotten around to decoding the Apple pasteboard. Maybe I'll tackle that one someday.
On your Linux box, you need a to be able to print from the command line, which should already be possible as long as your printer works. In my example, I also use enscript to format the text before piping the text to the lpr print command. Enscript should be present on most systems, and I can't imagine anyone actually prints text that isn't word wrapped.
Here is the script that goes on the phone. If you want to run it by tapping an icon on SpringBoard, you need to set up ssh keys and follow these directions. If you want to run it from MobileTerminal and type your ssh password in every time, change the scp line to "scp ispool USER@IP:/PATH/TO/PUT/FILE." This script can be named anything you like. (Update: I changed the first command, which was really long, to make two shorter lines)
#! /bin/sh
cd /var/mobile
file=/var/mobile/Library/Preferences/com.hitoriblog.pasteboardstacker.plist
text=$(awk 'BEGIN{ RS="</string>"}{gsub(/.*<string>/,"");print;exit}' $file | sed '
s/</</g
s/>/>/g
s/&/\&/g')
echo $text | tr -d  > ispool
scp -i ~/.ssh/KEYFILE ./ispool USER@IP:/PATH/TO/PUT/FILE
rm ispool
ssh USER@IP iprint
This goes on the Linux box and is called "iprint." If you want to name it something else, change "iprint" on the last line of the previous script to the new name. This uses enscript, but that's optional and you can change that whole line to "cat ispool | lpr" if you like.
#! /bin/sh
cd /PATH/TO/FILE
cat ispool | enscript -h -B -1 --word-wrap --media=A4
rm ispool
Or, if you would like a Prowl notification of the print job...
#! /bin/sh
cd /PATH/TO/FILE
cat ispool | enscript -h -B -1 --word-wrap --media=A4> tmpspool 2>&1
job=$(cat ispool)
output=$(cat tmpspool)
rm ispool tmpspool
curl -k https://prowl.weks.net/publicapi/add -F apikey=xxxxx -F application="Print job:" -F description="$output $job"
Update: I found that piping over ssh does work as it should. I don't know why it wasn't working for me the other day, except maybe because I was figuring out this whole print thing at 2 in the morning. That's what happens when you lay in bed and think "I'd like to print this out but don't want to get up." Anyway, this script can be ran on the phone to print the contents of the clipboard. I still like the above method because it allow me to get the output via Prowl notification, but this is simpler:
#! /bin/sh
file=/var/mobile/Library/Preferences/com.hitoriblog.pasteboardstacker.plist
text=$(awk 'BEGIN{ RS="</string>"}{gsub(/.*<string>/,"");print;exit}' $file
echo $text | tr -d  | slogin -i ~/.ssh/KEYFILE USER@IP lpr
Sunday, December 13, 2009
Need more room on your iPhone's root partition?
I always move all my fonts after every update. It frees up about 100mb of space.
mv /System/Library/Fonts /private/var/ && ln -s /private/var/Fonts /System/Library/Fonts
Saturday, December 12, 2009
Script for disabling some iPhone launch daemons
#! /bin/sh
# test for root
if [ `id -u` != 0 ]; then echo "Oops, you need to be root to run this script"; exit 0; fi
echo "Made by fubaya using description of the daemons by jdys_1991 at http://modmyi.com/forums/file-mods/682255-speed-up-your-iphone-ipod-removing-launch-daemons.html.
Press enter to continue..."
read
echo "This script only works on daemons listed as "Safe", "Conditional", or "Jailbreak" by jdys_1991 on the modmyi forum post. It will list them one by one and ask if you want to disable them by moving them to /var/mobile/LaunchDaemonsBackup.
Press enter to continue..."
read
script=$0
mkdir /var/mobile/LaunchDaemonsBackup
backupdir=/var/mobile/LaunchDaemonsBackup/
daemondir=/System/Library/LaunchDaemons/
ls $daemondir > .daemonlist
###################################################
function daemon {
# edited Dec-12 to send unnecessary output to /dev/null
if echo $1 | grep -i -f .daemonlist > /dev/null
then
echo -------------------------------------
echo $1 | grep -i "# $1" $script
echo
# edited Dec-12 to change "delete" to "disable"
echo "Do you want to disable $1?" y or n?
echo -------------------------------------
read choice
# edited Dec-12 to add confirmation that file was moved
[ $choice = "y" ] && mv $daemondir$1 $backupdir && echo "$1 successfully disabled"
[ $choice = "n" ] && echo "$1 not disabled"
fi
}
daemon com.apple.DumpPanic.plist
daemon com.apple.ReportCrash.DirectoryService.plist
daemon com.apple.ReportCrash.Jetsam.plist
daemon com.apple.ReportCrash.SafetyNet.plist
daemon com.apple.ReportCrash.SimulateCrash.plist
daemon com.apple.ReportCrash.plist
daemon com.apple.CrashHousekeeping.plist
daemon com.apple.aslmanager.plist
daemon com.apple.syslogd.plist
daemon com.apple.powerlog.plist
daemon com.apple.stackshot.server.plist
daemon com.apple.tcpdump.server.plist
daemon com.apple.iqagent.plist
daemon com.apple.mobile.profile_janitor.plist
daemon com.apple.chud.chum.plist
daemon com.apple.chud.pilotfish.plist
daemon com.apple.AddressBook.plist
daemon com.apple.accessoryd.plist
daemon com.apple.apsd.plist
daemon com.apple.dataaccess.dataaccessd.plist
daemon com.apple.datamigrator.plist
daemon com.apple.racoon.plist
daemon com.apple.MobileInternetSharing.plist
daemon com.apple.aggregated.plist
daemon com.apple.AOSNotification.plist
daemon com.apple.AdminLite.plist
daemon com.bigboss.sbsettingsd.plist
daemon com.imalc.insomnia.plist
daemon com.mxweas.MxT2d.plist
daemon com.saurik.Cydia.Startup.plist
daemon org.nodomain.scrobbled.plist
###################################################
rm .daemonlist
num=$(ls $backupdir | wc -l)
echo
echo "$num daemons have been moved to $backupdir. Please reboot for changes to take effect. Do you want me to
delete myself? y or n?"
read choice
[ $choice = "y" ] && echo "Deleting myself..." && sleep 1.5 && echo "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."
###################################################
# Safe Daemons - These can be deleted by any user, with no adverse effects on the device
# com.apple.DumpPanic.plist (Safe)- Dumps crashes for evaluation by Apple.
# com.apple.ReportCrash.plist (Safe)- Collects data about what caused a crash, what programs were running at the time, etc.
# com.apple.ReportCrash.DirectoryService.plist (Safe)- Collects data about what caused a crash, what programs were running at the time, etc.
# com.apple.ReportCrash.Jetsam.plist (Safe)- Collects data about what caused a crash, what programs were running at the time, etc.
# com.apple.ReportCrash.SafetyNet.plist (Safe)- Collects data about what caused a crash, what programs were running at the time, etc.
# com.apple.ReportCrash.SimulateCrash.plist (Safe)- Collects data about what caused a crash, what programs were running at the time, etc.
# com.apple.CrashHouseKeeping.plist (Safe)- Also deals with crashes.
# com.apple.aslmanager.plist (Safe)- This daemon manages system logs.
# com.apple.syslogd.plist (Safe)- Logs system events.
# com.apple.powerlog.plist (Safe)- This is used to monitor any incompatibilities with 3rd party chargers.
# com.apple.stackshot.server.plist (Safe)- This daemon's function is currently unknown, but removing it has no adverse effects on one's device. Some more information can be found here, although the page is quite technical and isn't very useful to an end-user.
# com.apple.tcpdump.server.plist (Safe)- This daemon is apparently used to dump traffic on a network. Removing this daemon has no adverse effects on one's device.
# com.apple.iqagent.plist (Safe)- This daemon's function is currently unknown, but removing it has no adverse effects on one's device.
# com.apple.mobile.profile_janitor.plist (Safe)- This daemon's function is currently unknown, but removing it has no adverse effects on one's device.
# com.apple.chud.chum.plist (Safe)- This daemon is thought to relate to Apple's CHUD (Computer Hardware Understanding Developer) tools. Removing this daemon will have no adverse effects on your device, unless you are a developer.
# com.apple.chud.pilotfish.plist (Safe)- This daemon is also thought to relate to Apple's CHUD tools. Removing this daemon will have no adverse effects on your device, unless you are a developer.
# Conditional Daemons - These daemons can be disabled by certain users who have no need for some features of their device.
# com.apple.AddressBook.plist (Conditional)- If removed, Contacts in the Phone application will load slightly slower. Disable this if you don't care about that.
# com.apple.accessoryd.plist (Conditional)- If removed, disables accessories like FM radio transmitters, iPhone docks, and AV cables. Accessories will be able to charge your device, but that is all they will be able to do. Remove this if you don't use any of these accessories.
# com.apple.apsd.plist (Conditional)- If removed, Push Notifications will no longer work. Disable this if you don't use Push Notifications.
# com.apple.dataaccess.dataaccessd.plist (Conditional)- If removed, contacts will no longer sync via Exchange or Google Sync. Disable this if you don't use those services.
# com.apple.datamigrator.plist (Conditional)- Used to transfer contacts from SIM card to phone. iPod touch users can delete this.
# com.apple.racoon.plist (Conditional)- Used for Virtual Private Networks. Disable this daemon if you do not use any VPNs.
# com.apple.MobileInternetSharing.plist (Conditional)- Used for Internet Tethering. Disable this if you have an iPod touch or if you aren't interested in tethering.
# com.apple.aggregated.plist (Conditional)- It is believed that this performs some function related to Audio-In. If you have an iPod touch and do not intend to use Audio-In, disable this. iPhone users should leave this alone.
# com.apple.AOSNotification.plist (Conditional)- This daemon deals with MobileMe syncing. If you do not use the MobileMe service, you can disable this.
# com.apple.AdminLite.plist (Conditional)- This daemon tries to return control of your device to you if it thinks that you are waiting for a lengthly process to respond. It does this by force-quitting the process, so if you're tired of your apps crashing and you would rather wait a few seconds for them to finish what they're doing, disable this daemon.
# Jailbreak Daemons - These are daemons installed by jailbreak applications.
# com.bigboss.sbsettingsd.plist (Jailbreak)- Related to SBSettings. I would suggest leaving it alone.
# com.imalc.insomnia.plist (Jailbreak)- Used to keep Insomnia running through resprings and reboots. If you don't want it to do that, disable this. (note from fubaya: disabling this causes the Insomnia toggle to disappear from SBSettings)
# com.mxweas.MxT2d.plist (Jailbreak)- The daemon that allows MxTube to download videos in the background. If disabled, the application will need to be reinstalled; however, if you don't use MxTube and are too lazy to uninstall it, you can disable this daemon.
# com.saurik.Cydia.Startup.plist (Jailbreak)- It's believed that this daemon deals with the AutoInstall trick for installing .deb files. If you don't know what that is and you don't use it, you can disable this daemon.
# org.nodomain.scrobbled.plist (Jailbreak)- The Scrobbler daemon.
Thursday, December 10, 2009
"Free memory"
Nothing is free.
A lot of iPhone users are obsessed with the amount of free memory they have. Apps like SBSettings will show how many megabytes of free memory you have and even allow you to free up more. A script is going around that allows you to free memory every time it drops by 2 megabytes!
This may go against conventional wisdom, but free memory isn't all it's cracked up to be. There is an old unix saying "free memory is wasted memory." The system keeps inactive data in memory in order to make things faster to look up if it's needed again later. This makes your amount of free memory look low, but it's nothing to worry about. If the memory is needed by another program, the kernel will instantly free it.
Example, you run an app which uses a certain library. That library is loaded into memory. You close the app, but the library stays in memory, just hanging out, doing nothing, making your free memory number go lower. If you load another app that uses that library, it will be faster to look up and will cause the app to load faster, but if the memory has been freed, it will be a little slower as the system has to read the library into memory from disk to use it with the app.
You may be able to see and hear an example of this on your home computer. I have 2GB ram on a Linux system that only needs 500MB, but if I boot my computer and open Firefox, it takes a few seconds to load and I will hear my hard drive clicking as it reads information from the disk. If I close it and open it again, it opens instantly with no drive clicking. That's because everything the system needed to run Firefox was still in memory. If I free the pagecache (echo 1 > /proc/sys/vm/drop_caches) my free memory goes up, but if I open Firefox again, it takes longer and my hard drive clicks the same as it did the first time.
Another example closer to topic is the mail app on the iPhone. Open it up and close it with the home button. Open and close it a couple more times and you should see that it opens almost instantly. Now go to SBSettings, free the memory and open mail again. It will be jerkier and slower than normal.
If you don't see a difference, open an email. It will probably take a couple of seconds to load the email. Once it's loaded, go back to your inbox. Now open the email again and it will open instantly. Go back and forth from your inbox to the email a couple of times and the email should open almost instantly every time. Now, without closing mail, use SBSettings to free memory. Then click the email and it will take a while to load. Again, the data in memory has been dumped and it has to be read anew.
This isn't to say that all free memory is bad, obviously. I have a 3G and wish I had as much free memory as the 3Gs guys. If an app needs X amount of memory and the system can't free that much, something will crash. Having extra memory is a good thing, but freeing memory to get the "free memory" number up means the system isn't using the memory the way it was designed. Things aren't being buffered and will need to be read from disk more often, and that's always slower.
But maybe there is some advantage to clearing out the memory before opening a large app. It would keep the system from having to flush the memory and write to disk while the app is opening and could make for a more stable app launch, but I suspect everything else will be slightly slower in general.
A lot of iPhone users are obsessed with the amount of free memory they have. Apps like SBSettings will show how many megabytes of free memory you have and even allow you to free up more. A script is going around that allows you to free memory every time it drops by 2 megabytes!
This may go against conventional wisdom, but free memory isn't all it's cracked up to be. There is an old unix saying "free memory is wasted memory." The system keeps inactive data in memory in order to make things faster to look up if it's needed again later. This makes your amount of free memory look low, but it's nothing to worry about. If the memory is needed by another program, the kernel will instantly free it.
Example, you run an app which uses a certain library. That library is loaded into memory. You close the app, but the library stays in memory, just hanging out, doing nothing, making your free memory number go lower. If you load another app that uses that library, it will be faster to look up and will cause the app to load faster, but if the memory has been freed, it will be a little slower as the system has to read the library into memory from disk to use it with the app.
You may be able to see and hear an example of this on your home computer. I have 2GB ram on a Linux system that only needs 500MB, but if I boot my computer and open Firefox, it takes a few seconds to load and I will hear my hard drive clicking as it reads information from the disk. If I close it and open it again, it opens instantly with no drive clicking. That's because everything the system needed to run Firefox was still in memory. If I free the pagecache (echo 1 > /proc/sys/vm/drop_caches) my free memory goes up, but if I open Firefox again, it takes longer and my hard drive clicks the same as it did the first time.
Another example closer to topic is the mail app on the iPhone. Open it up and close it with the home button. Open and close it a couple more times and you should see that it opens almost instantly. Now go to SBSettings, free the memory and open mail again. It will be jerkier and slower than normal.
If you don't see a difference, open an email. It will probably take a couple of seconds to load the email. Once it's loaded, go back to your inbox. Now open the email again and it will open instantly. Go back and forth from your inbox to the email a couple of times and the email should open almost instantly every time. Now, without closing mail, use SBSettings to free memory. Then click the email and it will take a while to load. Again, the data in memory has been dumped and it has to be read anew.
This isn't to say that all free memory is bad, obviously. I have a 3G and wish I had as much free memory as the 3Gs guys. If an app needs X amount of memory and the system can't free that much, something will crash. Having extra memory is a good thing, but freeing memory to get the "free memory" number up means the system isn't using the memory the way it was designed. Things aren't being buffered and will need to be read from disk more often, and that's always slower.
But maybe there is some advantage to clearing out the memory before opening a large app. It would keep the system from having to flush the memory and write to disk while the app is opening and could make for a more stable app launch, but I suspect everything else will be slightly slower in general.
Saturday, December 5, 2009
ssh tricks and security
If you have a jailbroken iPhone with ssh installed, you've probably heard about the handful of worms going around that exploits the fact that people don't change their default iPhone passwords.
Of course, the fix is simple. Change your damn password! As an added bit of security, if you have SBSettings, you can get an ssh toggle to turn off ssh access when you're not using it. That should be good enough, but why not go a little further?
First, set up ssh keys using this how-to. It may seem confusing the first time, but it's really very simple. I've done it twice. The first time took a few minutes and the second time took about 30 seconds. I set up keys to login to my computer from my iPhone, and also keys to login to my phone from my computer.
(As a side note; if you have ssh keys setup on a phone or computer that gets lost, you will need to remove it's entry in authorized_keys on the other computer and delete the key.)
Simply setting up ssh keys doesn't help with security yet. We'll get to that, but right now let's look at the tricks you can do with ssh keys, mainly the convenience of being able to login with without a password. Instead, the computers are authenticated with the keys. You can login with slogin:
Another command that works with ssh keys is scp, which is ssh's copy command that copies files between computers:
Now, let's get back to ssh security. Once the keys are working, let's look at the ssh setup. The file we want to have a look at should be located at /etc/ssh/sshd_config.
There are a few lines that can greatly enhance our security. They are probably commented out and look like "# Something", so you will need to remove the "#" in order for the option to take effect. These are the options we want to look at:
Port 22 - The default port for ssh is 22 and everyone knows it. Anyone port scanning your computer or phone will probably probe ports for common services like email, web server and ssh, and it may only take one or two seconds to scan the common ports. Well, computers have 65535 ports, so why run ssh on the ssh port? Pick a random port!
(EDIT: I found that editing /etc/ssh/sshd_config didn't change the port on the iPhone. After a little google work, I found that launchd overides the port configuration, but you can change the phone's ssh listening port by editing /etc/services. You will see two lines "ssh 22/udp" and "ssh 22/tcp". Change both "22"s to whatever port you want to use.)
Don't forget to allow that port in firewalls and routers and specify it when using scp or ssh. To specify ports for those programs, use -P for scp and -p for slogin. Examples using port 5555:
PubkeyAuthentication yes - These are the ssh keys I've been talking about. We want to use those.
PasswordAuthentication no - This is how you normally login through ssh. You can turn this off so the only way to login is with the ssh keys. Even if someone knows your password, they can't get in without the keys.
Once you're finished editing the config file on your computer, restart the ssh daemon by running:
(EDIT: I found that flipping the SBSettings ssh toggle off and back on will load the new preferences)
Once you're all finished, enjoy being more secure!
Of course, the fix is simple. Change your damn password! As an added bit of security, if you have SBSettings, you can get an ssh toggle to turn off ssh access when you're not using it. That should be good enough, but why not go a little further?
First, set up ssh keys using this how-to. It may seem confusing the first time, but it's really very simple. I've done it twice. The first time took a few minutes and the second time took about 30 seconds. I set up keys to login to my computer from my iPhone, and also keys to login to my phone from my computer.
(As a side note; if you have ssh keys setup on a phone or computer that gets lost, you will need to remove it's entry in authorized_keys on the other computer and delete the key.)
Simply setting up ssh keys doesn't help with security yet. We'll get to that, but right now let's look at the tricks you can do with ssh keys, mainly the convenience of being able to login with without a password. Instead, the computers are authenticated with the keys. You can login with slogin:
slogin -i ~/.ssh/SSH_FILENAME user@IPYou can also put that in a script and simply run the script to login.
Another command that works with ssh keys is scp, which is ssh's copy command that copies files between computers:
scp -i ~/.ssh/SSH_FILENAME FILE_TO_COPY user@IP:/PATH/TO/COPY/TOYou can also modify that a little to put it in a script and run the script with the file you want to copy as an argument:
scp -i ~/.ssh/SSH_FILENAME $1 user@IP:/PATH/TO/COPY/TOAnother script to transfer directories:
scp -r -i ~/.ssh/SSH_FILENAME $1 user@IP:/PATH/TO/COPY/TOYou can put all of these on your iPhone and computer and perhaps name the ssh scripts "sshcomp" and "sshphone", the scp scripts "tocomp" and "tophone", and the "ssh -r" scripts to recursively copy a directory "tocompr" and "tophoner" and never have to worry about typing in long ssh or scp commands again.
Now, let's get back to ssh security. Once the keys are working, let's look at the ssh setup. The file we want to have a look at should be located at /etc/ssh/sshd_config.
There are a few lines that can greatly enhance our security. They are probably commented out and look like "# Something", so you will need to remove the "#" in order for the option to take effect. These are the options we want to look at:
Port 22 - The default port for ssh is 22 and everyone knows it. Anyone port scanning your computer or phone will probably probe ports for common services like email, web server and ssh, and it may only take one or two seconds to scan the common ports. Well, computers have 65535 ports, so why run ssh on the ssh port? Pick a random port!
(EDIT: I found that editing /etc/ssh/sshd_config didn't change the port on the iPhone. After a little google work, I found that launchd overides the port configuration, but you can change the phone's ssh listening port by editing /etc/services. You will see two lines "ssh 22/udp" and "ssh 22/tcp". Change both "22"s to whatever port you want to use.)
Don't forget to allow that port in firewalls and routers and specify it when using scp or ssh. To specify ports for those programs, use -P for scp and -p for slogin. Examples using port 5555:
scp -i ~/.ssh/SSH_FILENAME -P 5555 $1 user@IP:/PATH/TO/COPY/TOPermitRootLogin no - Set this as no and login as a regular user and use "su" instead.
slogin -i ~/.ssh/SSH_FILENAME -p 5555 user@IP
PubkeyAuthentication yes - These are the ssh keys I've been talking about. We want to use those.
PasswordAuthentication no - This is how you normally login through ssh. You can turn this off so the only way to login is with the ssh keys. Even if someone knows your password, they can't get in without the keys.
Once you're finished editing the config file on your computer, restart the ssh daemon by running:
/etc/rc.d/rc.sshd stopI'm not certain how to do this on the iPhone. sshd is launched demand by launchd and I'm not sure when the config file is read. I would assume it's read at launch and that you can turn ssh off and back on in SBSettings, but I'm not familiar enough with launchd and ssh on the phone to say for sure, so you may have to reboot the phone.
/etc/rc.d/rc.sshd start
(EDIT: I found that flipping the SBSettings ssh toggle off and back on will load the new preferences)
Once you're all finished, enjoy being more secure!
Thursday, December 3, 2009
Script for deleting iPhone language packs
This script is outdated, please see the script here. Also, don't use the version of this script found on sinful iphone forums by Monsieurtalbot. He made a few ugly edits to the echo commands and claimed to have written the script. When called out, he then claimed to have rewritten it and fixed a bug that made Terminal crash, but a simple look at the code shows no rewrite. It's the same (outdated) script except uglier due to poorly formatted echos.
#! /bin/sh
# Feb 9 2010
echo
# test for root
if [ `id -u` != 0 ]; then echo "Oops, you need to be root to run this script"; exit 0; fi
echo "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 hit ctrl c. On the
iPhone keyboard, control is a black dot
that is found on the far right when you
tap 123 then # =."
echo
echo "If you want to see how it runs without
making any changes, just answer no when it
asks you which languages to delete."
echo
echo "Press enter to begin."
read
echo "Please contact me at ijdmas at gmail dotcom
if this script asks you to delete a language
but doesn't list that language. It will
look like this:
\"Do you want to delete:? y or n?\""
echo
echo "This is due to someone using the long name
for a language which Ive not seen yet.
Example, if Vulcan used to be vu.lproj
and someone starts using Vulcan.lproj,
it will cause that problem. If it
happens, it is safe to answer no and
continue."
echo
echo "Press enter to begin."
read
# create temp files
touch .langlist_fubaya .keeplist_fubaya .deletelist_fubaya .alllist_fubaya
# update database, locate all lproj, and grep directories minus English
echo "Searching for language packs. Please wait..."
updatedb && locate lproj | grep -E lproj$ | grep -v -i English | grep -v -i \/en > .alllist_fubaya
# get a list of all languages
cat .alllist_fubaya | while read file; do basename "$file"; done | grep -E lproj$ | sort | uniq > .langlist_fubaya
echo ---------------- >> langpack.log
echo langlist >> langpack.log
cat .langlist_fubaya >> langpack.log
# display true names beside the language codes
# ask user if they want to keep them or not, put keepers in ".keeplist_fubaya" file
echo ---------------- >> langpack.log
for i in $(cat .langlist_fubaya) ; do
q=$(cat $0 | grep -i "\# $i" | tr -d \#)
[ -n "$q" ] && echo "Delete:$q? y or n?" || echo "Delete: $i (unrecognized)? y or n?"
read choice
# make sure "y" or "n" was entered, else keep repeating the question
while [[ $choice != 'y' ]] && [[ $choice != 'n' ]]
do
[ -n "$q" ] && echo "Delete:$q?" y or n? || echo "Delete: $i (unrecognized)?" y or n?
read choice
done
echo "delete:$i: $choice" >> langpack.log
[ $choice = "n" ] && echo $i >> .keeplist_fubaya
echo
done
echo ---------------- >> langpack.log
echo keeplist >> langpack.log
cat .keeplist_fubaya >> langpack.log
# put master list into delete list, filtering out keepers
cat .alllist_fubaya | grep -v -f ./.keeplist_fubaya > .deletelist_fubaya
# show final list of lang packs and confirm the user wants to delete them
echo
echo "Please wait while I compile a list of languages to delete. You will be asked for confirmation before anything is deleted"
echo ---------------- >> langpack.log
echo deletelist >> langpack.log
cat .deletelist_fubaya >> langpack.log
echo
echo -------------------------------------
cat .deletelist_fubaya | while read file; do basename "$file"; done | grep -E lproj$ | sort | uniq | tr '\n' ' '
echo
echo -------------------------------------
echo "This is your last chance. Are you sure you want to delete the language packs listed? Type y or n"
read choice
if [ $choice = "y" ]
then
# do the deed
echo ---------------- >> langpack.log
echo "final confirmation: $choice" >> langpack.log
echo ---------------- >> langpack.log
echo "Please wait while I delete the chosen language packs..." && while read file; do rm -rf "$file"; done < .deletelist_fubaya
# how many did we delete?
num=$(cat .deletelist_fubaya | wc -l)
# clean up temp files
rm .langlist_fubaya .keeplist_fubaya .deletelist_fubaya .alllist_fubaya
echo
echo "$num language pack directories have been
deleted. A log file has been created at
`pwd`/langpack.log. Please hang on to
that until you are sure there are no
problems. My contact information is at
the top of the log file. The only other
thing left is me, this script located at
`pwd`/`basename $0`. Do you want me to
delete myself? y or n?"
read choice
[ $choice = "y" ] && echo "Deleting myself..." && sleep 1.5 && echo "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."
else # if user selected "n" to deleting the language packs
rm .langlist_fubaya .keeplist_fubaya .deletelist_fubaya .alllist_fubaya
echo "Ok, I won't delete anything. If you made a mistake, just run me again."
fi
# Arabic.lproj
# Chinese.lproj
# Croatian.lproj
# Czech.lproj
# Danish.lproj
# Dutch.lproj
# Finnish.lproj
# French.lproj
# German.lproj
# Greek.lproj
# Hebrew.lproj
# Indonesian.lproj
# Italian.lproj
# Japanese.lproj
# Korean.lproj
# Malay.lproj
# Norwegian.lproj
# Polish.lproj
# Portuguese.lproj
# Romanian.lproj
# Russian.lproj
# Slovak.lproj
# Spanish.lproj
# Swedish.lproj
# Thai.lproj
# Turkish.lproj
# Ukrainian.lproj
# ar.lproj (Arabic)
# cs.lproj (Czech)
# cs_CZ.lproj (Czech)
# da.lproj (Danish)
# da_DK.lproj (Danish)
# de.lproj (German)
# de_DE.lproj (German)
# el.lproj (Greek)
# el_GR.lproj (Greek)
# es.lproj (Spanish)
# es_419.lproj (Spanish)
# es_ES.lproj (Spanish)
# fi.lproj (Finnish)
# fi_FI.lproj (Finnish)
# fr.lproj (French)
# fr_CA.lproj (French)
# fr_FR.lproj (French)
# he.lproj (Hebrew)
# hr.lproj (Croatian)
# hr_HR.lproj (Croatian)
# hu.lproj (Hungary)
# id.lproj (Indonesian)
# it.lproj (Italian)
# it_IT.lproj (Italian)
# ja.lproj (Japanese)
# ko.lproj (Korean)
# ms.lproj (Malay)
# nl.lproj (Dutch)
# nl_NL.lproj (Dutch)
# no.lproj (Norwegian)
# no_NO.lproj (Norwegian)
# pl.lproj (Polish)
# pl_PL.lproj (Polish)
# pt.lproj (Portuguese)
# pt_PT.lproj (Portuguese)
# ro.lproj (Romanian)
# ro_RO.lproj (Romanian)
# ru.lproj (Russian)
# ru_RU.lproj (Russian)
# rus.lproj (Russian)
# sk.lproj (Slovak)
# sk_SK.lproj (Slovak)
# sp.lproj (Spanish)
# sp_es.lproj (Spanish)
# sv.lproj (Swedish)
# sv_SE.lproj (Swedish)
# th.lproj (Thai)
# tr.lproj (Turkish)
# tr_TR.lproj (Turkish)
# uk.lproj (Ukranian)
# zh-Hans.lproj (Chinese)
# zh-Hant.lproj (Chinese)
# zh_CN.lproj (Chinese)
# zh_HK.lproj (Chinese)
# zh_TW.lproj (Chinese)
# end of script
Monday, November 23, 2009
Deleting iPhone language packs
Every iPhone application has the option of including language packs. There come in the form of a seperate directory for every language the app supports. Inside those directories are files with various strings in that language that the app may use. Some apps may not support any additional languages and some may support 20.
They say (and I don't know who *they* are) that removing them can increase the phone's performance. I don't know how accurate that is, but it obviously does increase free space on the phone.
So here is one way to remove them from MobileTerminal, or any other command line program that can run commands on the phone.
First, log in as root by whatever means you wish. Either su in MobileTerminal, ssh root@IP, or whatever.
Run this command to update the locate database: updatedb
Now, we want to build a list of directories to delete by using the locate command to find all the language packs. Luckily, they are all found in *.lproj directories, so we start with locate lproj.
The output will include all the files in an .lproj directory, so let's use a grep regular expression to get only the directories. locate lproj | grep -E lproj$ will output only files that end with lproj, so it will output English.lproj, but not English.lproj/somefile.txt
Now we want to filter out the directories we want to keep. In my case, all I want to keep is English. On the iPhone, English can be either en.lproj or English.lproj so I piped the output to grep -v to filter out both: grep -E -v -i '(en.l|English)'
It may be simpler to grep the one at a time with -v and -i. "-v" is like a 'reverse grep' which displays everything except the string you specify and "-i" makes it case insensitive.
The official iPhone apps usually use long names like "English" and "Italian" while other apps will often use "en" and "it", so be sure to look for long and short names.
So, if you wanted to keep German, you could run this to save it to a text file:
Once you're sure everything looks safe to delete, then run this command:
They say (and I don't know who *they* are) that removing them can increase the phone's performance. I don't know how accurate that is, but it obviously does increase free space on the phone.
So here is one way to remove them from MobileTerminal, or any other command line program that can run commands on the phone.
First, log in as root by whatever means you wish. Either su in MobileTerminal, ssh root@IP, or whatever.
Run this command to update the locate database: updatedb
Now, we want to build a list of directories to delete by using the locate command to find all the language packs. Luckily, they are all found in *.lproj directories, so we start with locate lproj.
The output will include all the files in an .lproj directory, so let's use a grep regular expression to get only the directories. locate lproj | grep -E lproj$ will output only files that end with lproj, so it will output English.lproj, but not English.lproj/somefile.txt
Now we want to filter out the directories we want to keep. In my case, all I want to keep is English. On the iPhone, English can be either en.lproj or English.lproj so I piped the output to grep -v to filter out both: grep -E -v -i '(en.l|English)'
It may be simpler to grep the one at a time with -v and -i. "-v" is like a 'reverse grep' which displays everything except the string you specify and "-i" makes it case insensitive.
The official iPhone apps usually use long names like "English" and "Italian" while other apps will often use "en" and "it", so be sure to look for long and short names.
So, if you wanted to keep German, you could run this to save it to a text file:
locate lproj | grep -E proj$ | grep -v -i "XXXXXX.lproj" > langpacks.txtJust add | grep -v -i "XXXXXX.lproj" for any languages you don't want deleted, and remember to add a grep for both long and short names.
Once you're sure everything looks safe to delete, then run this command:
while read file; do rm -rf "$file"; done < langpacks.txtTo recap: if you're certain you only want English languages on your phone, run this:
updatedbI deleted over 3000 language pack directories with this, and I only have less than 2 pages of apps installed.
locate lproj | grep -E proj$ | grep -E -v -i '(en.l|English)' > langpacks.txt
while read file; do rm -rf "$file"; done < langpacks.txt
Subscribe to:
Posts (Atom)