rsync 学习笔记(一)编译

news/2024/9/19 14:04:16/文章来源:https://www.cnblogs.com/sandyflower/p/18407939

一、背景

  rsync二进制程序依赖外部库,由于安全问题,有时会单独升级依赖的外部库。另外为了防止因为栈溢出攻击导致服务器被黑,需要对rsync及其依赖的外部库重新编译,开启安全编译选项,增加黑客破解的复杂度。

  所有的库编译必须要求加上如下编译选项:

  • 栈保护(-fstack-protector-all/-fstack-protector-strong)
  • 堆栈不可执行(-Wl,-z,noexecstack)
  • GOT表保护(-Wl,-z,relro)
  • 地址无关代码/地址无关可执行(-fPIC/-fPIE -pie)
  • 立即加载(-Wl,-z,now)
  • strip
  • 指定动态库搜索路径(-Wl,--disable-new-dtags,–rpath,./)

栈保护选项,编译器如果支持strong则开启 -fstack-protector-strong,编译器如果不支持则开启-fstack-protector-all

-Wl,--disable-new-dtags,–rpath,./  指定动态库搜索路径,根据实际引用的库的相对路径配置,如果组件不依赖其它库则不需要

二、操作步骤

1、 rsync依赖的开源库

(1)   通过 ldd rsync 命令查看 rsync二进制软件依赖的库

远程到安装rsync的服务器上,执行 ldd rsync,查看rsync依赖哪些库。

 

通过上图的执行结果,可以看到 rsync 依赖的开源库包括如下:

  • libattr
  • libacl
  • libz
  • liblz4
  • libzstd
  • libxxhash
  • libcrypto

(2)   访问 rsync的github代码库,查看其说明再次确认依赖的库情况

访问地址:https://github.com/RsyncProject/rsync/blob/master/INSTALL.md

从上面可以看到官方介绍依赖的开源库是:

  • acl
  • xattr
  • xxhash
  • zstd
  • lz4
  • openssl crypto

和 ldd 查看比较发现缺少一个libz,而这个对应的是zlib,观察rsync的代码库可以发现其内置了zlib,但是我们需要安全编译,也方便日后可以单独升级 zlib,因此需要关闭不使用其内置的zlib,直接依赖外部的zlib库。

总结以上,rsync依赖的开源库如下

  • acl
  • xattr
  • xxhash
  • zstd
  • lz4
  • openssl crypto
  • zlib

2、 准备工作

2.1 准备编译服务器

准备一台编译服务器,其上已经安装了gcc,用于开源库编译,这里以 10.33.43.42服务器为例,该服务器为一台x64结构服务器。

2.2 下载所有开源库源码

2.2.1 下载 rsync 开源库源码

  • 官网地址 https://rsync.samba.org/download.html

 

  • 进入github https://github.com/RsyncProject/rsync/releases

 

 

这里选择 3.3.0 版本。

2.2.2 下载 Acl  开源库源码

  • 远程到编译服务器
  •  执行yum info acl

 

可以看到其中有两个版本,第一个地址访问不了,所以选择第二个地址

 

点击 download 可以看到所有能下载的源码:

https://download.savannah.nongnu.org/releases/acl/

 

选择下载最新 2.3.2 版本。

2.2.3 下载 xxHash 开源库源码

https://github.com/Cyan4973/xxHash

https://github.com/Cyan4973/xxHash/releases

点击 右下角的 release链接可以看到所有的发布版本

 

这里选择 0.8.2 版本

2.2.4 下载 attr 开源库源码

  •  在编译服务器上通过yum info attr方式,发现找不到它的rmp文件,基于此,从网上直接查找
  •  网络搜索 libattr.so 官网,可以找到如下

 

  • 直接访问https://savannah.nongnu.org/projects/attr

 

  • 点击上图的download,也就是地址:http://download.savannah.nongnu.org/releases/attr/

 

这里选择使用 2.5.2 版本。

2.2.5 下载 zstd 开源库源码

  • 在 rsync 的install.cmd 上直接点击 zstd 的链接,跳转到 zstd 官网

 

  • 直接在官网上点击github

  • Github上点击 右下角的 release 链接可以看到多个发布版本

 

这里选择 1.5.6 版本

2.2.6 下载 lz4 开源库源码

  • 在 rsync 的install.cmd 上直接点击 lz4的链接,跳转到lz4官网

  • 进入lz4官网:https://lz4.org/

  • 进入github:https://github.com/lz4/lz4

 

这里选择 1.10.0版本

2.2.7 下载 zlib 开源库源码

 

 

