这里开始时间和持续时间共同确定一天内任务生效的时间段,哪果选选从0点开始持续时间12个小时,则每天的0点到12点任务生效。对于每天执行的任务最长持续时间不能超过一天,也可以选择无限期,效果跟一天是一样的。
Views: 4
转换为C语言模块后可以与Python解释器编译到一起作为内置模块用,也可以外部模块import后使用。
嵌入式模块可以嵌入到独立C语言程序中执行
首先编写普通的python模块代码,然后在python代码的基础上创建pyx代码,通过cdef声明可以定义原生C语言函数,而不用通过Python解释器调用,可以更好的与C语言交互。
pyx代码的写法可以参考cython官方文档
hello.pyx文件
cdef public char *say_hello_to(char* name):
return name
c-test.c文件
#include "Python.h"
#include "hello.h"
int main(int argc, char *argv[])
{
PyObject *pmodule;
char *result;
wchar_t *program;
// 读取命令行参数
program = Py_DecodeLocale(argv[0], NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode argv[0], got %d arguments\n", argc);
exit(1);
}
/* 把模块注册为内置模块 */
if (PyImport_AppendInittab("test", PyInit_hello) == -1) {
fprintf(stderr, "Error: could not extend in-built modules table\n");
exit(1);
}
/* 把命令行参数传给Python解释器 */
Py_SetProgramName(program);
/* 初始化Python,这一步是必须的. */
Py_Initialize();
/* 调用Python中的函数. */
result = say_hello_to("hetao");
// PyErr_Print();
printf("result:%s\n", result);
/* Clean up after using CPython. */
PyMem_RawFree(program);
Py_FinalizeEx();
return 0;
/* Clean up in the error cases above. */
exit_with_error:
PyMem_RawFree(program);
Py_Finalize();
return 1;
}
cython hello.pyx --3str
执行cython后会生成hello.c和hello.h两个文件
gcc -o libhello.so -shared -fPIC -I/usr/include/python3.10 hello.c
gcc -o test-c -I/usr/include/python3.10 -I./ -L./ -ltest -lpython3.10 -Wl,-rpath . test-c.c
运行结果
$ ./test-c
result:hetao
hello.pyx文件
def say_hello_to(name):
return name
setup.py文件
from setuptools import setup
from Cython.Build import cythonize
setup(
name='Hello',
ext_modules=cythonize("hello.pyx"),
)
构建模块
python setup.py build_ext --inplace
test-hello.py文件
import hello
result = hello.say_hello_to("hetao")
print(result)
cdef、def 和 cpdef 的区别:
在 Cython 中,有三种不同的函数声明方式:cdef、def 和 cpdef。
cdef 声明的函数是纯 C 函数,只能从 Cython 代码中调用,不可从 Python 代码中访问。
def 声明的函数是 Python 函数,可以从 Python 代码中调用,但会带来一些性能开销。
cpdef 声明的函数是混合函数,既可以从 Cython 代码中调用,也可以从 Python 代码中调用,其底层其实生成了两个函数版本。
关于编译参数:
获取编译参数
python3-config –cflags
获取链接参数
python3-config –ldflags
Views: 1
#include "Python.h"
int main()
{
Py_Initialize();
PyObject *pmodule = PyImport_ImportModule("os");
//获取当前用户的id
PyObject *pfunc = PyObject_GetAttrString(pmodule, "geteuid");
PyObject *arg = Py_BuildValue("()");
PyObject *result = PyObject_Call(pfunc, arg, NULL);
long retval = PyLong_AsLong(result);
printf("result: %ld\n", retval);
Py_XDECREF(result);
Py_FinalizeEx();
return 0;
}
gcc -c -I/usr/include/python3.10 -L/usr/lib/python3.10/config-3.10-x86_64-linux-gnu -L/usr/lib/x86_64-linux-gnu -lpython3.10 -lcrypt -ldl -lm -lm test.c
gcc -o test test.o -L/usr/lib/python3.10/config-3.10-x86_64-linux-gnu -L/usr/lib/x86_64-linux-gnu -lpython3.10 -lcrypt -ldl -lm
执行后返回如下:
$ ./test
result: 1001
这种方法可以调用普通Python函数
Views: 1
C语言写的Python模块中可以有python函数,也可以有C函数。
以下代码导入Python模块并执行其中的C函数
ctest.c文件内容
#include "Python.h"
#include "test.h"
int main(int argc, char *argv[])
{
PyObject *pmodule;
int *result;
wchar_t *program;
// 读取命令行参数
program = Py_DecodeLocale(argv[0], NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode argv[0], got %d arguments\n", argc);
exit(1);
}
/* 把模块注册为内置模块 */
if (PyImport_AppendInittab("test", PyInit_test) == -1) {
fprintf(stderr, "Error: could not extend in-built modules table\n");
exit(1);
}
/* 把命令行参数传给Python解释器 */
Py_SetProgramName(program);
/* 初始化Python,这一步是必须的. */
Py_Initialize();
/* 调用Python中的函数. */
result = hello(1, 2);
// PyErr_Print();
printf("result:%d,%d,%lu\n", result[0], result[2], sizeof(result));
/* Clean up after using CPython. */
PyMem_RawFree(program);
Py_FinalizeEx();
return 0;
/* Clean up in the error cases above. */
exit_with_error:
PyMem_RawFree(program);
Py_Finalize();
return 1;
}
编译
gcc -o ctest -I/usr/include/python3.10 -I./ -L./ -ltest -lpython3.10 -Wl,-rpath . ctest.c
如果是调用python自带的内置函数则不需要执行PyImport_AppendInittab,直接调用即可。
只有C语言写的模块才能注册为内置模块
关于Python解释器初始化的问题:
cython官方文档上说如果不调用Py_Initialize()进行初始化极有可能会发生程序崩溃,但并没有说明什么情况下会崩溃。经过我的测试如果所调用的C函数不涉及Python代码,也不会调用其它可能会执行Python代码的函数则不会崩溃,反之就会发生断错误。也就是说只能在C语言的内存空间内执行。对于一些Python内置的C语言写的函数是可以不初始化就调用的,如果是那种需要import的就不可以了。
Views: 1
nft add chain inet fw4 gfw_prerouting { type filter hook prerouting priority mangle\; policy accept\; }
nft add chain inet fw4 gfw_output { type route hook output priority mangle\; policy accept\; }
nft add rule inet fw4 gfw_prerouting ip daddr @GFWLIST counter ct mark set 0x10
nft add rule inet fw4 gfw_prerouting ip daddr @GFWLIST counter meta mark set ct mark
nft add rule inet fw4 gfw_output ip daddr @GFWLIST counter ct mark set 0x10
nft add rule inet fw4 gfw_output ip daddr @GFWLIST counter meta mark set ct mark
以上gfw_output链处理本地发现的包,gfw_prerouting处理转发的包,在foward链中处理mark是不生效的(所以无法用uci配置)。
通过配置文件配置nft
创建文件/etc/nftables.d/11-gfw.nft
文件内容:
chain gfw_forward {
type filter hook prerouting priority mangle; policy accept;
ip daddr @GFWLIST counter ct mark set 0x10
ip daddr @GFWLIST counter meta mark set ct mark
}
chain gfw_output {
type route hook output priority mangle; policy accept;
ip daddr @GFWLIST counter ct mark set 0x10
ip daddr @GFWLIST counter meta mark set ct mark
}
service firewall restart
这里要注意的是output hook只能是rotue链,不能是filter链,而prerouting则只能是filter链
Views: 3
nft中的set是属于某个table下面的,不像ipset是全局的,所以要先建立table
nft list tables
nft add table inet gfw
nft add set inet gfw GFWLIST { type ipv4_addr\; }
nft add set inet gfw GFWLIST6 { type ipv6_addr\; }
添加IP地址
nft add element inet gfw GFWLIST { 111.22.33.4 };
nft list set inet gfw GFWLIST
删除IP地址
nft delete element inet gfw GFWLIST {20.205.243.166}
openwrt中配置nftset
openwrt中默认的table是fw4,family是inet
关于family:
ip ipv4协议
ipv6 ipv6协议
inet 双栈协议
不指定family时nft默认是ipv4协议,dnsmasq中不指定family时默认也是ipv4协议
Views: 6
openwrt升级后原来安装的软件包就没有了,用这条命令可以重新安装所有丢失的软件包(前提是升级前对软件列表进行了备份)
opkg update && opkg list-installed | cut -f 1 -d ' '| sort -u > /tmp/currentpkg && cat /etc/backup/installed_packages.txt | cut -f 1 | sort -u > /tmp/oldpkg && grep -v -F -x -f /tmp/currentpkg /tmp/oldpkg > /tmp/inst && opkg install $(cat /tmp/inst | sort -u) && rm /tmp/currentpkg /tmp/oldpkg /tmp/inst
Views: 3
Views: 6
下载openwrt代码
git clone https://gitea.hetao.me/openwrt/openwrt
cd openwrt
curl https://downloads.openwrt.org/snapshots/targets/mediatek/filogic/config.buildinfo --output .config
curl https://downloads.openwrt.org/snapshots/targets/mediatek/filogic/feeds.buildinfo --output feeds.conf
config.buildinfo配置中已经包含了
CONFIG_ALL=y
CONFIG_ALL_KMODS=y
CONFIG_ALL_NONSHARED=y
对feeds.config中的域名替换为gitea.hetao.me,替换后如下
src-git packages https://gitea.hetao.me/feed/packages.git
src-git luci https://gitea.hetao.me/project/luci.git
src-git routing https://gitea.hetao.me/feed/routing.git
src-git telephony https://gitea.hetao.me/feed/telephony.git
./scripts/feeds update -a
./scripts/feeds install -a
对编译配置进行自定义修改,主要是编译目标板子改为bpi r3,集成luci和中文,开启ccache,修改opkg源和固件版本号,这是我用的配置
http://openwrt.hetao.me/snapshots/targets/mediatek/filogic/config.buildinfo
make menuconfig
sed -i '/is not set/d' .config
make defconfig
IGNORE_ERRORS=1 make -j 70
把编译后的镜像和ipk包复制到web服务器
rsync -avP bin/* root@openwrt.hetao.me:/opt/web/data/nginx/www/openwrt/snapshots/
这样就可以通过 https://openwrt.hetao.me/snapshots/ 访问openwrt源了
Views: 15