Linux crontab 自動化例行性工作

查看例行性工作

1
2
# 查看自己的 crontab
crontab -l

建立例行性工作

1
2
# 編輯 crontab 內容
crontab -e

如果要用高權限執行例行性工作可以加上sudo

1
sudo crontab -e

工作設定的格式

每個例行工作會有時間搭配要下達的指令,*代表所對應的時間只要一改變就執行,例如下面範例每分鐘都會執行一次python3 test.py指令(因為全部是*號)

1
2
*        *           *        *        *            python3 test.py
MIN(分鐘) HOUR(小時) DOM(日) MON(月) DOW(星期幾) 指令(CMD)

指令

1
2
sudo crontab -e
01 14 * * * /home/joe/myscript >> /home/log/myscript.log 2>&1

參考:
https://ithelp.ithome.com.tw/articles/10293218
https://blog.gtwang.org/linux/linux-crontab-cron-job-tutorial-and-examples/
https://askubuntu.com/a/121560

CMake教學系列一使用CMake編譯專案

安裝最新版的CMake,越新越好,因為新版的CMake提供更多的工具幫你尋找函式庫或套件,尤其如果你需要用到CUDA,新版的CMake可以省去你許多的麻煩
{: .prompt-tip }

安裝CMake

Ubuntu可以跟著這篇官方教學安裝最新的CMake

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sudo apt-get update
sudo apt-get install ca-certificates gpg wget

test -f /usr/share/doc/kitware-archive-keyring/copyright ||
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null

# Ubuntu 20.04
echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ focal main' | sudo tee /etc/apt/sources.list.d/kitware.list >/dev/null
sudo apt-get update

test -f /usr/share/doc/kitware-archive-keyring/copyright ||
sudo rm /usr/share/keyrings/kitware-archive-keyring.gpg

sudo apt-get install kitware-archive-keyring

sudo apt-get install cmake

嘗試用CMake編譯程式

讓我們嘗試用CMake編譯一個開源專案

1
2
git clone https://github.com/CLIUtils/CLI11.git # 下載專案
cd CLI11 #進入資料夾

然後我們就可以開始編譯,過程中你會發現CMake幫你建立了一個build資料夾,第一行指令-S表示source directoryB會幫你建立一個build資料夾如果他不存在的話,CMake產生的東西會全部放在build資料夾裡面,你隨時可以刪除他而且他也不需要被版本控制。第二行的-j讓你可以指定要用多少核心來加速編譯。第三行-t代表執行測試程式,如果你沒有測試程式也可以不需要這行指令。

1
2
3
cmake -S . -B build
cmake --build build -j 8
cmake --build build -t test

你很容易在網路上看到CMake傳統的編譯方式,不過在CMake 3.15之後你可以用前面提到的新的方法,他可以幫你處理掉一些小麻煩。

1
2
3
4
5
mkdir build
cd build
cmake ..
make
make test

{: .prompt-tip }

查看編譯選項

CLI11資料夾中,你可以用cmake -S . -L列出所有你可以設定的選項,有些是CMake內建的選項,有些是這著專案中設定讓你可以選的選項。cmake -S . -LH不但會列出所有選項,還把說明文字也印出來。在許多開源專案用CMake編譯的時候經常會需要知道他提供哪些選項,這個指令會非常有幫助。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$ cmake -S . -B build -LH
-- CMake 3.22.1
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE)
-- Doxygen not found, building docs has been disabled
-- Configuring done
-- Generating done
-- Build files have been written to: /home/steven/CLI11/build
-- Cache values
// Build the testing tree.
BUILD_TESTING:BOOL=OFF

// Path to a file.
Boost_INCLUDE_DIR:PATH=Boost_INCLUDE_DIR-NOTFOUND

// Turn on boost test (currently may fail with Boost 1.70)
CLI11_BOOST:BOOL=ON

// Build CLI11 examples
CLI11_BUILD_EXAMPLES:BOOL=ON

// Build CLI11 json example
CLI11_BUILD_EXAMPLES_JSON:BOOL=OFF

// Build the tests with NVCC to check for warnings there - requires CMake 3.9+
CLI11_CUDA_TESTS:BOOL=OFF

