存档

‘Linux’ 分类的存档

php-memcached扩展安装

2017年11月3日 没有评论

由于服务器上的php-memcached的序列化处理使用的是igbinary,而本地使用的是php默认的,在本地跑线上环境代码的时候就遇到问题了。具体是查看错误日志看到如下信息:


'ErrorException' with message 'Memcached::get(): could not unserialize value, no igbinary support'

查看memcached的igbinary support发现值是”no”,由于以前没自己动手搞过这块的东西。看了官方配置手册以后,以为只需要在配置文件中把”memcached.serializer”的配置设置为igbinary就可以了那。但是修改以后发现并没有作用。

接下来查看了一下扩展的编译参数,发现有个选项是”–enable-memcached-igbinary”,另外2个类似的参数分别是”–enable-memcached-json” 和”–enable-memcached-msgpack”.现在就找到了问题所在,需要重新重新编译memcached扩展以支持igbinary。

开始编译,编译参数如下:


./configure --enable-memcached --enable-memcached-igbinary --with-php-config=/usr/local/bin/php-config

但是很不幸,并没有如期待的那样编译成功,遇到如下错误:


"./php_memcached.h:23:10: fatal error: 'Zend/zend_smart_str.h' file not found
#include "Zend/zend_smart_str.h""

搜索了整个电脑硬盘,也没有找到这个头文件。打开php-memcached在github上的项目地址,发现它在readme里面说3.x版本是支持php7的,而php5.2-5.6需要使用2.x版本,所以就从github上的release历史里面下载了php-memcached2.2版本,当然从php官方地址也是可以下载到相应的版本的。我特地下载了php7.1.11的源码查看了一下,果然有缺失的头文件。

接下来安装上面的编译参数再次进行编译,就成功了。

分类: Linux, PHP 标签:

redis批量删除key

2017年10月23日 没有评论

最近生产环境的redis服务器由于key过期不及时,现在发现时key的个数已经暴增到5000多万了。然后运维同学那边就报警了,最大内存12G,已经用了9G多了,正好下面快要双11了,让我们快些解决。

redis服务器里面堆积大量的队列状态相关的key,其实这些key可以设置有效期,或者任务完成以后删除或者过期,但是由于我们使用类库的问题,这些key既没有删除也没有过期,堆积到redis里面去了,现在我们要做的就是删除这些无用key。在删除这些keys的过程中,走了不少弯路,这里说一下我最终采用的方案。

redis的del函数可以删除单个key,也可以删除多个key,del函数官方文档可以看这里。在google之后看到目前网络上很多文章的思路是使用keys匹配返回要删除的key,然后调用del函数去删除。这种方案在数据量较小时无可厚非,但如果像我这样面临的处理的数据有5千W时,keys的阻塞问题可能会给线上生产环境带来致命的问题。所以我们需要对这种方案作出一些修改。

可喜的是自从2.8.0以后redis提供scan来遍历key,而且这个过程是非阻塞,不会影响线上生产环境。最终经过修改的方案是用scan遍历要删除的key,然后调用del删除。

下面是我用python写的用来删除key的脚本。

import sys,redis

r = redis.Redis(host="127.0.0.1", port=6379,db=0)

if  len(sys.argv) <= 1:
    print("必须指明匹配key字符串")
    exit(1)
pattern = sys.argv[1]

cursor = 0
num = 1
while 1 :
    resut = r.scan(cursor, pattern, 10000)
    del_keys = []
    for i in resut[1]:
        key = i.decode()
        del_keys.append(key)
    #print("del keys len :%d" % len(result))
    if len(del_keys) == 0:
        break
    r.delete(*del_keys)
    cursor = resut[0]
    print("delete keys num : %dw" % (num))
    num +=1

print("done\n")

如何利用我这个脚本删除符合某个规则的key哪,如以king开头的key?

下面的命令即可完成上面的问题。


python3 main.py "king*"

期间我看到网上利用keys+del的lua脚本的方案,花了一段时间把scan+del改成lua脚本来删除。但是可惜的是目前redis并不支持这么做,由于scan返回的结果是不确定的,所以禁止在其后直接调用del操作。

参考资料:《How to atomically delete keys matching a pattern using Redis》

分类: Linux, Python 标签:

