用 bash source 時,出現 “file not found”

今天遇到很鳥的問題。
情境是這樣的:目前的目錄下有 .config,而 scripts 目錄下有個 shell script ,名稱是 Configure。Configure 的內容很簡單,就是 source .config。接著,在目前的目錄下輸入 sh scripts/Configure,你就會遇到 “.config: file not found” 的訊息。
試了好久,雖然知道可以用 bash 執行來解決,但是就是覺得奇怪,因為 9.04 的 bash 3.2 是沒問題的,但到了 9.10 的 bash 4.0 就不行了。
最後在這裡:Re: source command differs if in bash or sh mode 找到答案:

This is a property of bash posix mode when you don’t have `.’ in $PATH:
28. The `.’ and `source’ builtins do not search the current directory
for the filename argument if it is not found by searching `PATH’.
> This behavior is new in version 4, old version 3.2 works fine.
The bash-3.2 behavior was a bug. Its fix is listed in CHANGES:
ggg. Fixed a bug that caused a shell running in Posix mode to search $PWD for
a file specified as an argument to source/. when the file was not found
in $PATH.

對,這是 bug,bash 3.2 沒問題,是因為他是 bug,4.0 的時候修正了,所以就有問題了,你必須要在 PATH 裡加入 . 才行。
好鳥。

gwibber 的 spell 問題

如果你用 gwibber 時,碰到下面錯誤的話,這是因為沒有中文的 aspell 資料檔的關係:

File "/usr/lib/python2.6/dist-packages/gwibber/gwui.py", line 455, in __init__
self.spell = gtkspell.Spell(self, None)
glib.GError: enchant error for language: zh_TW.UTF-8

解法很簡單,修改 /usr/lib/python2.6/dist-packages/gwibber/gwui.py 把 455 行的前後加上 exception handling 即可:

try:
self.spell = gtkspell.Spell( self, None )
except:
pass

修改時要注意縮排問題,python 對這點可是很講究的!

解決 opera 10 不能用 ibus 問題

環境:
Ubuntu 9.10
Opera 10
輸入法:ibus
解決方法:
編輯 /usr/bin/opera,在 OPERA_BINARYDIR 之下加上

export QT_IM_MODULE=XIM

,然後重新啟動就行了。

grub 從不是第1個硬碟開機

我承認,這標題下的很爛,但一時也想不到更好的。

情況是這樣的,我第一個硬碟已經裝了 Linux,這時候我卻想裝 Windows,是故,我只能裝在第二個硬碟上。Windows 非常機車,如果第一個硬碟沒有 NTFS 的 partition 是不給你裝的。這時候只能先拔第一個硬碟的電源,把 Windows 裝到第二個硬碟上之後,再重新把第一個硬碟的電源裝回去。

接下來,因為不想老是在 BIOS 裡切換開機順序,所以把腦筋動到 grub 上。根據 grub 的 manual,只要利用 map 就行了,但我還是試了好一陣子,後來才發現是順序的問題,我試的時候把 map 放到最前面去了。正確的順序是這樣的:

title		Windows XP
root		(hd1,0)
makeactive
map (hd0) (hd1)
map (hd1) (hd0)
chainloader	+1

這樣就可以不用在 BIOS 裡切換開機順序了。如果你不是用第二個硬碟,而是第3個或第四個硬碟,只要類推為 hd2、hd3 即可。

wine 的選單

我用的是 Ubuntu。
用 wine 安裝程式以後,Wine 選單裡會多出該程式的項目,但移除程式以後,這些項目還存在,即便你之前有備份 .wine,將備份檔案回存了,也不會有用。關鍵在於 wine 其實是把這些選單項目放在 $HOME/.config/menus/applications-merged 下,所以只要把該刪除的項目從這個資料夾下刪除即可。
2009/10/14 補充:$HOME/.local/share/applications/wine/Programs 下的也要記得刪掉,否則會出現在”其他”選單裡…