// Install the CLI11 folder to include during install process
CLI11_INSTALL:BOOL=OFF
...以下省略

如果你想要設定選項值,你可以在CMake指令中用-D加上選項名稱來設定,例如

1
cmake -DCLI11_INSTALL=ON -S . -B build

這時候被設定的值會被保存在build資料夾裡面的CMakeCache.txt。你可以打開這份文件並且找到這個選項被設定的值。你可以看到CLI11_INSTALL:BOOL=ON

1
2
3
4
5
6
7
8
9
10
11
...以上省略
//Build the tests with NVCC to check for warnings there - requires
// CMake 3.9+
CLI11_CUDA_TESTS:BOOL=OFF

//Install the CLI11 folder to include during install process
CLI11_INSTALL:BOOL=ON

//Value Computed by CMake
CLI11_IS_TOP_LEVEL:STATIC=ON
...以下省略

{: file=’CMakeCache.txt’}

如果在設定一次就可以發現他的值被改成OFF

1
cmake -DCLI11_INSTALL=OFF -S . -B build
1
2
3
4
5
6
7
8
9
10
11
...以上省略
//Build the tests with NVCC to check for warnings there - requires
// CMake 3.9+
CLI11_CUDA_TESTS:BOOL=OFF

//Install the CLI11 folder to include during install process
CLI11_INSTALL:BOOL=OFF

//Value Computed by CMake
CLI11_IS_TOP_LEVEL:STATIC=ON
...以下省略

{: file=’CMakeCache.txt’}
另外還有一些常見的CMake標準選項你可以設定

CMake除錯技巧

這節特別重要,如果要自己撰寫CMakeLists.txt話十分有用。--trace-source選項讓你指定你有興趣的檔案,並且依照他執行的順序依序印出他所執行的行數

1
cmake build --trace-source="CMakeLists.txt"

動手寫第一個CMakeLists.txt

我們將製作一個簡單的C語言程式,並且寫一個CMakeLists.txt

1
2
3
mkdir cmakeQuickStart
cd cmakeQuickStart
code .

cmakeQuickStart資料夾內建立一個CMakeLists.txt和一個simple.cpp

  1. cmake_minimum_required指定使用這份CMakeLists.txt最小所需的CMake版本。
  2. project指定專案名稱,而專案使用的語言預設為C++和C。如果要指定專案語言可以輸入LANGUAGES參數。
  3. 最後你要輸出執行檔或是library。add_executable指令輸出執行檔,add_library指令輸出library,輸出的執行檔或是library檔名在跟第一個參數一樣。在這裡特別注意,add_executable``add_library第一個參數為兩個東西命名,首先他命名了輸出檔案的檔案名稱,其次是他命名了一個CMake的targettarget在後面會很常用到。
1
2
3
4
5
6
7
/* simple.c or simple.cpp */
#include <stdio.h>

int main() {
printf("Hello, World!\n");
return 0;
}

{: file=’simple.cpp’}

1
2
3
4
5
cmake_minimum_required(VERSION 3.15)

project(MyProject)

add_executable(myexample simple.cpp)

{: file=’CMakeLists.txt’}

你也可以把CMakeLists.txt改成下面這樣,他指定了CMake的版本範圍,並且為專案增加說明和版本號

1
2
3
4
5
6
7
8
9
10
11
12
cmake_minimum_required(VERSION 3.15...3.21)

project(MyProject
VERSION
1.0
DESCRIPTION
"Very nice project"
LANGUAGES
CXX
)

add_executable(myexample simple.cpp)

{: file=’CMakeLists.txt’}

接下來你就可以編譯你的程式了,編譯後你會看到build資料夾出現一個myexample檔,跟你在add_executable指定的名稱一樣

1
2
cmake -S . -B build
cmake --build build

More Modern CMake
https://hsf-training.github.io/hsf-training-cmake-webpage/

An Introduction to Modern CMake
https://cliutils.gitlab.io/modern-cmake/

Python呼叫C++系列(一)環境設定

我製作了一個SORT: Simple online and realtime tracking的C++的Python binding
歡迎參考看看
sort-cpp-pybind11
{: .prompt-tip }

第二篇連結

  • 作業系統: Ubuntu 22.04
  • IDE: VSCode
  • CMake 3.22.1
  • python 3.10.4

