Subscribe to RSS Subscribe to Comments Blog of Roy Chan

Blog of Roy Chan

Progress dialog box of Zenity

Zenity is the tool to display different types of GTK+ dialog box. It is very useful if you want to write a simple GUI shell script.

Apart from those simple yes-no/ok-cancel dialog box, zenity also provide interesting dialog box like the progress dialog box. The dialog box can be show with the commend “zenity --progress“. To make it meaningful, you may need to add more options of it.

The option “--text=string” control a short description show above the progress bar in the dialog box and “--percentage=num” set the percentage show in the progress bar.

You must not miss the following 4 options which applicable to all zenity dialog box. “--title=string” set the title of the dialog box and “--window-icon=path” set the window icon show beside the title. “--width=num” and “--height=num” control the size in pixels of the window. For example:

zenity --progress --title='Waiting...' --window-icon='/usr/share/pixmaps/gnome-about-logo.png' --text='Waiting for you to press Cancel' --percentage=50

Zenity progress dialog box

Sure, you won’t happy with the above functions. Let make the dialog box moving. Option “--pulsate” can make the progress bar beating right and left:

yes | zenity --progress --pulsate

Zenity pulsating progress box

Not satisfied? Me too! So, when will the Ok button press-able. Can the progress bar grow to show the progress of a task? Yes, it can. During the zenity show the progress dialog box, it also listen to the STDIN. If you type an number and press ENTER in the terminal you run zenity, you will see the number become the percentage show progress bar of the dialog box. If you start and line with “#”, type few words after it and press ENTER, the words will replace the description above the progress bar. In short, zenity --progress received the following format from STDIN:

num1
# description1
num2
# description2
...
# ...

Where num percentage of the progress bar and description change the progress description. The following script demo and explain more clear about the progress dialog box:

for x in 10 20 30 40 50 60 70 80 90 100
do
    echo $x
    echo "# Count to $x"
    sleep 1
done | zenity --progress --title='Counter'

Zenity progress box

You see that when the progress bar become 100%, the Ok button is activated.

Besides, you will found that if you press the “Cancel” button during the script working. The dialog box will disappear but you won’t see the prompt while script still running and not affected. You should expect the “Cancel” button will stop the script but it’s not. Option “--auto-kill” should be added to make it happen. It make the “Cancel” button kill parent process of zenity - the shell. Beware that if you type zenity on the command line, it will kill the shell and close the whole terminal. If you run zenity in a shell script, the script will be killed.

The last option you shall not missed is “--auto-close” which close the dialog automatically when the progress bar reach 100.

Many people demonstrate zenity progress with wget which show a progress dialog to show the progress while wget downloading file. But it seems the output format of wget was changed and all script I found online didn’t work. Here is my fix of the demo.

wget "$url" 2>&1 | \
     sed -u 's/^.* \+\([0-9]\+%\) \+\([0-9.]\+[GMKB]\) \+\([0-9hms.]\+\).*$/\1\n# Downloading... \2 (\3)/' | \
     zenity --progress --title='Download' --auto-kill --auto-close

It refine the wget output:

11550K .......... .......... .......... .......... .......... 21%  304K 2m51s
11600K .......... .......... .......... .......... .......... 21%  296K 2m50s
11650K .......... .......... .......... .......... .......... 22%  321K 2m50s
11700K .......... .......... .......... .......... .......... 22%  475K 2m49s

to zenity --progress format.


Share It: [del.icio.us] [Technorati] [Google Bookmark] [Yahoo MyWeb] [Furl]


How gnome-codec-install in Ubuntu work?

Ok, I know that I can ask people to install all GStreamer plugin to solve the codecs problems. But some people keep asking which package they need exactly. One thing in Ubuntu 7.04 that help me a lot is that is that it can detect the codec you need when you try to play a multimedia file and help you to install the packages. However, I still need to told people which package they really need on other distros.

I try to look around the gnome-codec-install and dig out how it know which package we need. First, gnome-codec-install is only a symbolic link of gnome-app-install. gnome-app-install put information of all available desktop applications in .desktop file under /usr/share/app-install/desktop. Those codecs package got the field “X-AppInstall-Codecs’ in their .desktop file. update-app-install will collect the information of all .desktop and build index in /var/cache/app-install/. The index file is in GDBM. I’m lazy to decode it. Therefore, I wrote a one-line shell command to build an index table from the .desktop files. Run the following command under /usr/share/app-install/desktop


