2012-04-29

[Linux] 檢查 SAMBA 與 NFS Server 是否存在

通常會透過 /etc/fstab 來處理掛載的設定,然後再使用 mount -a 來重新確認掛載,最好在排程的程序用到掛載目錄時也執行一次 mount -a,掛載目錄在斷線後是不會自動回復的,mount -a 的 Timeout 其實還蠻久的,尤其是 Server 不存在的時候,所以最好還是用對應的 client 先確認 server 是否存在。

而檢查 NFS 的 client 可以用 showmount 來處理,在 Ubuntu 上的安裝方式如下:
sudo aptitude install nfs-common

而 SAMBA 的 client 則是用 smbclient,在 Ubuntu 上的安裝方式如下:
sudo aptitude install smbclient


檢查 NFS Server 是否存在的流程

以 Shell 的方式檢查
# 先以 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

以 PHP 的方式檢查
/*先以 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;
}



檢查 SAMBA Server 是否存在的流程

以 Shell 的方式檢查
# 先以 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

以 PHP 的方式檢查
/*先以 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;
}
2012-04-23

[PHP] 簡易的圖片相似度比較

由於相似图片搜索的php实现的 API 不怎麼符合我的用途,所以我重新定義 API 的架構,改寫成比較簡單的函數方式,雖然還是用物件的方式包裝。

<?php
/**
 * 圖片相似度比較
 *
 * @version     $Id: ImageHash.php 4429 2012-04-17 13:20:31Z jax $
 * @author      jax.hu
 *
 * <code>
 *  //Sample_1
 *  $aHash = ImageHash::hashImageFile('wsz.11.jpg');
 *  $bHash = ImageHash::hashImageFile('wsz.12.jpg');
 *  var_dump(ImageHash::isHashSimilar($aHash, $bHash));
 *
 *  //Sample_2
 *  var_dump(ImageHash::isImageFileSimilar('wsz.11.jpg', 'wsz.12.jpg'));
 * </code>
 */

class ImageHash {

    /**取樣倍率 1~10
     * @access public
     * @staticvar int
     * */
    public static $rate = 2;

    /**相似度允許值 0~64
     * @access public
     * @staticvar int
     * */
    public static $similarity = 80;

    /**圖片類型對應的開啟函數
     * @access private
     * @staticvar string
     * */
    private static $_createFunc = array(
        IMAGETYPE_GIF   =>'imageCreateFromGIF',
        IMAGETYPE_JPEG  =>'imageCreateFromJPEG',
        IMAGETYPE_PNG   =>'imageCreateFromPNG',
        IMAGETYPE_BMP   =>'imageCreateFromBMP',
        IMAGETYPE_WBMP  =>'imageCreateFromWBMP',
        IMAGETYPE_XBM   =>'imageCreateFromXBM',
    );


    /**從檔案建立圖片
     * @param string $filePath 檔案位址路徑
     * @return resource 當成功開啟圖片則回傳圖片 resource ID,失敗則是 false
     * */
    public static function createImage($filePath){
        if(!file_exists($filePath)){ return false; }

        /*判斷檔案類型是否可以開啟*/
        $type = exif_imagetype($filePath);
        if(!array_key_exists($type,self::$_createFunc)){ return false; }

        $func = self::$_createFunc[$type];
        if(!function_exists($func)){ return false; }

        return $func($filePath);
    }


    /**hash 圖片
     * @param resource $src 圖片 resource ID
     * @return string 圖片 hash 值,失敗則是 false
     * */
    public static function hashImage($src){
        if(!$src){ return false; }

        /*缩小圖片尺寸*/
        $delta = 8 * self::$rate;
        $img = imageCreateTrueColor($delta,$delta);
        imageCopyResized($img,$src, 0,0,0,0, $delta,$delta,imagesX($src),imagesY($src));

        /*計算圖片灰階值*/
        $grayArray = array();
        for ($y=0; $y<$delta; $y++){
            for ($x=0; $x<$delta; $x++){
                $rgb = imagecolorat($img,$x,$y);
                $col = imagecolorsforindex($img, $rgb);
                $gray = intval(($col['red']+$col['green']+$col['blue'])/3)& 0xFF;

                $grayArray[] = $gray;
            }
        }
        imagedestroy($img);

        /*計算所有像素的灰階平均值*/
        $average = array_sum($grayArray)/count($grayArray);

        /*計算 hash 值*/
        $hashStr = '';
        foreach ($grayArray as $gray){
            $hashStr .= ($gray>=$average) ? '1' : '0';
        }

        return $hashStr;
    }


    /**hash 圖片檔案
     * @param string $filePath 檔案位址路徑
     * @return string 圖片 hash 值,失敗則是 false
     * */
    public static function hashImageFile($filePath){
        $src = self::createImage($filePath);
        $hashStr = self::hashImage($src);
        imagedestroy($src);

        return $hashStr;
    }


    /**比較兩個 hash 值,是不是相似
     * @param string $aHash A圖片的 hash 值
     * @param string $bHash B圖片的 hash 值
     * @return bool 當圖片相似則回傳 true,否則是 false
     * */
    public static function isHashSimilar($aHash, $bHash){
        $aL = strlen($aHash); $bL = strlen($bHash);
        if ($aL !== $bL){ return false; }

        /*計算容許落差的數量*/
        $allowGap = $aL*(100-self::$similarity)/100;

        /*計算兩個 hash 值的漢明距離*/
        $distance = 0;
        for($i=0; $i<$aL; $i++){
            if ($aHash{$i} !== $bHash{$i}){ $distance++; }
        }

        return ($distance<=$allowGap) ? true : false;
    }


    /**比較兩個圖片檔案,是不是相似
     * @param string $aHash A圖片的路徑
     * @param string $bHash B圖片的路徑
     * @return bool 當圖片相似則回傳 true,否則是 false
     * */
    public static function isImageFileSimilar($aPath, $bPath){
        $aHash = ImageHash::hashImageFile($aPath);
        $bHash = ImageHash::hashImageFile($bPath);
        return ImageHash::isHashSimilar($aHash, $bHash);
    }

}
2012-04-12

[Ubuntu] 時間同步設定

繼上次Ubuntu 時間及時區設定 [Linux]那篇文章後,最近有學到新的時間同步的設定方式。

vim /etc/cron.daily/ntpdate
#!/bin/bash

# Sync NTP Server
ntpdate -s tock.stdtime.gov.tw watch.stdtime.gov.tw time.stdtime.gov.tw clock.stdtime.gov.tw tick.stdtime.gov.tw ntp.ubuntu.com pool.ntp.org

# Update BIOS time
hwclock --systohc

chmod +x /etc/cron.daily/ntpdate
2012-04-11

[MySQL] 整數型態的大小

類型Byte肯定位數最大位數最大值無符號最大值
TINYINT123127255
SMALLINT2453276765535
MEDIUMINT378838860716777215
INT491021474836474294967296
BIGINT81920922337203685477580718446744073709551615