日志

Ubuntu下通过Crontab设置计划任务

  • 简介

cron 是一个在指定时间执行指定任务的系统守护进程.

crontab是一个简单的文本文件,它包含一行行的指令,以及指定每行指令何时执行的时间参数.它通过特定的方式进行编辑,crontab中的每一行命令会在设定的时间由cron在后台执行.每个用户均有其独立的crontab文件,不管用户是否已经登录系统,crontab中的命令都会在规定的时间被执行.如果你的任务需要用到管理员权限(administrative privileges),你可以通过root的crontab创建你的计划任务.

  • 创建计划任务

为当前用户创建一个计划任务

crontab -e

如果你希望任务以管理员权限运行,将其加入到root的crontab下即可

sudo crontab -e

首次创建会要求你先选择默认的文本编辑器,自行决定. 如需更换编辑器可执行以下指令

select-editor

crontab文件类似这样,你可以根据指定的格式编辑添加你的crontab计划任务

# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
*/10 * * * * cd /var/www/test && python task.py >> ~/test.log

其中 */10 * * * * cd /var/www/test && python task.py >> ~/test.log 就是一个计划任务的全部配置

一条crontab的配置分为六段,其中前五段属于时间段,用于指定执行的时间,第六段属于命令段,用于指定要执行的命令.除了命令段以外,其他各段不能包含空格,段与段之间允许空格.

每段的意思如下:

分钟 (0-59), 小时 (0-23, 0 = 凌晨), 日 (1-31), 月 (1-12), 星期 (0-6, 0 = 星期日), 命令

多个时间值用逗号隔开,区间用横杠表示(例如 1-5),时间步长控制以斜杠标识,例如上面 */10 的写法是指每隔10分钟的意思,其等价于 0,10,20,30,40,50  (* 和 */1 等价).上面的crontab的意思是指每隔10分钟执行一次命令

“cd /var/www/test && python task.py >> ~/test.log”

终极例子

阅读全文

日志

MAMP PRO 安装PHP扩展 以Memcache为例

1.编译memcache模块需要php的源码,根据php版本去官网下载php的源码,我的是php5.3.29

2.生成zend_config.h备用

cd php5.3.29

./configure

3.安装autoconf,已安装可以无视

curl -O http://ftp.gnu.org/gnu/autoconf/autoconf-2.68.tar.bz2;

tar -xvf autoconf-2.68.tar.bz2

cd autoconf-2.68

./configure && make

sudo make install

4.下载编译安装

curl -O http://pecl.php.net/get/memcache-2.2.4.tgz;

tar xf memcache-2.2.4.tgz;

cd memcache-2.2.4;

mkdir /Applications/MAMP/bin/php/php5.3.29/include/

# /Volumes/SOFT/php-5.3.29 是 php 的目录,根据实际自己改
ln -s /Volumes/SOFT/php-5.3.29 /Applications/MAMP/bin/php/php5.3.29/include/php

#建议 pwd 一下看看当前目录是不是memcache-2.2.4下,下面两行命令都必须要在这个目录下执行
/Applications/MAMP/bin/php/php5.3.29/bin/phpize;

./configure --with-php-config=/Applications/MAMP/bin/php/php5.3.29/bin/php-config

make

sudo make install

5.修改php.ini的配置

(!!!!不是到MAMP/bin/php/php.3.29/conf/php.ini下修改,这样是不会生效的,曾经被坑过!)
点 mamp 菜单,file->edit template -> php -> php 5.3.29 php.ini ,增加:

extension = memcache.so

MAMP会提示重启服务,yes就好了

安装结束

在页面输出一下PHPinfo(),command+f 搜索Memcache是否已经enable即可.

转载请注明出处:

© http://hejunhao.me

日志

PHP 基于 MySQL数据 导出 EXCEL文件

操作Excel可以使用第三方开源库,例如强大的:PHPEXCEL.

这里主要采用的是非第三方类库依赖,而是基于PHP5原生支持的fputcsv实现,基本可以满足日常需求.