centos7防火墙firewalld

2017年10月19日 没有评论

centos7防火墙管理工具由我们以前熟知的iptables转变为了firewall。那么firewall是什么哪?firewall的服务是firewalld (防火墙守护)服务,引入了一个信任级别的概念来管理与之相关联的连接与接口。它支持 ipv4 与 ipv6,并支持网桥,采用 firewall-cmd (command) 或 firewall-config (gui) 来动态的管理 kernel netfilter 的临时或永久的接口规则,并实时生效而无需重启服务。

区域(zone)

Firewall 能将不同的网络连接归类到不同的信任级别.

区域 默认规则策略
trusted 允许所有的数据包。
home 拒绝流入的数据包,除非与输出流量数据包相关或是ssh,mdns,ipp-client,samba-client与dhcpv6-client服务则允许。
internal 等同于home区域
work 拒绝流入的数据包,除非与输出流量数据包相关或是ssh,ipp-client与dhcpv6-client服务则允许。
public 拒绝流入的数据包,除非与输出流量数据包相关或是ssh,dhcpv6-client服务则允许。
external 拒绝流入的数据包,除非与输出流量数据包相关或是ssh服务则允许。
dmz 拒绝流入的数据包,除非与输出流量数据包相关或是ssh服务则允许。
block 拒绝流入的数据包,除非与输出流量数据包相关。
drop 拒绝流入的数据包,除非与输出流量数据包相关。

过滤规则

source 根据源地址过滤
interface 根据网卡过滤
service 根据服务名过滤
port 根据端口过滤
icmp-block icmp 报文过滤,按照 icmp 类型配置
masquerade ip 地址伪装
forward-port 端口转发
rule 自定义规则

管理firewalld服务

# systemctl start firewalld         # 启动,
# systemctl enable firewalld        # 开机启动
# systemctl stop firewalld          # 关闭
# systemctl disable firewalld       # 取消开机启动

接下来我们会重点来看一下firewall-cmd命令,它是我们配置firewall的核心命令。

firewall-cmd

我们可以通过”firewall-cmd –help”来查看完整的命令帮助文档。

参数 作用
–get-default-zone 查询默认的区域名称。
–set-default-zone=<区域名称> 设置默认的区域,永久生效。
–get-zones 显示可用的区域。
–get-services 显示预先定义的服务。
–get-active-zones 显示当前正在使用的区域与网卡名称。
–add-source= 将来源于此IP或子网的流量导向指定的区域。
–remove-source= 不再将此IP或子网的流量导向某个指定区域。
–add-interface=<网卡名称> 将来自于该网卡的所有流量都导向某个指定区域。
–change-interface=<网卡名称> 将某个网卡与区域做关联。
–list-all 显示当前区域的网卡配置参数,资源,端口以及服务等信息。
–list-all-zones 显示所有区域的网卡配置参数,资源,端口以及服务等信息。
–add-service=<服务名> 设置默认区域允许该服务的流量。
–add-port=<端口号/协议> 允许默认区域允许该端口的流量。
–remove-service=<服务名> 设置默认区域不再允许该服务的流量。
–remove-port=<端口号/协议> 允许默认区域不再允许该端口的流量。
–reload 让“永久生效”的配置规则立即生效,覆盖当前的。

查看运行状态:

[root:~]# firewall-cmd –state
running

查看当前的区域:

[root:~]# firewall-cmd –get-default-zone
public

查看已被激活的区域信息:

[root:~]# firewall-cmd –get-active-zones
public
interfaces: eth0

查询eth0网卡的区域:

[root:~]# firewall-cmd –get-zone-of-interface=eth0
public

在public中分别查询ssh与http服务是否被允许:


[root:~]# firewall-cmd --zone=public --query-service=ssh
yes
[root:~]# firewall-cmd --zone=public --query-service=http
no

查看指定级别的接口:

[root:~]# firewall-cmd –zone=public –list-interfaces
ens33

查看指定级别的所有信息:


[root:~]# firewall-cmd --zone=public --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33
sources:
services: dhcpv6-client ssh
ports:
protocols:
masquerade: no
forward-ports:
sourceports:
icmp-blocks:
rich rules:

查看所有级别被允许的信息:

[root:~]# firewall-cmd –get-service