2.2.8 下载 openssl 开源库源码

 

 

这里使用 openssl 3.0.15 版本

3、 开源库编译

  通过第二章节,准备的开源库源码包或者已经编译好的库如下:

  

3.1 准备工作

 远程到编译服务器,创建如下目录

/opt/wf

     |-- openssl

     |--rsync

         |--include

         |--lib

  •  将本地准备的openssl(已经编译好的)目录下的所有目录和文件上传到编译服务器/opt/wf/openssl目录下;
  • 将本地准备的 libz.so.1 文件上传到编译服务器/opt/wf/rsync/lib目录下;
  • 将本地准备的所有tar.gz包上传到编译服务器/opt/wf/rsync/include目录下;

3.1 attr开源库编译

远程到编译服务器,执行以下命令

  • 解压源码

cd /opt/wf/rsync/include

tar -zxvf attr-2.5.2.tar.gz

mv attr-2.5.2 attr

  • ./configure

cd attr

./configure CFLAGS="-fstack-protector-all-fPIC" CPPFLAGS="-fstack-protector-strong -fPIC  " LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./"

 

  • make
  • make install

 

可以看到so文件被安装到了/usr/lib目录下,编译好的库文件为libattr.so.1.1.2502

  • 将libattr.so.1.1.2502拷贝并重命名到指定目录下

cp /usr/lib/libattr.so.1.1.2502 /opt/wf/rsync/lib/libattr.so.1

3.2 acl 开源库编译

远程到编译服务器,执行以下命令

  • 解压源码

cd /opt/wf/rsync/include

tar -zxvf acl-2.3.2.tar.gz

mv acl-2.3.2 acl

  • ./configure

cd acl

./configure CFLAGS="-fstack-protector-all-fPIC" CPPFLAGS="-fstack-protector-strong -fPIC  " LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now-Wl,--disable-new-dtags,-rpath,./"

 

  • make
  • make install

 

可以看到so文件被安装到了/usr/lib目录下,编译好的库文件为libacl.so.1.1.2302

  • 将libacl.so.1.1.2302拷贝并重命名到指定目录下

cp /usr/lib/libacl.so.1.1.2302 /opt/wf/rsync/lib/libacl.so.1

3.3 xxHash 开源库编译

xxHash 源码中没有提供configure,已经存在MakeFile文件,所以需要将编译选项直接作为make 的参数传递进去。

 远程到编译服务器,执行以下命令

  • 解压源码

cd /opt/wf/rsync/include

tar -zxvf xxHash-0.8.2.tar.gz

mv xxHash-0.8.2 xxHash

cd xxHash

  •  make

make CFLAGS="-fstack-protector-all-fPIC" CPPFLAGS="-fstack-protector-strong -fPIC  " LDFLAGS="-shared -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now-Wl,--disable-new-dtags,-rpath,./"

  •  make install

可以看到xxHash目录下有编译好的so文件libxxhash.so.0.8.2

  • 将libxxhash.so.0.8.2拷贝并重命名到指定目录下

cp libxxhash.so.0.8.2 /opt/wf/rsync/lib/libxxhash.so.0

3.4 zstd 开源库编译

zstd源码中没有提供configure,已经存在MakeFile文件,所以需要将编译选项直接作为make 的参数传递进去。

远程到编译服务器,执行以下命令

  • 解压源码

cd /opt/wf/rsync/include

tar -zxvf zstd-1.5.6.tar.gz

mv zstd-1.5.6 zstd

cd zstd

  • make

make CFLAGS="-fstack-protector-all-fPIC" CPPFLAGS="-fstack-protector-strong -fPIC  " LDFLAGS="-shared -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now-Wl,--disable-new-dtags,-rpath,./"

  • make install

 

可以看到zstd/lib目录下有编译好的so文件libzstd.so.1.5.6

  • 将libzstd.so.1.5.6拷贝并重命名到指定目录下

cp lib/libzstd.so.1.5.6 /opt/wf/rsync/lib/libzstd.so.1

3.5 lz4 开源库编译

Lz4源码中没有提供configure,已经存在MakeFile文件,所以需要将编译选项直接作为make 的参数传递进去。

远程到编译服务器,执行以下命令

  • 解压源码

cd /opt/wf/rsync/include

tar -zxvf lz4-1.10.0.tar.gz

mv lz4-1.10.0 lz4

cd lz4

  • make

make CFLAGS="-fstack-protector-all -fPIC -I/opt/wf/rsync/include/lz4/lib"  CPPFLAGS="-fstack-protector-strong-fPIC -I/opt/wf/rsync/include/lz4/lib"  LDFLAGS="-pie -Wl,-z,noexecstack-Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./"

  • make install

 

