ruby和linux shell共同編程的樣本,rubyshell
有了shell為毛還要ruby呢?話不能這麼說,有些小功能用ruby還是很方便的,比如說字串的反轉再加1功能用shell來寫就比較麻煩.str="123456",我們定義一個反轉後再+1的小方法:
2.1.5 :020 > class String2.1.5 :021?> def r_add_12.1.5 :022?> replace reverse.each_byte.map {|byte|byte+1}.pack("c*")2.1.5 :023?> end2.1.5 :024?> end
執行後str變為:
2.1.5 :026 > "123456".r_add_1
=> "765432"
下面我們寫一個指令碼把shell中的變數r_add_1一下:
#!/opt/local/bin/bashexport id="abc123456789" #justcat <<EOF | ruby |read retclass Stringdef r_add_1replace reverse.each_byte.map {|b|b+1}.pack("c*")endendputs ENV["id"].dup.r_add_1EOF
執行一下看看:
apple@kissAir: ruby_src$./read.sh
apple@kissAir: ruby_src$echo $ret
apple@kissAir: ruby_src$
咦,為毛ret變數為空白值啊?道理很簡單:管道2側是2個不同進程,加上主bash的進程,一共是3個進程。你不用指望read ret進程建立的變數會在主bash進程中生效啊!一種解決辦法是用小括弧強制read ret和echo在一個進程中執行以擷取返回值:cat <<EOF|ruby|(read ret;echo $ret):
apple@kissAir: ruby_src$./read.sh
:98765432dcb
必須要加小括弧哦,否則read ret和echo還是在2個進程,等於做無用功啊!你可以這樣做:
apple@kissAir: ruby_src$my_val=$(./read.sh)
apple@kissAir: ruby_src$echo $my_val
:98765432dcb
這樣就將返回結果儲存在主bash進程中的my_val變數中了哦。或者你在while迴圈中自己處理吧,因為while迴圈和read也在一個進程裡哦,改寫後的shell代碼如下:
#!/opt/local/bin/bashexport id="abc123456789"#只是樣本,實際可以動態擷取id的值cat <<EOF | ruby | while read ret;do echo ">>>>" $ret;doneclass Stringdef r_add_1replace reverse.each_byte.map {|b|b+1}.pack("c*")endendputs ENV["id"].dup.r_add_1EOF
你要是覺得看的cat那一行太長,可以把do...done放到EOF結尾的後面,效果是一樣的:
#!/opt/local/bin/bashexport id="abc123456789"#只是樣本,實際可以動態擷取id的值cat <<EOF | ruby | while read retclass Stringdef r_add_1replace reverse.each_byte.map {|b|b+1}.pack("c*")endendputs ENV["id"].dup.r_add_1EOFdo echo ">>>>" $retdone
最後執行read.sh都會顯示:
apple@kissAir: ruby_src$./read.sh
>>>> :98765432dcb
一切皆有可能!你最後肯定還會問:為毛我不用$my_val=$(ruby -e"xxx")這種純ruby的更簡單方法,而要用shell+ruby混合的複雜方法呢??答案是:我不是在舉ruby+shell的例子嗎!? 呵呵