摘要

本系列文章將介紹如何利用Pybind11以及scikit-build來幫助我們製作Python的C++ extension,並且介紹如何把用C++實作的追蹤演算法SORT轉換成python extension

C++ 重點提示

  • 編譯與直譯

Python屬於直譯式語言,而C++是屬於編譯語言。
因為我們用文字寫的程式電腦是看不懂的,必須有個工具幫我們將程式翻譯成電腦懂的機器碼,他就像我們跟電腦之間的翻譯員。
直譯語言用的是直譯器(Interpreter)他像是個即時翻譯員,當我們在命令提示字元或是Bash,輸入Python的時候,打開的就是直譯器,我們每輸入一行(或一段)的程式,直譯器會馬上幫我們翻譯成機器碼,所以我們可以直接看到輸出結果。
而編譯語言使用的是編譯器(Compiler),他向翻譯社一樣,要把所有的程式全部都寫完後,送進編譯器一口起全部翻成機器碼。

  • 標頭檔(head file)

用來描述function或是class介面的檔案,介面的意思就是function會需要什麼參數,然後回傳直會是什麼,又或者是class有哪些method、member variable和method使用的參數和回傳值。而程式實作方式(
Implement)都放在原碼檔。就像上圖的Num.h那樣。

  • 原碼檔(source file)

紀錄程式實作方式的檔案,所有的實作方式都會被記錄在原碼檔。

  • 動態/靜態函式庫

有時候程式提供者不想揭露實作方式的時候,可能就會給動態/靜態函式庫以及標頭檔,因為動態/靜態函式庫是機械碼所以人類是看不懂的,要使用動態/靜態函式庫我們必須利用標頭檔來了解有哪些函式可以呼叫,並且利用標頭檔來呼叫和使用動態/靜態函式庫。

以下面的程式為例,我們有兩個原始碼檔和一個標頭檔,標頭檔紀錄Num類別的成員變數和方法的輸入和輸出,原始碼檔紀錄getNum函式
的運作主程式的運作

Num的標頭檔(Num.h)

1
2
3
4
5
6
7
8
9
// Num.h 的內容
class Num
{
private:
int num;
public:
Num(int n);
int getNum();
};

Num的原始碼檔(Num.cpp)

1
2
3
4
5
6
7
8
// Num.cpp 的內容
#include "Num.h"
Num::Num() : num(0) { }
Num::Num(int n): num(n) {}
int Num::getNum()
{
return num;
}

主程式main的原始碼檔(main.cpp)

1
2
3
4
5
6
7
8
9
10
// main.cpp 的內容
#include <iostream>
#include "Num.h"
using namespace std;
int main()
{
Num n(35);
cout << n.getNum() << endl;
return 0;
}

CMake管理C++專案

如果曾經使用過Visual Studio寫過C++的話,就會看過Visual Studio幫我們製造一個.sln檔,這個檔案記錄了專案的設定。不過不同的軟體編輯器有不同的專案檔,大家常用的軟體編輯器也都不一樣。因此CMake就扮演軟體編輯器通譯的角色,只要我們可以跟CMake說我們專案的設定,CMake就能夠幫我們製造不同軟體編輯器的專案檔,而且CMake是跨平台的,因此不管開發者是在Windows還是Linux上開發,CMake都可以幫我們產生是和的專案檔,讓開發者合作順暢。

站在CMake之上來管理Python C++混和呼叫的專案上:scikit-build

Python C++混和的專案面臨到更多複雜的設定,單純使用CMake並不好寫,而scikit-build幫我們處理好Python C++混和型的專案常用的工具或是編譯流程,省去我們重新造輪子的工。

環境設定

設定VScode和開發環境

可以參考這篇

安裝Pybind11

官方提供多樣的安裝方式,可以參考官方文件,這裡我們採用pip安裝,注意要先用venv建立虛擬環境

1
2
3
python3 -m venv venv
. venv/bin/activate
pip install pybind11

測試安裝

  • 首先建立一個簡單的python c++ extension程式example.cpp
1
2
3
4
5
6
7
8
9
10
11
include <pybind11/pybind11.h>

int add(int i, int j) {
return i + j;
}