grep  -l 'X-AppInstall-Codecs' * | while read file;
    do
        pkg=`basename "$file" .desktop`;
        grep 'X-AppInstall-Codecs' $file | \
            sed -e 's/^X-AppInstall-Codecs//' \
                -e 's/[=;]0.10:/\n'$pkg':/g' \
                -e 's/\.desktop$//'
    done | awk -F: '{printf "%s:%s\n", $2, $1}' | sort | less

Share It: [del.icio.us] [Technorati] [Google Bookmark] [Yahoo MyWeb] [Furl]


Tr - TRanslate characters

以下早八年前為PCWeekly HKLUG專欄寫的文章:

tr 是 Unix/Linux 一個很普遍的小工具,其功能也很簡單,主要把一組字母 map 成另一組字元。舉個例,請在打以下的指令:

 tr vms wnt

打了後請亂打堆字再按 [Enter] ,你會發覺 tr 會重覆顯示你所打的字,但「v」會變成了「w」,「m」變成了「n」,「s」則變成了「t」。要結束這個遊戲可以開個新行打 Ctrl-D 再按 [Enter] 。好了,相信閣下現在應該知到了 tr 的作用是什麼了。 tr 最常會被用作轉換大小階,看過以上的例題,閣下或者以為要打:

 tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ

這長長的指令。事實上只要用「tr a-z A-Z」就夠了。

簡簡單單一個程式,配合 Unix 上其他工具就有很多妙用。如閣下要把一目錄上所有檔案名稱轉成大寫,以可以在 bash/ksh/sh 用以下指令:

 for f in *
 do
   mv $f `echo $f | tr a-z A-Z`
 done

要把 vi 上把某行全部轉成小寫,可以在 vi 的編輯模式打「!!tr A-Z a-z」,一個段落則可以打 「!}tr A-Z a-z」。要轉整個檔案可以打「:%!tr A-Z a-z」。

有沒有發覺原本在 DOS/WIN 的文字檔放到 Unix/Linux 上看,每行都多了個「^M」。這是因為 Unix 、 DOS 及 Mac 等的文字檔格式都有所分別。 Unix 習慣每行用一個 Linefeed (ASCII 10) 分格, Mac 用一個 Carrier Return (ASCII 13) ,而 DOS 則要用一個 Carrier Return 跟一個 Linefeed 來分格,檔尾還要加個 Ctrl-Z (ASCII 26) 。要把 DOS 或 Mac 的文字檔轉成 Unix/Linux 格式最簡單可以利用 tr 。

  • Mac 轉 Unix/Linux - tr \\015 \\012 <mac.txt >unix.txt
  • Unix/Linux 轉 Mac - tr \\012 \\015 <unix.txt >mac.txt
  • DOS/Win 轉 Unix/Linux - tr -d \\015\\032 <dos.txt >unix.txt

012, 015 和 032 分別是 10, 13 和 26 的八進位。參數「-d」則叫 tr 把輸入檔中所有包括在字元組中的字元刪掉。


Share It: [del.icio.us] [Technorati] [Google Bookmark] [Yahoo MyWeb] [Furl]


One line shell command to show the top referer of your WWW site

First show you the big monster:

egrep ‘HTTP/[0-9.]*” *[23][0-9][0-9]’ access.log | \
  egrep -iv ‘\.(js|css|jpg|jpeg|png|gif)[” ]’ | \
  sed -e ’s/^.*HTTP\/[0-9.]\+”\?[[:space:]]\+[0-9]\+[[:space:]]\+\(-\|[0-9]\+\)[[:space:]]\+”\?//i’ \
    -e ’s/”.*$//’ | \
  egrep -v ‘^-’ | egrep -v ‘blog\.xychen\.org’ | \
  sed -e ’s/^http:\/\/[^\/]*\(\.google\.\|google\.pchome\|google\.sina\).*q=\([^&]*\).*$/[Google]:\2/i’  \
    -e ’s/^http:\/\/[^\/]*search\.yahoo\..*[^a-z0-9]p=\([^&]*\).*$/[Yahoo]:\1/i’ \
    -e ’s/^http:\/\/[^\/]*\.soso\..*[^a-z0-9]w=\([^&]*\).*$/[SoSo]:\1/i’ \
    -e ’s/^http:\/\/[^\/]*\.baidu\..*[^a-z0-9]wd=\([^&]*\).*$/[Baidu]:\1/i’ \
    -e ’s/^http:\/\/[^\/]*\.hisearch\.hinet\..*[^a-z0-9]k=\([^&]*\).*$/[Hinet]:\1/i’ \
    -e ’s/=/=3D/g’ -e ’s/%\([0-9A-F][0-9A-F]\)/=\1/gi’ | recode /QP.. | \
  sort | uniq -c | sort -nr | head

