FOTA差分包編譯服務(wù)器搭建

奈何公司測試組電腦沒有Linux系統(tǒng),每次測試FOTA升級用的差分包都需要找我來制作,實(shí)在麻煩。本想搞個QT界面弄得專業(yè)點(diǎn),后面有時間再去搞吧,現(xiàn)在打算先臨時寫一個應(yīng)急。


image

一、Ubuntu端先搭建FTP服務(wù)器

參考之前搭建的記錄
Ubuntu14.04搭建FTP服務(wù)器記錄 - chenwr2018的博客 - CSDN博客 https://blog.csdn.net/chenwr2018/article/details/90512929

因?yàn)檫€沒實(shí)現(xiàn)多人同時制作差分包的功能,為了保證編譯過程中不受影響,服務(wù)端限制了客戶端的連接數(shù)。
保證當(dāng)前服務(wù)器只有一個IP連接,并且一個IP只有2個客戶端連接數(shù),一個用來上傳文件,一個用來下載。
只需在vsftpd.conf中添加,重啟服務(wù)即可。
max_clients=2
max_per_ip=1

二、Inotify工具

Inotify 是一個 Linux特性,它監(jiān)控文件系統(tǒng)操作,比如讀取、寫入和創(chuàng)建。Inotify 反應(yīng)靈敏,用法非常簡單,并且比 cron 任務(wù)的繁忙輪詢高效得多。

1.安裝Inotify工具

sudo apt-get install inotify-tools

2.參數(shù)說明

inotifywait

語法:
inotifywait [-hcmrq] [-e ] [-t ] [--format ] [--timefmt ] [ ... ]
參數(shù):
-h,--help
輸出幫助信息
@
排除不需要監(jiān)視的文件,可以是相對路徑,也可以是絕對路徑。
--fromfile 
從文件讀取需要監(jiān)視的文件或排除的文件,一個文件一行,排除的文件以@開頭。
-m, --monitor
接收到一個事情而不退出,無限期地執(zhí)行。默認(rèn)的行為是接收到一個事情后立即退出。
-d, --daemon
跟--monitor一樣,除了是在后臺運(yùn)行,需要指定--outfile把事情輸出到一個文件。也意味著使用了--syslog。
-o, --outfile 
輸出事情到一個文件而不是標(biāo)準(zhǔn)輸出。
-s, --syslog
輸出錯誤信息到系統(tǒng)日志
-r, --recursive
監(jiān)視一個目錄下的所有子目錄。
-q, --quiet
指定一次,不會輸出詳細(xì)信息,指定二次,除了致命錯誤,不會輸出任何信息。
--exclude 
正則匹配需要排除的文件,大小寫敏感。
--excludei 
正則匹配需要排除的文件,忽略大小寫。
-t , --timeout 
設(shè)置超時時間,如果為0,則無限期地執(zhí)行下去。
-e , --event 
指定監(jiān)視的事件。
-c, --csv
輸出csv格式。
--timefmt 
指定時間格式,用于--format選項(xiàng)中的%T格式。
--format 
指定輸出格式。
%w 表示發(fā)生事件的目錄
%f 表示發(fā)生事件的文件
%e 表示發(fā)生的事件
%Xe 事件以“X"分隔
%T 使用由--timefmt定義的時間格式

inotifywatch

語法:
inotifywatch [-hvzrqf] [-e ] [-t ] [-a ] [-d ] [ ... ]
參數(shù):
-h, --help
輸出幫助信息
-v, --verbose
輸出詳細(xì)信息
@
排除不需要監(jiān)視的文件,可以是相對路徑,也可以是絕對路徑。
--fromfile 
從文件讀取需要監(jiān)視的文件或排除的文件,一個文件一行,排除的文件以@開頭。
-z, --zero
輸出表格的行和列,即使元素為空
--exclude 
正則匹配需要排除的文件,大小寫敏感。
--excludei 
正則匹配需要排除的文件,忽略大小寫。
-r, --recursive
監(jiān)視一個目錄下的所有子目錄。
-t , --timeout 
設(shè)置超時時間
-e , --event 
只監(jiān)聽指定的事件。
-a , --ascending 
以指定事件升序排列。
-d , --descending 
以指定事件降序排列。