可以看到lz4/lib目录下有编译好的so文件liblz4.so.1.10.0

  • 将liblz4.so.1.10.0拷贝并重命名到指定目录下

cp lib/liblz4.so.1.10.0 /opt/wf/rsync/lib/liblz4.so.1

3.6 rsync 开源库编译

远程到编译服务器,执行以下命令

  • 解压源码

cd /opt/wf/rsync/include

tar -zxvf rsync-3.3.0.tar.gz

mv rsync-3.3.0 rsync

cd rsync

  • 修改checksum.c 中的源码

将文件中的 EVP_MD_CTX_create 全部修改成 EVP_MD_CTX_new

 

  • 指定openssl库的位置

先通过export 指定 openssl 的库路径,这里使用的是openssl 3 ,位置在/opt/wf/openssl

export LD_LIBRARY_PATH=/opt/wf/openssl/lib:$LD_LIBRARY_PATH

  • ./configure

./configure --disable-md2man--with-included-zlib=no --with-included-poptCFLAGS="-fstack-protector-all -fPIC -I/opt/wf/openssl/include"  CPPFLAGS="-fstack-protector-strong-fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack-Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./  -L/opt/wf/openssl/lib -lssl -lcrypto"

  • 修改configure.status

将该文件拿到本地,搜索关键字SIZEOF_,将其内容修改成如下:

 

  • make

 

可以看到编译好的rsync文件就在当前目录下

ldd rsync 可以看到这个二进制文件依赖的库

 

  • 将openssl/lib下的libcrypto.so.3\libssl.so.3 以及 rsync 移动到 /opt/wf/rsync/lib下

cp rsync /opt/wf/rsync/lib/

cp /opt/wf/openssl/lib/libssl.so.3 /opt/wf/rsync/lib/

cp /opt/wf/openssl/lib/libcrypto.so.3 /opt/wf/rsync/lib/

  • 进入到/opt/wf/rsync/lib 下,再次执行ldd rsync ,查看其依赖的库是否都在当前目录下(最好重新打开一个远程)

 

可以看到到此rsync编译完毕,只要将 /opt/wf/rsync/lib 下所有库和文件拿到本地即可,这样rsync 编译完成。

3.7 检查编译出来的库是否都是安全的

使用公共安全库提供的checksec.sh-2.7.1.zip 程序进行校验,将该包放置到编译服务器/opt/wf下,进行如下操作:

cd /opt/wf

unzip checksec.sh-2.7.1.zip

mv checksec.sh-2.7.1 check

cd check

./checksec  --dir=/opt/wf/rsync/lib    #如果检查单个文件使用 --file=xxxx.so

 

明显以上库是安全的。

四、问题与总结

1、Acl 编译报错提示缺失“attr/error_context.h”

  在执行 ./configure 命令时,直接报错了,配置不通过,如下:

 

原因分析

提示缺失 attr/error_context.h 找不到,因此acl 依赖attr,需要先编译attr开源库和安装。

解决办法

先编译和安装attr开源库,再编译acl 开源库。

2、xxHash编译报错提示“undefined reference to main”

现象