RH-Satellite-6 amanda-client … xmpp-server

管理规则:


# firewall-cmd --panic-on # 丢弃
# firewall-cmd --panic-off # 取消丢弃
# firewall-cmd --query-panic # 查看丢弃状态
# firewall-cmd --reload # 更新规则,不重启服务
# firewall-cmd --complete-reload # 更新规则,重启服务

添加某接口至某信任等级,譬如添加 eth0 至 public,永久修改:

# firewall-cmd –zone=public –add-interface=eth0 –permanent

设置默认的信任级别:

[root:~]# firewall-cmd –set-default-zone=public
success

允许https服务流量通过public区域,要求立即生效且永久有效:

[root:~]# firewall-cmd –zone=public –add-service=https –permanent
success

不再允许http服务流量通过public区域,要求立即生效且永久生效:

[root:~]# firewall-cmd –zone=public –remove-service=http –permanent
success

允许 tcp 端口 8080 至 dmz 级别:

[root:~]# firewall-cmd –zone=dmz –add-port=8080/tcp
success

列出 dmz 级别的被允许的进入端口:

[root:~]# firewall-cmd –zone=dmz –list-ports

8080/tcp

允许某范围的 udp 端口至 public 级别,并永久生效:

[root:~]# firewall-cmd –zone=public –add-port=5000-6000/udp –permanent
success

改变ens33接口的区域

[root:~]# firewall-cmd –zone=work –change-interface=ens33 –permanent
success

删除 public zone 中的 eth0:

[root:~]# firewall-cmd –zone=public –remove-interface=eth0 –permanent
success

打开ip伪装:

[root:~]# firewall-cmd –zone=external –add-masquerade
success

关闭ip伪装:

[root:~]# firewall-cmd –zone=external –remove-masquerade

打开端口转发:

[root:~]# firewall-cmd –zone=public –add-masquerade

转发 tcp 22 端口至 3753

[root:~]#firewall-cmd –zone=public –add-forward-port=port=22:proto=tcp:toport=3753

转发22 端口数据至另一个 ip 的相同端口上:

[root:~]#firewall-cmd –zone=public –add-forward-port=port=22:proto=tcp:toaddr=192.168.1.100

转发 22 端口数据至另一 ip 的 2055 端口上:

[root:~]#firewall-cmd –zone=public –add-forward-port=port=22:proto=tcp:toport=2055:toaddr=192.168.1.100

封禁 ip:


[root:~]#firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='222.222.222.222' reject"

通过 ipset 来封禁 ip:


[root:~]#firewall-cmd --permanent --zone=public --new-ipset=blacklist --type=hash:ip

[root:~]#firewall-cmd --permanent --zone=public --ipset=blacklist --add-entry=222.222.222.222

参考文章:

《CentOS 7 下使用 Firewall》

《CentOS7-firewall防火墙使用》

分类: Linux 标签: ,

log4cpp简明教程

2017年10月13日 没有评论

log4cpp是一款c++开源的日志库,我也是刚刚使用,所以对它的了解不是很多。这是第一次在项目中使用log4cpp,当然我在c++方面的项目经验也是屈指可数。这篇文章会是一个简明的教程,方便类似我这样的新手可以快速入门,不会有太高深的内容。log4cpp相关的背景和特点这里也不再多说,感兴趣的可自行查找资料。

基本步骤

1、实例化1个appender对象

2、实例化1个layout对象,并将layout绑定到appender

3、获得Category并设置优先级和添加apprender

4、调用Category写日志

参考代码

这是1个根据日期划分日志文件的简单样例。main.cpp代码

#include <iostream>
#include <log4cpp/Category.hh>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/DailyRollingFileAppender.hh>

using namespace std;
using namespace log4cpp;

int main() {
     DailyRollingFileAppender *appender = new DailyRollingFileAppender(
         string("default"),
         string("/Users/king/c_project/logger/build/log/data.log")
     );
     string patter = "%d[%p] %m%n";
     PatternLayout *layout = new PatternLayout();
     layout->setConversionPattern(patter);
     appender->setLayout(layout);
     Category& root = Category::getRoot();
     root.addAppender(appender);
     root.info("This is test.");
     root.error("sql error.");

     cout << "done!" << endl;
     return 0;
}