可監(jiān)聽事件
access  文件讀取
modify  文件更改。
attrib  文件屬性更改,如權(quán)限,時間戳等。
close_write 以可寫模式打開的文件被關(guān)閉,不代表此文件一定已經(jīng)寫入數(shù)據(jù)。
close_nowrite   以只讀模式打開的文件被關(guān)閉。
close   文件被關(guān)閉,不管它是如何打開的。
open    文件打開。
moved_to    一個文件或目錄移動到監(jiān)聽的目錄,即使是在同一目錄內(nèi)移動,此事件也觸發(fā)。
moved_from  一個文件或目錄移出監(jiān)聽的目錄,即使是在同一目錄內(nèi)移動,此事件也觸發(fā)。
move    包括moved_to和 moved_from
move_self   文件或目錄被移除,之后不再監(jiān)聽此文件或目錄。
create  文件或目錄創(chuàng)建
delete  文件或目錄刪除
delete_self 文件或目錄移除,之后不再監(jiān)聽此文件或目錄
unmount 文件系統(tǒng)取消掛載,之后不再監(jiān)聽此文件系統(tǒng)。

3.實(shí)際測試

Ubuntu端

root@chenwr-pc:/home# inotifywait -rm /home/workspace/project/Build_FOTA/EC20-delta-gentools
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v1/ OPEN 666
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v1/ MODIFY 666
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v1/ MODIFY 666
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v1/ CLOSE_WRITE,CLOSE 666
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ OPEN 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ MODIFY 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ MODIFY 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ CLOSE_WRITE,CLOSE 233

PC端

發(fā)送文件至Ubuntu端FTP服務(wù)器

E:\windows_to_linux_FTP
ftp> open 192.168.1.35
連接到 192.168.1.35。
220 (vsFTPd 3.0.2)
200 Always in UTF8 mode.
ftp> user FTP
331 Please specify the password.

230 Login successful.
ftp> put 1.zip /home/workspace/project/Build_FOTA/EC20-delta-gentools/v1/666
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
ftp: 發(fā)送 252 字節(jié),用時 0.00秒 252000.00千字節(jié)/秒。
ftp> put 1.zip /home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/233
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
ftp: 發(fā)送 252 字節(jié),用時 0.00秒 252.00千字節(jié)/秒。
ftp>

保存日志
inotifywait -rm /home/workspace/project/Build_FOTA/EC20-delta-gentools | tee /var/log/ftp_message
后續(xù)直接通過管道來逐行讀取就好,就沒必要寫到文件中。主要目的是判斷FTP接受文件完畢。

使用該監(jiān)控文件變化會出現(xiàn)一個問題,PC端FTP傳輸數(shù)據(jù)都是小塊小塊的傳輸

/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ MODIFY 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ MODIFY 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ MODIFY 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ MODIFY 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ MODIFY 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ MODIFY 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ MODIFY 233
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ CLOSE_WRITE,CLOSE 233

所以腳本執(zhí)行的條件還是判斷關(guān)鍵語句吧
/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ CLOSE_WRITE

三、完整的demo

1.ubuntu端shell腳本

測試代碼:
auto_build_fota.sh