在执行make(make CFLAGS="-fstack-protector-all -fPIC"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./")命令时,直接报错,具体如下

 

解决办法

   将make命令中的系列参数 –pie修改成 -shared

make CFLAGS="-fstack-protector-all -fPIC"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-shared -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./" 将-pie去掉换成-shared 才正常  (分析出来是这个原因是直接make可以成功,将直接make过程与添加编译选择的执行过程做了比较,发现需要改成shared)

3、zstd编译报错提示“undefined reference to main”

现象

在执行make(make CFLAGS="-fstack-protector-all -fPIC"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./")命令时,直接报错,具体如下

 

解决办法

   将make命令中的系列参数 –pie修改成 -shared

make CFLAGS="-fstack-protector-all -fPIC"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-shared -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./" 将-pie去掉换成-shared 才正常  (分析出来是这个原因是直接make可以成功,将直接make过程与添加编译选择的执行过程做了比较,发现需要改成shared)

 

4、 lz4编译报错提示“fatal error:xxhash.h:No such file or directory”

现象

在执行make(make CFLAGS="-fstack-protector-all -fPIC"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./")命令时,直接报错,具体如下

根据错误提示,貌似是在提示找不到 xxhash.h 文件

分析

   深入会发现xxhash.h 文件其实在 lz4的lib目录下,也就是说make时其无法自动搜索到lib目录,找到这个文件,为此编译时需要加上-I指定追加的文件搜索路径。

 

解决办法

make  CFLAGS="-fstack-protector-all -fPIC -I/opt/wf/rsync/include/lz4/lib"  CPPFLAGS="-fstack-protector-strong -fPIC -I/opt/wf/rsync/include/lz4/lib"  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./"

在CFLAGS和CPPFLAGS上都加上-I/opt/wf/rsync/include/lz4/lib选项,在进行编译可以成功。

 

5、 rsync configure命令执行完之后,make报错“error:unknown type name ‘int32’”

现象

首先执行:./configure --disable-md2man --with-included-zlib=no --with-included-popt CFLAGS="-fstack-protector-all -fPIC"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./"

再次执行make命令,执行的时候报如下错误

 

分析

   在rsync github issue 上查到有人提过这个问题,查看作者的回复发现是因为rsync默认是32位上编译的,而我们当前编译服务器是64位操作系统,所以检测不通过,需要手动更改configure命令执行完成之后生成的config.status文件。

 

从图上可以看到这些值全是0,需要修改成正确的值。

解决方案

   将config.status文件拿到本地,按照关键字“SIZEOF_”,将对应的key值修改成如下的值。

 

6、 rsync 编译需要指定openssl

现象

由于openssl 也需要重新安全编译,因此rsync只能依赖我们编译好的openssl,不能使用系统默认的openssl。对此,rsync编译的时候需要指定openssl,否则会出现如下错误:

配置的命令为

 ./configure --disable-md2man --with-included-zlib=no --with-included-popt CFLAGS="-fstack-protector-all -fPIC"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./"

  make 之后 生成的 rsync文件使用 ldd 查看依赖的库

 

提示:version ‘libcrypto.so.10’ not found (required by ./rsync)

通过查看资料和网上百度,需要在LDFLAGS上添加-lssl –lcrypto 表示使用指定的openssl 库进行编译,添加-L/opt/wf/openssl/lib表示在编译的时候从指定的openssl 的库目录加载库文件;在CFLAGS上添加-I/opt/wf/openssl11/openssl/include表示在编译的时候从指定的openssl的头文件目录加载需要的头文件。

因此 最终的configure命令调整成如下:

./configure --disable-md2man --with-included-zlib=no --with-included-popt CFLAGS="-fstack-protector-all -fPIC -I/opt/wf/openssl/include"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./  -L/opt/wf/openssl/lib -lssl -lcrypto"

7、 rsync configure时提示“./configtest:error while loading shared libraries:libssl.so.1”

现象

    执行了./configure --disable-md2man --with-included-zlib=no --with-included-popt CFLAGS="-fstack-protector-all -fPIC -I/opt/wf/openssl/include"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./  -L/opt/wf/openssl/lib -lssl -lcrypto" 命令过程中,发现自行失败,提示的具体信息如下:

 

分析

    通过界面提示的错误分析,发现 gcc 编译成功生成了configtest二进制文件,但是在执行的时候提示configtest需要libssl.so.1 库,但是加载不到这个库。在编译configtest二进制文件,虽然在编译的时候通过rpath指定了./ 相对路径,但是libssl.so.1 文件的确不在configtest 所属当前目录下,其在 /opt/wf/openssl/lib 下,因此想到使用export 的方式指定库搜索路径。

解决方案

为了解决上述找不到ssl库的问题,需要在执行configure命令之前,先通过export 指定 openssl 的库路径,export LD_LIBRARY_PATH=/opt/wf/openssl/lib

8、 rsync configure时提示”libssl.so:file format not recognized;treating as linker script”

现象

  执行了./configure --disable-md2man --with-included-zlib=no --with-included-popt CFLAGS="-fstack-protector-all -fPIC -I/opt/wf/openssl/include"  CPPFLAGS="-fstack-protector-strong -fPIC  "  LDFLAGS="-pie -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags,-rpath,./  -L/opt/wf/openssl/lib -lssl -lcrypto" 命令过程中,发现自行失败,提示的具体信息如下:

分析

   通过查找相关资料,发现是 openssl/lib 下的libssl.so 文件是 ASCII text 格式的

  执行命令 file libssl.so

 

解决方案

  不能在本地解压 openssl.zip 文件之后再上传到编译服务器上,需要将zip包直接上传到编译服务器上,然后通过 unzip 命令进行解压,才不会改变so文件的编码格式。

 

五、小知识点

1、查看so的编码信息

  file xxx.so

2、编译时可指定 头文件路径

gcc xxx xxx -I/opt/wf/test/include

3、编译时可指定依赖库的所在路径

gc xxx xxx -L/opt/wf/test/lib

4、编译时可指定运行的时候从哪个目录搜索依赖的库

gc xxx xxx -Wl,-rpath=.       

-Wl,-rpath=.  表示从运行文件的当前目录去搜索库

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/795387.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go runtime 调度器精讲(一):Go 程序初始化

原创文章,欢迎转载,转载请注明出处,谢谢。0. 前言 本系列将介绍 Go runtime 调度器。要学好 Go 语言,runtime 运行时是绕不过去的,它相当于一层“操作系统”对我们的程序做“各种类型”的处理。其中,调度器作为运行时的核心,是必须要了解的内容。本系列会结合 Go plan9 …

煤矿皮带跑偏监测识别系统

煤矿皮带跑偏监测识别系统对皮带状况进行实时监测,不用手动控制。一旦监测到皮带跑偏或者其他异常情况时,应该马上开展警报,通知监督管理办公室,并提醒负责人及时处置,并把警报截屏和视频储存到数据库系统系统中生成表格。煤矿皮带跑偏监测识别系统根据时间段对告警记录和…

GIS建库软件:地理信息与遥感领域的数据基石

在地理信息与遥感科学的浩瀚星海中,建库软件是构筑数据宇宙的基石,它不仅承载着海量地理空间数据,更是连接信息与应用的桥梁。本文将从其定义、关键技术、应用场景及未来发展四个方面,深入剖析建库软件如何支撑并推动整个行业的发展。建库软件:数据海洋的港湾建库软件,顾…

mysql月份前后格式变化记录

select DATE_FORMAT(2024-10-11 - INTERVAL 1 MONTH,%Y-%m) 一, DATE_FORMAT(2024-10-11,%Y-%m) 二, DATE_ADD(2024-10-11, INTERVAL 1 MONTH) 三 ,DATE_FORMAT(DATE_ADD(2024-10-11, INTERVAL 1 MONTH) ,%Y-%m) 四,REPLACE(DATE_FORMAT(DATE_ADD(2024-10-11, INTERVAL 1 MONT…

煤矿皮带撕裂检测系统

煤矿皮带撕裂检测系统可以全天候监管皮带的运送的工作情况,当煤矿皮带撕裂检测系统监管皮带撕裂时,马上停止皮带的运送,精准定位到皮带的裂开部位,工作员能够及时到现场维护保养。及时发现皮带撕裂,能够减少安全事故带来的损失,能够有效提升皮带机生产运输过程的效率。煤…

GIS数据采集软件:地理信息与遥感技术的智慧之眼

在信息时代,数据如同血液,滋养着各行各业的创新与进步,而地理信息与遥感领域中的数据采集软件,正是这股生命之源,它不仅为科学研究、城市规划、环境保护、灾害监测、资源管理等提供了精确数据支持,更是智慧城市建设的基石。本文将深入探讨其技术发展、应用及未来趋势,为…

工地反光衣穿戴识别

工地反光衣穿戴识别系统依据现场监控摄像头采集的视频图像,应用最新的神经网络算法,检测到一些人不穿反光衣服时,前端抓拍设备实时上传视频流至系统服务器,然后实时读取视频流并进行语音报警广播。工地反光衣穿戴识别系统的另一个闪光点是能够应用现有的监控摄像机,实时监…

深入理解DocumentFragment -文档片段

什么是文档片段? (MDN解释:)DocumentFragment,文档片段接口,一个没有父对象的最小文档对象。它被作为一个轻量版的 Document 使用,就像标准的document一样,存储由节点(nodes)组成的文档结构。 作用是什么 与document相比,最大的区别是DocumentFragment 不是真实 DOM…

LeetCode Hot100刷题记录-141.环形链表

给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅…

[Python] Python 基础教程

1 概述 1.1 简介Python 是一种解释型、面向对象、动态数据类型的高级程序设计语言。https://www.python.org/Python 由 Guido van Rossum 于 1989 年底发明,第一个公开发行版发行于 1991 年。 像 Perl 语言一样, Python 源代码同样遵循 GPL(GNU General Public License) 协议。…

从数据洞察到智能决策:合合信息infiniflow RAG技术的实战案例分享

从数据洞察到智能决策:合合信息&infiniflow RAG技术的实战案例分享从数据洞察到智能决策:合合信息&infiniflow RAG技术的实战案例分享 标题取自 LLamaIndex,这个内容最早提出于今年 2 月份 LlamaIndex 官方博客。从 22 年 chatGpt 爆火,23 年大模型尝鲜,到 24 年真…