MySql UDF 调用外部程序和系统命令

1.mysql利用mysqludf的一个mysql插件可以实现调用外部程序和系统命令

下载lib_mysqludf_sys程序:https://github.com/mysqludf/lib_mysqludf_sys

2.安装说明:

2.1查询mysql插件路径:

在mysql里查询mysql插件目录的路径:show variables like “plugin_dir”;

2.2解压源码:

将下载下的插件(lib_mysqludf_sys-master.zip)解压后拷贝进/tmp目录下

#cd /tmp
#cd /ib/mysqludf_sys/lib_mysqludf_sys-master/
#ls
Makefile                        lib_mysqludf_sys.html
install.sh                      lib_mysqludf_sys.so
lib_mysqludf_sys.c              lib_mysqludf_sys.sql
2.3编译源码:

修改一下Makefile文件, 根据自身系统的MySQL环境而定

# cat Makefile
LIBDIR=/usr/lib

install:
        gcc -Wall -I/usr/include/mysql -I. -shared lib_mysqludf_sys.c -o $(LIBDIR)/lib_mysqludf_sys.so
#修改后,根据自己的系统环境决定
# cat Makefile
LIBDIR=/usr/lib64/mysql/plugin

install:
        gcc -fPIC -Wall -I/usr/local/include/mysql -I. -shared lib_mysqludf_sys.c -o $(LIBDIR)/lib_mysqludf_sys.so# makegcc -Wall -I/usr/local/include/mysql -I. -shared lib_mysqludf_sys.c -o /usr/lib64/mysql/plugin/lib_mysqludf_sys.so#说明:不确定需不需要执行这一步,我执行了。有的教程说用,有的没说。#chcon -t texrel_shlib_t mysql/lib/mysql/plugin/lib_mysqludf_sys.so

#备注:#下面是另一个教程的编译方法,未测试,不知道可以不可以,上面是我自己的编译方法,建议上面的方法(如果用上个编译方法,则不需要再执行下面的编译)#gcc -DMYSQL_DYNAMIC_PLUGIN -fPIC -Wall -I/usr/include/mysql -I. -shared lib_mysqludf_sys.c -o $(LIBDIR)/lib_mysqludf_sys.so

到这里就已经正常的编译出了.so文件了,可以查看/usr/lib64/mysql/plugin目录下是否有lib_mysqludf_sys.so文件。如果在编译的过程中出现问题,请自行google

2.4创建函数

在mysql中执行下面的命令

DROP FUNCTION IF EXISTS lib_mysqludf_sys_info;
DROP FUNCTION IF EXISTS sys_get;
DROP FUNCTION IF EXISTS sys_set;
DROP FUNCTION IF EXISTS sys_exec;
DROP FUNCTION IF EXISTS sys_eval;

CREATE FUNCTION lib_mysqludf_sys_info RETURNS string SONAME ‘lib_mysqludf_sys.so‘;
CREATE FUNCTION sys_get RETURNS string SONAME ‘lib_mysqludf_sys.so‘;
CREATE FUNCTION sys_set RETURNS int SONAME ‘lib_mysqludf_sys.so‘;
CREATE FUNCTION sys_exec RETURNS int SONAME ‘lib_mysqludf_sys.so‘;
CREATE FUNCTION sys_eval RETURNS string SONAME ‘lib_mysqludf_sys.so‘;
2.5测试
2.5.1验证step 1:

在mysql中执行命令

mysql> SELECT sys_exec (‘touch /var/lib/mysql/test.txt ‘);
+---------------------------------------------+
| sys_exec (‘touch /var/lib/mysql/test.txt ‘) |
+---------------------------------------------+
| 32512 |
+---------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT sys_eval(‘id‘);
+----------------+
| sys_eval(‘id‘) |
+----------------+
| NULL           |
+----------------+
1 row in set (0.40 sec)