<?php
// 输出Excel文件头 
header('Content-Type: application/vnd.ms-excel;charset=gbk');
header('Content-Disposition: attachment;filename="文件名.csv"');
header('Cache-Control: max-age=0');

// 从数据库中获取数据 
$sql = 'select * from `table` where ……';
$stmt = @mysql->query($sql);

// PHP文件句柄,php://output 表示直接输出到浏览器 
$fp = fopen('php://output', 'a');

// 输出Excel列头信息 
$head = array('姓名', '性别', '年龄', 'Email', '电话', '……');
foreach ($head as $i => $v) {
    // CSV的Excel支持GBK编码,一定要转换,否则乱码 
    $head[$i] = iconv('utf-8', 'gbk', $v);
}

// 写入列头 
fputcsv($fp, $head);

// 计数器 
$cnt = 0;
// 每隔$limit行,刷新一下输出buffer,节约资源 
$limit = 100000;

// 逐行取出数据,节约内存 
while ($row = $stmt->fetch(FETCH_NUM)) {

    $cnt ++;
    if ($limit == $cnt) { //刷新一下输出buffer,防止由于数据过多造成问题 
        ob_flush();
        flush();
        $cnt = 0;
    }

    foreach ($row as $i => $v) {
        $row[$i] = iconv('utf-8', 'gbk', $v);
    }
    fputcsv($fp, $row);
}
日志

MySQL修改用户密码和重命名用户名

  • 修改用户密码

mysql修改用户密码通过 SET PASSWORD 语句实现

# 修改当前用户的密码

SET PASSWORD = PASSWORD('密码文本') | OLD_PASSWORD('密码文本') | '密码哈希'

注意:OLD_PASSWORD方法使用 mysql 4.1版本以前 的方式对密码进行哈希加密处理,高版本mysql可以通过此方式兼容旧版的用户密码

# 修改用户 alice 的密码为 123456(必须具备 `mysql` 数据库的 UPDATE 权限),host不指定时默认为 '%'

SET PASSWORD FOR 'alice'@'localhost' =  PASSWORD('123456');
  • 重命名用户

mysql修改用户名通过 RENAME USER 语句实现

# 将 alice 用户名修改为 bob,host不指定时默认为 '%'

# 必须要具备`mysql` 数据库的 UPDATE 权限或 CREATE USER 权限,当系统变量 read_only 为 enabled 时还需具备SUPER权限

RENAME USER 'alice'@'localhost' TO 'bob'@'localhost';
转载请注明出处:

© http://hejunhao.me

日志

MySQL添加用户、授权和访问控制

  • 有哪些方式?

你可以通过两种方式创建MySQL用户:

  1. 通过账户管理语句,例如GRANT、CREATE USER等.
  2. 直接用INSERT、UPDATE、DELETE等语句操作MySQL的授权表(mysql.user、mysql.host、mysql.db、mysql.tables_priv、mysql.columns_priv)

显然方式1比方式2更简洁和有助于减少错误

另外你也可以通过GUI工具(如:MySQL WorkBench)或第三方程序(如:phpmyadmin)

  • 通过账户管理语句实现

a) 通过root用户(或具备CREATE USER 权限的用户)连接mysql

mysql -u root -p 你的用户密码

b) CREATE USER 语句用法

# 创建一个名为 alice 密码为 alicepass 的用户,该用户只能从 localhost 连接

CREATE USER 'alice'@'localhost' IDENTIFIED BY 'alicepass';
# 创建一个名为 bob 密码为 bobpass 的用户,允许该用户从任意host连接

CREATE USER 'bob'@'%' IDENTIFIED BY 'bobpass';
# 创建一个名为 chris 密码为 chrispass 的用户,该用户允许从任何 example.com 域名下的host来连接

CREATE USER 'chris'@'%.example.com' IDENTIFIED BY 'chrispass';

c) GRANT 语句用法

# 给 alice 用户分配所有权限,必须要从 localhost 连接