#!/bin/sh
sleep 5 # wait server start
BUILD_FOTA="/home/workspace/project/Build_FOTA/EC20-delta-gentools"
SCRIPT="./update_gen.sh a"
content1="/home/workspace/project/Build_FOTA/EC20-delta-gentools/v1/ CLOSE_WRITE,CLOSE targetfiles.zip"
content2="/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ CLOSE_WRITE,CLOSE targetfiles.zip"
flag=0;
log=$BUILD_FOTA/log
echo "start auto build fota script" > $log
/usr/bin/inotifywait -rm $BUILD_FOTA \
| while read line
do
    if [ "$line" = "$content1" ]; then
        echo $(data)
        echo $line >> $log
        echo "recv targetfiles.zip suc from client pc" >> $log
        flag=1
    fi
    if [ "$line" = "$content2" ] && [ $flag = 1 ] ; then
        flag=0
        echo $line >> $log
        cd $BUILD_FOTA
        echo "cur path $(pwd)" >> $log
        echo "start build time: $(date)" >> $log
        $SCRIPT 2>&1 | tee -a $log
        if [ $? != 0 ]; then
            echo "Build Script run failded!" >> $log
        else
            echo "Build Script run success!" >> $log
            echo "Build end time: $(date)" >> $log
            cp $BUILD_FOTA/mainapp* $BUILD_FOTA/bak
            echo "60 sec after to delete mainapp_fota" >> $log
            sleep 60
            rm -f $BUILD_FOTA/mainapp*
            if [ $? != 0 ]; then
                echo "mainapp delete failed" >> $log
            else
                echo "mainapp delete success" >> $log
            fi
        fi
    fi
done

/usr/bin/inotifywait -rm $BUILD_FOTA | while read line
逐行讀取監(jiān)控目錄的信息,一旦有新文件產(chǎn)生會有信息產(chǎn)生。通過判斷關(guān)鍵語句/home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/ CLOSE_WRITE,得出該文件FTP傳輸結(jié)束,緊接著觸發(fā)編譯腳本。

設(shè)置該腳本開機(jī)自啟
簡單在/etc/rc.local文件中添加要啟動的腳本

image

2.PC端bat腳本

(1)auto_build_fota.bat腳本

@echo off
title mainapp_fota差分包編譯工具
mode con lines=20 cols=55
color 3f
echo.
echo             請不要關(guān)閉此窗口,耐心等待!?。?echo.

set file1=1.zip
set file2=2.zip
set ftplog=ftp_log
set ftpfilename=ftp.cfg

set b=%cd%
echo %b%
if exist %file1% (
    if exist %file2% (
        echo 文件上傳中......
        goto ftp_upload
    ) else (
        echo %file2% is not exist!
        pause
        exit
    )
) else (
    echo %file1% is not exist!
    pause
    exit
)

:ftp_upload
echo open 192.168.1.35>"%ftpfilename%" 
echo user ftp>>"%ftpfilename%" 
echo 123456>>"%ftpfilename%"
echo.>>"%ftpfilename%"
echo put %file1% /home/workspace/project/Build_FOTA/EC20-delta-gentools/v1/targetfiles.zip>>"%ftpfilename%"
echo put %file2% /home/workspace/project/Build_FOTA/EC20-delta-gentools/v2/targetfiles.zip>>"%ftpfilename%"  
echo bye >>"%ftpfilename%" 
ftp -n -s:"%ftpfilename%" >"%ftplog%" 
del "%ftpfilename%"

find %ftplog% "Failed to establish connection" > C:\null
if "%errorlevel%"=="0" (
    goto firewall_error
) else (
    echo targetfiles.zip 文件上傳成功!
    echo.
    goto progress_bar_compile
    pause
)
goto:eof


:ftp_download
echo open 192.168.1.35>"%ftpfilename%" 
echo user ftp>>"%ftpfilename%" 
echo 123456>>"%ftpfilename%"
echo.>>"%ftpfilename%"
echo mget /home/workspace/project/Build_FOTA/EC20-delta-gentools/mainapp* >>"%ftpfilename%"
echo.>>"%ftpfilename%"
echo bye >>"%ftpfilename%" 
ftp -n -s:"%ftpfilename%" >>"%ftplog%"
del "%ftpfilename%"
find %ftplog% "mainapp_" > C:\null
IF ERRORLEVEL 1 goto download_error
echo mainapp_fota 文件下載成功!
pause
goto:eof

