tag:blogger.com,1999:blog-59465307047421309702024-03-06T16:20:07.273+08:00Jax 的工作紀錄除了在整理學習上的經驗,同時也能幫助其他需要的人Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.comBlogger14125tag:blogger.com,1999:blog-5946530704742130970.post-43492161064296939902015-03-04T11:20:00.000+08:002015-03-04T11:20:06.120+08:00[Java] 執行 shell command<pre class="java:nogutter:nocontrols" name="code">Process p = Runtime.getRuntime().exec("ping -n 3 google.com");
p.waitFor();
Scanner sc = new Scanner(p.getInputStream(), "MS950");
String output = sc.useDelimiter("\\Z").next();
sc.close();
System.out.println("exitValue: " + p.exitValue());
System.out.println(output);
</pre><br />
Output:<br />
<pre class="none:nogutter:nocontrols" name="code">exitValue: 0
Ping google.com [173.194.72.138] (使用 32 位元組的資料):
回覆自 173.194.72.138: 位元組=32 時間=21ms TTL=48
回覆自 173.194.72.138: 位元組=32 時間=20ms TTL=48
回覆自 173.194.72.138: 位元組=32 時間=18ms TTL=48
173.194.72.138 的 Ping 統計資料:
封包: 已傳送 = 3,已收到 = 3, 已遺失 = 0 (0% 遺失),
大約的來回時間 (毫秒):
最小值 = 18ms,最大值 = 21ms,平均 = 19ms
</pre>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-49095090587741562782013-05-30T22:21:00.000+08:002013-07-18T12:32:50.903+08:00[PHP] 從網頁執行 SVN 更新想說寫一個透過網頁就可以執行 SVN 更新的程式,結果並不是我想得那樣簡單,有一些眉角需要注意的說。<br />
<br />
先以 Apache 的使用者帳號執行 SVN checkout,這樣 Apache 才有 SVN 的連結權力,才可以透過網頁執行 SVN update<br />
<br />
<pre class="sh" name="code">su -s /bin/bash www-data
cd /var/www
svn checkout http://www.xxx.com/svn/my_site
</pre><br />
<br />
<ol><li>在用 PHP 執行 shell 指令前要加上 <strong>export LANG=C.UTF-8</strong> 的環境宣告,不然 SVN update 時遇到中文會出現 error,Ubuntu 的 Apache 預設是 LANG=C</li>
<li>接著要為 SVN 補上 <strong>--accept theirs-full</strong> 的參數,這是當衝突發生時,都以 SVN Server 的檔案版本為主</li>
<li>最後再加上 <strong>2>&1</strong>,讓 PHP 可以取得包含錯誤的所有訊息</li>
</ol><pre class="php" name="code"><?php
putenv('LANG=C.UTF-8');
$result = shell_exec('svn update --accept theirs-full /var/www/my_site 2>&1');
echo nl2br($result);
</pre>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-6086723317997082992012-04-29T21:16:00.001+08:002012-04-29T21:16:51.090+08:00[Linux] 檢查 SAMBA 與 NFS Server 是否存在通常會透過 <strong>/etc/fstab</strong> 來處理掛載的設定,然後再使用 <strong>mount -a</strong> 來重新確認掛載,最好在排程的程序用到掛載目錄時也執行一次 mount -a,掛載目錄在斷線後是不會自動回復的,mount -a 的 Timeout 其實還蠻久的,尤其是 Server 不存在的時候,所以最好還是用對應的 client 先確認 server 是否存在。 <br />
<br />
而檢查 NFS 的 client 可以用 showmount 來處理,在 Ubuntu 上的安裝方式如下: <br />
<strong>sudo aptitude install nfs-common</strong><br />
<br />
而 SAMBA 的 client 則是用 smbclient,在 Ubuntu 上的安裝方式如下:<br />
<strong>sudo aptitude install smbclient</strong><br />
<br />
<br />
<strong>檢查 NFS Server 是否存在的流程</strong><br />
<br />
以 Shell 的方式檢查<br />
<pre class="sh" name="code"># 先以 client 確認 server 是否存在
/sbin/showmount 192.168.0.6 >/dev/null 2>&1
if [ "j$?" != "j0" ]; then
echo "NFS Server is not exist"
exit 1
fi
# 重新確認掛載
mount -a >/dev/null 2>&1
if [ "j$?" != "j0" ]; then
echo "NFS Server mount failed"
exit 1;
fi
</pre><br />
以 PHP 的方式檢查<br />
<pre class="php" name="code">/*先以 client 確認 server 是否存在*/
$state = shell_exec('/sbin/showmount 192.168.0.6 >/dev/null 2>&1; echo $?');
if(trim($state)!='0'){
echo "NFS Server is not exist";
exit;
}
/*重新確認掛載*/
if(shell_exec('mount -a 2>&1')){
echo "NFS Server mount failed"
exit;
}
</pre><br />
<br />
<br />
<strong>檢查 SAMBA Server 是否存在的流程</strong><br />
<br />
以 Shell 的方式檢查<br />
<pre class="sh" name="code"># 先以 client 確認 server 是否存在
smbclient -NL //192.168.0.6 >/dev/null 2>&1
if [ "j$?" != "j0" ]; then
echo "SAMBA Server is not exist"
exit 1
fi
# 重新確認掛載
mount -a >/dev/null 2>&1
if [ "j$?" != "j0" ]; then
echo "SAMBA Server mount failed"
exit 1;
fi
</pre><br />
以 PHP 的方式檢查<br />
<pre class="php" name="code">/*先以 client 確認 server 是否存在*/
$state = shell_exec('smbclient -NL //192.168.0.6 >/dev/null 2>&1; echo $?');
if(trim($state)!='0'){
echo "SAMBA Server is not exist";
exit;
}
/*重新確認掛載*/
if(shell_exec('mount -a 2>&1')){
echo "SAMBA Server mount failed"
exit;
}
</pre>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-17682424429005087692012-03-16T22:55:00.001+08:002012-03-16T22:59:04.829+08:00[PHP] 檢查 XML 文件結構利用 SimpleXML 去檢查 XML 結構是否符合規格,為了讓這個程式可以多用途,採用了一個基準文件的作為結構準則,依據裡面定義的節點跟屬性,去檢查文件是否符合基本要求的格式。<br />
<br />
<pre class="php" name="code"><?php
/**檢查 XML 文件結構
* @param string $baseFilePath 基準結構文件
* @param string $checkFilePath 待檢查文件
* @return bool 當結構與基準文件相符合時則回傳 true,否則是 false
* */
function checkXmlFileStructure($baseFilePath,$checkFilePath){
/*開啟 Base File*/
if(!file_exists($baseFilePath)){ return false; }
$base = simplexml_load_file($baseFilePath);
if($base===false){ return false; }
/*開啟 Check File*/
if(!file_exists($checkFilePath)){ return false; }
$check = simplexml_load_file($checkFilePath);
if($check===false){ return false; }
/*比較起始點的名稱*/
if($base->getName() != $check->getName()){ return false; }
/*比較結構*/
return checkXmlStructure($base,$check);
}
/**檢查 XML 結構
* @param SimpleXMLElement $base 基準結構物件
* @param SimpleXMLElement $check 待檢查 XML 物件
* @return bool 當結構與基準物件相符合時則回傳 true,否則是 false
* */
function checkXmlStructure($base,$check){
/*檢查屬性*/
foreach ($base->attributes() as $name => $baseAttr){
/*必要的屬性不存在*/
if(!isset($check->attributes()->$name)){ return false; }
}
/*當沒有子節點時,則檢查對象也不能有子節點*/
if(count($base->children())==0){
return (count($check->children())==0);
}
/*將檢查對象的子節點分群*/
$checkChilds = array();
foreach($check->children() as $name => $child){
$checkChilds[$name][] = $child;
}
/*檢查子節點*/
$checked = array();
foreach($base->children() as $name => $baseChild){
/*跳過已經檢查的子節點*/
if(in_array($name, $checked)){ continue; }
$checked[] = $name;
/*檢查必要的子節點是否存在*/
if(empty($checkChilds[$name])){ return false; }
foreach ($checkChilds[$name] as $child){
/*遞迴檢查子節點*/
if( !checkXmlStructure($baseChild, $child) ){ return false; }
}
}
return true;
}
/*==============================================================================*/
if(isset($_SERVER['argv'])){
parse_str(preg_replace('/&[\-]+/','&',join('&',$_SERVER['argv'])), $_GET);
if(empty($_GET['base_file']) || empty($_GET['check_file'])){
echo "Run: ".basename(__FILE__)." base_file=base.xml check_file=check.xml\n"; exit(1);
}
exit( checkXmlFileStructure($_GET['base_file'],$_GET['check_file']) ? 0 : 1);
}else{
if(empty($_GET['base_file']) || empty($_GET['check_file'])){
echo "Run: ".basename(__FILE__)."?base_file=base.xml&check_file=check.xml<br />"; exit;
}
echo( checkXmlFileStructure($_GET['base_file'],$_GET['check_file']) ? '1' : '0');
}
</pre><br />
<br />
<strong>使用方式(shell)</strong><br />
<pre class="sh" name="code">php check_xml_file_structure.php base_file=base.xml check_file=check.xml
if [ "j$?" != "j0" ]; then
echo "Run Error"
fi
</pre><br />
<br />
<strong>測試範例 1</strong><br />
base_1.xml<br />
<pre class="xml" name="code"><?xml version="1.0" encoding="UTF-8"?>
<items>
<item>
<Category>Category文字</Category>
<Title>Title文字</Title>
</item>
</items>
</pre><br />
check_1.xml<br />
<pre class="xml" name="code"><?xml version="1.0" encoding="UTF-8"?>
<items>
<item>
<Category>Category文字</Category>
<Title>Title文字</Title>
</item>
<item>
<Category>Category文字</Category>
<Title>Title文字</Title>
<Description>Description文字</Description>
</item>
</items>
</pre><br />
<br />
<strong>測試範例 2</strong><br />
base_2.xml<br />
<pre class="xml" name="code"><?xml version="1.0" encoding="UTF-8"?>
<items>
<item category="Category文字" Title="Title文字"/>
</items>
</pre><br />
check_2.xml<br />
<pre class="xml" name="code"><?xml version="1.0" encoding="UTF-8"?>
<items>
<item category="Category文字" Title="Title文字" Description="Description文字" />
<item category="Category文字" Title="Title文字" />
<item category="Category文字" Title="Title文字" Description="Description文字" />
</items>
</pre>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-79472047259197573052012-03-08T16:00:00.000+08:002012-03-08T16:00:19.738+08:00[Linux] 使用 MD5 檢查 FTP 上傳的檔案<pre class="sh" name="code">#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
MAIL_TO="my_mail@gmail.com"
TARGET_PATH="/var/www/file/show.mp4"
FILE="upload_file"
EXTEND="mp4"
cd /home/ftp_user
# md5 file is not exist
if [ ! -f $FILE.md5 ]; then exit 0; fi
# MD5 check sum
md5sum -c $FILE.md5 >/dev/null 2>&1
if [ "j$?" != "j0" ]; then
# Notice: md5 check fail
echo "" |mail -s "[Failed] $FILE.$EXTEND md5 check sum fail" $MAIL_TO
rm -f ./$FILE.md5
exit 1;
fi
mv ./$FILE.$EXTEND $TARGET_PATH
rm -f ./$FILE.md5
exit 0;
</pre>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-35887615674236923632011-09-13T18:01:00.000+08:002013-06-10T22:51:39.689+08:00[轉載] Linux shell script 的彩色控制轉載自:<a target="_blank" href="http://tinux.no-ip.com/wordpress/?p=89">Linux shell script 的彩色控制</a><br />
<br />
Linux 下的終端機畫面不是只能換換背景而已,顯示出來的顏色也是能控制的。使用的顏色就像以前的DOS 時代,或者現在的BBS 顏色控制方式一樣。<br />
<br />
以shell 的顯示為例,顯示的格式如下:<br />
<br />
\33[ 文字樣式 ; 文字顏色 ; 背景顏色 m<br />
文字內容………………<br />
\33[0m<br />
<br />
文字樣式有列下幾種色碼可以使用:<br />
<ul><li>0 一般亮度</li>
<li>1 高度度</li>
<li>4 加底線</li>
<li>5 灰底</li>
</ul><br />
文字顏色則都是3開頭,有下列色碼:<br />
<ul><li>30 黑色</li>
<li>31 紅色</li>
<li>32 綠色</li>
<li>33 黃色</li>
<li>34 藍色</li>
<li>35 紫色</li>
<li>36 青綠</li>
<li>37 白色</li>
</ul><br />
再來是背景顏色色碼,都是4開頭:<br />
<ul><li>40 黑色</li>
<li>41 紅色</li>
<li>42 綠色</li>
<li>43 黃色</li>
<li>44 藍色</li>
<li>45 紫色</li>
<li>46 青綠</li>
<li>47 白色</li>
</ul><br />
如果我要在畫面上顯示高亮度的綠色(32)及黑色背景,可以如下:<br />
<pre class="sh:nocontrols" name="code">sprintf "\33[1;32;40m 我的文字 \33[0m"
</pre><br />
也可以分開來寫比較清楚<br />
<pre class="sh:nocontrols" name="code">sprintf "\33[1;32;40m "
sprintf "我的文字"
sprintf "\33[0m"
</pre><br />
記得shell 輸出碼要用 printf 而不是用一般的 echo。echo 的話要寫成 echo -e 。<br />
但並不是所有的終端機畫面都是用黑色背景的。如果我們不要指定它的黑色背景,讓它使用系統原始背景色,可以省略背景描述變成如下:<br />
<pre class="sh:nocontrols" name="code">sprintf "\033[1;32m"
sprintf "我的文字"
sprintf "\033[0m"
</pre><br />
是不是就比較完美了呢。<br />
<br />
其實這些控制碼和BBS 的還真像。Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-49574951393655037392011-04-07T17:25:00.001+08:002013-08-06T22:45:09.809+08:00[轉載][Shell] if 條件式選項列表轉載自:<a target="_blank" href="http://linux.vbird.org/linux_basic/0340bashshell-scripts.php#test">利用 test 指令的測試功能 - 鳥哥的 Linux 私房菜 -- 學習 Shell Scripts</a><br />
<br />
<table class="table_list" width="100%" cellspacing="0" cellpadding="3" border="1"><caption>1. 關於某個檔名的『檔案類型』判斷</caption>
<tr class="header"><th>標誌</th><th>意義</th><th>範例</th></tr>
<tr><td><b>-e</b></td><td>$FILE 是否存在?(常用)</td><td>if[ -e $FILE ]; then</td></tr>
<tr><td><b>-f</b></td><td>$FILE 是否存在且為檔案(file)?(常用)</td><td>if[ -f $FILE ]; then</td></tr>
<tr><td><b>-d</b></td><td>$FILE 是否存在且為目錄(directory)?(常用)</td><td>if[ -d $FILE ]; then</td></tr>
<tr><td><b>-b</b></td><td>$FILE 是否存在且為一個 block device 裝置?</td><td>if[ -b $FILE ]; then</td></tr>
<tr><td><b>-c</b></td><td>$FILE 是否存在且為一個 character device 裝置?</td><td>if[ -c $FILE ]; then</td></tr>
<tr><td><b>-S</b></td><td>$FILE 是否存在且為一個 Socket 檔案?</td><td>if[ -S $FILE ]; then</td></tr>
<tr><td><b>-p</b></td><td>$FILE 是否存在且為一個 FIFO (pipe) 檔案?</td><td>if[ -p $FILE ]; then</td></tr>
<tr><td><b>-L</b></td><td>$FILE 是否存在且為一個連結檔?</td><td>if[ -L $FILE ]; then</td></tr>
</table><br />
<table class="table_list" width="100%" cellspacing="0" cellpadding="3" border="1"><caption>2. 關於檔案的權限偵測,如 -r $FILE 表示可讀否 (但 root 權限常有例外)</caption>
<tr class="header"><th>標誌</th><th>意義</th><th>範例</th></tr>
<tr><td><b>-r</b></td><td>偵測該檔名是否存在且具有『可讀』的權限?</td><td>if[ -r $FILE ]; then</td></tr>
<tr><td><b>-w</b></td><td>偵測該檔名是否存在且具有『可寫』的權限?</td><td>if[ -w $FILE ]; then</td></tr>
<tr><td><b>-x</b></td><td>偵測該檔名是否存在且具有『可執行』的權限?</td><td>if[ -x $FILE ]; then</td></tr>
<tr><td><b>-u</b></td><td>偵測該檔名是否存在且具有『SUID』的屬性?</td><td>if[ -u $FILE ]; then</td></tr>
<tr><td><b>-g</b></td><td>偵測該檔名是否存在且具有『SGID』的屬性?</td><td>if[ -g $FILE ]; then</td></tr>
<tr><td><b>-k</b></td><td>偵測該檔名是否存在且具有『Sticky bit』的屬性?</td><td>if[ -k $FILE ]; then</td></tr>
<tr><td><b>-s</b></td><td>偵測該檔名是否存在且為『非空白檔案』?</td><td>if[ -s $FILE ]; then</td></tr>
</table><br />
<table class="table_list" width="100%" cellspacing="0" cellpadding="3" border="1"><caption>3. 兩個檔案之間的比較</caption>
<tr class="header"><th>標誌</th><th>意義</th><th>範例</th></tr>
<tr><td><b>-nt</b></td><td>(newer than)判斷 $FILE1 是否比 $FILE2 新</td><td>if[ $FILE1 -nt $FILE2 ]; then</td></tr>
<tr><td><b>-ot</b></td><td>(older than)判斷 $FILE1 是否比 $FILE2 舊</td><td>if[ $FILE1 -ot $FILE2 ]; then</td></tr>
<tr><td><b>-ef</b></td><td>判斷 $FILE1 與 $FILE2 是否為同一檔案, <br />
可用在判斷 hard link 的判定上。 <br />
主要意義在判定,兩個檔案是否均指向同一個 inode 哩!</td><td>if[ $FILE1 -ef $FILE2 ]; then</td></tr>
</table><br />
<table class="table_list" width="100%" cellspacing="0" cellpadding="3" border="1"><caption>4. 關於兩個整數之間的判定</caption>
<tr class="header"><th>標誌</th><th>意義</th><th>範例</th></tr>
<tr><td><b>-eq</b></td><td>兩數值相等 (equal)</td><td>if[ n1 -eq n2 ]; then</td></tr>
<tr><td><b>-ne</b></td><td>兩數值不等 (not equal)</td><td>if[ n1 -ne n2 ]; then</td></tr>
<tr><td><b>-gt</b></td><td>n1 大於 n2 (greater than)</td><td>if[ n1 -gt n2 ]; then</td></tr>
<tr><td><b>-lt</b></td><td>n1 小於 n2 (less than)</td><td>if[ n1 -lt n2 ]; then</td></tr>
<tr><td><b>-ge</b></td><td>n1 大於等於 n2 (greater than or equal)</td><td>if[ n1 -ge n2 ]; then</td></tr>
<tr><td><b>-le</b></td><td>n1 小於等於 n2 (less than or equal)</td><td>if[ n1 -le n2 ]; then</td></tr>
</table><br />
<table class="table_list" width="100%" cellspacing="0" cellpadding="3" border="1"><caption>5. 判定字串的資料</caption>
<tr class="header"><th>標誌</th><th>意義</th><th>範例</th></tr>
<tr><td><b>-z</b></td><td>判定字串是否為 0 ?若 $STR 為空字串,則為 true</td><td>if[ -z $STR ]; then</td></tr>
<tr><td><b>-n</b></td><td>判定字串是否非為 0 ?若 $STR 為空字串,則為 false。 <br />
註: -n 亦可省略 </td><td>if[ -n $STR ]; then</td></tr>
<tr><td><b>=</b></td><td>判定 $STR1 是否等於 $STR2 ,若相等,則回傳 true</td><td>if[ $STR1 = $STR2 ]; then</td></tr>
<tr><td><b>!=</b></td><td>判定 $STR1 是否不等於 $STR2 ,若相等,則回傳 false</td><td>if[ $STR1 != $STR2 ]; then</td></tr>
</table><br />
<table class="table_list" width="100%" cellspacing="0" cellpadding="3" border="1"><caption>6. 多重條件判定</caption>
<tr class="header"><th>標誌</th><th>意義</th><th>範例</th></tr>
<tr><td><b>-a</b></td><td>(and)兩狀況同時成立</td><td>if[ -r $FILE -a -x $FILE ]; then</td></tr>
<tr><td><b>-o</b></td><td>(or)兩狀況任何一個成立</td><td>if[ -r $FILE -o -x $FILE ]; then</td></tr>
<tr><td><b>!</b></td><td>反相狀態</td><td>if[ ! -x $FILE ]; then</td></tr>
</table>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-28236959073330723892011-01-25T11:09:00.000+08:002011-01-25T11:09:03.157+08:00[Shell] backup mysql data by day (note)<pre class="sh" name="code">#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH
DATE=$(date +%Y%m%d)
TARGET=/root/my_backup
OPT="--opt -c -n -t --skip-triggers"
ID="root"
PW="1234"
DB="mydb"
TMP=$TARGET/$DB.$DATE.bak.sql"
BAK=$TARGET/$DB.$DATE.bak.tgz"
#==( Backup MySQL )=======================================
mysqldump -u$ID -P$PW $OPT $DB > $TMP
tar -zcf $BAK $TMP
rm $TMP
exit 0
</pre>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-24128424277222021552011-01-25T10:14:00.001+08:002014-03-05T14:47:09.639+08:00[Shell] 依據遠端清單進行目錄同步這個任務的狀況是:<br />
有些新的檔案會被加入,而舊的檔案會被移除,檔案的內容基本上是不會變動的,所以可透過檔名來進行同步。<br />
<br />
<br />
檔案下載與錯誤處理:<br />
這裡用 curl 來處理下載的問題,並且當發生錯誤時重試三次。<br />
<pre class="sh" name="code">#!/bin/bash
# download_file.sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH
LIMIT=3 # retry 3 times
LOCAL_PATH=$1
REMOTE_URL=$2
FILE_NAME=$3
while [ $LIMIT \> 0 ] ; do
#echo $REMOTE_URL/$FILE_NAME
rm -f $LOCAL_PATH/$FILE_NAME.tmp
curl -f -o $LOCAL_PATH/$FILE_NAME.tmp $REMOTE_URL/$FILE_NAME > /dev/null
if [ "$?" == "0" ]; then
mv -f $LOCAL_PATH/$FILE_NAME.tmp $LOCAL_PATH/$FILE_NAME
exit 0;
fi
LIMIT=$(($LIMIT-1))
done
exit 1;
</pre><br />
<br />
清單比較:<br />
從遠端下載檔案清單與本地端的目錄進行比對,並處理刪除跟下載的動作。<br />
<pre class="sh" name="code">#!/bin/bash
# folder_sync.sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH
REMOTE_URL=http://remote_site/pics
REMOTE_LIST_URL=http://remote_site/pics/file.list
LOCAL_PATH=/var/www/pics
# get remote list
REMOTE_LIST=$(curl -f $REMOTE_LIST_URL |tr -d '\r')
if [ "$?" != "0" ]; then exit 1; fi
# get local list
cd $LOCAL_PATH
LOCAL_LIST=$(ls -1)
if [ "$?" != "0" ]; then
LOCAL_LIST=""
fi
# Check loacl file exists in the list
for ITEM in $LOCAL_LIST ; do
echo "$REMOTE_LIST" |grep "^$ITEM\$" > /dev/null
if [ "$?" != "0" ]; then
# delete old file
rm -f $ITEM &> /dev/null
fi
done
# Check remote file exists in the list
for ITEM in $REMOTE_LIST ; do
echo "$LOCAL_LIST" |grep "^$ITEM\$" > /dev/null
if [ "$?" != "0" ]; then
# download new file
download_file.sh $LOCAL_PATH $REMOTE_URL $ITEM &> /dev/null
fi
done
exit 0;
</pre>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-28547533967342641542011-01-24T16:29:00.003+08:002014-03-05T14:47:09.642+08:00[Shell] 透過版本編號與遠端的 package 同步有一個的任務是要將一個用 tar 封裝的目錄從 server 端同步到 client 上,然後有機個考量點:<br />
<ul><li>必須確保 client 永遠都讀得到資料</li>
<li>最小的資料中斷</li>
<li>最小的硬碟存取</li>
<li>必要的錯誤處理</li>
</ul><br />
<br />
建立 server 端的 package<br />
<pre class="sh" name="code">#!/bin/bash
# package_build.sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH
PROJECT_NAME=metadata
SOURCE_PATH=/var/projects
PORTING_PATH=/var/www
PACKAGE_NAME=$PROJECT_NAME.$(/bin/date +%s)
OLD_PACKAGE=$(find $PORTING_PATH -name "$PROJECT_NAME.*.tgz")
# Create Package
cd $SOURCE_PATH/$PROJECT_NAME
tar -zcf $PORTING_PATH/$PACKAGE_NAME.tgz ./*
# Update version number to release
echo $PACKAGE_NAME > $PORTING_PATH/$PROJECT_NAME.latest
# remove old version
#rm -f $OLD_PACKAGE
echo -e "<< $PACKAGE_NAME package complete >>"
exit 0
</pre><br />
<br />
client 端的同步處理<br />
<pre class="sh" name="code">#!/bin/bash
# package_sync.sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH
REMOTE_URL=http://remote_site/
TARGET_PATH=/var/www
PROJECT_NAME=metadata
PROJECT_PATH=$TARGET_PATH/$PROJECT_NAME
# get now version
NOW_VERSION=$PROJECT_NAME.0000000000
if [ -h "$PROJECT_PATH" ] && [ -d "$PROJECT_PATH" ]; then
NOW_VERSION=$(readlink $PROJECT_PATH)
fi
echo -e 'NOW_VERSION' $NOW_VERSION
# get remote version
REMOTE_VERSION=$(curl -f $REMOTE_URL/$PROJECT_NAME.latest |tr -d '\r')
if [ "j$?" != "j0" ]; then exit 1; fi
echo -e 'REMOTE_VERSION' $REMOTE_VERSION
# deff version, not deff goto exit.
if [ ! "$NOW_VERSION" \< "$REMOTE_VERSION" ]; then exit 0; fi
echo -e "Update package"
# create now version folder
mkdir -p $TARGET_PATH/$REMOTE_VERSION
if [ "$?" != "0" ]; then exit 1; fi
# Download Package
cd $TARGET_PATH/$REMOTE_VERSION
curl -o $PROJECT_NAME.tgz $REMOTE_URL/$REMOTE_VERSION.tgz
if [ "$?" != "0" ]; then exit 1; fi
# Decompression Package
tar -zxf $PROJECT_NAME.tgz
rm -f $PROJECT_NAME.tgz
# Update version link
cd $TARGET_PATH
ln -sfn $REMOTE_VERSION $PROJECT_NAME
# remove old version
rm -rf $NOW_VERSION
exit 0;
</pre>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-18941081355548729082011-01-24T13:47:00.003+08:002011-01-25T10:16:23.747+08:00[Shell] 等待所有子程序結束當在用 shell 開其他子程序時,通常會希望在所有程序結束時做一些處理,最簡單的方式就是用一支迴圈去等待其他子程序的結束,這裡用到 jobs 這個指令去檢查子程序是不是還在執行。<br />
<br />
<pre class="sh" name="code">#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH
# job msg log temp file
MSG_LOG=/tmp/job_log
rm -f $MSG_LOG
# background job function
bg_job(){
JOB=$1
sleep $JOB
echo $JOB "End" >> $MSG_LOG
}
JOB_LIST=(
"5"
"6"
"3"
"4"
)
# run all job
for FLASH in "${JOB_LIST[@]}" ; do
bg_job $FLASH &
done
# Waiting for the end of all the job
while [ "j$(jobs -r)" != "j" ] ; do
sleep 1
done
# show job msg
cat $MSG_LOG
echo "<< bg_job all complete >>"
exit 0;
</pre>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-44675983534248874342011-01-19T01:20:00.005+08:002011-01-25T11:11:17.701+08:00[Shell] 使用 sfdisk 分割硬碟<pre class="sh" name="code">#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH
# disk path
DEVICE=/dev/sdb
# use sfdisk create device partition,size by Megabyte
sfdisk -uM $DEVICE <<EOF
,512
,512
EOF
# format to ext2
mke2fs $DEVICE"1"
mke2fs $DEVICE"2"
exit 0;
</pre>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-10560751569134164932010-10-12T10:19:00.004+08:002012-03-08T16:01:43.518+08:00[Shell] FTP 上傳<pre class="sh" name="code">#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH
#==( 上傳至 FTP )==
ftp -i -n 192.168.2.100 <<FTPIT
user username password
bin
put /home/user/local_file /home/user/remote_file
quit
FTPIT
exit 0
</pre>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-22950943020519977482009-03-19T01:25:00.012+08:002011-05-06T18:13:43.461+08:00[Shell] 利用 tar 作資料備份一般在 console 使用 tar 做備份壓縮時,都會習慣使用<span style="color: rgb(255, 0, 0); font-weight: bold;">相對路徑做壓縮</span>,在解壓縮時也比較方便,可是再寫 Shell 做 crontab 排程時,也想要使用相對路徑做壓縮的話,必須用一些方法,下面的 script 還加上過濾檔案的機制,可以<span style="color: rgb(255, 0, 0); font-weight: bold;">排除一些隱藏檔或特定目錄</span>的備份。<br />
<br />
<pre class="sh" name="code">#!/bin/bash
# Program : 備份指定目錄
# History : 2009/03/19
# Author : Jax
# E-mail : weskerjax@gmail.com
# Website : http://jax-work-archive.blogspot.com/
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH
# 排除不需要備份的檔案類型
EXCLUDE=""
FILTER=(
"*.bak" # 排除副檔名為 .bak 的檔案
".*" # 排除所有隱藏檔
"/CVS/" # 排除所有目錄為 CVS 的目錄
"Smarty/cache" # 排除路徑為 Smarty/cache 的目錄
"Smarty/tpl_c" # 排除路徑為 Smarty/tpl_c 的目錄
)
for i in "${FILTER[@]}" ; do
EXCLUDE="$EXCLUDE --exclude=$i"
done
# 時間參數
DATE=$(date +%Y%m%d)
# 配份目錄
TARGET_DIR="/home/web"
# 備份檔名路徑目錄
ZIP_FILE="/home/backup/backup_$DATE.tar.bz2"
# 執行壓縮指令
tar -jcf $ZIP_FILE $EXCLUDE -C $TARGET_DIR $(ls $TARGET_DIR)
exit 0;
</pre><br />
<br />
原始檔:<a target="_blank" href="http://sites.google.com/site/weskerjax/code-demo/server_backup.sh">server_backup.sh</a>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0