Mustek Bearpaw 1200TA in Ubuntu

如果你正好用的掃描器跟我一樣是 Mustek BearPaw 1200TA 或者是開啟 xsane 遇到 gt68xx:libusb 錯誤時,你可以試著到這裡:SANE GT68xx Backend Homepage 去下載適當的 .usb 檔案。下載以後,把它複製到 /usr/share/sane/gt68xx 目錄下,變更權限為 a+r,然後重新開啟 xsane,這樣就能正常使用掃描器了。

在 Ubuntu 9.04 使用 svk 出現 Can’t locate Time/Progress.pm

在公司正想用 svk 把 monodevelop source code 拉回來時,發現有 Can’t locate Time/Progress.pm 訊息,然後就停止運行了。
Launchpad 找了一下,發現已經有人回報了:Bug #317487 in svk (Ubuntu): “2.2.1 needs Time::Progress”,後續的回覆裡,也提供了好幾個 workaround,我選擇直接修改 Notify.pm,因為以後 apt-get upgrade 時,新檔案會把舊檔案覆蓋掉。

kernel 怎麼執行 hotplug?

因為只知道 hotplug 這關鍵字,直接以 hotplug 找,從 lib/kobject_uevent.c 裡可以看到放 “/sbin/hotplug” 的變數:uevent_helper。再往後找,可以看到 call_usermodehelper 使用了此變數。
call_usermodehelper 定義在 kmod.h 裡,是一個 static inline function。裡面則呼叫了 call_usermodehelper_setup 去設置環境,末了再呼叫 call_usermodehelper_exec 去執行。
p.s. 似乎不能在 IRQ 中斷處理常式裡去呼叫,會造成 kernel crash 掉,仔細想想,這樣有合理,因為 IRQ 中斷處理常式應該要盡早處理結束。如果是這樣,處理就比較麻煩了,可能就要利用 thread 跟 queue 來作。現階段,先不要作這個好了,雖然主動通知的功能很酷…

ecryptfsd

ecryptfs-utils 裡的 ecryptfsd 可以透過 netlink 或 misc 方式與 kernel 的 ecryptfs module 溝通,Ubuntu 有修改過 kernel 的 ecryptfs ,讓 ecryptfsd 以 misc 的方式溝通。
而我,就卡在這裡搞了好久,因為我始終用 kernel 的預設值,也就是 netlink 的方式。
照理來說,netlink 應該也是可以才對,只是在 ecryptfsd 裡有段 code(嚴格來說應該是 libecryptfs.so),在以 sendto 送出封包以後,檢查回傳值,如果大於 0 ,就當作錯誤。你可以查一下 sendto 函式的說明,裡面清楚地寫了,當傳送成功,會回傳 sendto() 所送出的 byte 數。ecryptfsd 以 sendto 送出了 16 bytes,收也收到了 16 bytes,這樣應該是要當作成功,但程式裡卻視為失敗。
我不知道修正這裡以後還會遇到什麼問題,所以我決定很鴕鳥地去改用 ubuntu 的 kernel …

直接設定密碼免提示輸入

用 passwd 設定密碼是免不了要回答提示問題的,有方法可以省掉嗎?
如果可以省掉,在大量設定密碼的情況下會很方便。

方法說穿了很簡單,先用 mkpasswd 產生密碼,再用 usermod 來變更使用者密碼。
以下節錄自 call useradd and passwd through no prompt script – LinuxQuestions.org

#!/bin/bash
## Set a default password and perform a password reset
l_user=$1
if [ "$l_user" != "" ]
then
l_password="Reset"
l_encrypted_pass=$(mkpasswd -s --hash=md5 ${l_password})
echo "/usr/sbin/usermod -p ${l_encrypted_pass} ${l_user}"
fi

感恩啦!本來已經想用 sed/awk 去硬改 passwd/shadow 檔案了說…