PYBIND11_MODULE(example, m) {
m.doc() = "pybind11 example plugin"; // optional module docstring

m.def("add", &add, "A function that adds two numbers");
}

{:file=’example.cpp’}

  • 編譯extension,注意venv必須已經啟動並且已經安裝pybind11,接著輸入以下指令,你會發現資料夾多了一個example.cpython-310-x86_64-linux-gnu.so檔案,代表動態函式庫已經編譯完成,你已經成功製作了一個python C++ extension
    1
    c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)
  • 嘗試從python內呼叫extension
    1
    2
    3
    4
    5
    6
    7
    8
    $ python
    Python 3.9.10 (main, Jan 15 2022, 11:48:04)
    [Clang 13.0.0 (clang-1300.0.29.3)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    import example
    example.add(1, 2)
    3
    >>>
    恭喜你完成了第一個extension!!

注意剛剛編譯的步驟我們下了一行很長的指令(c++ -O3 -Wall -shared …….),你可能會想在Linux可以這樣編譯,那如果我的電腦是Windows或是masOS怎麼辦呢? CMake專門幫我們處理這些問題,後面我們會介紹更多CMake的用法。
{: .prompt-tip }

參考:

https://zhuanlan.zhihu.com/p/52874931
https://developer.lsst.io/
https://blog.csdn.net/zzh123353/article/details/121582409

下面的連結有些marco是舊的
https://people.duke.edu/~ccc14/cspy/18G_C++_Python_pybind11.html
https://developer.lsst.io/v/billglick-slurm-queues/coding/python_wrappers_for_cpp_with_pybind11.html

TensorRT系列(一)環境設定

本文章版本資訊

  • TensorRT 8.6.1

apt 安裝TensorRT的方法

https://docs.nvidia.com/deeplearning/tensorrt/archives/tensorrt-861/install-guide/index.html#installing-debian

利用Docker 建立TensorRT環境

docker tensorrt的版本與tensorrt版本對應表
https://docs.nvidia.com/deeplearning/frameworks/support-matrix/index.html

1
docker run --gpus all -it --rm -v local_dir:container_dir nvcr.io/nvidia/tensorrt:22.07-py3

其中local_dir換成自己電腦的某一個資料夾,他將與Docker container共用,container_dir換成container裡面的資料夾路徑

參考:
https://docs.nvidia.com/deeplearning/tensorrt/quick-start-guide/index.html#install
https://github.com/wang-xinyu/tensorrtx#tutorials

Python OpenCV圖片裁剪

OpenCV 座標

Python OpenCV 裁剪圖片

OpenCV 的蒲覑本質上就是一個 numpy array, 因此可以利用numpy array提供的方法來完成裁剪圖片的功能

1
crop_img = img[y:y+h, x:x+w] # x, y 為圖片的裁剪圖片的左上角座標,h, w 分別為裁剪圖片的高和寬

參考:
https://stackoverflow.com/a/15589825

fastapi使用自己的openapi檔

步驟

  • 參考官方離線版文件的說明
  • 寫一個route可以回傳openapi的json
  • 把openapi_url=app.openapi_url改型成
    1
    openapi_url=<回傳openapi json 的route>

ssh連線設定

非對稱式加密

  • 非對稱式加密有兩把key,一把只能加密,一把只能解密
  • 非對稱式加密public key是公開給外界,作為解密專用key,只能解密用對應的private key加密的內容
  • 非對稱式加密private key必須妥善保存,作為加密專用key,只被對應的public key解密

public key像帳號,private key像密碼

把自己的的public key提供給目標連線電腦,就像在那台帳號註冊帳號一樣

ssh會把public key存在~/.ssh/authorized_keys這個檔案裡面

  1. 利用ssh-copy-id複製public key到ssh server主機
  • linux
    1
    ssh-copy-id 192.168.122.7  # 指令為ssh-copy-id 遠端主機的ip
  • windows
    在powershell中沒有ssh-copy-id這個指令,不過我們可以用下面指令達成相同目標
    1
    type $env:USERPROFILE\.ssh\id_rsa.pub | ssh {IP-ADDRESS-OR-FQDN} "cat >> .ssh/authorized_keys"

參考:
https://kb.iu.edu/d/aews
https://www.chrisjhart.com/Windows-10-ssh-copy-id/