mysql> SELECT sys_eval(‘cp /home/cassiano/Desktop/index.html /home/cassiano/‘);
+------------------------------------------------------------------+
| sys_eval(‘cp /home/cassiano/Desktop/index.html /home/cassiano/‘) |
+------------------------------------------------------------------+
|                                                                  |
+------------------------------------------------------------------+
1 row in set (0.02 sec)

从上面的执行结果看出,所有执行都失败了,这是由于apparmor引起(具体原因未知),在shell命令行执行下面的命令

#sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/
#sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysql
2.5.2验证step 2:
mysql> SELECT sys_eval(‘id‘);
+-------------------------------------------------+
| sys_eval(‘id‘)                                  |
+-------------------------------------------------+
| uid=116(mysql) gid=125(mysql) groups=125(mysql) |
+-------------------------------------------------+
1 row in set (0.09 sec)

mysql> SELECT sys_eval(‘pwd‘);
+-----------------+
| sys_eval(‘pwd‘) |
+-----------------+
| /var/lib/mysql  |
+-----------------+
1 row in set (0.01 sec)

BUT...
下面的操作失败了...     -_-
mysql> SELECT sys_eval(‘cp /home/cassiano/Desktop/index.html /home/cassiano/‘);
+------------------------------------------------------------------+
| sys_eval(‘cp /home/cassiano/Desktop/index.html /home/cassiano/‘) |
+------------------------------------------------------------------+
| NULL                                                             |
+------------------------------------------------------------------+
1 row in set (0.02 sec)

mysql> SELECT sys_exec(‘cp /home/cassiano/Desktop/index.html /home/cassiano/‘);
+------------------------------------------------------------------+
| sys_exec(‘cp /home/cassiano/Desktop/index.html /home/cassiano/‘) |
+------------------------------------------------------------------+
|                                                              256 |
+------------------------------------------------------------------+
1 row in set (0.00 sec)

原因未知,解决办法,在shell中执行下面的命令:

#sudo chown mysql:mysql /home/cassiano/teste/ -R
2.5.3验证step3:

写一个小脚本测试一下:

#cd /tmp
#vi test.sh
    #/bin/sh
    date > testlog.txt
    exit 0

#chmod +x ./test.sh

在mysql中测试:

#mysql
mysql> select sys_exec("/tmp/test.sh");
+--------------------------+
| sys_exec("/tmp/test.sh") |
+--------------------------+
|                        0 |
+--------------------------+
1 row in set (0.03 sec)

mysql> select sys_exec("/tmp/test.sh");
+--------------------------+
| sys_exec("/tmp/test.sh") |
+--------------------------+
|                        0 |
+--------------------------+
1 row in set (0.02 sec)

mysql> select sys_exec("/tmp/test.sh");
+--------------------------+
| sys_exec("/tmp/test.sh") |
+--------------------------+
|                        0 |
+--------------------------+
1 row in set (0.02 sec)

mysql> select sys_exec("/tmp/test.sh");
+--------------------------+
| sys_exec("/tmp/test.sh") |
+--------------------------+
|                        0 |
+--------------------------+
1 row in set (0.02 sec)

mysql> exit;

验证是否执行成功:

# cat test.txt
Tue May 15 17:48:05 CST 2014
Tue May 15 17:48:05 CST 2014
Tue May 15 17:48:06 CST 2014
Tue May 15 17:48:06 CST 2014
# pwd
/tmp

#测试完成。。。成功。。。

3.参考文章

MySQL使用udf调用系统程序
mysql通过函数执行本地命令和外部程序
MySQL UDF执行外部命令
mysql UDF 遇到问题解答
apparmor

最后说明:技术问题,baidu搜索的结果太少,建议google...

时间: 2024-08-14 23:15:15

MySql UDF 调用外部程序和系统命令的相关文章

MySQL 实现调用外部程序和系统命令