GRANT ALL PRIVILEGES ON *.* TO 'alice'@'localhost' WITH GRANT OPTION;
# 给  bob 用户分配所有数据库的 RELOAD、PROCESS 权限,并且可以把这些权限授权给其他用户(WITH GRANT OPTION的作用)

GRANT RELOAD,PROCESS ON *.* TO 'bob'@'%' WITH GRANT OPTION;
# 给 chris 用户分配 customer 数据库的 SELECT,INSERT,UPDATE,DELETE,CREATE,DROP 权限,必须从任何 example.com 域名下的host来连接

GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON customer.* TO 'chris'@'%.example.com';

d) REVOKE 语句用法

# 撤销 david 用户所有数据库的所有权限

REVOKE ALL PRIVILEGES ON *.* FROM 'david'@'%';

e) DROP USER 语句用法

# 删除 alice 用户,不再允许该用户从localhost连接,不指定host时默认为 '%' ,DROP USER不会自动关闭任何已经打开的用户SESSION,一旦SESSION被关闭则该用户即被移除

DROP USER 'alice'@'localhost';
转载请注明出处:

© http://hejunhao.me

日志

Nginx与Apache的区别

可以举一个简单的例子来说明Apache的工作流程,我们平时去餐厅吃饭.餐厅的工作模式是一个服务员全程服务客户,流程是这样,服务员在门口等候客人(listen),客人到了就接待安排的餐桌上(accept),等着客户点菜(request uri),去厨房叫师傅下单做菜(磁盘I/O),等待厨房做好(read),然后给客人上菜(send),整个下来服务员(进程)很多地方是阻塞的.这样客人一多(HTTP请求一多),餐厅只能通过叫更多的服务员来服务(fork进程),但是由于餐厅资源是有限的(CPU),一旦服务员太多管理成本很高(CPU上下文切换),这样就进入一个瓶颈.

再来看看Nginx得怎么处理?餐厅门口挂个门铃(注册epoll模型的listen),一旦有客人(HTTP请求)到达,派一个服务员去接待(accept),之后服务员就去忙其他事情了(比如再去接待客人),等这位客人点好餐就叫服务员(数据到了read()),服务员过来拿走菜单到厨房(磁盘I/O),服务员又做其他事情去了,等厨房做好了菜也喊服务员(磁盘I/O结束),服务员再给客人上菜(send()),厨房做好一个菜就给客人上一个,中间服务员可以去干其他事情.整个过程被切分成很多个阶段,每个阶段都有相应的服务模块.我们想想,这样一旦客人多了,餐厅也能招待更多的人.

日志

PHP中使用cURL请求

cURL是一个非常强大的工具,它支持多种多样的协议(HTTP,FTP,TELNET等等)进行数据传输.因而cURL不受限于它能干什么,不管是基本的HTTP请求还是复杂的FTP上传或者是与需要验证处理的HTTPS网站进行交互,cURL都可以胜任。PHP通过cURL函数库对cURL提供了支持,下面主要介绍PHP cURL中使用最频繁的GET、POST方法和返回数据的处理,以及一些有用的cURL设置项。

  • 基本

在我们通过cURL请求进行各样操作之前,首先我们需要初始化一个cURL的实例对象,我们可以通过调用curl_init()这个方法来完成,它返回一个cURL的句柄。该方法提供一个可选参数,可以通过该参数设置要发送请求的URL地址,在此我们先不传参,下面会用另一种方式进行设置。

  • 设置

当我们拿到cURL的句柄后,我们就可以对其进行一系列的参数设定,下面是一些主要的设置项:

CURLOPT_RETURNTRANSFER

true:将返回的数据以文件流的形式返回;false:将返回的数据直接输出显示;

CURLOPT_CONNECTTIMEOUT

发起连接时等待的时间(秒);

CURLOPT_TIMEOUT

请求超时时间(秒);

CURLOPT_USERAGENT

设置请求的用户代理;

CURLOPT_URL

设置请求的URL地址

CURLOPT_POST

是否以POST方式发起请求

CURLOPT_POSTFIELDS

POST参数值

