tag:blogger.com,1999:blog-59465307047421309702024-03-06T16:20:07.273+08:00Jax 的工作紀錄除了在整理學習上的經驗,同時也能幫助其他需要的人Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.comBlogger44125tag:blogger.com,1999:blog-5946530704742130970.post-73823492425666495782013-05-29T20:38:00.000+08:002013-06-10T22:26:29.107+08:00[轉載][Ubuntu] 檔案系統格式簡介發信人: tdb.bbs@ptt.cc (tbd), 看板: Linux<br />
標 題: [分享] 檔案系統格式簡介<br />
發信站: 批踢踢實業 (Wed Jul 19 06:22:33 2006)<br />
轉信站: SayYa!ctu-reader!news.nctu!ptt<br />
Origin: sally.csie.ntu.edu.tw<br />
<br />
在 MS Winsows 的世界,硬碟可以格式化成 NTFS、FAT32、FAT16 等等。相同的,在 GNU/Linux 底下也是有很多不同的檔案系統格式可以選擇喔。目前在 GNU/Linux 底下,比較常用的有以下這幾種格式 Ext3, ReiserFS, XFS 和 JFS 等數種。當然各種格式都有其憂缺點,所以我們將在下面給與簡單的介紹。<br />
<br />
除了 Ext2 以外,其它幾種都是日誌型檔案系統。那什們是日誌系統呢?就是系統會多用一些額外的空間紀錄硬碟的資料狀態,因而在不正常開關機後,不需整個硬碟從新掃描,來恢復系統狀態。<br />
<br />
<br />
<strong>Ext2</strong><br />
此為一非常老舊且不支援日誌系統的檔案系統格式,早期 Linux 玩家還記得吧,每次不正常關機後,重新開機時錯誤檢查很久,且在沒有正常關機下,常常會讓您一次不見很多檔案,現在很少人使用這款檔案系統了!<br />
<br />
<strong>Ext3</strong><br />
為 Ext2 個改良版,所以 Ext2 可以直接升級成為 Ext3 而不必從新格式化,這也可以讓舊的 Ext2 系統更加穩定。而主要和 Ext2 的差別是,增加了日誌系統 (metadata),所以在不正常開關機時,可以迅速使系統恢復。而因為它舊有的系統相容,和所以很多發行版預設使用 Ext3。而在實際測試上,它的硬碟使用率不佳,大概只有真正空間的 93%會被使用到,並且其它效能測試表現中等。而且它在格式化與建立檔案系統的時間也是其它種類的數十倍。<br />
<br />
<strong>ReiserFS</strong> - <a target="_blank" href="http://www.namesys.com">http://www.namesys.com</a><br />
它是採用日誌型系統,為 Hans Reiser 所創使,所以以他的名子命名。技術上使用的是 B*-tree 為基礎的檔案系統,其特色為能很有效率地處理大型檔案到眾多小檔案都可以用很高的效率處理。實務上 ReiserFS 在處理檔案小於 1k 小檔案時,甚至效率可以比 Ext3 快約 10 倍,所以 ReiserFS 專長在處理很多小檔案。而在一般操作上,它的效能表現也有中上的程度。<br />
<br />
<strong>XFS</strong> - <a target="_blank" href="http://oss.sgi.com/projects/xfs/">http://oss.sgi.com/projects/xfs/</a><br />
為繪圖工作站公司 SGI 為了高級繪圖處理器系統 IRIX 所設計的檔案格式,也是日誌型系統。而 SGI 亦將其移植到 GNU/Linux 上。而他本來是針對高效能繪圖設計,且為高階工作站使用,所以他在穩定行和效率是無雍致疑的。而在實務上的表現,它的處理各種檔案大小混合的情況下效率最好,並且在一般使用上有不錯的表現。<br />
<br />
<strong>JFS</strong> - <a target="_blank" href="http://jfs.sourceforge.net">http://jfs.sourceforge.net</a><br />
為全球最大電腦供應商 IBM 為 AIX 系列設計的日誌型檔案系統,技術上使用的是 B+-tree 為基礎的檔案系統,和 ReiserFS 使用 B*-tree 不同。而在穩定度上,IBM AIX 伺服器使用它,而此系列機器很多都在金融上使用,所以穩定是沒話說的。而它最重要的特色是在處理檔案 I/O 的時候,是這些檔案系統裏面最不佔 CPU 資源的,也就是 CPU 使用率最低。但在這樣節省使用 CPU 的情況下,它的效率表現也有中上以上的程度。<br />
<br />
<br />
雖然 Ext3 效能不好 (在日誌型檔案系統中效率上最糟糕的),那為何那們多人使用?那是因為當時 Ext3 可以直接從 Ext2 升級,而不需要先備份然後格式化後再把檔案拷備回去,所以造成使用人數較多了。但這也是不能怪它,因為它為了和 Ext2 相容,所以有很多的歷史包袱存在。因此我建議新的電腦考慮使用 ReiserFX,XFS 或 JFS。若是以效能為考慮,則可以選擇 ReiserFS 或 XFS。若是系統資源不多,要使用最低的 CPU 使用率,那們可以選擇 JFS,它有著最好的效能資源比。<br />
<br />
而網路上有一些檔案系統效能評估,這裡列出來給讀者參考一下<br />
<br />
<a target="_blank" href="http://www.debian-administration.org/articles/388">http://www.debian-administration.org/articles/388</a><br />
<a target="_blank" href="http://fsbench.netnation.com/">http://fsbench.netnation.com/</a><br />
<a target="_blank" href="http://linuxgazette.net/122/TWDT.html">http://linuxgazette.net/122/TWDT.html</a><br />
<a target="_blank" href="http://linuxgazette.net/102/piszcz.html">http://linuxgazette.net/102/piszcz.html</a>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com4tag:blogger.com,1999:blog-5946530704742130970.post-89624465096605849712012-09-05T13:01:00.004+08:002023-02-25T21:38:11.120+08:00[Ubuntu] 用 logrotate 定期切割 Apache log 檔Ubuntu 預設已經為 Apache 建立了 log 分割管理,但在建立虛擬主機(Virtual Host),但又很龜毛的將 log 獨立到個別的子目錄下的話,預設的 logrotate 是沒有辦法處理到的,所以請記得為這龜毛的動作加上額外設定。<br />
<br />
編輯屬於 Apache 的設定檔,在檔案最後面加上額外的設定。<br />
<b>vim /etc/logrotate.d/apache2</b><br />
<pre class="cfg" name="code">/var/log/apache2/blog/*.log {
daily
missingok
rotate 52
dateext
compress
delaycompress
notifempty
create 640 root adm
sharedscripts
postrotate
/etc/init.d/apache2 reload > /dev/null
endscript
}
</pre><br />
參數說明:<br />
<b>daily</b> 每天整理,其他還有 weekly, monthly, yearly<br />
<b>missingok</b> 允許 log 檔不存在<br />
<b>nomissingok</b> 不允許 log 檔不存在,會丟出錯誤 (預設)<br />
<b>rotate 7</b> 保留 7 次的分割<br />
<b>size 1M</b> 大小超過 1M 就執行分割,單位可以是 1024, 100k, 4M, 1G<br />
<b>dateext</b> 用日期來建立分割檔名,而非流水號<br />
<b>dateformat -%Y%m%d</b> 日期格式<br />
<b>compress</b> 壓縮分割,預設用 gzip (預設)<br />
<b>nocompress</b> 不壓縮分割<br />
<b>delaycompress</b> 延後壓縮直到下一次 rotate<br />
<b>notifempty</b> 如果 log 是空的就不執行<br />
<b>copytruncate</b> 以[複製清空]的方式分割 log,這樣可以用不到 postrotate 設定<br />
<b>mail xxx@address</b> 將分割內容用 mail 寄出<br />
<b>prerotate/endscript</b> 分割前要執行的指令<br />
<b>postrotate/endscript</b> 分割後要執行的指令 <br />
<br />
<br />
測試設定檔是否正確<br />
<b>logrotate -f /etc/logrotate.conf</b> <br />
<br />
<br />
參考來源:<br />
<a target="_blank" href="http://ihower.tw/blog/archives/3565/">使用 logrotate 定期整理 Rails Log 檔案</a><br />
<a target="_blank" href="http://blog.jsdan.com/3616">[ubuntu] 使用 logrotate 定期切割壓縮 apache2 的 log 檔</a>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-13295502360347923762012-05-05T01:53:00.000+08:002013-06-10T22:34:10.512+08:00[轉載] 让PHP更快的提供文件下载作者:<a target="_blank" href="http://www.laruence.com/">Laruence</a><br />
本文地址:<a target="_blank" href="http://www.laruence.com/2012/05/02/2613.html">http://www.laruence.com/2012/05/02/2613.html</a><br />
<br />
一般来说, 我们可以通过直接让URL指向一个位于Document Root下面的文件, 来引导用户下载文件.<br />
<br />
但是, 这样做, 就没办法做一些统计, 权限检查, 等等的工作. 于是, 很多时候, 我们采用让PHP来做转发, 为用户提供文件下载.<br />
<br />
<pre class="php" name="code"><?php
$file = "/tmp/dummy.tar.gz";
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="'
. basename($file) . '"');
header("Content-Length: ". filesize($file));
readfile($file);
</pre><br />
但是这个有一个问题, 就是如果文件是中文名的话, 有的用户可能下载后的文件名是乱码.<br />
<br />
于是, 我们做一下修改(参考: :<br />
<br />
<pre class="php" name="code"><?php
$file = "/tmp/中文名.tar.gz";
$filename = basename($file);
header("Content-type: application/octet-stream");
//处理中文文件名
$ua = $_SERVER["HTTP_USER_AGENT"];
$encoded_filename = urlencode($filename);
$encoded_filename = str_replace("+", "%20", $encoded_filename);
if (preg_match("/MSIE/", $ua)) {
header('Content-Disposition: attachment; filename="'
. $encoded_filename . '"');
} else if (preg_match("/Firefox/", $ua)) {
header("Content-Disposition: attachment; filename*=\"utf8''"
. $filename . '"');
} else {
header('Content-Disposition: attachment; filename="'
. $filename . '"');
}
header('Content-Disposition: attachment; filename="'
. $filename . '"');
header("Content-Length: ". filesize($file));
readfile($file);
</pre><br />
恩, 现在看起来好多了, 不过还有一个问题, 那就是readfile, 虽然PHP的readfile尝试实现的尽量高效, 不占用PHP本身的内存, 但是实际上它还是需要采用MMAP(如果支持), 或者是一个固定的buffer去循环读取文件, 直接输出.<br />
<br />
输出的时候, 如果是Apache + PHP mod, 那么还需要发送到Apache的输出缓冲区. 最后才发送给用户. 而对于Nginx + fpm如果他们分开部署的话, 那还会带来额外的网络IO.<br />
<br />
那么, 能不能不经过PHP这层, 直接让Webserver直接把文件发送给用户呢?<br />
<br />
今天, 我看到了一个有意思的文章: <a target="_blank" href="http://www.jasny.net/articles/how-i-php-x-sendfile/">How I PHP: X-SendFile</a>.<br />
<br />
我们可以使用Apache的module <a target="_blank" href="https://tn123.org/mod_xsendfile/">mod_xsendfile</a>, 让Apache直接发送这个文件给用户:<br />
<br />
<pre class="php" name="code"><?php
$file = "/tmp/中文名.tar.gz";
$filename = basename($file);
header("Content-type: application/octet-stream");
//处理中文文件名
$ua = $_SERVER["HTTP_USER_AGENT"];
$encoded_filename = urlencode($filename);
$encoded_filename = str_replace("+", "%20", $encoded_filename);
if (preg_match("/MSIE/", $ua)) {
header('Content-Disposition: attachment; filename="'
. $encoded_filename . '"');
} else if (preg_match("/Firefox/", $ua)) {
header("Content-Disposition: attachment; filename*=\"utf8''"
. $filename . '"');
} else {
header('Content-Disposition: attachment; filename="'
. $filename . '"');
}
header('Content-Disposition: attachment; filename="'
. basename($file) . '"');
//让Xsendfile发送文件
header("X-Sendfile: $file");
</pre><br />
X-Sendfile头将被Apache处理, 并且把响应的文件直接发送给Client.<br />
<br />
Lighttpd和Nginx也有类似的模块, 大家有兴趣的可以去找找看<br />
<br />
<hr />mod-xsendfile 在 Ubuntu 的安裝方法:<br />
<strong>sudo apt-get install libapache2-mod-xsendfile</strong>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-57973715503495346402012-05-05T01:27:00.001+08:002013-06-10T22:33:47.762+08:00[PHP] 使用 php5-ffmpeg 擷取影片圖片前幾天在玩 FFmpeg 的時後,突然發現 Ubuntu 上多了 php5-ffmpeg 這個擴充套件,就想來玩玩看,看好不好用,有兩個結論:<ol><li>讀取影片取決於 FFmpeg 的支援性,如果想要什麼格式都支援的話,建議自己重新編譯 FFmpeg。</li>
<li>效率並沒有我想像中的快,兩分鐘的影片取十張圖,大約 30 秒。</li>
</ol>安裝方法:<br />
<strong>sudo apt-get install ffmpeg php5-ffmpeg php5-gd</strong><br />
<br />
擷圖測試範例:<br />
<pre class="php" name="code"><?php
$page = 10;
$prefix = 'screencap';
$mov = new ffmpeg_movie('gt.avi');
$count = $mov->getFrameCount();
$range = (int)round($count/($page+1));
for($i=1; $i<=$page; $i++){
$frameNum = $range*$i;
$imgFile = $prefix.'_'.$i.'.png';
$frame = $mov->getFrame($frameNum);
if(!$frame){ continue; }
$gdImage = $frame->toGDImage();
if(!$gdImage){ continue; }
imagepng($gdImage, $imgFile);
imagedestroy($gdImage);
echo '<img src="'.$imgFile.'" border="1" /><br />';
}
</pre><br />
參考文件:<br />
<a target="_blank" href="http://ffmpeg-php.sourceforge.net/doc/api/ffmpeg_movie.php">ffmpeg_movie object methods</a><br />
<a target="_blank" href="http://www.sitepoint.com/forums/printthread.php?t=292670">FFmpeg and PHP</a>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-31691041480423325242012-05-03T14:49:00.003+08:002023-02-25T21:39:35.301+08:00[Ubuntu 11] HTTP Live Streaming 安裝與測試<strong>安裝 Apache</strong><br />
<pre class="sh" name="code">apt-get install apache2
</pre><br />
在 <strong>/etc/apache2/mods-available/mime.conf</strong> 加入以下內容: <br />
<pre class="cfg" name="code"># HLS file type
AddType application/x-mpegURL .m3u8
AddType video/MP2T .ts
</pre><br />
<br />
Ubuntu 11.04 預設的 FFmpeg 是沒有啟用 h.264 的支援,所以要自己編譯。<br />
<br />
<strong>安裝編譯時所需要的套件</strong><br />
<pre class="sh" name="code">apt-get update
apt-get install build-essential checkinstall subversion git libfaac-dev libjack-jackd2-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libsdl1.2-dev libtheora-dev libva-dev libvdpau-dev libvorbis-dev libx11-dev libxfixes-dev libxvidcore-dev texi2html yasm zlib1g-dev libx264-dev librtmp-dev
</pre><br />
<br />
<strong>編譯 FFmpeg</strong><br />
<pre class="sh" name="code">cd /opt
git clone git://git.videolan.org/ffmpeg
cd ffmpeg
./configure --prefix=/usr --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libfaac --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --disable-ffplay --enable-shared --enable-gpl --enable-postproc --enable-version3 --enable-nonfree --enable-avfilter --enable-pthreads --enable-vdpau --enable-librtmp
make -j$(grep processor /proc/cpuinfo |wc -l)
checkinstall --pkgname=ffmpeg --pkgversion="5.0.1" --backup=no --deldoc=yes --default
</pre><br />
<br />
segmenter 是用來切割 FFmpeg 轉好的 ts 檔<br />
<strong>編譯 segmenter</strong><br />
<pre class="sh" name="code">cd /opt
svn co http://httpsegmenter.googlecode.com/svn/trunk
cd trunk
sed 's/\/local//g' Makefile.txt > Makefile
make -j$(grep processor /proc/cpuinfo |wc -l)
checkinstall --pkgname=segmenter --pkgversion="2" --backup=no --deldoc=yes --default
</pre><br />
<br />
<br />
<strong>測試影片轉檔</strong> <br />
<pre class="sh" name="code">cd /var/www
ffmpeg -i gt4.avi -f mpegts -vcodec libx264 -acodec libmp3lame gt4_pre.ts
ffmpeg -i gt4.avi -f mpegts -acodec libmp3lame -ar 48000 -ab 64k -s 720x480 -vcodec libx264 -b 800k -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -subq 5 -trellis 1 -refs 1 -coder 0 -me_range 16 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -bt 200k -maxrate 800k -bufsize 800k -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -level 30 -aspect 720:480 -g 30 -async 2 gt4_pre.ts
</pre><br />
<br />
<strong>測試 RTMP 串接轉檔</strong> <br />
<pre class="sh" name="code">ffmpeg -i rtmp://flashstream.adobe.com/ondemand/flash/cs5/prod/production-performance_400x224 -f mpegts -vcodec libx264 -acodec libmp3lame rtmp_pre.ts
</pre><br />
<br />
<strong>測試影片切割</strong> <br />
<pre class="sh" name="code">segmenter -i gt4_pre.ts -d 10 -o gt4_pre -x stream.m3u8 -p http://192.168.0.10/
</pre><br />
<br />
<strong>利用 pipe 從轉檔到切割</strong> <br />
<pre class="sh" name="code">ffmpeg -i gt4.avi -f mpegts -vcodec libx264 -acodec libmp3lame - |segmenter -i - -d 10 -o gt4_pre -x stream.m3u8 -p http://192.168.0.10/
</pre><br />
<br />
<strong>m3u8 檔案格式</strong> <br />
<pre class="cfg" name="code">#EXTM3U
#EXT-X-TARGETDURATION:10
#EXTINF:11,
http://192.168.0.10/gt4_pre-1.ts
#EXTINF:11,
http://192.168.0.10/gt4_pre-2.ts
#EXTINF:11,
http://192.168.0.10/gt4_pre-3.ts
#EXTINF:11,
http://192.168.0.10/gt4_pre-4.ts
#EXTINF:5,
http://192.168.0.10/gt4_pre-5.ts
#EXT-X-ENDLIST
</pre><br />
<br />
<strong>以 HTML5 播放影片</strong><br />
<pre class="xml" name="code"><html>
<head><title>Video Test</title></head>
<body>
<center>
<video tabindex="0" width="720" height="480"><source src="/stream.m3u8"></video>
</center>
</body>
</html>
</pre><br />
<br />
參考文件:<br />
<a href="http://buildall.wordpress.com/2011/05/09/how-to-compile-and-install-ffmpeg-in-ubuntu-11-04/">How to compile and install ffmpeg in Ubuntu 11.04</a><br />
<a href="http://ubuntuforums.org/showpost.php?p=9868359&postcount=1289">Install FFmpeg and x264 on Ubuntu Lucid Lynx 10.04 LTS</a><br />
<a href="http://www.ioncannon.net/programming/452/iphone-http-streaming-with-ffmpeg-and-an-open-source-segmenter/">iPhone HTTP Streaming with FFMpeg and an Open Source Segmenter</a><br />
<a href="http://tools.ietf.org/html/draft-pantos-http-live-streaming-08">HTTP Live Streaming draft-pantos-http-live-streaming-08</a><br />
<a href="http://southking.iteye.com/blog/1477533">http live streaming(m3u8 streaming)(m3u8)</a>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com2tag: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-23409275371862514732012-04-12T14:03:00.000+08:002013-06-10T22:39:24.361+08:00[Ubuntu] 時間同步設定繼上次<a href="/2009/07/ubuntu.html">Ubuntu 時間及時區設定 [Linux]</a>那篇文章後,最近有學到新的時間同步的設定方式。<br />
<br />
<b>vim /etc/cron.daily/ntpdate</b><br />
<pre class="sh" name="code">#!/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
</pre><br />
<b>chmod +x /etc/cron.daily/ntpdate</b>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-61697428906592415472012-03-14T14:48:00.003+08:002013-06-10T22:38:24.354+08:00[Ubuntu 11] 安裝 Redmine 與 SVN<strong>安裝 LAMP & Redmine</strong><br />
<pre class="sh" name="code"># 安裝 LAMP
apt-get install apache2 php5 mysql-server php5-mysql libapache2-mod-php5 libapache2-mod-auth-mysql
# 安裝 svn, dav_svn
apt-get install subversion libapache2-svn
# 安裝 redmine
apt-get install redmine redmine-mysql libapache2-mod-fcgid libapache2-mod-passenger
# 可以使用下面的方式重新設定 redmine DB 連結
#dpkg-reconfigure redmine
# 啟用 Apache 套件 php5, headers, expires
a2enmod php5 dav_svn auth_mysql cgid fcgid passenger rewrite ssl setenvif
# 安裝 git, phpmyadmin
apt-get install mercurial git-core phpmyadmin
# 連結 phpmyadmin 設定檔
cd /etc/apache2/conf.d/
ln -s ../../phpmyadmin/apache.conf phpmyadmin.conf
service apache2 restart
</pre><br />
<br />
<strong>安裝 Redmine 套件</strong><br />
<pre class="sh" name="code">gem install pandoc-ruby rdiscount rpeg-markdown bluefeather
cd /usr/share/redmine/vendor/plugins
# 安裝 Code Review 套件
hg clone https://bitbucket.org/haru_iida/redmine_code_review
rake db:migrate_plugins RAILS_ENV=production
# 安裝 Markdown Extra formatter 套件
git clone git://github.com/juno/redmine_markdown_extra_formatter.git
# 安裝 reStructuredText formatting 套件
git clone git://github.com/alphabetum/redmine_restructuredtext_formatter.git
cd redmine_restructuredtext_formatter
git checkout pandoc-ruby
</pre><br />
<br />
<strong>建立SVN庫</strong><br />
<pre class="sh" name="code">mkdir -p /home/repoadmin/repos
svnadmin create /home/repoadmin/repos/team1
svnadmin create /home/repoadmin/repos/team2
chown -R www-data:www-data /home/repoadmin/repos
</pre><br />
<br />
<strong>建立SVN認證時需要的DB使用者(redmine_svn_auth)</strong><br />
<pre class="sql" name="code">CREATE USER 'redmine_svn_auth'@'localhost' IDENTIFIED BY 'redmine_svn_auth';
GRANT SELECT(id, login, hashed_password, status ,type) ON redmine_default.users TO 'redmine_svn_auth'@'localhost';
</pre><br />
<br />
<strong>設定 Apache2 Site</strong> <br />
<pre class="sh" name="code">cd /etc/apache2/sites-available/
cp default redmine_svn
vim redmine_svn
</pre><br />
<pre class="xml" name="code"><VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /usr/share/redmine/public
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /usr/share/redmine/public>
Options ExecCGI FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
RewriteEngine On
RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} dispatch.fcgi$
RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
</Directory>
<Location /svn>
DAV svn
SVNParentPath /home/repoadmin/repos
SVNPathAuthz off
AuthBasicAuthoritative Off
AuthUserFile /dev/null
AuthType Basic
AuthName "Subversion Repository"
# auth_mysql help in http://localhost/doc/libapache2-mod-auth-mysql/DIRECTIVES.gz
Auth_MYSQL On
Auth_MySQL_Host localhost
Auth_MYSQL_DB redmine_default
Auth_MYSQL_Username redmine_svn_auth
Auth_MYSQL_Password redmine_svn_auth
Auth_MYSQL_Password_Table users
Auth_MYSQL_Username_Field login
Auth_MYSQL_Password_Field hashed_password
Auth_MySQL_Password_Clause " AND status=1 AND type='User' "
Auth_MYSQL_Empty_Passwords Off
Auth_MYSQL_Encryption_Types SHA1Sum
# Options: Crypt_DES, Crypt_MD5, Crypt, PHP_MD5, SHA1Sum, MySQL, Apache
Require valid-user
</Location>
LogLevel warn
CustomLog /var/log/apache2/redmine_access.log combined
ErrorLog /var/log/apache2/redmine_error.log
</VirtualHost>
</pre><br />
<br />
<strong>重新啟動 Apache</strong> <br />
<pre class="sh" name="code">a2dissite default
a2ensite redmine_svn
service apache2 restart
</pre><br />
<br />
<strong>測試網址</strong> <br />
<ul><li>Redmine: <a target="_blank" href="http://localhost/">http://localhost/</a></li>
<li>SVN: <a target="_blank" href="http://localhost/svn/team1/">http://localhost/svn/team1/</a></li>
</ul><br />
<br />
參考來源:<br />
<a target="_blank" href="http://blog.longwin.com.tw/2011/03/redmine-debian-ubuntu-linux-2011/">將 Redmine 安裝於 Debian、Ubuntu Linux</a><br />
<a target="_blank" href="http://www.redmine.org/projects/redmine/wiki/HowTo_Install_Redmine_in_Ubuntu">Ubuntu 10.04 using Passenger</a><br />
<a target="_blank" href="http://www.pigo.idv.tw/archives/851">svn 使用和 redmine 相同帳號進行認證</a>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com4tag:blogger.com,1999:blog-5946530704742130970.post-58584606472707223002012-03-08T16:43:00.000+08:002012-03-08T16:43:48.455+08:00Ubuntu 10 設定預設語系<pre class="sh" name="code">sudo vim /etc/default/locale
LANG="zh_TW.UTF-8"
LANGUAGE="zh_TW:zh"
</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-7912197072555984552012-03-07T14:06:00.002+08:002013-06-10T22:40:22.436+08:00[Ubuntu] 安裝 Oracle Client 與 PDO_OCI於 <a target="_blank" href="http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html">Oracle Database Instant Client</a> 下載 Client/SDK <br />
(Version 10.2.0.4 Instant Client Package - Basic, Instant Client Package - SDK)<br />
<strong>oracle-instantclient-basic-10.2.0.4-1.i386.rpm</strong><br />
<strong>oracle-instantclient-devel-10.2.0.4-1.i386.rpm</strong><br />
<br />
<pre class="sh" name="code"># 安裝套件轉換器
apt-get install alien
# 轉換 rpm 套件到 deb,並安裝
alien -i oracle-instantclient-basic*.rpm
alien -i oracle-instantclient-devel*.rpm
# 安裝 Apache2,PHP,MySQL
apt-get install apache2 php5 mysql-server php5-mysql libapache2-mod-php5
# 安裝 PEAR
apt-get install php-pear php5-dev dh-make-php make re2c
# 下載 PDO_OCI 原始檔
pecl download pdo
pecl download pdo_oci
tar zxvf PDO-1.0.3.tgz
tar zxvf PDO_OCI-1.0.tgz
mkdir -p PDO_OCI-1.0/include/php/ext/
mv PDO-1.0.3 PDO_OCI-1.0/include/php/ext/pdo
cd PDO_OCI-1.0/
phpize
./configure --with-pdo-oci=instantclient,/usr,10.2.0.4
make -j$(grep processor /proc/cpuinfo |wc -l)
make install # /usr/lib/php5/20xxxxxx+lfs/pdo_oci.so
vim /etc/php5/conf.d/pdo_oci.ini # 建立 pdo_oci.ini, 內容如下:
extension=pdo_oci.so
vim /etc/apache2/envvars # 在最後面加入環境變數, 內容如下:
export NLS_LANG="TRADITIONAL CHINESE_TAIWAN.UTF8"
export NLS_DATE_FORMAT="YYYY-MM-DD HH24:MI:SS"
# 重新啟動 Apache
service apache2 restart
</pre><br />
參考來源:<br />
<a target="_blank" href="http://blog.longwin.com.tw/2008/06/debian_php_oracle_ext_pdo_oci_2008/">Debian 安裝設定 PHP 連 Oracle extension 使用 PDO(PDO_OCI)</a><br />
<a target="_blank" href="https://help.ubuntu.com/community/Oracle%20Instant%20Client">Oracle Instant Client</a>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-54697940549134641752011-12-16T06:49:00.002+08:002013-06-10T22:47:27.154+08:00[PHP] 縮圖方式的比較<ul><li><a target="_blank" href="http://php.net/manual/en/function.imagecopyresized.php">imageCopyResized</a> 速度快,但縮圖的品質很粗糙</li>
<li><a target="_blank" href="http://php.net/manual/en/function.imagecopyresampled.php">imageCopyResampled</a> 縮圖的品質好,但花費的時間有點多</li>
</ul>這兩種的缺點是,都會根據圖片的像素大小,而佔用PHP的記憶體,會造成 <strong>Fatal error: Out of memory</strong> 的錯誤出現,有一種狀況是一個 3MB 大小的 JPEG 實際的像素大小卻是 128MB,再來 GD 支援的圖片類型有限,大約就是四五種常用類型。<br />
<br />
優點是指需要安裝 GD 套件,這個套件不管是在 Windows 或 Linux 上很容易找到跟安裝,在處理圖片的類型明確跟尺寸不大的情況下,使用這兩個函數是不錯的。<br />
<br />
為了改善 <strong>imageCopyResampled</strong> 效率,可以利用 <strong>imageCopyResized</strong> 做預先縮圖,例如要縮圖的大小為 100*100 時,可以先將圖片縮小成四倍或八倍,如 400*400 或 800*800,可改善超大圖造成的效率不好。<br />
<br />
<ul><li><a target="_blank" href="http://www.imagemagick.org/script/index.php">ImageMagick</a> + <a target="_blank" href="http://php.net/manual/en/book.imagick.php">Imagick</a> 使用外部的程式來處理圖片,使用指令的方式或透過 Imagick 套件來處理縮圖。</li>
</ul>缺點是透過指令的方式很不友善,且容易受到系統權限的限制,而 Imagick 套件在 Windows 上不容易找到合適的 DLL。<br />
<br />
優點是支援下面多種格式,效率快且沒有記憶體錯誤的問題。<br />
<blockquote>3FR, A, AI, ART, ARW, AVI, AVS, B, BGR, BGRA, BMP, BMP2, BMP3, BRF, BRG, C, CAL, CALS, CAPTION, CIN, CIP, CLIP, CMYK, CMYKA, CR2, CRW, CUR, CUT, DCM, DCR, DCX, DDS, DFONT, DJVU, DNG, DOT, DPX, EPDF, EPI, EPS, EPS2, EPS3, EPSF, EPSI, EPT, EPT2, EPT3, ERF, EXR, FAX, FITS, FRACTAL, FTS, G, G3, GBR, GIF, GIF87, GRADIENT, GRAY, GRB, GROUP4, HALD, HISTOGRAM, HRZ, HTM, HTML, ICB, ICO, ICON, INFO, INLINE, IPL, ISOBRL, J2C, JNG, JP2, JPC, JPEG, JPG, JPX, K, K25, KDC, LABEL, M, M2V, M4V, MAP, MAT, MATTE, MIFF, MNG, MONO, MOV, MP4, MPC, MPEG, MPG, MRW, MSL, MSVG, MTV, MVG, NEF, NULL, O, ORF, OTB, OTF, PAL, PALM, PAM, PATTERN, PBM, PCD, PCDS, PCL, PCT, PCX, PDB, PDF, PDFA, PEF, PES, PFA, PFB, PFM, PGM, PGX, PICON, PICT, PIX, PJPEG, PLASMA, PNG, PNG24, PNG32, PNG8, PNM, PPM, PREVIEW, PS, PS2, PS3, PSB, PSD, PTIF, PWP, R, RADIAL-GRADIENT, RAF, RAS, RBG, RGB, RGBA, RGBO, RLA, RLE, SCR, SCT, SFW, SGI, SHTML, SR2, SRF, STEGANO, SUN, SVG, SVGZ, TEXT, TGA, THUMBNAIL, TIFF, TIFF64, TILE, TIM, TTC, TTF, TXT, UBRL, UIL, UYVY, VDA, VICAR, VID, VIFF, VST, WBMP, WMF, WMV, WMZ, WPG, X, X3F, XBM, XC, XCF, XPM, XPS, XV, XWD, Y, YCbCr, YCbCrA, YUV</blockquote>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-51173276919070396272011-12-15T18:51:00.001+08:002015-03-13T14:40:27.903+08:00[PHP] Documentor (phpdoc) 備忘<strong>Linux 安裝指令</strong><br />
sudo pear install -o PhpDocumentor<br />
<br />
<br />
<strong>Windows 安裝指令</strong><br />
C:\wamp\bin\php\php5.2.4\pear.bat install -o PhpDocumentor <br />
<br />
<br />
<strong>使用方式</strong><br />
<pre class="sh" name="code">phpdoc --parseprivate \
--output HTML:frames:earthli \
--ignore Smarty/ \
--directory /var/www/lib,/var/www/data_mod,/var/www/etc \
--target /var/www/docs
</pre><br />
<br />
<strong>phpdoc 參數說明</strong><br />
<table><tr valign="top"><td>-f</td><td>--filename</td><td>要解析的檔案名稱,可使用 ‘,’分隔多個檔案 “file1,file2”,可以包含完整路徑和使用 * ? 萬用符號。</td></tr>
<tr valign="top"><td>-d</td><td>--directory</td><td>要解析的目錄路徑,可使用 ‘,’分隔多個目錄路徑 “directory1,directory2”。</td></tr>
<tr valign="top"><td>-t</td><td>--target</td><td>指定要輸出的目錄。</td></tr>
<tr valign="top"><td>-i</td><td>--ignore</td><td>要忽略的檔案名稱,可使用 ‘,’分隔多個檔案 “file1,file2”,可以使用 * ? 萬用符號。</td></tr>
<tr valign="top"><td>-is</td><td>--ignoresymlinks</td><td>忽略系統連結的檔案或目錄,預設是關閉的。</td></tr>
<tr valign="top"><td>-it</td><td>--ignore-tags</td><td>忽略解析的標籤。 @package, @subpackage, @access, @ignore 可能是無法忽視。</td></tr>
<tr valign="top"><td>-q</td><td>--quiet</td><td>不顯示解析/轉換的訊息,在 cron 排程時可以選擇開啟,預設是關閉的。</td></tr>
<tr valign="top"><td>-ti</td><td>--title</td><td>產生出的文件的標題,預設為 ‘Generated Documentation’。</td></tr>
<tr valign="top"><td>-h</td><td>--help</td><td>顯示幫助訊息。</td></tr>
<tr valign="top"><td>-pp</td><td>--parseprivate</td><td>將私有(private)成員函式或私有變數也都加入程式文件裡。不然產生出的文件裡只會有公開(public)和保護(protected)的成員函式和變數。</td></tr>
<tr valign="top"><td>-o</td><td>--output</td><td>設置輸出文件的格式</td></tr>
<tr valign="top"><td colspan="3"><ul><li>HTML:frames:* - 包含iframe的HTML格式</li>
<li>HTML:frames:default – Javadoc風格的文檔模板,很少有格式</li>
<li>HTML:frames:earthli – 漂亮的模板(作者:Marco von Ballmoos)</li>
<li>HTML:frames:l0l33t – 流行模板</li>
<li>HTML:frames:phpdoc.de – 類似於phpdoc.de的PHPDoc輸出</li>
<li>HTML:frames:phphtmllib – 非常棒的用戶貢獻模板</li>
<li>HTML:frames:phpedit – 基於PHPEdit Help Generator的文檔</li>
<li>HTML:Smarty:* - 不使用iframe的HTML格式</li>
<li>HTML:Smarty:default – 使用css控制的黑體模板</li>
<li>HTML:Smarty:HandS – 基於PHP的格式,但是經過優化,帶有logo圖片</li>
<li>HTML:Smarty:PHP – 風格接近PHP官網</li>
<li>CHM:default:* - 輸出CHM幫助文檔</li>
<li>CHM:default:default – windows幫助文檔,基於HTML:frames:l0l33t</li>
<li>PDF:default:* - PDF格式</li>
<li>PDF:default:default – 標準純文本PDF格式</li>
<li>XML:DocBook:* - 以DocBook格式輸出的XML</li>
<li>XML:DocBook/peardoc2:default – 可以被編譯成peardoc的文檔</li>
</ul></td></tr>
<tr valign="top"><td>-j</td><td>--javadocdesc</td><td>相容 JavaDoc 的格式,預設是關閉的</td></tr>
</table><br />
<br />
<strong>中文亂碼的問題</strong><br />
新版的 phpdoc 輸出的格式已經是 UTF-8 了,所以只要在目錄下增加一個 .htaccess 文件,然後內容為:<br />
<code>AddCharset UTF-8 .html</code><br />
<br />
<br />
參考文件:<br />
<a target="_blank" href="http://pkwbim-programming-note.blogspot.com/2008/01/phpdocumentor-0.html">多采多姿的程式筆記: phpDocumentor筆記 - 0 立即體驗</a><br />
<a target="_blank" href="http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_phpDocumentor.howto.pkg.html">phpDocumentor Tutorial</a><br />
<a target="_blank" href="http://luchuan.iteye.com/blog/954147">phpDocumentor学习记录</a>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-3077178893263655682011-12-14T21:02:00.000+08:002013-06-10T22:48:26.350+08:00[轉載] Linux Rsync 參數說明轉載自: <a target="_blank" href="http://gaaan.com/cafetw?p=89899">Rsync 中文參數說明</a><br />
<br />
<strong>內容開始</strong><br />
rsync 資料同步<strong>敘述:</strong><br />
rsync和rcp的模式很相似,不過rsync有需多參數可以使用來加速檔案傳送.<br />
rsync遠端更新協定(remote-update protocol)可以透過網路來傳輸兩端檔案不同的地方.<strong>語法:</strong><br />
<code>rsync [OPTION]... SRC [SRC]... DEST</code><br />
<code>rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST</code><br />
<code>rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST</code><br />
<code>rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST</code><br />
<code>rsync [OPTION]... [USER@]HOST:SRC [DEST]</code><br />
<code>rsync [OPTION]... [USER@]HOST::SRC [DEST]</code><br />
<code>rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]</code><br />
<br />
<br />
<strong>rsyncd 的設定檔:</strong><br />
<code>/usr/local/etc/rsyncd.conf</code><br />
<br />
說明:<br />
<table border="0"><tr valign="top"><td>[ohaha]:</td><td> rsync區段的設定名稱</td></tr>
<tr valign="top"><td>path:</td><td> 備份資料存放的路徑</td></tr>
<tr valign="top"><td>auth users:</td><td> 連結rsync服務的帳號</td></tr>
<tr valign="top"><td>uid,gid:</td><td> 採用何種身分進行檔案存取</td></tr>
<tr valign="top"><td>secerts file:</td><td> 帳號密碼檔位置</td></tr>
<tr valign="top"><td>read only:</td><td> 是否唯讀</td></tr>
</table><br />
<br />
<strong>參數:</strong><br />
<table border="0"><tr valign="top"><td>-h,</td><td>--help</td><td>顯示rsync求助資訊.</td></tr>
<tr valign="top"><td></td><td>--version</td><td>顯示rsync版本.</td></tr>
<tr valign="top"><td>-v,</td><td>--verbose</td><td>複雜的輸出訊息.</td></tr>
<tr valign="top"><td>-q,</td><td>--quiet</td><td>安靜模式,幾乎沒有訊息產生.常用在以cron執行rsync.</td></tr>
<tr valign="top"><td>-I,</td><td>--ignore-times</td><td>通常rsync為了加快速度會忽略同樣檔案大小且同樣存取時間點的檔案. 可以透過此參數關閉此快速檢查.</td></tr>
<tr valign="top"><td></td><td>--size-only</td><td>rsync只檢查檔案大小是否改變,不管時間存取點是否改變. 通常用在mirror,且對方時間不太正確時.</td></tr>
<tr valign="top"><td>-c,</td><td>--checksum</td><td>在傳送之前透過128bit的md4檢查碼來檢查所有要傳送的檔案.(會拖慢速度.)</td></tr>
<tr valign="top"><td>-a,</td><td>--archive</td><td>archive mode 權限保存模式,相當於 -rlptgoD 參數. 很快速的保存幾乎所有的權限設定,除了硬式連結(透過-H設定).</td></tr>
<tr valign="top"><td>-r,</td><td>--recursive</td><td>複製所有下層的資料(遞迴)</td></tr>
<tr valign="top"><td>-R,</td><td>--relative</td><td>使用相對路徑.<br />
如: rsync foo/bar/foo.c remote:/tmp/ 在遠端產生/tmp/foo.c檔案 <br />
rsync -R foo/bar/foo.c remote:/tmp/ 在遠端產生/tmp/foo/bar/foo.c 檔案</td></tr>
<tr valign="top"><td>-R,</td><td>--relative</td><td>不使用相對路徑.</td></tr>
<tr valign="top"><td>-b,</td><td>--backup</td><td>目的地端先前已經存在的檔案在傳輸或刪除前會被備份.</td></tr>
<tr valign="top"><td></td><td>--backup-dir=DIR</td><td>設定備份的資料夾.</td></tr>
<tr valign="top"><td></td><td>--suffix=SUFFIX</td><td>指定備份的檔案名稱字尾形式(預設為~).</td></tr>
<tr valign="top"><td>-K,</td><td>--keep-dirlinks</td><td>接收方將連結到資料夾的檔案視為資料夾處理</td></tr>
<tr valign="top"><td>-l,</td><td>--links</td><td>複製所有的連結</td></tr>
<tr valign="top"><td>-H,</td><td>--hard-links</td><td>保留硬式連結</td></tr>
<tr valign="top"><td>-p,</td><td>--perms</td><td>保留檔案權限</td></tr>
<tr valign="top"><td>-o,</td><td>--owner</td><td>保留檔案擁有者(root only)</td></tr>
<tr valign="top"><td>-g,</td><td>--group</td><td>保留檔案群組</td></tr>
<tr valign="top"><td>-D,</td><td>--devices</td><td>保留device資訊(root only)</td></tr>
<tr valign="top"><td>-t,</td><td>--times</td><td>保留時間點</td></tr>
<tr valign="top"><td>-n,</td><td>--dry-run</td><td>不實際執行傳送,只顯示將會有的傳輸動作</td></tr>
<tr valign="top"><td>-S,</td><td>--sparse</td><td>嘗試去處理稀疏的檔案,讓這些檔案在目的端佔去較少的磁碟空間.</td></tr>
<tr valign="top"><td>-W,</td><td>--whole-file</td><td>複製所有的檔案,不額外作檢查.</td></tr>
<tr valign="top"><td></td><td>--no-whole-file</td><td>關閉 --whole-file 參數</td></tr>
<tr valign="top"><td>-x,</td><td>--one-file-system</td><td>不要跨越檔案系統分界(只在一個檔案系統處理)</td></tr>
<tr valign="top"><td>-B,</td><td>--block-size=SIZE</td><td>強制透過rsync程式去比對修復block-sizeforce</td></tr>
<tr valign="top"><td>-e</td><td>--rsh=COMMAND</td><td>定義所使用的remote shell</td></tr>
<tr valign="top"><td></td><td>--rsync-path=PATH</td><td>定義rsync在遠端機器存放資料的路徑</td></tr>
<tr valign="top"><td></td><td>--existing</td><td>只比對更新目的端已經存在的檔案</td></tr>
<tr valign="top"><td></td><td>--ignore-existing</td><td>忽略目的端已經存在的檔案(也就是不更新)</td></tr>
<tr valign="top"><td></td><td>--delete</td><td>刪除傳送端已經不存在,而目的端存在的檔案</td></tr>
<tr valign="top"><td></td><td>--delete-excluded</td><td>除了把傳送端已經不存在,而目的端存在的檔案刪除之外, 也刪除 --exclude 參數所包含的檔案.</td></tr>
<tr valign="top"><td></td><td>--delete-after</td><td>rsync預設會在檔案傳送前進行相關刪除動作確保接收端有足夠的檔案空間, 但可以透過 --delete-after 讓刪除動作在檔案傳送後再行刪除.</td></tr>
<tr valign="top"><td></td><td>--ignore-errors</td><td>忽略任何錯誤既使是I/O error 也進行 --delete 刪除動作.</td></tr>
<tr valign="top"><td></td><td>--max-delete=NUM</td><td>定義rsync不要刪除超過 NUM 個檔案.</td></tr>
<tr valign="top"><td></td><td>--partial</td><td>rsync若遇到傳輸過程中斷時,會把那些已經傳輸的檔案刪除. <br />
在某種狀況下保留那些部分傳送的檔案是令人高興的. <br />
你可以透過 --partial 參數達到這個目的.</td></tr>
<tr valign="top"><td></td><td>--partial-dir=DIR</td><td>在 --partial 參數啟動時,你還可以定義rsync把那些部分傳送的檔案 <br />
寫入定義的資料夾,而非直接寫入目的端.需要注意的是, 此資料夾不應該被其他使用者可以寫入.(如:/tmp)</td></tr>
<tr valign="top"><td></td><td>--force</td><td>當目的端資料夾被傳送端非資料夾名稱覆蓋時,強制rsync刪除資料夾, 即使該資料夾不是空的.</td></tr>
<tr valign="top"><td></td><td>--numeric-ids</td><td>不將傳送端檔案的uid及gid值,與目的端的使用者/群組進行配對. 若傳送端並沒有uid及gid的對應名稱(如:原帳號群組被刪除的遺留檔案), 或目的端沒有相對應的帳號/群組,保留數字型態的uid/gid</td></tr>
<tr valign="top"><td></td><td>--timeout=TIMEOUT</td><td>設定 I/O 逾時的時間(秒). 超過這個秒數而沒有資料傳送,rsync將會結束. 預設為0,也就是沒有定義逾時時間.</td></tr>
<tr valign="top"><td>-T,</td><td>--temp-dir=DIR</td><td>定義rsync在接收端產生暫時性的複製檔案時使用資料夾暫存. 預設是直接在接收端資料夾直接產生暫存檔案.</td></tr>
<tr valign="top"><td></td><td>--compare-dest=DIR</td><td>定義rsync在目的端建立資料夾來比對傳送過來的檔案.</td></tr>
<tr valign="top"><td></td><td>--link-dest=DIR</td><td>與 --compare-dest 相同,但同時會針對無法改變的檔案建立硬式連結.</td></tr>
<tr valign="top"><td>-z,</td><td>--compress</td><td>壓縮模式,當資料在傳送到目的端進行檔案壓縮.</td></tr>
<tr valign="top"><td>-P</td><td></td><td>-P參數和 --partial --progress 相同.只是為了把參數簡單化.</td></tr>
<tr valign="top"><td>-C,</td><td>--cvs-exclude</td><td>排除那些通常不希望傳送的檔案.定義的方式與CVS傳送相同:<br />
RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS .make.state<br />
.nse_depinfo *~ *$ *.old *.bak *.BAK *.orig *.rej <br />
*.a *.olb *.o *.obj *.so *.exe *.Z *.elc *.ln core .svn/ <br />
符合以上條件的都會被忽略而不傳送.</td></tr>
<tr valign="top"><td></td><td>--exclude=PATTER</td><td>符合PATTERN(規則表示式)樣式的檔案不進行傳送</td></tr>
<tr valign="top"><td></td><td>--exclude-from=FILE</td><td>和--exclude參數相同,不過是把不進行傳送的檔案事先寫入某一檔案. 執行時,透過此參數讓rsync讀取. (; #開頭的行列或空白行會被rsync忽略)</td></tr>
<tr valign="top"><td></td><td>--include=PATTERN</td><td>定義rsync不要排除符合pattern樣式的檔案.</td></tr>
<tr valign="top"><td></td><td>--include-from=FILE</td><td>和--include參數相同,只不過把要包含的檔案寫到某一檔案.</td></tr>
<tr valign="top"><td></td><td>--files-from=FILE</td><td>把要傳送的檔案名稱都精確的寫入某一檔案,讓rsync讀取. 如: rsync -a --files-from=/tmp/foo /usr remote:/backup</td></tr>
<tr valign="top"><td>-0</td><td>--from0</td><td>定義檔案所要讀取的檔案是null字元結尾.</td></tr>
<tr valign="top"><td></td><td>--version</td><td>顯示版本訊息.</td></tr>
<tr valign="top"><td></td><td>--daemon</td><td>定義rsync以daemon型態執行.</td></tr>
<tr valign="top"><td></td><td>--no-detach</td><td>當以daemon型態執行時,不要進行分裂且變成背景程序.</td></tr>
<tr valign="top"><td></td><td>--address=ADDRESS</td><td>定義所要連結(bind)的ip位址或是host名稱(daemon限定)</td></tr>
<tr valign="top"><td></td><td>--config=FILE</td><td>定義所要讀取的設定檔rsyncd.conf位置(daemon限定) 預設值為 /usr/local/etc/rsyncd.conf</td></tr>
<tr valign="top"><td></td><td>--port=PORT</td><td>定義rsyncd(daemon)要執行的port(預設為tcp 873)</td></tr>
<tr valign="top"><td></td><td>--blocking-io</td><td>使用blocking I/O連結遠端的shell,如rsh , remsh</td></tr>
<tr valign="top"><td></td><td>--no-blocking-io</td><td>使用non-blocking連結遠端的shell,如ssh (預設值)</td></tr>
<tr valign="top"><td></td><td>--stats</td><td>顯示檔案傳送時的資訊狀態</td></tr>
<tr valign="top"><td></td><td>--progress</td><td>顯示傳送的進度.(給檔案傳送時,怕無聊的人用的..)</td></tr>
<tr valign="top"><td></td><td>--log-format=FORMAT</td><td>定義log的格式(在rsyncd.conf設定)</td></tr>
<tr valign="top"><td></td><td>--password-file=FILE</td><td>從檔案讀取與遠端rsync伺服器連結的密碼</td></tr>
<tr valign="top"><td></td><td>--bwlimit=KBPS</td><td>定義傳輸頻寬的大小(KBytes/秒)</td></tr>
<tr valign="top"><td></td><td>--write-batch=FILE</td><td>把紀錄資料寫入一個檔案(給其他相同環境且相同需求的機器使用)</td></tr>
<tr valign="top"><td></td><td>--read-batch=FILE</td><td>透過讀取紀錄檔案來進行傳輸.(檔案由 --write-batch 參數產生)</td></tr>
<tr valign="top"><td></td><td>--checksum-seed=NUM</td><td>定義檔案 checksum-seed 的大小(byte)</td></tr>
<tr valign="top"><td>-4</td><td>--ipv4</td><td>使用IPv4協定</td></tr>
<tr valign="top"><td>-6</td><td>--ipv6</td><td>使用IPv6協定</td></tr>
</table>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-63347940949406513472011-12-14T15:26:00.006+08:002023-02-26T14:14:51.949+08:00[Ubuntu] 掛載 Windows 分享目錄<ul><li>安裝 smbfs 套件<br />
<code>sudo apt-get install smbfs</code></li>
<li>建立掛載目錄<br />
<code>sudo mkdir /mnt/windows_share</code></li>
<li>開放最大權限<br />
<code>sudo chmod 777</code></li>
<li>測試掛載<br />
<pre class="sh" name="code">sudo mount -t cifs //192.168.0.10/my_share /mnt/windows_share -o username=jax,password=1234,noacl,noperm,codepage=cp950,iocharset=big5,file_mode=0666,dir_mode=0777
</pre></li>
<li>察看是否成功<br />
<code>df -h</code><br />
Filesystem Size Used Avail Use% Mounted on<br />
//192.168.0.10/my_share 7.9G 208K 7.9G 1% /mnt/windows_share</li>
<li>卸載<br />
<code>sudo umount /mnt/windows_share</code></li>
<li>修改開機掛載設定檔<br />
<code>sudo vim /etc/fstab</code><br />
<pre class="cfg" name="code">/mnt/windows_share was on //192.168.0.10/my_share
//192.168.0.10/my_share /mnt/windows_share cifs username=jax,password=1234,noacl,noperm,codepage=cp950,iocharset=big5,file_mode=0666,dir_mode=0777 0 0
</pre></li>
<li>套用開機設定檔<br />
<code>mount -a</code></li>
<li>再次察看是否成功<br />
<code>df -h</code><br />
Filesystem Size Used Avail Use% Mounted on<br />
//192.168.0.10/my_share 7.9G 208K 7.9G 1% /mnt/windows_share</li>
</ul><br />
參考資料:<br />
<a target="_blank" href="http://geek-garden.blogspot.com/2011/01/ubuntu-mount-windows.html">在 ubuntu 中 mount windows 分享的目錄</a><br />
<a target="_blank" href="http://indeepnight.blogspot.com/2007/05/mount.html">載掛(Mount)遠端資料夾的應用</a><br />
<a target="_blank" href="http://blog.sina.com.cn/s/blog_53d86b2d0100qeot.html">ubuntu的几个技巧: 自动连接Windows共享文件夹, 定时文件同步备份</a>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-28869189601373658192011-08-18T16:42:00.007+08:002013-06-10T22:52:50.445+08:00[轉載] apache2ctl 指令轉載自:<a target="_blank" href="http://tw.myblog.yahoo.com/ok-free/article?mid=5985&next=5984&l=f&fid=14">Ubuntu系統網絡應用服務器Apache配置基礎</a><br />
<br />
apache2ctl 是 Apache2 服務器的前端程序。他可以幫助管理員控制 Apache2 後台 daemon 的功能。 <br />
<br />
<dl><dt>apache2ctl -v</dt>
<dd>顯示 apache 的版本。</dd>
<dt>apache2ctl -V</dt>
<dd>顯示 apache 的版本和編譯參數。</dd>
<dt>apache2ctl -h</dt>
<dd>輸出命令列選項的簡要說明。</dd>
<dt>apache2ctl -l</dt>
<dd>輸出一個靜態編譯在服務器中的模塊的列表。
它不會列出使用 LoadModule 指令動態加載的模塊。</dd>
<dt>apache2ctl -L</dt>
<dd>輸出一個指令的列表,并包含了各指令的有效參數和使用區域。</dd>
<dt>apache2ctl -t</dt>
<dd>僅對配置文件執行語法檢查。</dd>
<dt>apache2ctl -t -D DUMP_VHOSTS<br />
apache2ctl -S</dt>
<dd>顯示虛擬主機配置的詳細信息。</dd>
<dt>apache2ctl -t -D DUMP_MODULES<br />
apache2ctl -M</dt>
<dd>顯示動態模組加載的詳細信息。 </dd>
<dt>apache2ctl start</dt>
<dd>啟動 apache2 daemon。</dd>
<dt>apache2ctl stop</dt>
<dd>停止 apache2 daemon。</dd>
<dt>apache2ctl restart</dt>
<dd>重新啟動 apache2 daemon。</dd>
<dt>apache2ctl status</dt>
<dd>顯示一個簡要的狀態報告。</dd>
<dt>apache2ctl graceful</dt>
<dd>優雅地重新啟動 apache2 daemon。
如果 daemon 尚未啟動,則啟動它。它和標準重新啟動的不同之處在於:不會中斷當前已經打開的連接,也不會立即關閉日誌。這意味著,如果在日誌滾動腳本使用它,則在處理日誌之前必須加入一個實實在在的延遲,以確保老的日誌文件在被處理前已經關閉。在重新啟動 daemon 之前,此命令會使用 configtest 自動檢查配置文件,以確保 apache 不會死掉。</dd>
<dt>apache2ctl graceful-stop</dt>
<dd>優雅地停止 apache2 daemon。
它和標準停止的不同之處在於:不會中斷當前已經打開的連接,也不會立即關閉日誌。</dd>
<dt>apache2ctl configtest</dt>
<dd>執行一次配置文件語法檢查。
它解析配置文件,並報告 Syntax Ok 或者是特定的語法錯誤詳細信息。</dd> </dl>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-41321001966529460582011-08-18T15:10:00.004+08:002011-08-18T16:00:42.422+08:00[Ubuntu] Apache 未設定 ServerName 造成的警告Ubuntu 下的 Apache 有時候在啟動時會出現以下的警告訊息:<br />
<strong style="background-color: white; color: red;">Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName</strong><br />
<br />
由於沒有任何 ServerName 的設定造成的警告,只要在 <strong>/etc/apache2/apache2.conf </strong> 中加入 <strong>ServerName localhost</strong> 的預設值就不會出現這個錯誤了。<br />
<br />
這個問題我之前也遇到過,但不常發生,久了就忘記該把設定寫在哪裡了,因為可以設定的地方有三四個,為了遵守統一的規則才不會亂。<br />
<br />
當要建立多個虛擬主機時,只要在 <strong><VirtualHost *:80></strong> 中才去覆寫 <strong>ServerName my_host_name</strong> 就不會衝突了。<br />
<br />
Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-87219539890261510532011-07-04T16:54:00.000+08:002011-07-04T16:54:45.265+08:00創:光速戰記 (Tron Legacy) console 上的指令<pre class="sh" name="code">$ whoami
flynn
$ uname -a
SolarOS 4.0.1 Generic_50203-02 sun4m i386
Unknown.Unknown
$ login -n root
Login incorrect
login:backdoor
No home directory specifed in password file!
Logging in with home=/
#bin/history
488 cd /opt/LLL/controller/laser/
489 vi LLLSDLaserControl.c
490 make
491 make install
492 ./sanity_check
493 ./configure -o test.cfg
494 vi test.cfg
495 vi ~/last_will_and_testament.txt
496 cat /proc/meminfo
497 ps -a -x -u
498 kill -9 2207
499 kill 2208
500 ps -a -x -u
501 touch /opt/LLL/run/ok
502 LLLSDLaserControl -ok 1
#
</pre>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.com0