这里保存目录如果要指定日志保存目录,请使用绝对路径。

编译链接


c++ main.cpp -o logger -llog4cpp

./logger

分类: C/C++, Linux 标签:

php-fpm配置unixsock引发问题

2017年10月11日 没有评论

今天把博客从原来的阿里云迁移出来了,在新环境搭建环境时,nginx和php-fpm都已经配好的时候(其实还是有问题的),访问首页提示403错误。nginx和fpm的用户都配置为www-data,按道理说同一用户不应该没有访问文件的权限。以前nginx和fpm一直都是使用socket通信的方式,第一次使用unixsock方式配置,有点不知所措。

查看nginx的错误日志,发现最新的错误日志信息是类似这样的:

connect() to unix:/var/run/php-fpm.sock failed (13: Permission denied) while connecting to upstream

也就说出问题的地方是/var/run/php-fpm.sock文件,不是站点目录下文件的权限。在google上面搜索了一下,在stackoverflow上面发现一篇“nginx error connect to php5-fpm.sock failed (13: Permission denied)”,也是unixsock方式配置nginx和php-fpm的问题。问题里面给说的方案是需要设置一下unixsock中listen.user、listen.group、listen.mode这几个参数,按照默认的值将其前面的注释去掉即可,类似如下。


listen.owner = www-data
listen.group = www-data
listen.mode = 0660

然后重启php-fpm,重新访问页面,一切正常了。

分类: Linux, PHP 标签:

git reflog恢复git reset删除数据

2017年5月11日 没有评论

我经常用git reset来恢复自己的工作区,但是偶尔也会失误把错误的分支的commit记录给删除掉了。今天工作中也有遇到一次,本来要删除测试分支的commit记录,但是在操作时没有注意所在的分支,就把工作分支的内容误删除掉了。那么我们如何恢复这些commit记录哪?

当你 (在一个仓库下) 工作时,Git 会在你每次修改了 HEAD 时悄悄地将改动记录下来。当你提交或修改分支时,reflog 就会更新。因此我们就可以用reflog的记录来恢复我们的工作区。

查看reflog记录


git reflog

你会看到如下的内容:

229e8d31 HEAD@{1}: pull origin xx: Fast-forward
fd54ce35 HEAD@{2}: checkout: moving from xxx to xxxx
66010f88 HEAD@{3}: merge xxxxx8: Merge made by the 'recursive' strategy.
085b2dba HEAD@{4}: reset: moving to HEAD~1
0f0bfb7d HEAD@{5}: checkout: moving from xxxx to xxxxx
73e400ba HEAD@{6}: commit: xxxxxx
5e9d0305 HEAD@{7}: reset: moving to HEAD~1
2ef40139 HEAD@{8}: reset: moving to 2ef40139
5e9d0305 HEAD@{9}: reset: moving to HEAD~1
2ef40139 HEAD@{10}: checkout: moving from sit to xxx
0f0bfb7d HEAD@{11}: merge xxx: Merge made by the 'recursive' strategy.

恢复工作区
我们可以根据commit的SHA来用git reset恢复。

git reset --hard fd54ce35

这时我们被我们误操作的记录就已经被恢复了,可以用git log来查看git提交记录。

分类: git, Linux 标签:

centos7安装redis3.2

2016年9月27日 没有评论

最近在学习laravel框架,打算在虚拟机里面装个redis,使用yum安装时发现提供的版本是2.8。目前最新的版本是3.2,而3.0以后redis提供了cluster,对集群有很好的支持。在google了一番以后也没有找到redis3.2的源,于是就开始编译安装了。

redis官网下载最新版本的redis源码,然后开始编译安装,可以参考源码里面的README。


wget http://download.redis.io/releases/redis-3.2.4.tar.gz

tar -xvf redis-3.2.4.tar.gz

cd redis-3.2.4

cat README.md

make

make install

mkdir /etc/redis

cp utils/redis.conf /etc/redis/

redis-server /etc/redis/redis.conf

这时候用安装基本完成了,但是上面安装基本上按照默认的方式安装,但是有些地方可以自定义。比如redis安装位置,可以使用`make PREFIX=/some/other/directory install`,其中的“/some/other/directory”就是redis安装位置。

