顯示具有 Shell 標籤的文章。 顯示所有文章
顯示具有 Shell 標籤的文章。 顯示所有文章
2015-03-04 11:20

[Java] 執行 shell command

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);

Output:
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
2013-05-30 22:21

[PHP] 從網頁執行 SVN 更新

想說寫一個透過網頁就可以執行 SVN 更新的程式,結果並不是我想得那樣簡單,有一些眉角需要注意的說。

先以 Apache 的使用者帳號執行 SVN checkout,這樣 Apache 才有 SVN 的連結權力,才可以透過網頁執行 SVN update

su -s /bin/bash www-data
cd /var/www
svn checkout http://www.xxx.com/svn/my_site 


  1. 在用 PHP 執行 shell 指令前要加上 export LANG=C.UTF-8 的環境宣告,不然 SVN update 時遇到中文會出現 error,Ubuntu 的 Apache 預設是 LANG=C
  2. 接著要為 SVN 補上 --accept theirs-full 的參數,這是當衝突發生時,都以 SVN Server 的檔案版本為主
  3. 最後再加上 2>&1,讓 PHP 可以取得包含錯誤的所有訊息
<?php
putenv('LANG=C.UTF-8');
$result = shell_exec('svn update --accept theirs-full /var/www/my_site 2>&1');
echo nl2br($result);
2012-04-29 21:16

[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-03-16 22:55

[PHP] 檢查 XML 文件結構

利用 SimpleXML 去檢查 XML 結構是否符合規格,為了讓這個程式可以多用途,採用了一個基準文件的作為結構準則,依據裡面定義的節點跟屬性,去檢查文件是否符合基本要求的格式。

<?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');
}


使用方式(shell)
php check_xml_file_structure.php base_file=base.xml check_file=check.xml

if [ "j$?" != "j0" ]; then
    echo "Run Error"
fi


測試範例 1
base_1.xml
<?xml version="1.0" encoding="UTF-8"?>
<items>
    <item>
        <Category>Category文字</Category>
        <Title>Title文字</Title>
    </item>
</items>

check_1.xml
<?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>


測試範例 2
base_2.xml
<?xml version="1.0" encoding="UTF-8"?>
<items>
    <item category="Category文字" Title="Title文字"/>
</items>

check_2.xml
<?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>
2012-03-08 16:00

[Linux] 使用 MD5 檢查 FTP 上傳的檔案

#!/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;
2011-09-13 18:01

[轉載] Linux shell script 的彩色控制

轉載自:Linux shell script 的彩色控制

Linux 下的終端機畫面不是只能換換背景而已,顯示出來的顏色也是能控制的。使用的顏色就像以前的DOS 時代,或者現在的BBS 顏色控制方式一樣。

以shell 的顯示為例,顯示的格式如下:

\33[ 文字樣式 ; 文字顏色 ; 背景顏色 m
文字內容………………
\33[0m

文字樣式有列下幾種色碼可以使用:
  • 0 一般亮度
  • 1 高度度
  • 4 加底線
  • 5 灰底

文字顏色則都是3開頭,有下列色碼:
  • 30 黑色
  • 31 紅色
  • 32 綠色
  • 33 黃色
  • 34 藍色
  • 35 紫色
  • 36 青綠
  • 37 白色

再來是背景顏色色碼,都是4開頭:
  • 40 黑色
  • 41 紅色
  • 42 綠色
  • 43 黃色
  • 44 藍色
  • 45 紫色
  • 46 青綠
  • 47 白色

如果我要在畫面上顯示高亮度的綠色(32)及黑色背景,可以如下:
sprintf "\33[1;32;40m 我的文字 \33[0m"

也可以分開來寫比較清楚
sprintf "\33[1;32;40m "
sprintf "我的文字"
sprintf "\33[0m"

記得shell 輸出碼要用 printf 而不是用一般的 echo。echo 的話要寫成 echo -e 。
但並不是所有的終端機畫面都是用黑色背景的。如果我們不要指定它的黑色背景,讓它使用系統原始背景色,可以省略背景描述變成如下:
sprintf "\033[1;32m"
sprintf "我的文字"
sprintf "\033[0m"

是不是就比較完美了呢。

其實這些控制碼和BBS 的還真像。
2011-04-07 17:25

[轉載][Shell] if 條件式選項列表

轉載自:利用 test 指令的測試功能 - 鳥哥的 Linux 私房菜 -- 學習 Shell Scripts

1. 關於某個檔名的『檔案類型』判斷
標誌意義範例
-e$FILE 是否存在?(常用)if[ -e $FILE ]; then
-f$FILE 是否存在且為檔案(file)?(常用)if[ -f $FILE ]; then
-d$FILE 是否存在且為目錄(directory)?(常用)if[ -d $FILE ]; then
-b$FILE 是否存在且為一個 block device 裝置?if[ -b $FILE ]; then
-c$FILE 是否存在且為一個 character device 裝置?if[ -c $FILE ]; then
-S$FILE 是否存在且為一個 Socket 檔案?if[ -S $FILE ]; then
-p$FILE 是否存在且為一個 FIFO (pipe) 檔案?if[ -p $FILE ]; then
-L$FILE 是否存在且為一個連結檔?if[ -L $FILE ]; then

2. 關於檔案的權限偵測,如 -r $FILE 表示可讀否 (但 root 權限常有例外)
標誌意義範例
-r偵測該檔名是否存在且具有『可讀』的權限?if[ -r $FILE ]; then
-w偵測該檔名是否存在且具有『可寫』的權限?if[ -w $FILE ]; then
-x偵測該檔名是否存在且具有『可執行』的權限?if[ -x $FILE ]; then
-u偵測該檔名是否存在且具有『SUID』的屬性?if[ -u $FILE ]; then
-g偵測該檔名是否存在且具有『SGID』的屬性?if[ -g $FILE ]; then
-k偵測該檔名是否存在且具有『Sticky bit』的屬性?if[ -k $FILE ]; then
-s偵測該檔名是否存在且為『非空白檔案』?if[ -s $FILE ]; then

3. 兩個檔案之間的比較
標誌意義範例
-nt(newer than)判斷 $FILE1 是否比 $FILE2 新if[ $FILE1 -nt $FILE2 ]; then
-ot(older than)判斷 $FILE1 是否比 $FILE2 舊if[ $FILE1 -ot $FILE2 ]; then
-ef判斷 $FILE1 與 $FILE2 是否為同一檔案,
可用在判斷 hard link 的判定上。
主要意義在判定,兩個檔案是否均指向同一個 inode 哩!
if[ $FILE1 -ef $FILE2 ]; then

4. 關於兩個整數之間的判定
標誌意義範例
-eq兩數值相等 (equal)if[ n1 -eq n2 ]; then
-ne兩數值不等 (not equal)if[ n1 -ne n2 ]; then
-gtn1 大於 n2 (greater than)if[ n1 -gt n2 ]; then
-ltn1 小於 n2 (less than)if[ n1 -lt n2 ]; then
-gen1 大於等於 n2 (greater than or equal)if[ n1 -ge n2 ]; then
-len1 小於等於 n2 (less than or equal)if[ n1 -le n2 ]; then

5. 判定字串的資料
標誌意義範例
-z判定字串是否為 0 ?若 $STR 為空字串,則為 trueif[ -z $STR ]; then
-n判定字串是否非為 0 ?若 $STR 為空字串,則為 false。
註: -n 亦可省略
if[ -n $STR ]; then
=判定 $STR1 是否等於 $STR2 ,若相等,則回傳 trueif[ $STR1 = $STR2 ]; then
!=判定 $STR1 是否不等於 $STR2 ,若相等,則回傳 falseif[ $STR1 != $STR2 ]; then

6. 多重條件判定
標誌意義範例
-a(and)兩狀況同時成立if[ -r $FILE -a -x $FILE ]; then
-o(or)兩狀況任何一個成立if[ -r $FILE -o -x $FILE ]; then
!反相狀態if[ ! -x $FILE ]; then
2011-01-25 11:09

[Shell] backup mysql data by day (note)

#!/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
2011-01-25 10:14

[Shell] 依據遠端清單進行目錄同步

這個任務的狀況是:
有些新的檔案會被加入,而舊的檔案會被移除,檔案的內容基本上是不會變動的,所以可透過檔名來進行同步。


檔案下載與錯誤處理:
這裡用 curl 來處理下載的問題,並且當發生錯誤時重試三次。
#!/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;


清單比較:
從遠端下載檔案清單與本地端的目錄進行比對,並處理刪除跟下載的動作。
#!/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;
2011-01-24 16:29

[Shell] 透過版本編號與遠端的 package 同步

有一個的任務是要將一個用 tar 封裝的目錄從 server 端同步到 client 上,然後有機個考量點:
  • 必須確保 client 永遠都讀得到資料
  • 最小的資料中斷
  • 最小的硬碟存取
  • 必要的錯誤處理


建立 server 端的 package
#!/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


client 端的同步處理
#!/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;
2011-01-24 13:47

[Shell] 等待所有子程序結束

當在用 shell 開其他子程序時,通常會希望在所有程序結束時做一些處理,最簡單的方式就是用一支迴圈去等待其他子程序的結束,這裡用到 jobs 這個指令去檢查子程序是不是還在執行。

#!/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;
2011-01-19 01:20

[Shell] 使用 sfdisk 分割硬碟

#!/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;
2010-10-12 10:19

[Shell] FTP 上傳

#!/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
2009-03-19 01:25

[Shell] 利用 tar 作資料備份

一般在 console 使用 tar 做備份壓縮時,都會習慣使用相對路徑做壓縮,在解壓縮時也比較方便,可是再寫 Shell 做 crontab 排程時,也想要使用相對路徑做壓縮的話,必須用一些方法,下面的 script 還加上過濾檔案的機制,可以排除一些隱藏檔或特定目錄的備份。

#!/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;


原始檔:server_backup.sh