:progress_bar_compile
cls
set a=^set /p=■^<nul^&ping/n 2 127.1^>nul^&
echo.
echo   正在編譯中...... 
echo.
echo ┌──────────────────────────────────────┐
set/p=  <nul&%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%%a%
echo    100%%
echo └──────────────────────────────────────┘
echo 編譯成功?。?!
goto ftp_download
pause
goto:eof

:upload_error
echo 文件上傳失敗
pause
goto:eof

:firewall_error
echo 請關(guān)閉windows防火墻后,重新運(yùn)行腳本。
pause
goto:eof

:download_error
echo 獲取mainapp_fota失敗,請重新運(yùn)行腳本。
pause
goto:eof

echo.
pause

(2)腳本簡單說明

1.mode con lines=20 cols=55 是設(shè)置你批處理運(yùn)行時窗口大小的

2.使用了 @echo off 之后就無需再用 @;命令前加@符號,表示不顯示@后面的命令。舉一個不和諧的例子:在入侵過程中(使用批處理來格式化敵人的硬盤)自然不能讓對方看到你使用的命令啦。

3.FTP參數(shù)說明

FTP [-v] [-d] [-i] [-n] [-g] [-s:filename] [-a] [-A] [-x:sendbuffer] [-r:recvbuffer] [-b:asyncbuffers] [-w:windowsize] [host]

  -v              禁止顯示遠(yuǎn)程服務(wù)器響應(yīng)。
  -n              禁止在初始連接時自動登錄。
  -i              關(guān)閉多文件傳輸過程中的
                  交互式提示。
  -d              啟用調(diào)試。
  -g              禁用文件名通配(請參閱 GLOB 命令)。
  -s:filename     指定包含 FTP 命令的文本文件;命令
                  在 FTP 啟動后自動運(yùn)行。
  -a              在綁字?jǐn)?shù)據(jù)連接時使用所有本地接口。
  -A              匿名登錄。
  -x:send sockbuf 覆蓋默認(rèn)的 SO_SNDBUF 大小 8192。
  -r:recv sockbuf 覆蓋默認(rèn)的 SO_RCVBUF 大小 8192。
  -b:async count  覆蓋默認(rèn)的異步計(jì)數(shù) 3
  -w:windowsize   覆蓋默認(rèn)的傳輸緩沖區(qū)大小 65535。
  host            指定主機(jī)名稱或要連接到的遠(yuǎn)程主機(jī)
                  的 IP 地址。

注意:
  - mget 和 mput 命令將 y/n/q 視為 yes/no/quit。
  - 使用 Ctrl-C 中止命令。

將FTP相關(guān)ip密碼等信息寫入文件中,再通過-s參數(shù)去實(shí)現(xiàn)命令自動運(yùn)行。

4.echo.為換行,因mget會可以模糊從FTP服務(wù)器上傳輸文件,如果FTP服務(wù)器存在多個前綴相同的文件時此時就需要回車來確認(rèn),因此需要記得mget語句寫入文件后再增加個echo.

5.程序返回碼 echo %errorlevel%
每個命令運(yùn)行結(jié)束,可以用這個命令行格式查看返回碼
用于判斷剛才的命令是否執(zhí)行成功
默認(rèn)值為0,一般命令執(zhí)行出錯會設(shè) errorlevel 為1
if "%errorlevel%"=="0" (
goto firewall_error
) else (
echo No Run
)

6.bat亂碼問題,在文件右鍵用“編輯”打開, 另存為時,UTF-8保存為ANSI格式。即可解決運(yùn)行是亂碼問題。

7.pc端將FTP運(yùn)行結(jié)果保存到文件中,可通過對文件的關(guān)鍵字來判斷FTP的運(yùn)行狀態(tài)。