MySQL 实现调用外部程序和系统命令 Refer: http://www.cnblogs.com/yunsicai/p/4080864.html 1) Download lib_mysqludf_sys $ git clone https://github.com/mysqludf/lib_mysqludf_sys.git 2) get mysql plugin dir as LIBDIR: mysql > show variables like 'plugin_dir'; +--------

ECMall的MySQL数据调用的简单方法

很多ecmall开发者会问,怎么使用Ecmall的mysql类库进行数据调用.从原理上来讲Ecmall的数据调用是以数据模块+模块类库的方式进行mysql数据调用的,所有数据模块都存储在includesmodels 目录下,这些调用对于初学者来讲是比较复杂的,例如商品的数据调用函数,不能用在店铺的数据调用上,每个数据表都有自己的函数自己的类库和少量的公共类库.因此初学者来讲,调用mysql数据很困难. 现在讲解一个简单的调用方法能满足95%以上的mysql数据调用请求.足够对ecmall进行二次

oracle使用java source调用外部程序

oracle使用java source调用外部程序

Ecmall MySql 数据库调用教程

从原理上来讲Ecmall的数据调用是以数据模块+模块类库的方式进行mysql数据调用的,所有数据模块都存储在\includes\models 目录下,这些调用对于初学者来讲是比较复杂的,例如商品的数据调用函数,不能用在店铺的数据调用上,每个数据表都有自己的函数自己的类库和少量的公共类库.因此初学者来讲,调用mysql数据很困难. 我现在讲解一个简单的调用方法能满足95%以上的mysql数据调用请求.足够对ecmall进行二次开发. 例子存储在配资网站上. 例子: $db = &db(); 第一步

PowerShell中调用外部程序和进程操作命令例子

学习PowerShell,我们不指望通过C#编程去搞定所有事情,我们应该记住cmd.exe或者说批处理给我们留下的宝贵财富——通过调用外部程序去解决问题.调用了外部程序,势必就要对进程进行管理,这就是本文要介绍的. 1.Get-Process,返回进程. Get-Process [-id] ,按pid获取Get-Process -name ,按进程名Get-Process -inputObject ,传入参数 举例:get-process -name mmc,显示所有mmc的进程. 2.Star

WPF调用外部程序

想通过main()函数传递参数,先重载下面的OnStartup() public partial class App : Application { public static string args0; protected override void OnStartup(StartupEventArgs e) { if(e.Args != null && e.Args.Length > 0) args0 = e.Args[0].ToString(); base.OnStartup(

Windows API调用外部程序之图片查看

最近顺手接了一个小活,任务目标是将一组图像依次显示出来.环境就是XP中,代码嵌入到一个MFC工程里,图片是未经处理的可能是JPEG2000格式的j2c,也可能是bitmap.当然还可能没有任何的文件头,这个最后看实际情况再添加吧. 主要就是调用外部程序(j2c可以用网上的ivanview或kakadu,bmp就用Windows的图片查看工具),打开/关闭这两个功能.文件便利可以用CFileFind类,这里用的FindFirstFile和FindNextFile. 打开可以使用system(),还

C#使用Process类调用外部程序(转)

在程序开发中,一个程序经常需要去调用其他的程序,C#中Process类正好提供了这样的功能.它提供对本地和远程进程的访问并使您能够启动和停止本地系统进程. 一.启动进程实例 Process myProcess = new Process(); try { myProcess.StartInfo.UseShellExecute = false; myProcess.StartInfo.FileName = "test.exe"; myProcess.StartInfo.CreateNoW

start 调用外部程序

批处理中调用外部程序的命令(该外部程序在新窗口中运行,批处理程序继续往下执行,不理会外部程序的运行状况),如果直接运行外部程序则必须等外部程序完成后才继续执行剩下的指令 例:start explorer d:\调用图形界面打开D盘 start /w 则等待结束 命令格式是这样的: start "title" "path" "最大化最小化等其它参数" 如果你要运行的程序没有空格,不需要加引号的话就start abc 就行了.. 由于start命令后