Here is the output of My blog:

     15 [Google]:中文字型
     12 [Yahoo]:速成字碼表
      9 [Google]:Beryl
      9 [Google]:beryl
      8 http://planet.debian.org.hk/
      7 [Google]: scim
      6 [Google]:色弱
      6 [Google]:任性
      5 http://www2.shoutmix.com/?sidekick
      4 http://www2.cbox.ws/box/?boxid=1129960&boxtag=9722&sec=main

It show me that 15 visits came to my site while searching “中文字型” with Google. 12 visits from searching “速成字碼表” with Yahoo. You can write a program to analyze the referer entry in your WW site log to obtain the above result. But I just show you how to do that with one line shell command. Sure, it might better to rewrite it with Perl while the one line shell command involve too many utilities and become too complex. But I had already finish it, why not share it.

First, I would like to filter out those unsuccessful visits and requests that only getting the images/javascript code/stylesheets:

egrep 'HTTP/[0-9.]*” *[23][0-9][0-9]‘ access.log | \
  egrep -iv ‘\.(js|css|jpg|jpeg|png|gif)[” ]

Then I need to dig out the referer from the log. I try to filter out the characters before and after the referer:

sed -e 's/^.*HTTP\/[0-9.]\+"\?[[:space:]]\+[0-9]\+[[:space:]]\+\(-\|[0-9]\+\)[[:space:]]\+"\?//i' \
  -e 's/".*$//' access.log >referer.log

Sure I don’t want to count the referer from my own site and request without referer:

 egrep -v '^-' referer.log | egrep -v 'blog\.xychen\.org'

Up to now, you can already pipe the result to the old shell trick - “sort | uniq -c | sort -nr | head” to show the top 10. However, being a crazy guy, I would like to group the refer from search engine (This part is complex and should be better using perl to handle it):

sed -e 's/^http:\/\/[^\/]*\(\.google\.\|google\.pchome\|google\.sina\).*q=\([^&]*\).*$/[Google]:\2/i'  \
  -e 's/^http:\/\/[^\/]*search\.yahoo\..*[^a-z0-9]p=\([^&]*\).*$/[Yahoo]:\1/i' \
  -e 's/^http:\/\/[^\/]*\.soso\..*[^a-z0-9]w=\([^&]*\).*$/[SoSo]:\1/i' \
  -e 's/^http:\/\/[^\/]*\.baidu\..*[^a-z0-9]wd=\([^&]*\).*$/[Baidu]:\1/i' \
  -e 's/^http:\/\/[^\/]*\.hisearch\.hinet\..*[^a-z0-9]k=\([^&]*\).*$/[Hinet]:\1/i' referer.log

While I’m insane, I even don’t want see those “%2F%e6“. Pls give me the “real” characters.

  sed -e 's/=/=3D/g' -e 's/%\([0-9A-F][0-9A-F]\)/=\1/gi' | recode /QP.. referer.log

I convert the URI encoding to Quota-Printable and decode it with recode. OK, now, I can use the old shell magic to get the top 10. First I sort it to group the same referer.

sort referer.log

Kick out the repeated line, left one only and the number of it had repeat.

sort referer.log | uniq -c

Sort the result with no. of repeat:

sort referer.log | uniq -c | sort -nr

Show only the top 10:

sort referer.log | uniq -c | sort -nr | head

Known problem

  1. It only a quick trick. I haven’t optimize it yet. Any recommendation?
  2. Fail to show the search keyword with the correct encoding. Most search engine use UTF8 but CN engine love GB2312 and some TW engine seems still using stupid Big5. Ummm… I nearly forget the zh-autoconvert…. Oops, zh-autoconvert can’t distinguish the UTF8 with Big5 or GB2312.

Share It: [del.icio.us] [Technorati] [Google Bookmark] [Yahoo MyWeb] [Furl]


Based on Fluidity© 1998-2007 Roy Hiu-yeung Chan