發表文章

目前顯示的是 5月, 2017的文章

syslog到遠端server與Ubuntu logger問題

收syslog的設定 修改/etc/rsyslog.conf, 把下面這段內容的註解打開,即可收容udp/tcp的syslog封包 # provides UDP syslog reception $ModLoad imudp $UDPServerRun 514 # provides TCP syslog reception $ModLoad imtcp $InputTCPServerRun 514 如果你要收容log的facility沒有設定過的話,記得還要去查看/etc/rsyslog.d/*.conf的修改 丟syslog的設定 可以參考下面這篇 http://www.rsyslog.com/sending-messages-to-a-remote-syslog-server/ 例如 local7.* @@other-server.example.net:10514 就是把local7的syslog丟到名稱為other-server.example.net埠號10514的遠端log server 進行自我測試 可以用logger指令進行測試 logger -dni "other-server.example.net" -P 10514 --tag "logname" "log test message $(date)" -p local7.debug  但是透過wireshark觀察到logger並沒有正常把封包送出,並且在本機上我看到了local7內容是我上面的指令送出的各條測試log 解決logger無法丟syslog 查了網路資訊 https://askubuntu.com/questions/371604/sending-udp-packets-with-logger-command 因為Ubuntu內建的logger版本2.20.1屏蔽掉了-n的設定,所以無法用logger完成自我測試工作 解決方法:自行編譯logger程式 #下載source, 並切換到2.21版 git clone git://git.debian.org/~lamont/util-linux.git cd util-linux.git g

Linux System Log