我们可以通过调用curl_setopt()方法设定指定的cURL参数值,该方法接收三个参数,分别是cURL句柄设置项(例如CURLOPT_URL)和设置值

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://hejunhao.me');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);

当我们需要设置大量参数时,显然重复使用大量curl_setopt并不方便,我们可以通过curl_setopt_array(),一次性设置大量参数。

<?php
$ch = curl_init();
$options = array(
    CURLOPT_URL => 'http://hejunhao.me',
    CURLOPT_HEADER => 0,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_NOPROGRESS => False,
    CURLOPT_TIMEOUT => 5
);
curl_setopt_array($ch, $options);
  • 发送请求

当我们设置好所有参数,准备发起请求时,我们通过调用curl_exec()方法来执行我们的请求,该方法接收一个cURL句柄参数。请求执行后会有三种可能的返回情况:
阅读全文

Git中的fetch和pull

Git中从远程的分支获取最新的版本到本地有这样2个命令:git fetch、git pull

1. git fetch:相当于是从远程获取最新版本到本地,不会自动merge

git fetch origin master
git log -p master..origin/master
git merge origin/master

以上命令的含义:
首先从远程的origin的master主分支下载最新的版本到origin/master分支上
然后比较本地的master分支和origin/master分支的差别
最后进行合并

上述过程其实可以用以下更清晰的方式来进行:

git fetch origin master:tmp
git diff tmp
git merge tmp

从远程获取最新的版本到本地的test分支上
之后再进行比较合并

2. git pull:相当于是从远程获取最新版本并merge到本地

git pull origin master

上述命令其实相当于git fetch 和 git merge
在实际使用中,git fetch更安全一些
因为在merge前,我们可以查看更新情况,然后再决定是否合并

日志

Memcache 和 Memcached 的区别

很多人都无法分辨这两者的区别,甚至有人会认为Memcached是服务器的daemon进程
从手册中可以看到这两个扩展:memcache | memcached

显然,Memcached 比 Memcache 多了更多的实现,关于两者的区别可以简单理解如下:
1.Memcached 是基于 libmemcached 库的比 Memcache 实现了更多的协议(eg. Multigets and multisets allow you to get/set multiple items at the same time.)
2.Memcached 相比 Memcache 作了更多的优化
3.Memcached 支持 Binary Protocol,因此有更高的性能体现

日志

PHP类的访问控制

PHP的类属性、方法的可见性通过三个关键词来定义,即public、protected和private

  • 关键词

  1. public

    类成员(方法、属性)可以随处访问;
    以var声明的类属性会被定义为public性质;
    为了兼容PHP4,如果没有指定访问控制,属性和方法默认为公有的;

  2. protected

    类成员可以被自身、继承类和父类访问。(注意:类实例对象不可访问)

  3. private

    类成员只允许自身访问

  • 例子

PHP version: PHP5.5

<?php
class obj{
    public $obj_pub = 'obj_pub';
    protected $obj_protected = 'obj_protected';
    private $obj_private = 'obj_private';

    public function print_data(){
        echo $this->obj_private;
	echo $this->obj_protected;
	echo $this->obj_private;
    }

    protected function method_protected(){}

    private function method_private(){}
}

$o = new obj();
echo $o->obj_pub;//公有属性调用
echo $o->obj_protected; //报错,实例对象不可访问受保护的类属性
echo $o->obj_private; //报错,实例对象不可访问私有属性
echo $o->print_data();//调用公有方法

class animal extends obj{
    
    public function print_1(){
	echo $this->obj_pub;//调用父类公有属性
	echo $this->obj_protected;//调用父类受保护的属性
    }

    public function print_2(){
	echo $this->obj_privatje;//报错,父类私有属性禁止子类访问
    }

    public function foo(){
	$this->print_data();//调用父类公有方法
	$this->method_protected();//调用父类受保护的方法
	$this->method_private();//报错,父类私有方法禁止子类访问
    }
}

$a = new animal();
$a->print_1();
$a->print_2();
$a->foo();
转载请注明出处:

© http://hejunhao.me

第 1 页,共 2 页12