为了方面我们管理redis,我们可以写一个redis.service配置文件来方便我们管理redis。

这里我就给一个很简单的service配置文件例子:


[Unit]
Description=redis service file
Wants=network.target

[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf
[Install]
WantedBy=multi-user.target

将上面的配置信息放入/lib/systemd/system/redis.service文件中,然后重新载入配置文件即可。还有一点就是需要修改/etc/redis/redis.conf中,将damonize改为yes,默认为no,即以守护进程的模式启动redis。


systemctl daemon-reload

#开机启动

systemctl enable redis.service

#启动redis

systemctl start redis.service

#关闭redis

systemctl stop redis.service

到此,redis的安装就完成了,可以使用redis-cli链接server了!

分类: Linux 标签:

mysql禁用validate-password插件

2016年8月17日 没有评论

近些版本的mysql做了很大的改动,在5.6.6以后的版本会开启validate-password插件。validate-password插件会对密码进行评估,如果不达标会提示你去进行修改.在生产环境这是非常不错的插件,弱口令就会消失,但是在开发环境就有些烦人了,谁都不想在每次等级都要输入一大串复杂的密码。所以我们可以选择降低validate-password对密码安全性的策略,或者直接就禁用它。

1 禁用validate-password

编辑my.cnf配置文件,在mysqld下面加入“validate-password=OFF”,然后重启mysql即可。

2 降低安全策略级别

首相我们来看一下validate-password相关的参数:

validate-password=ON/OFF/FORCE/FORCE_PLUS_PERMANENT: 决定是否使用该插件(及强制/永久强制使用)。

validate_password_dictionary_file:插件用于验证密码强度的字典文件路径。

validate_password_length:密码最小长度。

validate_password_mixed_case_count:密码至少要包含的小写字母个数和大写字母个数。

validate_password_number_count:密码至少要包含的数字个数。

validate_password_policy:密码强度检查等级,0/LOW、1/MEDIUM、2/STRONG。

validate_password_special_char_count:密码至少要包含的特殊字符数。

其中,关于validate_password_policy-密码强度检查等级:

0/LOW:只检查长度。

1/MEDIUM:检查长度、数字、大小写、特殊字符。

2/STRONG:检查长度、数字、大小写、特殊字符字典文件。

我们可以将安全策略降低为LOW,相信这样虽然还会有长度限制,但是已经足够简单了。

编辑my.cnf文件,在mysqld下面加入:


[mysqld]

validate_password_policy=LOW

然后重启mysql即可!

mysql重置root密码

2016年4月14日 没有评论

今天在mac上面安装mysql,安装之后用root登录,发现进不去,说需要密码,使用DMG包安装时提示我生成的随机密码也尝试了,依旧不行!不过生成root密码页面提示如果无法登录可以尝试查看How to Reset the Root Password,进行重置root密码工作。如果你觉得自己英文还行可以直接参考前面那个连接去查看,好了,下面进入正题重置密码。

我是在mac下面做的重置root操作,不过windows下面的很类似,本文的必要条件是你有管理mysql服务器账号或者在本机上面,如果上面2个都不满足,那么这篇文章就不适合你了。

第一步关闭正在运行mysql服务器。

官网手册的命令是这样的,不过你可以像我这样通过ps查看mysql的进程id,然后kill它,当然这里最好把ps中启动mysql的命令先记录下来,后面会使用的。

kill `cat /mysql-data-directory/host_name.pid`
#ps方法
ps aux|grep 'mysql'
#这里把%pid%替换为上面ps给的进程id
sudo kill %pid%

第二步建立mysql init文件
这一步是要建立一个mysql init文件,配合mysqld的–init-file参数来使用的.init-file参数英文说明是”Read SQL commands from this file at startup”,我的个人理解是读取指定文件中的sql语句,并在mysql启动的时候执行它们。
mysql版本5.7.6和以后使用”ALTER USER ‘root’@’localhost’ IDENTIFIED BY ‘MyNewPass’;”,如果你的版本是其他版本可以使用”SET PASSWORD FOR ‘root’@’localhost’ = PASSWORD(‘MyNewPass’);”尝试一下。

#5.7.6和以后版本
ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass';
#5.7.6以前版本
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('MyNewPass');

保存文件。
第三步重启mysql
这时候我们来重启我们的mysql,不过是加上–init-file参数的命令。还记得我上面让你记住的ps下面的mysql启动命令吧,就是这里用的。官方手册是”mysqld_safe –init-file=/home/me/mysql-init &”,也许在其他类*unix系统上面可以,但是我在mac下面尝试了,启动不起来!如果你是centos或者ubuntu用户可以尝试一下官方手册的命令,不过mac下面还是建议使用ps中显示的命令,再后面追加–init-file参数。


#官网手册命令,mac用户不推荐

mysqld_safe --init-file=/home/me/mysql-init &

#mac用户推荐命令

sudo /usr/local/mysql/bin/mysqld --user=_mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --plugin-dir=/usr/local/mysql/lib/plugin --log-error=/usr/local/mysql/data/mysqld.local.err --pid-file=/usr/local/mysql/data/mysqld.local.pid --init-file=/Users/king/sql/alter_root.sql &

“/Users/king/sql/alter_root.sql”为你第二步是保存的sql文件.此时再使用root用户用你重置的命令登录就可以成功登录了!

windows下面的重置root密码功能应该和mac下面类似,只要把shell命令换成dos命令即可,具体的可以参考上面的官网手册地址。

==2016-9-26号补更============================================================================

前几天在虚拟机里面装了mysql5.7.15,装完以后用root空密码登录失败.于是就用上面的方法重置密码,发现它并没有mysqld_safe文件,于是上面的方法就不是很适用了,就把重新查找了些资料,花了好久才解决!

我在stackoverflow上面找到了一种解决办法:

1. 停止mysql服务:
systemctl stop mysqld

2. 设置mysql的环境变量参数 
systemctl set-environment MYSQLD_OPTS="--skip-grant-tables"

3. 启动mysql服务
systemctl start mysqld

4. root无密码登录
mysql -u root

5. 更新root密码
mysql> UPDATE mysql.user SET authentication_string = PASSWORD('MyNewPassword')
    -> WHERE User = 'root' AND Host = 'localhost';
mysql> FLUSH PRIVILEGES;
mysql> quit

6. 关闭mysql服务
systemctl stop mysqld

7. 删除mysql环境参数
systemctl unset-environment MYSQLD_OPTS

8. 再次启动:
systemctl start mysqld

9. 用root登录:
. mysql -u root -p
当然可以把

skip-grant-tables写到”my.cnf”中重启mysql也可达到同样的目的!

centos安装EPEL源

2016年4月7日 没有评论

在虚拟机里面使用我的one_shell_install_lnmp脚本安装lnmp环境的时候,发现报错了,提示缺少libmcrypt-devel包。以前我是在centos7下面测试过我的脚本的,是可以通过的,于是我就又检查了一下脚本,里面有安装libmcrypt-devel 这个选项。我又试着单独执行了一下安装libmcrypt-devel包的命令,依然是没有任何反应。刚开始我第一时间没有想到源的问题,类似以往的习惯去google,发现也有同学和我类似,说163源上面没有libmcrypt-devel这个包,于是就有了今天这个文章。当然这篇文章是笔记性质的,如果对你有帮助,十分荣幸,有问题也可以留言。

EPEL是什么

EPEL全名是Extra Packages for Enterprise Linux(epel wiki:https://fedoraproject.org/wiki/EPEL),是一个由特别兴趣小组创建、维护并管理的,针对 红帽企业版 Linux(RHEL)及其衍生发行版(比如 CentOS、Scientific Linux、Oracle Enterprise Linux)的一个高质量附加软件包项目。

其实我也是今天才了解的EPEL,以前虽然使用过它,但是对它没有什么系统了解,上面介绍它的内容也是摘自wiki。

EPEL安装

我写了一个install_epel.sh的shell脚本, 功能就是检测当前系统是否有epel源,如果不存在就安装。


#!/bin/bash

#检查epel源是否安装
yum repolist|egrep "epel" >& /dev/null
if [ $? -ne 0 ];then
epel_file="epel.noarch.rpm"
wget http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm -O $epel_file
rpm -ivh $epel_file
rm -f $epel_file
yum makecache
fi

关于yum或者epel其他介绍,请自行google!

分类: Linux 标签: ,