2010年10月28日 星期四

在 linux 下的 UTF-8 termial 使用 telnet 連上中文 bbs 與 mud

目前是使用 PCMan X 上 bbs,在巴哈洽特上看到有人推廣 doommud,連過去卻無法輸入任何字元,在 termial 裡使用 telnet 連上去則是中文全變亂碼,google 了一下才發現解法,只要使用 luit 就行了


luit -encoding big5 telnet doommud.twbbs.org 4000


在 Xfce Terminal Emulator 和 rxvt-unicode 測試過,拿來上 bbs 也行,只是不在 big5 範圍內的文字會無法顯示,一些 ascii art 也會跑掉,單純看文章應該是夠用的,但是只能在 X window 下的 terminal emulator 使用,一般的 terminal 大概要使用 zhcon 才能正常顯示? (沒試過)

參考:
[Tips]解決utf8環境下,telnet bbs亂碼
Luit -- locale and ISO 2022 support for Unicode terminals

2010年9月30日 星期四

利用 shell script 一次同步多個目錄

買了顆日立 1T 硬碟搭配 CyberSLIM S1 來備份資料,雖然只能使用 USB 傳輸,但總比再弄張 sata 轉接卡接硬碟來的方便。

平常電源都是關閉,只有要傳資料時才會開啟,但每次都要 sudo mount ,接著在不同目錄內找新資料傳過去,實在很麻煩,這時想到可以利用 rsync 來同步資料夾,不用自己比對,想說這麼簡單的東西不必再用 Python ,練習寫個 shell script 就行了,沒想到也是卡了快一天...Orz

作法是在 /etc/fstab 內先將硬碟設定為一般使用者可以 mount ( pass 要設為 0 ,不然一開機就會檢查,然後卡住... )
# get UUID
blkid

# In /etc/fstab, set user, noauto
/dev/disk/by-uuid/a123-456a-789d-abcd /mnt/HDD ext4 rw,user,noauto,suid,dev,exec,async 0 0

sync.sh:

#!/bin/bash
# Description:
# sync multiple folders to external Hard disk

MOUNT_POINT=/mnt/HDD

### array in shell script
SOURCE_DIR=(
/mnt/SOURCE_1/
/mnt/SOURCE_2/
/mnt/SOURCE_3/
)

DEST_DIR=(
/mnt/DEST_1
/mnt/DEST_2
/mnt/DEST_3
)

# check if Hard disk mounted or not
if [[ -z `mount | grep "$MOUNT_POINT"` ]]
then
mount $MOUNT_POINT
echo "mount $MOUNT_POINT "
else
echo "$MOUNT_POINT already mounted !!"
fi

echo

# if unable to mount external Hard disk , stop the script and leave
if [[ -z `mount | grep "$MOUNT_POINT"`]]
then
echo "***** Unable to mount $MOUNT_POINT *****"
exit 1
fi

### seq : like range() in python
### ${#SOURCE_DIR[*]} : total element number in $SOURCE_DIR

# use for loop to sync multiple directories, counter start from 0
for counter in `seq 0 $(( ${#SOURCE_DIR[*]} - 1 ))`
do
echo "*********************************************"
echo "Source:" ${SOURCE_DIR[$counter]}
echo "Dest: " ${DEST_DIR[$counter]}
echo "*********************************************"
echo
rsync -av --exclude="*.sh" ${SOURCE_DIR[$counter]} \
${DEST_DIR[$counter]}
echo
done

exit 0;
裡面大部份程式碼都是從網路上的範例 copy 過來,應該還有更好的寫法,但可以正常運作就足夠了。

令我驚訝的是 shell script 內也有 for ... in ... ( 不好意思,我什麼都不知道 ),命令串接也很好用;但變數存取、運算和陣列相關的操作讓我很想用 python ;一些簡單的東西用 shell script 寫起來應該會很方便,只是目前還不熟...

2010年7月18日 星期日

944 Happy Numbers

範圍 1 ~ 99999
( 9^2 ) * 5 = 405
1 ~ 405 共有 67 個 Happy Number

最後卡 WA 的原因是
Print a blank line between two consecutive test cases.

between 而非 after each case ...Orz

2010年7月10日 星期六

mount DVD and windows share folder with chinese characters

在 Windows 下有燒錄一些光碟,裡面資料包含了中文檔名,換用 Linux 讀取時發現全部變成問號,網路上搜尋後發現要在 /etc/fstab 內設定 iocharset=utf8 就能正常顯示中文

/dev/dvd /media/dvd auto ro,user,noauto,unhide,iocharset=utf8 0 0


家中有台 windows 開分享資料夾,要丟資料到那台列印前,先使用

smbclient -L //WINDOWS_SERVER_NAME_OR_IP -U username

輸入正確密碼後,就會列出該台電腦上有分享的服務,確認要連線的分享資料夾後

sudo mount -t cifs -o iocharset=utf8,username=USER_NAME //WINDOWS_SERVER_NAME_OR_IP/SHARE_FOLDER /mnt/SHARE_FOLDER