(3)BAT腳本如何判斷文件是否存在?

SET file1=1.zip
SET file2=2.zip
echo 文件上傳中......
set b=%cd%
echo %b%
if exist %file1% (
    echo %file1% is exist!
) else (
    echo %file1% is not exist!
)
if exist %file2% (
    echo %file2% is exist!
) else (
    echo %file2% is not exist!
)

(4)bat如何編寫函數(shù)

bat 腳本之 使用函數(shù) - caopeng的專欄 - CSDN博客 https://blog.csdn.net/peng_cao/article/details/73999076

格式
:func
函數(shù)內(nèi)部動作
goto:eof

實(shí)例

@echo off
@title copy sth to current filepath
mode con lines=5 cols=40

SET SourceFile=1.zip
SET GenFile1=2.zip

if exist %SourceFile% (
    if not exist %GenFile1% (
        echo %GenFile1% is no exist!
        call:hello
    ) else (
        echo %GenFile1% is exist!
    )
) else (
    echo %SourceFile% is not exist!
)

:hello
echo hello world
pause
goto:eof
echo Success
ping -n 3 127.0.0.1 > nul
pause

使用call會繼續(xù)執(zhí)行一次函數(shù),goto就不會。

image

(5)bat腳本for循環(huán)

指定次數(shù)循環(huán)
FOR /L %variable IN (start,step,end) DO command [command-parameters]
組合命令:
FOR /L %variable IN (start,step,end) DO (
Command1
Command2
……
)

(6)進(jìn)度條簡單實(shí)例

(現(xiàn)在還不清楚進(jìn)度條如何同步,正在編譯的狀態(tài)暫時按照時間來計(jì)時。)

@echo off
cls
set a=^set /p=■^<nul^&ping/n 1 127.1^>nul^&

echo.
echo   正在編譯中...... 
echo.
echo ┌──────────────────────────────────────┐
:cycle
for %%i in (■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■) do (set/p=<nul&%a% goto jindu)
goto:eof
echo    100%%
echo └──────────────────────────────────────┘
echo 編譯成功?。。?pause
:jindu

goto cycle
goto:eof

四、參考資料

bat批處理修改cmd窗口大小、標(biāo)題、字體、背景顏色 - zj0910 - CSDN博客 https://blog.csdn.net/zj0910/article/details/46942861

.bat文件中call命令的用法 - 村長 - CSDN博客 https://blog.csdn.net/a_little_a_day/article/details/78243518

在程序里調(diào)用ftp批處理(sh)上傳文件,如何判斷文件已成功上傳-CSDN論壇 https://bbs.csdn.net/topics/80459535

利用windows系統(tǒng)ftp命令編寫的BAT文件上傳[轉(zhuǎn)] - 風(fēng)之語 - BlogJava http://www.blogjava.net/gf7/archive/2010/07/21/326690.html

FTP返回值詳解 - pgmsoul的專欄 - CSDN博客 https://blog.csdn.net/pgmsoul/article/details/6384731

[轉(zhuǎn)]Bat腳本處理ftp超強(qiáng)案例解說 - 是誰??? - 博客園 http://www.cnblogs.com/hanxianlong/p/5497663.html

bat命令入門與高級技巧詳解DOS/BAT腳本之家 https://www.jb51.net/article/97204.htm

inotify-tools使用方法介紹 - wangkangluo1 - 博客園 http://www.cnblogs.com/wangkangluo1/p/3685587.html

Linux下的文件更新觸發(fā)同步 - kenyon的個人頁面 - OSCHINA https://my.oschina.net/Kenyon/blog/177265

FTP命令詳解(含操作實(shí)例) - IndexMan的專欄 - CSDN博客 https://blog.csdn.net/indexman/article/details/46387561

mget命令, ftp命令詳解 - wajika - 博客園 https://www.cnblogs.com/wajika/p/6484420.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容