Config files in Ubuntu:    /etc/rsyslog.conf    /etc/rsyslog.d/*.conf Restart system log service in Ubuntu:    sudo service rsyslog restart     sudo /etc/init.d/rsyslog restart  #Ubuntu上不建議使用這個重啟服務 Show system log in Ubuntu:   tail -15 /var/log/syslog C Sample Code for the system log #include <stdio.h> #include <syslog.h> int main() {     syslog(LOG_CRIT,"LOG_CRIT\n");     syslog(LOG_ERR,"LOG_ERR\n");     syslog(LOG_WARNING,"LOG_WARNING\n");     syslog(LOG_INFO,"LOG_INFO\n");     syslog(LOG_DEBUG,"LOG_DEBUG\n");     printf("done!\n");     return 0; } Show the result: $tail -5 /var/log/syslog Mar 21 11:57:52 yhchiu-workstation a.out: LOG_CRIT Mar 21 11:57:52 yhchiu-workstation a.out: LOG_ERR Mar 21 11:57:52 yhchiu-workstation a.out: LOG_WARNING Mar 21 11:57:52 yhchiu-workstation a.out: LOG_INFO Mar 21 11:57:52 yhchiu-workstation a.out: LOG_DEBUG Advanced C Sample Code #define LOGNAM

用Python手寫檔案伺服器

這是一個用Python寫的迷你檔案伺服器, 有在Ubuntu上測試過python2.7和python3.4版都可以使用。 如果要接受所有來源的ThisServerIp請使用0.0.0.0作為Server位址 如果要當作一般的網站ThisServerPort請使用80 要提供下載的檔案請把絕對路徑寫在DownloadFilePath1和DownloadFilePath2上 執行的方法 1. For Windows python.exe MyServer.py 2. For Ubuntu python MyServer.py 測試用URL http://127.0.0.1:8080/GetFileInfo http://127.0.0.1:8080/GetFileInfo?name=file1 http://127.0.0.1:8080/GetFileInfo?name=file2 http://127.0.0.1:8080/DownloadFile1 http://127.0.0.1:8080/DownloadFile2 GetFileInfo沒有指定參數name的時候會回應json格式的資訊 DownloadFile1, DownloadFile2是直接下載script指定的檔案 檔案伺服器MyServer.py #!/usr/bin/python # coding=utf-8 import os.path, sys import hashlib, json, shutil if sys.version_info >= (3,0):     from urllib.parse import parse_qs     from http.server import SimpleHTTPRequestHandler,BaseHTTPRequestHandler,HTTPServer else:     from urlparse import parse_qs     from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer     from SimpleHTTPServer import SimpleHTTPRequestHand

C格式化輸出入整理

printf格式化輸出 "%c" 字元 "%d"和"%i" 有號整數 "%u" 無號整數 "%o" 8進位的無號整數 "%#o" 8進位的無號整數,前面會帶0 "%x" 16進位的無號整數 "%#x" 小寫16進位的無號整數,前面會帶0x "%#X"  大寫16進位的無號整數,前面會帶0x "%p" 印出(void*)指標位址 "%f" float浮點數,若為科學表示法會用小寫顯示 "%F" float浮點數,若為科學表示法會用大寫顯示 "%e" float浮點數,以科學表示法會用小寫顯示 "%E" float浮點數,以科學表示法會用大寫顯示 "%g" double浮點數,若為科學表示法會用小寫顯示 "%#g" double浮點數,若為科學表示法會用小寫顯示,並且尾數為0時依然會顯示0 "%G" double浮點數,若為科學表示法會用大寫顯示 "%#G" double浮點數,若為科學表示法會用大寫顯示,並且尾數為0時依然會顯示0 符點數相關 "%10.3f" 輸出float符點數,預設為10個字元寬度,小數點下保留三位 "%10.3f" 輸出float符點數,預設為10個字元寬度 浮點數實測結果如下: $ printf "%#g\n" 0.0000011 1.10000e-06 $ printf "%g\n" 0.0000011 1.1e-06 $ printf "%#G\n" 0.0000011 1.10000E-06 $ printf "%G\n" 0.0000011 1.1E-06 $ printf "%10.3f\n"  0.0011      0.001 $ printf "%10.3

Android.mk編譯C/C++,APP,改APK簽章

1. 編譯C/C++程式 ##是用來單行註解 LOCAL_PATH:= $(call my-dir) # call function my-dir will return the path of Android.mk include $(CLEAR_VARS) # 清除內建以LOCAL_開頭的變數 LOCAL_SRC_FILES:= foo.c # 程式碼檔案, 用空格,如果要換行,必須在每行結尾打\ LOCAL_MODULE:= foo # 本模組名稱, 整個AOSP內的模組名稱必須不同 include $(BUILD_EXECUTABLE) # 模組編譯成執行檔 增加C/C++編譯器的flag LOCAL_CFLAGS += -Wall 這功能比較常用的是增加Macro定義的功能 LOCAL_CFLAGS += -DPLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION) LOCAL_CFLAGS += -DPLATFORM_VERSION=$(PLATFORM_VERSION) 只針對C++編譯時加入flag使用CXXFLAGS LOCAL_CXXFLAGS += -Wall 增加C/C++的header引用目錄 LOCAL_C_INCLUDES := \     $(TOP)/frameworks/av/media/libstagefright/include \     $(TOP)/frameworks/av/include/media 如果要寫多行的時候記得注意換行時要用\符號,然後, 有些編輯器會自動把第2行前面的空白變成Tab造成編譯問題(這是因為Makefile的規則寫法是要用Tab才有效) $(TOP)是AOSP編譯時會自動帶入workspace的頂層目錄 使用Static Library LOCAL_STATIC_LIBRARIES := \     libstagefright_nuplayer \     libstagefright_rtsp 使用的Shared Library LOCAL_SHARED_LIBRARIES := \     libbinder \     libcamera_client 指定模組輸出的路徑

Wireshark的封包過濾器(display filter)範例

Wireshark可以在界面上設定封包過濾條件,不過這是將所有收進來的封包過濾後顯示出來,所以稱為Display Filter,實際上Wireshark背後還是收了非常多資料,所以不建議抓太久,wireshark抓太多資料常常會當機,因為GUI繪圖會來不及 一些DisplayFilter的規則例子 https://wiki.wireshark.org/DisplayFilters 基本邏輯 and && or || 等於與不等於 == != not ! ( ip.addr == 10.43.54.65 ) 包含內容 sip.To  contains "string" matches http.request.uri matches "gl=se quot; 範例 限制IP層的目的地主機為10.11.12.13 ip.dst_host==10.11.12.13 抓一般TCP 80 port的封包( http web server ) tcp.port eq 80 多個條件 ip.addr==10.129.193.37 || ip.addr==10.129.193.27 可以不用括號,不過執行結果順序不太清楚 http && ip.src==192.168.1.4 可以用括號 udp && (ip.dst_host==10.129.193.27) 包含byte順序0x010104的tcp封包 tcp contains 01:01:04 查看MPEG TS的PAT mp2t.pid==0x0 裏面會寫PMT有幾個,他的PID是多少 假設PMT是0x500,則設定來找出PMT mp2t.pid==0x500 查某個PID的PTS封包 mp2t.pid==0x201 && mpeg-pes.pts_flag==1

wget指令筆記

基本使用 wget {url}   # 抓取指定url,檔名自動產生成url最後檔案含參數,例如 http://www.test.idv/abc?xxx123=abs,會輸出成abc?xxx123=abs的檔案 wget  -O {output name}{url}  # 指定抓取檔案的輸出名稱 wget -q {url} # 安靜模式--quit,不會顯示抓取的狀態與進度 wget -d {url} # debug模式, 會顯示request和response wget -S {url} #顯示server response的訊息 wget -o {output name} {url}  # 將wget的抓取資訊輸出到指定檔案 wget -c {url} # 續傳功能, 如果server沒支援也無法續傳 wget --no-proxy {url} #不透過proxy抓取檔案 重新嘗試機制 wget -t=10 --retry-connrefused --waitretry={wait sec time} {url} #等待數秒後的時間再抓取,嘗試最多10次 wget -T={sec for timeout} {url} #設定所有類型的timeout時間 wget --dns-timeout={sec} --connect-timeout={sec} --read-timeout={sec} {url} #分別設置各種timeout時間 特殊用途 wget --user-agent={agent-string} {url} #設定user-agent的字串內容, 短option是-U wget --referer={refer-url} {url} wget --post-data={data-string} {url} wget --post-file={file path} {url}  #和post-data只能2取1 wget --method={HTTP-method} {url} wget --header={header-string} {url} wget --secure-protocol={secure method} {url} # auto, SSLv2, SSLv3, TLSv1 wget

Android shell指令應用

查看Android已安裝的package pm list package 察看某個package的啟動用Activity dumpsys package com.android.launcher 找到類似下面這段,其中粗體就是啟動用的Activity       android.intent.action.MAIN:         2cc5dc80 com.android.launcher/com.android.launcher2.Launcher  filter 2cc2b7f8           Action: "android.intent.action.MAIN"           Category: "android.intent.category.LAUNCHER" 啟動APP的Activity am start -n com.android.launcher/com.android.launcher2.Launcher 上面這個Launcher也就是Android桌面環境 啟動內建的Player播放某個URL的影音內容 am start -n com.android.gallery3d/com.android.gallery3d.app.MovieActivity -d http://10.11.13.14:8080/hls/test.m3u8 啟動內建的Browser am start -n com.android.browser/.BrowserActivity 啟動Android設定頁面 am start -a android.settings.SETTINGS 察看使用容量 dumpsys diskstats Latency: 1ms [512B Data Write] Data-Free: 934860 K / 1015704 K total = 92% free Cache-Free: 485316 K / 495944 K total = 97% free System-Free: 372412 K / 793488 K total = 46% free 察看記憶體用量 dumpsys meminfo dumpsys m

C程式編譯流程

圖片
我們平常用編譯總共會經過四個階段Preprocessing, Compilation, Assembly以及Linking,gcc可以將各階段產生的結果輸出,只要依照左側的指令就能獲得各階段的檔案內容。 右下角的指令則是linking用的,其中各個.so和.o的檔案路徑是隨著Linux發行版會有不同,這裡是用Ubuntu 14.04 64bit的環境作演示。如果想查看設定可以透過gcc編譯程式碼時加上-v查看你目前電腦中的設置。 C程式編譯的四個階段

Bash條件判斷與迴圈

圖片
基本判斷式 if [ ${default_option} -eq 1 ]; then   echo "\ ${default_option}=1 " else   echo "\ ${default_option}!=1 " fi -eq  判斷相等的數值 -ne   判斷不相等的數值 -lt   判斷小於的數值 -le   判斷小於等於的數值 -gt   判斷大於的數值 -ge  判斷大於等於的數值 簡短if-else寫法 [ ${default_option} -eq 1 ] && echo "\${default_option}=1" || echo "\${default_option}!=1" 在BASH內的if-else和其他條件控制內不能為空敘述(換行也沒有用),如果想要寫可以使用冒號 : 寫在需要寫空敘述的位置。 字串檢測 if [ -z "${compile_path}" ]; then   echo 'zero length string' else   echo 'non-zero length string' fi -z判斷長度為0的字串 -n判斷長度為非0的字串 [ A == B ] [ A != B ] [ A < B ] [ A > B ] 確認檔案/目錄存在 if [ -f "/opt/toolchain/test.bin" ]; then   echo 'file exist' else   echo 'file not found' fi -f用來判斷是一般檔案 -d 用來判斷是目錄 -b 用來判斷是block檔 -h 用來判斷是symbol檔 -x 用來判斷是可執行檔 -s 用來判斷檔案存在且檔案大小大於0 多條件判斷 if [ -f "build/envsetup.sh" ] &&a

find搜尋指定名稱的檔案

find可以列出搜尋符合指定檔案名的檔案 例如要搜尋當前目錄及子目錄中檔案名稱包含 _flow的檔案,-iname是不分大小寫 find ./ -iname "*_flow*" find -p -iname "*_flow*" 要注意有些Linux系統不能用一個以上的星號 上面的範例在打想要搜尋的檔名時寫上雙引號是要避免BASH的萬用字元問題,導致搜尋不了檔案 這問題的成因是Bash的萬用字元*具有自動展開功能,如果在當前工作目錄有符合的檔案,例如: 有over_flow和my_flow_chart,在*_flow*不加上雙引號的時候,find實際上獲得的指令會變變成find . -name over_flow my_flow_chart,導致find指令無法執行你想要的工作 搜尋指定inode號碼 find . -inum {指定的inode號碼} 檔案的inode號碼用ls -i {檔案名稱}可以查看 搜尋檔案權限為4000的檔案 find . -perm -4000 搜尋可執行檔 find . -executable -type f 修改時間超過七天的檔案 find . -type f -daystart -ctime +7 -atime {n} access時間n天內 -ctime {n} changed時間n天內 -mtime {n} modified時間n天內 -newer {file} 比某檔案還新 找屬於特定使用者或群組的檔案  find . -user root -name *.h find . -group root -name *.h 刪除空的目錄 find . -type d -empty -delete 刪除副檔名為.bak的檔案 find . -name "*.bak" -exec rm -f {} \; \;是-exec結尾用的符號 怕會刪除到不正確的可以先用echo將找到的檔案路徑都印出來 find . -name "*.bak" -exec echo {} \; 結合xargs -i來刪除檔案 find . -name "*.bak" | xargs

Ubuntu上開發OpenCV C++程式

安裝開發套件 sudo apt-get install libopencv-dev python-opencv 手動編譯程式 參考這篇 http://stackoverflow.com/questions/23162399/linking-opencv-libraries-with-g 指令會是 g++ test.cpp  $(pkg-config --libs --cflags opencv) -o test 這是用pkg-config列出安裝的開發套件資訊, pkg-confif --cflags opencv會印出 -I/usr/include/opencv 這是gcc用的設定include目錄option,確實我們可以在目錄下找到opencv.hpp,完整路徑是/usr/include/opencv2/opencv.hpp。而pkg-config --libs opencv會印出 /usr/lib/x86_64-linux-gnu/libopencv_calib3d.so /usr/lib/x86_64-linux-gnu/libopencv_contrib.so /usr/lib/x86_64-linux-gnu/libopencv_core.so /usr/lib/x86_64-linux-gnu/libopencv_features2d.so /usr/lib/x86_64-linux-gnu/libopencv_flann.so /usr/lib/x86_64-linux-gnu/libopencv_gpu.so /usr/lib/x86_64-linux-gnu/libopencv_highgui.so /usr/lib/x86_64-linux-gnu/libopencv_imgproc.so /usr/lib/x86_64-linux-gnu/libopencv_legacy.so /usr/lib/x86_64-linux-gnu/libopencv_ml.so /usr/lib/x86_64-linux-gnu/libopencv_objdetect.so /usr/lib/x86_64-linux-gnu/libopencv_ocl.so /usr/lib/x86_64-linux-gnu/libopencv_

改變Ubuntu時區以及實作ISO8601標準時間格式

圖片
ISO8601是一種國際標準時間表示格式,細節請參考Wiki條目 https://zh.wikipedia.org/wiki/ISO_8601 用date可以查看電腦上的時區 $ date +%z +0800 如果要設定時區,請將環境變數TZ設定成下面網站提供的城市時區字串 https://whatbox.ca/wiki/Changing_Your_Bash_Timezone 例如: 美國紐約(-4:00)是America/New_York $ export TZ=America/New_York 而台北(+8:00)是Asia/Taipei $ export TZ=Asia/Taipei 沒有用export的話不會改date的時區 如果也可以可以找/usr/share/zoneinfo/裡面有的時區資料來用 $ find /usr/share/zoneinfo/ -name Taipei /usr/share/zoneinfo/right/Asia/Taipei /usr/share/zoneinfo/Asia/Taipei /usr/share/zoneinfo/posix/Asia/Taipei 下面是我用C/C++的strftime實作ISO 8601標準時間格式,不過Windows和Ubuntu上有些不同,Windows上用dev C++開發時發現localtime回傳的結構是沒有gmtoff欄位的,所以回傳的時間資料可以直接使用,而Ubuntu上會有gmtoff,表示時區位移資料,需要額外處理時區資訊。 #include <time.h> #include <stdio.h> int main(void) {   struct tm *local;   time_t t; #ifndef _WIN32   struct tm s_tl, s_tgm;   time_t tl, tgm; #endif   char buff[64] = {0};   char buff2[64] = {0};   t = time(NULL); // get current time in sec #ifndef _WIN

APT操作簡記

圖片
更新套件清單 $ sudo apt-get update 如果你遇到安裝套件會找不到檔案下載的時候,表示你的套件清單已經太舊了需要更新 安裝套件 $ sudo apt-get install [package name] 搜尋套件 $ apt-cache search [search keyword] 如果想要找以安裝檔案所隸屬的套件,可以用dpkg來反查詢 $ dpkg -S `which sort` 有人會推薦使用apt-file套件來搜尋,不過列出的套件會比較多 安裝apt-file $ sudo apt-get install apt-file $ sudo apt-file update $ apt-file find [file full path or keyword] $ apt-file search [file full path or keyword] 例如 apt-file search `which ls` apt-file search --regex /tracker-extract$ 如果要更強的搜尋功能,可以到Ubuntu官方套件庫網站搜尋 http://packages.ubuntu.com/ 下載套件的程式碼(如果有的話) $ apt-get source [package name] 查詢APT已安裝/可以安裝的套件版本 $ apt-cache policy [package name] 例如: sudo apt-cache policy apt 指定安裝套件的版本 $ sudo apt-get install [package name]=version 例如: sudo apt-get install python-django=1.6.1-2 強制重新安裝套件 $ sudo apt-get -f --reinstall install {套件名稱} 由於build code有時候需要不同版本的套件,但是會因為有更新的版本無法使用,因此需要下列指令,-f 是強制安裝,但若是電腦有更新的套件版本或者曾經安裝過此套件,這個參數會變成修復,所以要搭配--reinstall 安裝編譯套件所需的套件 $ su

dpkg指令簡記

從deb檔案安裝套件 dpkg -i python_2.7.deb 印出deb檔案的資訊 dpkg -I python_2.7.deb 印出deb檔案內的檔案 dpkg -c python_2.7.deb 列出安裝的套件 dpkg --get-selections  dpkg --get-selections | grep gtk # 找出帶有gtk字串的 查詢安裝的套件狀態 dpkg -l gtk dpkg -l "gtk*" # 開頭為gtk的所有套件, 使用*時建議用引號把參數包起來 dpkg -l "*"    # 所有套件 移除套件 dpkg -r {套件名稱}  #移除(Remove) dpkg -P  {套件名稱}  #移除和清除(Purge) 查詢套件安裝的檔案列表 dpkg -L  {套件名稱} 查訊套件資訊 dpkg -s {套件名稱} 反查詢檔案路徑可能是哪個套件安裝的 dpkg -S {檔案路徑} 如果檔案路徑只打檔案名稱時, 會把不相關的都找出來, 例如: 只打檔案名稱 $ dpkg -S date bash-completion: /usr/share/bash-completion/completions/munin-update update-manager: /usr/share/help/C/update-manager/figures/download-progressbar.png update-manager: /usr/share/doc/update-manager 當你給完整路徑時 $ dpkg -S /bin/date coreutils: /bin/date dpkg的紀錄檔 /var/log/dpkg.log 參考資料 https://debian-handbook.info/browse/zh-TW/stable/sect.manipulating-packages-with-dpkg.html

Demangle C++ function name at runtime

C++的函數名稱都會mangle 靜態Demanlge只要使用c++filt指令就能處理 動態的Demangle需要使用libstdc++的功能或是libliberty提供的函數功能 #include <iostream> #include <stdlib.h> #include <typeinfo> #include <cxxabi.h> // libstdc++ #include <libiberty/demangle.h> // libliberty // Prerequirement for Ubuntu // sudo apt-get install libiberty-dev // Please compile with -liberty // example: gcc test.cpp -liberty using namespace std; int main(int argc, char** argv) {     char* demangled_name = NULL;     int status;     int options = DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES;     if (argc<=1) {         cerr << "Please assign a mangling C++ function name" << endl;         return -1;     }     cout << "Demangle the mangling string [" << argv[1] << "]" << endl;     // libstdc++     // https://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html     demangled_name = abi::__cxa_demangle(argv[1],0,0,&status);