一樣驗證密碼後就能使用分享資料夾。

在測試的時候才發現不輸入帳號密碼也可以看到 XP 上面的所有磁碟分割和服務,嚇了一跳,趕快把 guest 的帳號停用,另外建帳號作分享之用;查了一下,XP 預設會共用所有磁碟分割 (連線還是要輸入帳號密碼) , 雖然只要管理者有設密碼,就不會隨便被連進去,遠端管理也很方便,但還是覺得不太安心,如果要隱藏共用磁碟的話,可以參考下方第四個連結。

Reference:
如何讓ubuntu顯示ms燒入光碟的文字
[分享] 在 ubuntu 下使用 big5 編碼的光碟片的注意事項

Mount a Windows Shared Folder on Linux with Samba
如何防止 Windows NT Server 4.0 的系統管理共用的建立

2010年4月18日 星期日

[Script] Split audio files by cue

自從去年那篇 Split(Rename) audio files by cue files 後,覺得還要一個一個打指令實在太麻煩了,就自己寫個 script 來完成全部步驟,所需 package 相同, 只是要多加一個 ffmpeg 來幫 ape 轉檔,shnsplit 內建是 mac ,但是原作者網站都掛了,AUR 上又連到 gentoo 的軟體包去抓,實在很怪,就用 ffmpeg 來轉,如果 cue 是 UTF-8 的話會移除 BOM 再餵給 cuebreakpoint 才不會出錯,分割完後使用 cuetag.sh 設定 tag 資訊,但只支援 id3 和 vorbis,最後再改檔名。

下載

內容:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# require: ffmpeg, cuebreakpoint, cueprint, cuetag.sh , shnsplit
# use ffmpeg to convert musics

import sys
import os
import glob
import getopt
import subprocess as sp

###### usage ######
usage = """ \
Usage :
-c cuefile: the cue files to be used
-i file : the music file to be split
-o format : specify the format to be converted
"""

###### main ######

def parse_opt():
c_file = m_file = format = ""
try:
opts, args = getopt.getopt( sys.argv[1:],"c:i:o:" )
for o in opts:
if o[0] == "-c":
c_file = o[1]
elif o[0] == "-i":
m_file = o[1]
elif o[0] == "-o":
format = o[1]

# raise Error if not correct args
for f in [ c_file, m_file, format]:
if f == "": raise ValueError

return c_file ,m_file ,format

except ( getopt.GetoptError, ValueError ):
print usage
sys.exit()

def try_cmd( cmd_arg ):
# error strings
error = ["error", "Error", "ERROR"]
try:
ret = sp.Popen([ cmd_arg ],stdout=sp.PIPE,stderr=sp.PIPE,\
shell=True).communicate()
# if error strings passed to stdout or stderror
# raise error and stop the script
for es in error:
if ( es in ret[0] ) or ( es in ret[1]):
raise OSError( "\n\nExecution failed !!!\n" +\
"error messages :\n\n" +\
ret[0] + ret [1] )
return ret[0]
except OSError, e:
raise

def track_rename( c_file ):
track_names = try_cmd("cueprint -t '%02n. %t\n' " + c_file)
track_names = track_names.split('\n')
tracks = glob.glob("./split_cue_tmp_*")
tracks = sorted( tracks )
file_type = tracks[0].rpartition('.')[2]
zf = zip(tracks, track_names)
for t_name in zf:
print t_name[0], t_name[1]
os.rename( t_name[0], t_name[1] + '.' + file_type)

def remove_BOM( utf8_file ):
with open(utf8_file,'r') as f:
content = f.readlines()

check_c = map( ord, [ c for c in content[0][0:3] ] )

if check_c == [239, 187, 191] :
print "There are BOM inside!"
content[0] = content[0][3:]
with open(utf8_file + ".tmp.cue" , 'w') as f:
f.writelines(content)
return utf8_file + ".tmp.cue"
else:
print "File with no BOM"
return utf8_file

def check_format( m_file, format ):
if format == "":
return False
f_string = [format.lower(), format.upper(), format.capitalize()]
f_info = try_cmd("file " + m_file)
print f_info
for s in f_string:
if s in f_info:
print "Orginal file format is the same as specified !!"
return True
# different file format, need conversion
return False

def split_tracks(c_file, m_file, format):
# mac not installed , use ffmpeg to convert ape
if check_format( m_file, "ape"):
new_m_file = m_file.rpartition('.')[0] + '.' + format.lower()
try_cmd("ffmpeg -i " + m_file + " " + new_m_file)
m_file = new_m_file

# cuebreakpoints |shnsplit
s_args = " -a split_cue_tmp_ -o " + format + " "
try_cmd("cuebreakpoints " + c_file + "|shnsplit " + s_args + m_file)
# use cuetag.sh to add tags (only for vorbis and id3)
try_cmd("cuetag.sh " + c_file + " split_cue_tmp_*")

def main():
c_file, m_file, format = parse_opt()
c_file = remove_BOM( c_file )
split_tracks(c_file, m_file, format)
track_rename(c_file)


if __name__ == "__main__":
main()