linux提供了一个daemon函数,使得进程可以脱离控制台运行,实现了后台运行的效果。但是进程后台运行后,原本在终端控制台输出的数据就看不到了。那么,怎样才能找回这些数据?

这里,文章主题就围绕着 如何获得后台进程的控制台数据,其中的原理要从daemon说起。

daemon主要做两件事:
1、创建子进程,退出当前进程,并且以子进程创建新会话。这样,就算父进程退出,子进程也不会被关闭
2、将标准输入,标准输出,标准错误都重定向/dev/null

daemon 实现大致如下:

int daemonize(int nochdir, int noclose)
{
  int fd;

  switch (fork()) {
  case -1:
    return (-1);
  case 0:
    break;
  default:
    _exit(EXIT_SUCCESS);
  }

  if (setsid() == -1)
    return (-1);

  if (nochdir == 0) {
    if(chdir("/") != 0) {
      perror("chdir");
      return (-1);
    }
  }

  if (noclose == 0 && (fd = open("/dev/null", O_RDWR, 0)) != -1) {
    if(dup2(fd, STDIN_FILENO) < 0) {
      perror("dup2 stdin");
      return (-1);
    }
    if(dup2(fd, STDOUT_FILENO) < 0) {
      perror("dup2 stdout");
      return (-1);
    }
    if(dup2(fd, STDERR_FILENO) < 0) {
      perror("dup2 stderr");
      return (-1);
    }

    if (fd > STDERR_FILENO) {
      if(close(fd) < 0) {
        perror("close");
        return (-1);
      }
    }
  }
  return (0);
}
所以,想取回进程的控制台数据,只要将标准输出,标准错误重定向到指定文件,然后读取这个文件就好了。

文章这里写了个例子,简单演示下(这里通过kill信号完成进程通信,有点粗暴)
代码如下,保存为 daemon_example.c
#include
#include
#include
#include

static int fd = -1;

void sigroutine(int dunno) {
  switch (dunno) {
  case SIGUSR1:
    fprintf(stderr, "Get a signal -- SIGUSR1 \n");
    if (fd != -1) close(fd);
    fd = open("/tmp/console_temp.log", O_RDWR|O_APPEND|O_CREAT, 0600);
    if (fd == -1) break;
    dup2(fd, STDIN_FILENO);
    dup2(fd, STDOUT_FILENO);
    dup2(fd, STDERR_FILENO);
    break;
    
  case SIGUSR2:
    fprintf(stderr, "Get a signal -- SIGUSR2 \n");
    if (fd != -1) close(fd);
    fd = open("/dev/null", O_RDWR, 0);
    if (fd == -1) break;
    dup2(fd, STDIN_FILENO);
    dup2(fd, STDOUT_FILENO);
    dup2(fd, STDERR_FILENO);
    break;
  }
  return;

}

int main() {
  signal(SIGUSR1, sigroutine);
  signal(SIGUSR2, sigroutine);

  daemon(1,0);
  for (;;){
      fprintf(stderr,"test \n") ; // 不断打印test
      sleep(1);
  }
  return 0;
}
然后,编译和执行这个程序:
$ gcc -o daemon_example daemon_example.c
$ chmod +x daemon_example
$ ./daemon_example
$ ps -ef| grep daemon_example
root 11328 1 0 19:15 ? 00:00:00 ./daemon_example
如上,进程后台运行了,拿到pid 11328

按ctrl+c 退出脚本,这时脚本会通知进程将标准输出和标准错误重定向到 /dev/null,继续后台运行。
[root@iZ25dcp92ckZ testdemo]# sh -x ./test.sh 16935  
+ pid=16935
+ ps -p 16935
+ '[' '!' 0 -eq 0 ']'
+ echo pid 16935
pid 16935
+ trap 'kill -usr2 16935 && exit 1' HUP INT QUIT TERM
+ kill -usr1 16935
+ echo it works,please wait..
it works,please wait..
+ sleep 1
+ tail -f -n 0 /tmp/console_temp.log
test
test
test
test
==========================================================
接着,写个脚本测试这个程序, 保存为test.sh:
#!/bin/bash

pid=$1
ps -p $pid>/dev/null
if [ ! $? -eq 0 ] ; then
  echo pid does not exist!
  exit 1
fi
echo pid $pid
trap "kill -usr2 $pid && exit 1" HUP INT QUIT TERM
kill -usr1 $pid
echo it works,please wait..
sleep 1
tail -f -n 0 /tmp/console_temp.log
echo done!
执行这个脚本,结果如下:
$ ./test.sh 11328
pid 11328
it works,please wait..
test
test
然后,按ctrl+c 退出脚本,这时脚本会通知进程将标准输出和标准错误重定向到 /dev/null,继续后台运行。
这样,这个脚本就成了后台进程的调试工具了,需要后台数据的时候执行一下,不需要就关闭。当然,这只是一个示例,实际应用中要做改善,比如kill信号改成pipe或socket通讯,缓存文件要限制大小,或自动清除等。

摘自:http://blog.csdn.net/mycwq/article/details/50479735
背景:发现用ansible去做sudo时,发现权限不够:
TASK [irdcops : 修改 /etc/sudoers] ***********************************************
skipping: [10.70.37.24]
fatal: [10.70.36.172]: FAILED! => {"changed": false, "failed": true, "msg": "Could not replace file: /tmp/tmpfToWiS to /etc/sudoers: [Errno 1] Operation not permitted"}
fatal: [10.70.36.173]: FAILED! => {"changed": false, "failed": true, "msg": "Could not replace file: /tmp/tmpvA5FJh to /etc/sudoers: [Errno 1] Operation not permitted"}


[root@v-szq-Localizationweb13 etc]# chmod 755 sudoers
chmod: changing permissions of `sudoers': Operation not permitted
[root@v-szq-Localizationweb13 etc]# lsattr sudoers
----i--------e- sudoers
[root@v-szq-Localizationweb13 etc]#  chattr -i sudoers
[root@v-szq-Localizationweb13 etc]# visudo

http://www.linuxeye.com/command/chattr.html







Form:http://jackxiang.com/post/1792/
随着时代的进步,女性在现代社会中所承担的责任和义务也越来越多,上有爹妈和公婆、下有孩子,时不时还要兼顾一下丈夫。面临工作上的压力和家庭中的重担,许多女性朋友都会忽视自身的健康.阅读全文
背景: 一个程序运行了多长时间,能用ps命令得出来,像系统运行多长时间可以用uptime,一样的道理。
最简单的这个命令:

实践如下:
ps -ef|grep mysql
root      4572     1  0 7月09 ?       00:00:00 /bin/sh /usr/local/mysql/bin/mysqld_safe


摘自 :http://www.cnblogs.com/fengbohello/p/4111206.html

写个小脚本,根据传入的参数显示对应进程的启动时间

ps -p 25352 -o lstart|grep -v "START"
比如运行:./showProRunTime.sh mysql 显示mysql进程的启动时间:
/usr/local/sbin/showProRunTime.sh


/tmp/synrpm.sh synrpm2repos
root     53504  0.0  0.1 119240  6436 ?        Ss   Jul17   0:00 /usr/local/php/bin/php /usr/local/sbin/synrpm2repos.php --daemon Sun Jul 17 16:57:39 2016

启动时间是:Sun Jul 17 16:57:39 2016
___________________________以下是参数说明_____________________________________________

ps -eo lstart 启动时间
ps -eo etime   运行多长时间.


ps -eo pid,lstart,etime | grep 5176


有些时候我们需要知道某个进程的启动时间!
显示某PID的启动时间命令:

ps -p PID -o lstart  


如下面显示httpd的启动时间:

for pid in $(pgrep httpd); do echo -n "${pid}"; ps -p ${pid} -o lstart | grep -v "START"; done  
====================================================================================
在Linux下,如果需要查看进程的启动时间, 常用ps aux命令,但是ps aux命令的缺陷在于只能显示时间到年、日期、或者时间, 无法具体到年月日时分秒。如果需要查看某个进程的具体启动时间, 使用 ps -p PID -o lstart,  其中,PID为某个进程的进程ID号。

如下所示, 显示系统中所有httpd进程的具体启动时间。

如下所示, 显示系统中所有httpd进程的具体启动时间。

for pid in $(pgrep httpd); do echo -n "${pid} " ; ps -p ${pid} -o lstart | grep -v "START" ; done
301 Mon Aug 27 11:21:59 2012
344 Mon Aug 27 11:33:13 2012
25065 Sun Aug 26 03:27:03 2012
25066 Sun Aug 26 03:27:03 2012
25067 Sun Aug 26 03:27:03 2012
25068 Sun Aug 26 03:27:03 2012
25069 Sun Aug 26 03:27:03 2012
25070 Sun Aug 26 03:27:03 2012
25071 Sun Aug 26 03:27:03 2012
25072 Sun Aug 26 03:27:03 2012
27903 Wed Jun 20 22:50:47 2012
32767 Mon Aug 27 11:21:48 2012

来自:http://www.iteye.com/topic/1135810
http://chromecj.com/web-development/2015-08/549.html
废话不多说,打开控制台,install package

搜 sublimelinter

先安装sublimelinter本体

安装完以后再搜索一下,安装sublimelinter-php

接下来,打开preferences-package settings-sublimeLinter-settings--user

如下配置:

{
    "user": {
        
        "linters": {
            
        },
        
        "paths": {
            "linux": [],
            "osx": [],
            "windows": [
                "D:\\xampp\\php"
            ]
        },
        
    }
}







就是添加一下 paths的参数值,指定一下你本地php目录。


然后关闭sublime,再次打开一个php脚本,试试吧。

有错误的地方在行号上会有红点提示在代码上会有红色方框,鼠标放红色方框上,错误信息在编辑器底部状态栏显示。

来自:http://my.oschina.net/cxz001/blog/204592
处理方法: 打开 /etc/.vimrc 并添加 set noswapfile 后 OK
vi /root/.vimrc
set noswapfile

非正常关闭vi编辑器时会生成一个.swp文件

关于swp文件
使用vi,经常可以看到swp这个文件,那这个文件是怎么产生的呢,当你打开一个文件,vi就会生成这么一个.(filename)swp文件以备不测(不测下面讨论),如果你正常退出,那么这个这个swp文件将会自动删除。下面说不测。
不测分为:1当你用多个程序编辑同一个文件时。
         2非常规退出时。
第一种情况的话,为了避免同一个文件产生两个不同的版本(vim中的原话),还是建议选择readonly为好。
第二种情况的话,你可以用vim -r filename恢复,然后再把swp文件删除(这个时候要确保你的swp文件没有用处了,要不然你会伤心的)
swp文件的来历,当你强行关闭vi时,比如电源突然断掉或者你使用了Ctrl+ZZ,vi自动生成一个.swp文件,下次你再编辑时,就会出现一些提示。

你可以使用

vi -r {your file name}

来恢复文件,然后用下面的命令删除swp文件,不然每一次编辑时总是有这个提示。

rm .{your file name}.swp

在网上搜到了一个类似的提示,不同的linux提示可能不一样

“.xorg.conf.swp” already exists!
[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit:

当然可以用R键恢复。

vi编辑器要正常退出可以使用Shift-ZZ 。



[SuSE] 【已解决】vi 命令 生成 .swp 文件相关问题

-> 例:使用vi a.dat时 会生成一个 .a.dat.swp 文件
       然后再开个终端 vi a.dat 时会提示:
      【“Swap file ".文件名.swp" already exists![O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit:】  

-> vi 版本:
   vi -vierson
     VIM - Vi IMproved 6.3 (2004 June 7, compiled Oct 20 2004 23:12:36)
        
->  问: (vi 一个文件时怎么样可以不让它产生.swp文件?
          或不让他提示【“Swap file ".文件名.swp" already exists![O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit:】)

处理方法: 打开 /etc/vimrc 并添加 set noswapfile 后 OK

来自:http://blog.163.com/phys_atom/blog/static/167644553201222784342904/
背景:最近有同事用sb编辑器,主要是它这个sftp有点意思,一个是可以同步映射到远程,这块Editplus也有,但好像它是一个从外网拿到内网机上后修改再同步外网,没有映入这一说,且外网同步到内网,内网到外网的操作上好像没有sb编辑器灵活和项多,sublime主要就是找文件很快这点很有助于提高效率。这块我觉得还是做一个ssh_key_file安全,于是做了一个,实践Ok。这块注意路径得是\/  \/ 这样写,否则连接不上哟。再就是生成的公钥匙是放在linux上,而自己则是私钥匙,这就相当于linux配置棉密码登录时把公钥匙给需要登录的服务器一样,我们windows是相当于被登录了,因为那个authorized_keys是在linux上,也就是公公钥。这块用windows的软件puTTY-Key来进行生成更快捷,否则得转(sublime使用的是PSFTP。 需要的私钥需要先用PuTTYgen来转换一下格式,转换完以后的文件后缀是ppk。)。


"D:\Program Files\TortoiseGit\bin\puttygen.exe"  这个git里安装小乌龟时也带这个:
PuTTYgen生成的框里放到服务器上,是公钥。
私钥匙放到windows机器里:D:\sshkey\sshkey.ppk  (Save private key)

阅读全文
我的是独立出来的放在:/usr/local/php/etc/php.d/opcache.ini

opcache.enable_cli=0
opcache.enable=0

/bin/systemctl restart  php-fpm.service
访问后再修改为1像上面这样restart一下即可。

打开页面看到如下错误:“PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible.”这可能是由缓存/加速器造成的,例如 Zend OPcache 或 eAccelerator。打开你的打开php.ini文件,找到:[opcache],设置为:opcache.enable=0 和 opcache.enable_cli=0。

[opcache]
opcache.enable=0
opcache.enable_cli=0  

[root@iZ25dcp92ckZ etc]# php -v
PHP 5.6.20 (cli) (built: Jul 11 2016 11:15:33)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2015, by Zend Technologies
    with Zend Guard Loader v3.3, Copyright (c) 1998-2014, by Zend Technologies

还没生效?
[root@iZ25dcp92ckZ php.d]# php -i|grep opcache

Additional .ini files parsed => /usr/local/php/etc/php.d/opcache.ini

找到:
/usr/local/php/etc/php.d/opcache.ini

[opcache]
zend_extension=/usr/local/php/ext/opcache.so
opcache.enable=0
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.save_comments=0
opcache.fast_shutdown=1
opcache.enable_cli=0
;opcache.optimization_level=0                  


[root@iZ25dcp92ckZ php.d]# service php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm  done
1. 系统版本

CentOS 6.6 x86_64 Desktop

2. 设置yum代理

在Shell中运行以下命令:

vi /etc/yum.conf
在上述文件的最后,添加如下内容:

# Proxy

proxy=http://username:password@proxy_ip:port
其中,username是登录代理服务器的用户名,password是登录密码,proxy_ip是代理服务器的域名或IP地址,port是代理服务器的端口号。也可以使用proxy_username和proxy_password来配置代理的用户名和密码。这样的配置完成后,所有的用户在使用yum时,都会使用代理,可以说是全局代理。如果需要为单独的用户配置代理,可以在用户的~/.bash_profile文件中设置。

在Shell中运行以下命令,验证配置是否正确:

yum search gcc
若上述命令的输出信息如下图所示,则表示配置成功:

显示大图


3. 设置wget代理

在shell中运行以下命令:

vi /etc/wgetrc
在上述文件的最后,添加如下内容:

# Proxy

http_proxy=http://username:password@proxy_ip:port/

ftp_proxy=http://username:password@proxy_ip:port/
其中,http_proxy是http代理,ftp_proxy是ftp代理,其余变量的意义和设置yum代理的方法相同。

在Shell中运行以下命令,验证配置是否正确:

wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm
若上述命令的输出信息如下图所示,则表示配置成功:



4. 设置系统全局代理

在shell中运行以下命令:

vi /etc/profile
在上述文件的最后,添加如下内容:

export http_proxy="http://username:password@proxy_ip:port"
各个变量的意义和设置yum代理的方法相同。配置的验证方法和yum代理、wget代理相同。
repo只要自己知道RPM位置,自己也可以写:


同步的是ymrepos.d里面的仓库明儿,一般都带x86或啥的,如果有多台不是64位成32位的需要yum下载,则不要用变量,直接写和服务器不一样的变量写死如死x86这样的路径。
关于CentOS6主CentOS7的不同变量了解,下面是centOS7的:
http://rpms.adiscon.com/v8-stable/epel-$releasever/$basearch
http://rpms.adiscon.com/v8-stable/epel-7/x86_64/
单位的机器是CentOS6且是64位的,上面的变量就变成:
http://rpms.adiscon.com/v8-stable/epel-6/x86_64/RPMS/
如果是32位的呢?变量部分会变成如下,就是这样:
http://rpms.adiscon.com/v8-stable/epel-6/i386/RPMS/
http://m.2cto.com/net/201512/455901.html

这个参数不常用,但提到架构问题了x86还是64位的:
  -a ARCH, --arch=ARCH  act as if running the specified arch (default: current
                        arch, note: does not override $releasever. x86_64 is a
                        superset for i*86.)

cat /etc/yum.repos.d/rsyslog.repo |grep releasever
name=Adiscon CentOS-$releasever - local packages for $basearch
#baseurl=http://rpms.adiscon.com/v8-stable/epel-$releasever/$basearch
===============================================================
如果执行的时候yum.repos.d里面的文件url写错了,会出现如下错误,也就是说写的目录下面必须有repodata这个索引文件夹:
http://rpms.adiscon.com/v8-stable/epel-6/i386/RPMS/repodata/repomd.xml: [Errno 14] HTTP Error 404 - Not Found
也就是它会去repos的索引里面找,改为:
baseurl=http://rpms.adiscon.com/v8-stable/epel-6/i386          再:yum clean all就可以在64位机器下载同步使用32位,供32位 使用。  
baseurl=http://rpms.adiscon.com/v8-stable/epel-7/x86_64/

上面这些文件形成多个repo,于是就可能在一台X86_64位的机器上下载多种架构的机型,只有配置多个repos文件:
reposync --repoid=rsyslog_v8_32
[rsyslog_v8_32]
baseurl=http://rpms.adiscon.com/v8-stable/epel-6/i386

[rsyslog_v8_64]
baseurl=http://rpms.adiscon.com/v8-stable/epel-6/x86_64
reposync --repoid=rsyslog_v8_64



同样:
[root@iZ25dcp92ckZ tmp]# reposync --repoid=rsyslog_v8_i386
/tmp/rsyslog_v8_i386/RPMS/*.rpm

建立软链接:
ln -s /tmp/rsyslog_v8_i386/RPMS /data/www/yum/centos/6/x86_64/rsyslog_v8_i386
ln -s /tmp/rsyslog_v8_64/RPMS /data/www/yum/centos/6/x86_64/rsyslog_v8_64
这样,两个版本都能同时提供服务了:
直接cd 到/data/www/yum/centos/6/x86_64 ,createrepo --update -d -p -o . .  ,它会扫子目录的如/data/www/yum/centos/6/x86_64/rsyslog_v8_64 和 /data/www/yum/centos/6/x86_64/rsyslog_v8_i386:
cat /etc/yum.repos.d/cntv-irdc.repo
[cntv-irdc]
name=Centos $releasever - $basearch rpm repository
baseurl=http://10.70.41.222/centos/$releasever/$basearch

==============================================================
最终目的是想:elk+kafka+rsyslog+hadoophdfs+zookeeper搭建及其应用,http://www.it165.net/admin/html/201604/7496.html。
CentOS6.5安装配置官方最新版rsyslog:  http://blog.chinaunix.net/uid-21142030-id-5616974.html
总原则及结论:在YUM仓库下建立一个新的目录存放,在上一层建立索引,也可读取到子目录的方法。

同步思想:三台机器,一台用来reposync同步并在上面开一个rsyncd的服务指向,另两台来同步它,
A:上面有crontab去定时reposync,同时有一个定时同步rpm后createrepo --update -d -p -o . . 。
BC两台:  在定时同步A完成后,也需要作一下:createrepo --update -d -p -o . . ,更新一下索引。
步骤零:
关于CentOS6主CentOS7的不同变量了解,下面是centOS7的:
http://rpms.adiscon.com/v8-stable/epel-$releasever/$basearch
http://rpms.adiscon.com/v8-stable/epel-7/x86_64/
单位的机器是CentOS6且是64位的,上面的变量就变成:
http://rpms.adiscon.com/v8-stable/epel-6/x86_64/RPMS/
如果是32位的呢?变量部分会变成如下,就是这样:
http://rpms.adiscon.com/v8-stable/epel-6/i386/RPMS/


步骤一:安装必要的reposync的rpm包和repo同步的源:
rpm 包安装需要: yum-utils-1.1.30-37.el6.noarch
rpm -qf /usr/bin/reposync  安装包是:yum-utils-1.1.30-37.el6.noarch
yum install -y http://rdo.fedorapeople.org/rdo-release.rpm


步骤二:
安装后如何同步:
wget http://rpms.adiscon.com/v8-stable/rsyslog.repo -o /etc/yum.repos.d/rsyslog.repo
/etc/yum.repos.d/rsyslog.repo

http://rpms.adiscon.com/ 里全是各个版本的rpm包。

cd /data/www/yum/centos/6/x86_64/rsyslog_v8

[root@bj_szq_yum_repos_36_172 rsyslog_v8]# reposync --repoid=rsyslog_v8
Error setting up repositories: Cannot retrieve repository metadata (repomd.xml) for repository: rsyslog_v8. Please verify its path and try again

抓取这块咱还需要再商量商量下抓取地址和同步范围:
http://www.rsyslog.com/rhelcentos-rpms/

http://rpms.adiscon.com/v8-stable/rsyslog.repo
http://rpms.adiscon.com/v8-stable/
————————————————————————————
http://king9527.blog.51cto.com/84461/1096111
http://gdlwolf.blog.51cto.com/343866/1729020
http://www.ipcpu.com/2015/08/reposync-yum/
http://www.programgo.com/article/53684909700/

用reposync 同步YUM源到本地,搭建本地YUM源服务器:
http://www.tuicool.com/articles/7rANJj
————————————————————————————
#安装rdo的源文件
yum install -y http://rdo.fedorapeople.org/rdo-release.rpm
#查看源ID的列表
yum repolist
摘自:http://www.ipcpu.com/2015/08/reposync-yum/

发现这个rpm包其实就是向/etc/yum.repos.d里添加一个repo文件,如下:
rpm -qpl rdo-release.rpm
/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Cloud
/etc/yum.repos.d/rdo-release.repo
/etc/yum.repos.d/rdo-testing.repo

安装发现多了上面这俩文件:
rpm -ihv rdo-release.rpm
准备中...                          ################################# [100%]
正在升级/安装...
1:rdo-release-mitaka-5             ################################# [100%]
[root@iZ25dcp92ckZ yum.repos.d]# ls -lart rdo-*
-rw-r--r-- 1 root root 326 6月  14 05:57 rdo-testing.repo
-rw-r--r-- 1 root root 209 6月  14 05:57 rdo-release.repo
查看仓库:
yum repolist |grep openstack
openstack-mitaka/x86_64 OpenStack Mitaka Repository                        1,182


mkdir -p /data/htdocs/openstack
cd   /data/htdocs/openstack
找仓库:
cat rdo-release.repo |grep openstack-mitaka
[openstack-mitaka]
baseurl=http://mirror.centos.org/centos/7/cloud/$basearch/openstack-mitaka/
找到了:
reposync --repoid=openstack-mitaka

实践如下: du -sh /data/htdocs/openstack/ 277M    /data/htdocs/openstack/
reposync --repoid=openstack-mitaka
Xaw3d-1.6.2-4.el7.x86_64.rpm   FAILED                                                          ]  15 kB/s |  32 kB  12:11:55 ETA
warning: /data/htdocs/openstack/openstack-mitaka/common/Xaw3d-devel-1.6.2-4.el7.x86_64.rpm: Header V4 RSA/SHA1 Signature, key ID 764429e6: NOKEY
Xaw3d-devel-1.6.2-4.el7.x86_64.rpm 的公钥尚未安装
(1/1182): Xaw3d-devel-1.6.2-4.el7.x86_64.rpm                                                              |  58 kB  00:00:03    
(2/1182): babel-1.3-6.el7.noarch.rpm                                                                      |  15 kB  00:00:01    
(3/1182): babel-2.3.4-1.el7.noarch.rpm                                                                    |  18 kB  00:00:01    
(4/1182): babel-doc-1.3-6.el7.noarch.rpm                                                                  | 208 kB  00:00:14    
(5/1182): babel-doc-2.3.4-1.el7.noarch.rpm                                                                | 234 kB
背景:redis这个新产品在sns时很火,而memcache早就存在, 但redis提供出来的功能,好多网站均把它当memcache使用,这是大才小用,这儿有30个方法来使用redis,值得了解。
这篇文章主要介绍了30个php操作redis常用方法代码例子,本文其实不止30个方法,可以操作string类型、list类型和set类型的数据,需要的朋友可以参考下
redis的操作很多的,以前看到一个比较全的博客,但是现在找不到了。查个东西搜半天,下面整理一下php处理redis的例子,个人觉得常用一些例子。下面的例子都是基于php-redis这个扩展的。
1,connect
描述:实例连接到一个Redis.
参数:host: string,port: int
返回值:BOOL 成功返回:TRUE;失败返回:FALSE
示例:

<?php  
$redis = new redis();  
$result = $redis->connect('127.0.0.1', 6379);  
var_dump($result); //结果:bool(true)  
?>  
2,set
描述:设置key和value的值
参数:Key Value
返回值:BOOL 成功返回:TRUE;失败返回:FALSE
示例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$result = $redis->set('test',"11111111111");  
var_dump($result);    //结果:bool(true)  
?>  
3,get
描述:获取有关指定键的值
参数:key
返回值:string或BOOL 如果键不存在,则返回 FALSE。否则,返回指定键对应的value值。
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$result = $redis->get('test');  
var_dump($result);   //结果:string(11) "11111111111"  
?>  
4,delete

描述:删除指定的键
参数:一个键,或不确定数目的参数,每一个关键的数组:key1 key2 key3 … keyN
返回值:删除的项数
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->set('test',"1111111111111");  
echo $redis->get('test');   //结果:1111111111111  
$redis->delete('test');  
var_dump($redis->get('test'));  //结果:bool(false)  
?>  
5,setnx
描述:如果在数据库中不存在该键,设置关键值参数
参数:key value
返回值:BOOL 成功返回:TRUE;失败返回:FALSE
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->set('test',"1111111111111");  
$redis->setnx('test',"22222222");  
echo $redis->get('test');  //结果:1111111111111  
$redis->delete('test');  
$redis->setnx('test',"22222222");  
echo $redis->get('test');  //结果:22222222  
?>  
6,exists
描述:验证指定的键是否存在
参数key
返回值:Bool 成功返回:TRUE;失败返回:FALSE
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->set('test',"1111111111111");  
var_dump($redis->exists('test'));  //结果:bool(true)  
?>  
7,incr
描述:数字递增存储键值键.
参数:key value:将被添加到键的值
返回值:INT the new value
实例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->set('test',"123");  
var_dump($redis->incr("test"));  //结果:int(124)  
var_dump($redis->incr("test"));  //结果:int(125)  
?>
  
8,decr
描述:数字递减存储键值。
参数:key value:将被添加到键的值
返回值:INT the new value
实例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->set('test',"123");  
var_dump($redis->decr("test"));  //结果:int(122)  
var_dump($redis->decr("test"));  //结果:int(121)  
?>
9,getMultiple
描述:取得所有指定键的值。如果一个或多个键不存在,该数组中该键的值为假
参数:其中包含键值的列表数组
返回值:返回包含所有键的值的数组
实例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->set('test1',"1");  
$redis->set('test2',"2");  
$result = $redis->getMultiple(array('test1','test2'));  
print_r($result);   //结果:Array ( [0] => 1 [1] => 2 )  
?>

10,lpush
描述:由列表头部添加字符串值。如果不存在该键则创建该列表。如果该键存在,而且不是一个列表,返回FALSE。
参数:key,value
返回值:成功返回数组长度,失败false
实例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
var_dump($redis->lpush("test","111"));   //结果:int(1)  
var_dump($redis->lpush("test","222"));   //结果:int(2)  
?>

11,rpush
描述:由列表尾部添加字符串值。如果不存在该键则创建该列表。如果该键存在,而且不是一个列表,返回FALSE。
参数:key,value
返回值:成功返回数组长度,失败false
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
var_dump($redis->lpush("test","111"));   //结果:int(1)  
var_dump($redis->lpush("test","222"));   //结果:int(2)  
var_dump($redis->rpush("test","333"));   //结果:int(3)  
var_dump($redis->rpush("test","444"));   //结果:int(4)  
?>

12,lpop
描述:返回和移除列表的第一个元素
参数:key
返回值:成功返回第一个元素的值 ,失败返回false
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
$redis->lpush("test","111");  
$redis->lpush("test","222");  
$redis->rpush("test","333");  
$redis->rpush("test","444");  
var_dump($redis->lpop("test"));  //结果:string(3) "222"  
?>

13,lsize,llen
描述:返回的列表的长度。如果列表不存在或为空,该命令返回0。如果该键不是列表,该命令返回FALSE。
参数:Key
返回值:成功返回数组长度,失败false
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
$redis->lpush("test","111");  
$redis->lpush("test","222");  
$redis->rpush("test","333");  
$redis->rpush("test","444");  
var_dump($redis->lsize("test"));  //结果:int(4)  
?>

14,lget
描述:返回指定键存储在列表中指定的元素。 0第一个元素,1第二个… -1最后一个元素,-2的倒数第二…错误的索引或键不指向列表则返回FALSE。
参数:key index
返回值:成功返回指定元素的值,失败false
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
$redis->lpush("test","111");  
$redis->lpush("test","222");  
$redis->rpush("test","333");  
$redis->rpush("test","444");  
var_dump($redis->lget("test",3));  //结果:string(3) "444"  
?>

15,lset
描述:为列表指定的索引赋新的值,若不存在该索引返回false.
参数:key index value
返回值:成功返回true,失败false
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
$redis->lpush("test","111");  
$redis->lpush("test","222");  
var_dump($redis->lget("test",1));  //结果:string(3) "111"  
var_dump($redis->lset("test",1,"333"));  //结果:bool(true)  
var_dump($redis->lget("test",1));  //结果:string(3) "333"  
?>

16,lgetrange
描述:
返回在该区域中的指定键列表中开始到结束存储的指定元素,lGetRange(key, start, end)。0第一个元素,1第二个元素… -1最后一个元素,-2的倒数第二…
参数:key start end
返回值:成功返回查找的值,失败false
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
$redis->lpush("test","111");  
$redis->lpush("test","222");  
print_r($redis->lgetrange("test",0,-1));  //结果:Array ( [0] => 222 [1] => 111 )  
?>

17,lremove
描述:从列表中从头部开始移除count个匹配的值。如果count为零,所有匹配的元素都被删除。如果count是负数,内容从尾部开始删除。
参数:key count value
返回值:成功返回删除的个数,失败false
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
$redis->lpush('test','a');  
$redis->lpush('test','b');  
$redis->lpush('test','c');  
$redis->rpush('test','a');  
print_r($redis->lgetrange('test', 0, -1)); //结果:Array ( [0] => c [1] => b [2] => a [3] => a )  
var_dump($redis->lremove('test','a',2));   //结果:int(2)  
print_r($redis->lgetrange('test', 0, -1)); //结果:Array ( [0] => c [1] => b )  
?>

18,sadd
描述:为一个Key添加一个值。如果这个值已经在这个Key中,则返回FALSE。
参数:key value
返回值:成功返回true,失败false
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
var_dump($redis->sadd('test','111'));   //结果:bool(true)  
var_dump($redis->sadd('test','333'));   //结果:bool(true)  
print_r($redis->sort('test')); //结果:Array ( [0] => 111 [1] => 333 )  
?>

19,sremove
描述:删除Key中指定的value值
参数:key member
返回值:true or false
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
$redis->sadd('test','111');  
$redis->sadd('test','333');  
$redis->sremove('test','111');  
print_r($redis->sort('test'));    //结果:Array ( [0] => 333 )  
?>

20,smove
描述:将Key1中的value移动到Key2中
参数:srcKey dstKey member
返回值:true or false
范例

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
$redis->delete('test1');  
$redis->sadd('test','111');  
$redis->sadd('test','333');  
$redis->sadd('test1','222');  
$redis->sadd('test1','444');  
$redis->smove('test',"test1",'111');  
print_r($redis->sort('test1'));    //结果:Array ( [0] => 111 [1] => 222 [2] => 444 )  
?>

21,scontains
描述:检查集合中是否存在指定的值。
参数:key value
返回值:true or false
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
$redis->sadd('test','111');  
$redis->sadd('test','112');  
$redis->sadd('test','113');  
var_dump($redis->scontains('test', '111')); //结果:bool(true)  
?>

22,ssize
描述:返回集合中存储值的数量
参数:key
返回值:成功返回数组个数,失败0
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
$redis->sadd('test','111');  
$redis->sadd('test','112');  
echo $redis->ssize('test');   //结果:2  
?>
  
23,spop
描述:随机移除并返回key中的一个值
参数:key
返回值:成功返回删除的值,失败false
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
$redis->sadd("test","111");  
$redis->sadd("test","222");  
$redis->sadd("test","333");  
var_dump($redis->spop("test"));  //结果:string(3) "333"  
?>

24,sinter
描述:返回一个所有指定键的交集。如果只指定一个键,那么这个命令生成这个集合的成员。如果不存在某个键,则返回FALSE。
参数:key1, key2, keyN
返回值:成功返回数组交集,失败false
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
$redis->sadd("test","111");  
$redis->sadd("test","222");  
$redis->sadd("test","333");  
$redis->sadd("test1","111");  
$redis->sadd("test1","444");  
var_dump($redis->sinter("test","test1"));  //结果:array(1) { [0]=> string(3) "111" }  
?>

25,sinterstore
描述:执行sInter命令并把结果储存到新建的变量中。
参数:
Key: dstkey, the key to store the diff into.
Keys: key1, key2… keyN. key1..keyN are intersected as in sInter.
返回值:成功返回,交集的个数,失败false
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
$redis->sadd("test","111");  
$redis->sadd("test","222");  
$redis->sadd("test","333");  
$redis->sadd("test1","111");  
$redis->sadd("test1","444");  
var_dump($redis->sinterstore('new',"test","test1"));  //结果:int(1)  
var_dump($redis->smembers('new'));  //结果:array(1) { [0]=> string(3) "111" }  
?>

26,sunion
描述:
返回一个所有指定键的并集
参数:
Keys: key1, key2, … , keyN
返回值:成功返回合并后的集,失败false
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
$redis->sadd("test","111");  
$redis->sadd("test","222");  
$redis->sadd("test","333");  
$redis->sadd("test1","111");  
$redis->sadd("test1","444");  
print_r($redis->sunion("test","test1"));  //结果:Array ( [0] => 111 [1] => 222 [2] => 333 [3] => 444 )  
?>

27,sunionstore
描述:执行sunion命令并把结果储存到新建的变量中。
参数:
Key: dstkey, the key to store the diff into.
Keys: key1, key2… keyN. key1..keyN are intersected as in sInter.
返回值:成功返回,交集的个数,失败false
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
$redis->sadd("test","111");  
$redis->sadd("test","222");  
$redis->sadd("test","333");  
$redis->sadd("test1","111");  
$redis->sadd("test1","444");  
var_dump($redis->sinterstore('new',"test","test1"));  //结果:int(4)  
print_r($redis->smembers('new'));  //结果:Array ( [0] => 111 [1] => 222 [2] => 333 [3] => 444 )
?>

28,sdiff
描述:返回第一个集合中存在并在其他所有集合中不存在的结果
参数:Keys: key1, key2, … , keyN: Any number of keys corresponding to sets in redis.
返回值:成功返回数组,失败false
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
$redis->sadd("test","111");  
$redis->sadd("test","222");  
$redis->sadd("test","333");  
$redis->sadd("test1","111");  
$redis->sadd("test1","444");  
print_r($redis->sdiff("test","test1"));  //结果:Array ( [0] => 222 [1] => 333 )  
?>
  
29,sdiffstore
描述:执行sdiff命令并把结果储存到新建的变量中。
参数:
Key: dstkey, the key to store the diff into.
Keys: key1, key2, … , keyN: Any number of keys corresponding to sets in redis
返回值:成功返回数字,失败false
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
$redis->sadd("test","111");  
$redis->sadd("test","222");  
$redis->sadd("test","333");  
$redis->sadd("test1","111");  
$redis->sadd("test1","444");  
var_dump($redis->sdiffstore('new',"test","test1"));  //结果:int(2)  
print_r($redis->smembers('new'));  //结果:Array ( [0] => 222 [1] => 333 )  
?>

30,smembers, sgetmembers
描述:
返回集合的内容
参数:Key: key
返回值:An array of elements, the contents of the set.
范例:

<?php  
$redis = new redis();  
$redis->connect('127.0.0.1', 6379);  
$redis->delete('test');  
$redis->sadd("test","111");  
$redis->sadd("test","222");  
print_r($redis->smembers('test'));  //结果:Array ( [0] => 111 [1] => 222 )  
?>
  
php-redis当中,有很多不同名字,但是功能一样的函数,例如:lrem和lremove,这里就不例举


来自:http://m.jb51.net/article/51884.htm
logrotate-3.7.8-26.el6_7.x86_64
/usr/sbin/logrotate -f /etc/rsync.logrotate
cat /etc/rsync.logrotate






日志分割常用方法:

自己写脚本分割
使用linux自带的logrotate
前者灵活,可以应对各种需求,自定义文件夹、文件名。后者配置简单,使用方便。

下面我们以分割nginx日志为例介绍一下使用logrotate分割日志实例。

logrotate简单介绍

logrotate使用cron按时调度执行,日志的执行过程原理为不断改名称:比如你有个access.log文件,需要保留4个日志文件,那么logrotate是这么轮转的:

access.log满足轮转条件?(调度时间,日志大小是否满足要求)如果需要轮转则进行下列步骤,否则跳过
access.log.3存在?如果存在则删除
access.log.2如果存在则改名为access.log.3
access.log.1如果存在则改名为access.log.2
access.log如果存在则改名为access.log.1
创建一个空的access.log文件

如下图所示:
点击在新窗口中浏览此图片
logrotate配置文件一般在:

/etc/logrotate.conf 通用配置文件,可以定义全局默认使用的选项。
/etc/logrotate.d/xxx 自定义服务配置文件

我们可以看下/etc/logrotate.conf里面的内容


我们新建一个/etc/logrotate.d/nginx来分割nginx日志,配置文件内容如下:


第一行:指明日志文件位置,多个以空格分隔
第二行:调用频率,有:daily,weekly,monthly可选
第三行:总共轮换多少个日志文件,这里为保留15个
第四行:限制条件,大于10M的日志文件才进行分割,否则不操作

sharedscripts用于指明以下是执行轮转前和轮转后自定义执行的命令,比如postrotate和endscript表示,轮转后,执行nginx的重新加载配置文件,避免日志轮转后不写日志。如果要轮转前执行某个命令可以使用prerotate代替postrotate即可,两者可同时存在。

可以通过man logrotate查看更多选项

默认logrotate是通过crontab定期执行的,我们也可以手动执行查看结果:

# logrotate -vf /data/log/nginx/access.log
v选项表示查看详细执行过程
f表示强制执行日志轮转(不然时间不到,日志文件大小等条件不满足,不会执行)
强烈建议执行一下,了解下执行过程。

验证是否执行,查看cron的日志即可

# grep logrotate /var/log/cron

摘自:http://www.williamsang.com/archives/1254.html
一直提示:Git不是最新,装了好几次还是不行,后来发现:
安装完TortoiseGit,右键,在桌面上TortoiseGit里面有一个abount,里面有安基于哪个git的目录,我这一直是在aptana了,后来删除后,就对了:
TortoiseGit 2.1.0.0 (D:\Program Files\TortoiseGit\bin)
git version 2.9.0.windows.1 (D:\Program Files\Git\bin; D:\Program Files\Git\mingw32\; D:\Program Files\Git\mingw32\etc\gitconfig; C:\ProgramData\Git\config)

这种情况有可能是因为:
1.早期安装过aptana,里面有那个git了。
2.同时后来安装了TortoiseGit的版本和aptana里的git匹配,后来让TortoiseGit自己升级后就慢慢匹配不起来了。
3.再后来,即使更新了新的git,但是TortoiseGit里指向的还是aptana里的,所以一直提示,后来我直接删除后就好了。

注意:这个TortoiseGit最好是不要让它自动更新为好,哈哈~再就是老的TortoiseGit还有中文文件名在提交到仓库里出现乱码问题,删都删除不掉。
背景:在本人用PHP和硬件进行交互的时候,用过dio_open这些,但硬件有硬件的特点,特别是一些位啥的,这儿就有一个问题涉及到串口16进制啥的,这位兄弟在实践中遇到的一些转化如:chr()、hexdec()、bin2hex()这3个函数,网上还提到了用pack()、unpack(),因为前面3个函数以及很好的解决了问题,所以就没有继续深入。 再就是用fiddler来看发送的十六进制,以及在进行十六进制转十进制的一些问题,很有价值:
一)转换函数:


二)再谈fiddler2的一个好处:
优雅的快速测试
由于PHP是弱类型,因此理解起来比较费解。接收数据和向硬件发送数据的数据类型是不一样的。用bin2hex()得到的是形如"11 00 00 FE"的字符串,用chr(hexdec())得到的是16进制的ASCII码,如果echo输出的话,会是乱码。那么如何测试(看到)自己生成的16进制ASCII码数据是否正确呢?1种是找一个TCP/IP工具发送过去,这种麻烦了点,我推荐用fiddler监听。


HexView中的黑色部分就是你发送的
你可以快速方便的用一个web页面输出你的ASCII码,在fiddler的HexView中,就可以看到原汁原味你发送的16进制数据了。另外,由于Swoole的监听类是CLI运行,因此我也非常推荐多写一点echo打印一下状态,在phpstorm的SSH客户端里可以快速的了解目前的情况,就像android-studio的Loger一样。

三)echo Carbon::now() . '/Device Numbers:' . $devNum . PHP_EOL;//老司机劝你多写点,最好packagist找个轮子或者自己写个Logger库


除开本人的一个眉批外,以上摘录自:
文/保安保安(简书作者)
原文链接:http://www.jianshu.com/p/b25e8b46bd02
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

Q:jac***@aliyun.com : 服务器内主要运行程序 : Nginx php-fpm
问题描述 : 最近几天发现我的虚拟vps:101.200.189.210,出现运行时到某个时间点cpu高达100%的问题,连续出现三天了。
强制重启后,一天左右cpu又是100%,ssh都连接不上去,一般出现在早上或晚上6点左右,劳烦看一下是咋回事,能否通过你们系统看到是哪个进程一下子占用了100%的CPU,是一天里有一次左右就让服务器师假死一样,看aliyun的后台说还在运行,但ssh不上去。今天再看看会不会挂吧~  
售后工程师 :  您好:我们查看到您的CPU使用率27日详见附件,这个是需要您在您的实例上去查看的,您查看您的服务器日志,系统日志,查看哪些异常与错误来排查您的异常进程占用CPU,建议您下载使用第三方杀毒软件进行查杀木马病毒,还请您了解。

难道真要进行三方杀毒软件进行查杀木马病毒:
http://www.cnblogs.com/kerrycode/p/4754820.html
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup

在目录里叫启动,这个位置放入想开机启动的,如outlook啥的即可。
背景:获取CPU的使用率情况不是很容易一下获取到,用top得到一堆,得写个C来获取。
calccpucmd.c

gcc calccpucmd.c -o calccpucmd
./calccpucmd
20

想获取一下目标机运行时linux系统的硬件占用情况,写了这几个小程序,以后直接用了。
方法就是读取proc下的文件来获取了。 cpu使用率:    /proc/stat ,内存使用情况:      /proc/meminfo
看程序 :

typedef struct PACKED         //定义一个cpu occupy的结构体
{
char name[20];      //定义一个char类型的数组名name有20个元素
unsigned int user; //定义一个无符号的int类型的user
unsigned int nice; //定义一个无符号的int类型的nice
unsigned int system;//定义一个无符号的int类型的system
unsigned int idle; //定义一个无符号的int类型的idle
}CPU_OCCUPY;

typedef struct PACKED         //定义一个mem occupy的结构体
{
char name[20];      //定义一个char类型的数组名name有20个元素
unsigned long total;
char name2[20];
unsigned long free;                      
}MEM_OCCUPY;

get_memoccupy (MEM_OCCUPY *mem) //对无类型get函数含有一个形参结构体类弄的指针O
{
     FILE *fd;        
     int n;            
     char buff[256];  
     MEM_OCCUPY *m;
     m=mem;
                                                                                                              
     fd = fopen ("/proc/meminfo", "r");
      
     fgets (buff, sizeof(buff), fd);
     fgets (buff, sizeof(buff), fd);
     fgets (buff, sizeof(buff), fd);
     fgets (buff, sizeof(buff), fd);
     sscanf (buff, "%s %u %s", m->name, &m->total, m->name2);
    
     fgets (buff, sizeof(buff), fd); //从fd文件中读取长度为buff的字符串再存到起始地址为buff这个空间里
     sscanf (buff, "%s %u", m->name2, &m->free, m->name2);
    
     fclose(fd);     //关闭文件fd
}

int cal_cpuoccupy (CPU_OCCUPY *o, CPU_OCCUPY *n)
{  
     unsigned long od, nd;  
     unsigned long id, sd;
     int cpu_use = 0;  
    
     od = (unsigned long) (o->user + o->nice + o->system +o->idle);//第一次(用户+优先级+系统+空闲)的时间再赋给od
     nd = (unsigned long) (n->user + n->nice + n->system +n->idle);//第二次(用户+优先级+系统+空闲)的时间再赋给od
      
     id = (unsigned long) (n->user - o->user);    //用户第一次和第二次的时间之差再赋给id
     sd = (unsigned long) (n->system - o->system);//系统第一次和第二次的时间之差再赋给sd
     if((nd-od) != 0)
     cpu_use = (int)((sd+id)*10000)/(nd-od); //((用户+系统)乖100)除(第一次和第二次的时间差)再赋给g_cpu_used
     else cpu_use = 0;
     //printf("cpu: %u/n",cpu_use);
     return cpu_use;
}

get_cpuoccupy (CPU_OCCUPY *cpust) //对无类型get函数含有一个形参结构体类弄的指针O
{  
     FILE *fd;        
     int n;          
     char buff[256];
     CPU_OCCUPY *cpu_occupy;
     cpu_occupy=cpust;
                                                                                                              
     fd = fopen ("/proc/stat", "r");
     fgets (buff, sizeof(buff), fd);
    
     sscanf (buff, "%s %u %u %u %u", cpu_occupy->name, &cpu_occupy->user, &cpu_occupy->nice,&cpu_occupy->system, &cpu_occupy->idle);
    
     fclose(fd);    
}

int main()
{
     CPU_OCCUPY cpu_stat1;
     CPU_OCCUPY cpu_stat2;
     MEM_OCCUPY mem_stat;
     int cpu;
    
     //获取内存
     get_memoccupy ((MEM_OCCUPY *)&mem_stat);
    
     //第一次获取cpu使用情况
     get_cpuoccupy((CPU_OCCUPY *)&cpu_stat1);
     sleep(10);
    
     //第二次获取cpu使用情况
     get_cpuoccupy((CPU_OCCUPY *)&cpu_stat2);
    
     //计算cpu使用率
     cpu = cal_cpuoccupy ((CPU_OCCUPY *)&cpu_stat1, (CPU_OCCUPY *)&cpu_stat2);
    
     return 0;
}







我们在搞性能测试的时候,对后台服务器的CPU利用率监控是一个常用的手段。服务器的CPU利用率高,则表明服务器很繁忙。如果前台响应时间越来越大,而后台CPU利用率始终上不去,说明在某个地方有瓶颈了,系统需要调优。这个是即使不懂技术的人都容易理解的事情。

上面理解对吗?我个人觉得不十分准确。这个要看后台你测试的进程是什么类型的。如果是计算密集型的进程,当前端压力越来越大的时候,很容易把CPU 利用率打上去。但是如果是I/O网络密集型的进程,即使客户端的请求越来越多,但是服务器CPU不一定能上去,这个是你要测试的进程的自然属性决定的。比 较常见的就是,大文件频繁读写的cpu开销远小于小文件频繁读写的开销。因为在I/O吞吐量一定时,小文件的读写更加频繁,需要更多的cpu来处理I/O 的中断。

在Linux/Unix下,CPU利用率分为用户态 ,系统态 和空闲态 ,分别表示CPU处于用户态执行的时间,系统内核执行的时间,和空闲系统进程执行的时间。平时所说的CPU利用率是指:CPU执行非系统空闲进程的时间 / CPU总的执行时间 。

在Linux的内核中,有一个全局变量:Jiffies。 Jiffies代表时间。它的单位随硬件平台的不同而不同。系统里定义了一个常数HZ,代表每秒种最小时间间隔的数目。这样jiffies的单位就是 1/HZ。Intel平台jiffies的单位是1/100秒,这就是系统所能分辨的最小时间间隔了。每个CPU时间片,Jiffies都要加1。 CPU的利用率就是用执行用户态+系统态的Jiffies除以总的Jifffies来表示。

在Linux系统中,可以用/proc/stat文件来计算cpu的利用率(详细的解释可参考:http: //www.linuxhowtos.org/System/procstat.htm)。这个文件包含了所有CPU活动的信息,该文件中的所有值都是从 系统启动开始累计到当前时刻。

如:

1.[sailorhzr@builder ~]$ cat /proc/stat  
2.cpu  432661 13295   86656 422145968   171474 233   5346  
3.cpu 0 123075   2462 23494   105543694 16586   0 4615  
4.cpu 1 111917   4124 23858   105503820 69697   123 371  
5.cpu 2 103164   3554 21530   105521167 64032   106 334  
6.cpu 3 94504   3153 17772   105577285 21158   4 24  
7.intr  1065711094 1057275779   92 0   6 6   0 4   0 3527   0 0   0 70   0 20   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   7376958 0   0 0   0 0   0 0   1054602 0   0 0   0 0   0 0   30 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0
8.ctxt  19067887  
9.btime  1139187531  
10.processes  270014  
11.procs_running  1  
12.procs_blocked  0    
13.
输出解释
CPU 以及CPU0、CPU1、CPU2、CPU3每行的每个参数意思(以第一行为例)为:


参数

解释


user (432661)
nice (13295)
system (86656)
idle (422145968)
iowait (171474)
irq (233)
softirq (5346)


从系统启动开始累计到当前时刻,用户态的CPU时间(单位:jiffies) ,不包含 nice值为负进程。1jiffies=0.01秒
从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间(单位:jiffies)
从系统启动开始累计到当前时刻,核心时间(单位:jiffies)
从系统启动开始累计到当前时刻,除硬盘IO等待时间以外其它等待时间(单位:jiffies)
从系统启动开始累计到当前时刻,硬盘IO等待时间(单位:jiffies) ,
从系统启动开始累计到当前时刻,硬中断时间(单位:jiffies)
从系统启动开始累计到当前时刻,软中断时间(单位:jiffies)

CPU时间=user+system+nice+idle+iowait+irq+softirq
“intr”这行给出中断的信息,第一个为自系统启动以来,发生的所有的中断的次数;然后每个数对应一个特定的中断自系统启动以来所发生的次数。

“ctxt”给出了自系统启动以来CPU发生的上下文交换的次数。

“btime”给出了从系统启动到现在为止的时间,单位为秒。

“processes (total_forks) 自系统启动以来所创建的任务的个数目。

“procs_running”:当前运行队列的任务的数目。

“procs_blocked”:当前被阻塞的任务的数目。

那么CPU利用率可以使用以下两个方法。先取两个采样点,然后计算其差值:

1.cpu usage=(idle 2 -idle 1 )/(cpu 2 -cpu 1 )* 100  
2.cpu usage=[(user_ 2  +sys_ 2 +nice_ 2 ) - (user_ 1  + sys_ 1 +nice_ 1 )]/(total_ 2  - total_ 1 )* 100
3.
以下用分别用bash和perl做的一个cpu利用率的计算:

本人注:以下代码则采用公式为:

1.total_ 0 USER[ 0 ]+NICE[ 0 ]+SYSTEM[ 0 ]+IDLE[ 0 ]+IOWAIT[ 0 ]+IRQ[ 0 ]+SOFTIRQ[ 0 ]  
2.total_ 1 =USER[ 1 ]+NICE[ 1 ]+SYSTEM[ 1 ]+IDLE[ 1 ]+IOWAIT[ 1 ]+IRQ[ 1 ]+SOFTIRQ[ 1 ]
3.cpu usage=(IDLE[ 0 ]-IDLE[ 1 ]) / (total_ 0 -total_ 1 ) *  100  
4.
###bash 代码
1.CODE: #!/bin/sh  
2.
3.##echo user nice system idle iowait irq softirq  
4.CPULOG_1=$(cat /proc/stat | grep  'cpu '  | awk  '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}' )
5.SYS_IDLE_1=$(echo  $CPULOG_1  | awk  '{print $4}' )  
6.Total_1=$(echo  $CPULOG_1  | awk  '{print $1+$2+$3+$4+$5+$6+$7}' )  
7.
8.sleep 5  
9.
10.CPULOG_2=$(cat /proc/stat | grep  'cpu '  | awk  '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}' )
11.SYS_IDLE_2=$(echo  $CPULOG_2  | awk  '{print $4}' )  
12.Total_2=$(echo  $CPULOG_2  | awk  '{print $1+$2+$3+$4+$5+$6+$7}' )  
13.
14.SYS_IDLE=`expr  $SYS_IDLE_2  -  $SYS_IDLE_1 `  
15.
16.Total=`expr  $Total_2  -  $Total_1 `  
17.SYS_USAGE=`expr  $SYS_IDLE / $Total *100 |bc -l`  
18.
19.SYS_Rate=`expr 100- $SYS_USAGE  |bc -l`  
20.
21.Disp_SYS_Rate=`expr  "scale=3; $SYS_Rate/1"  |bc`  
22.echo  $Disp_SYS_Rate %  
23.
24.  
###perl 代码
1.#!/usr/bin/perl  
2.
3.use warnings;  
4.
5.$SLEEPTIME =5;  
6.
7.if  (-e  "/tmp/stat" ) {  
8.unlink  "/tmp/stat" ;  
9.}  
10.open (JIFF_TMP,  ">>/tmp/stat" ) || die  "Can't open /proc/stat file!/n" ;  
11.open (JIFF,  "/proc/stat" ) || die  "Can't open /proc/stat file!/n" ;  
12.@jiff_0 =<JIFF>;  
13.print JIFF_TMP  $jiff_0 [0] ;  
14.close (JIFF);  
15.
16.sleep  $SLEEPTIME ;  
17.
18.open (JIFF,  "/proc/stat" ) || die  "Can't open /proc/stat file!/n" ;  
19.@jiff_1 =<JIFF>;  
20.print JIFF_TMP  $jiff_1 [0];  
21.close (JIFF);  
22.close (JIFF_TMP);  
23.
24.@USER =`awk  '{print /$2}'   "/tmp/stat" `;  
25.@NICE =`awk  '{print /$3}'   "/tmp/stat" `;  
26.@SYSTEM =`awk  '{print /$4}'   "/tmp/stat" `;  
27.@IDLE =`awk  '{print /$5}'   "/tmp/stat" `;  
28.@IOWAIT =`awk  '{print /$6}'   "/tmp/stat" `;  
29.@IRQ =`awk  '{print /$7}'   "/tmp/stat" `;  
30.@SOFTIRQ =`awk  '{print /$8}'   "/tmp/stat" `;  
31.
32.$JIFF_0 = $USER [0]+ $NICE [0]+ $SYSTEM [0]+ $IDLE [0]+ $I
对于数量于质量来讲,就像打篮球,如果数量不够,那么质量肯定不行,
但在追求数量的同时,不要太偏向数量,举例:投了1000个球,但一个球没有进,这样反而会影响了后期的质量。
也就是说在质量面前,数量是一定要有的,这是前提,如果数量不够,投出来的质量可能并不是特别好或不稳定。
也就是数量和质量是相互关系的,

但是它们又是分开的,如果没有数量的积累,那么就和质量就无关了。
但是它们又是统一的,如果在数量的同时,也追求了进球的成功概率,那么离成功就不选 了。
数量是前提,在数量的基础上进行不段调整修正,投球的角度和抛物线,提高进球稳定性,那么质量就在这个过程中给加强 了。
但数量是必须的,如果没有一定的数量积累,那么对于基本功是没法练成的,比如手臂力的练成及方向稳定性的修正正是在数量下进行累计的,手脑并用,数量是必须的,是研究任何事物的起码,通俗点说是通过多做题目,多投篮,在做的过程中领悟,在数量 里练习并悟道,正是快速认识事物研究学习的一般规律。---jackX
git clone https://github.com/dufferzafar/netuse /usr/local/netuse
cd /usr/local/netuse
cp config.py.example config.py
ln -s netuse.py /usr/bin/netuse

Crontab:



vi /usr/bin/netuse
#!/usr/bin/python3  
不存在python3怎么办?
ln -s /usr/bin/python /usr/bin/python3


vi /usr/local/netuse/dumper 把网卡修改成自己的网卡eth1:
# which registers itself as a ppp device.
echo $(cat /sys/class/net/ppp0/statistics/rx_bytes)";"$(date +%s) >> ~/.net/$year/$month/down/$date                                                          
echo $(cat /sys/class/net/ppp0/statistics/tx_bytes)";"$(date +%s) >> ~/.net/$year/$month/up/$date
修改为:

修改为:eth1


标准统计(主要看看vps一天多少流量):
[root@iZ25z0ugwgtZ netuse]# netuse
Downloaded:        5 MB
Uploaded:          0 MB

Data Left:      10235 MB
Days Left:         3 Days
End Date:       2016-06-29 (11:59 PM)

Suggested:      3411 MB (Per Day)

一周一瞥(好像有点问题):
[root@iZ25z0ugwgtZ netuse]# netuse -w
Data downloaded this week:

Traceback (most recent call last):
  File "/bin/netuse", line 277, in <module>
    weekly()
  File "/bin/netuse", line 186, in weekly
    format="{:>5.0f}",
  File "/usr/local/netuse/termgraph.py", line 56, in chart
    print_blocks(labels[i], data[i], step, args)
  File "/usr/local/netuse/termgraph.py", line 63, in print_blocks
    blocks = int(count / step)
ZeroDivisionError: integer division or modulo by zero
背景:在windows下提交了一个git更新,想在linux下强制更新(这个linux下的文件也被我改动了),以windows下提交的为准怎么办?还会出错,如下:
Git pull 强制覆盖本地文件,与在git bash下实践OK,AddTime:2016-9-29

来自:http://blog.csdn.net/baple/article/details/49872765


一)出错:
新增文件add commit后,push回原分支失败,报错:
  Counting objects: 20, done.
  Delta compression using up to 24 threads.
  Compressing objects: 100% (11/11), done.
  Writing objects: 100% (11/11), 1.30 KiB, done.
  Total 11 (delta 5), reused 0 (delta 0)
  error: insufficient permission for adding an object to repository database ./objects


二)git本地有修改如何强制更新到远程:
本地有修改和提交,如何强制用远程的库更新更新。我尝试过用git pull -f,总是提示 You have not concluded your merge. (MERGE_HEAD exists)。
我需要放弃本地的修改,用远程的库的内容就可以,应该如何做?傻傻地办法就是用心的目录重新clone一个,正确的做法是什么?

正确的做法应该是:
git fetch --all
git reset --hard origin/master
git fetch 只是下载远程的库的内容,不做任何的合并git reset 把HEAD指向刚刚下载的最新的版本

参考链接:

http://stackoverflow.com/questions/1125968/force-git-to-overwrite-local-files-on-pull
背景:对chkconfig还没用熟悉又来了一个新的。
rpm -qf  /usr/bin/systemctl
systemd-219-19.el7_2.11.x86_64

yum remove systemd-219-19.el7_2.11  -y
错误:尝试移除受保护的 "systemd",为嘛不让卸载??



我们对service和chkconfig两个命令都不陌生,systemctl 是管制服务的主要工具, 它整合了chkconfig 与 service功能于一体。

systemctl is-enabled iptables.service
systemctl is-enabled servicename.service #查询服务是否开机启动
systemctl enable vsftpd.service #开机运行服务
systemctl disable vsftpd.service #取消开机运行
systemctl start vsftpd.service #启动服务
systemctl stop vsftpd.service #停止服务
systemctl restart vsftpd.service #重启服务
systemctl reload vsftpd.service #重新加载服务配置文件
systemctl status vsftpd.service #查询服务运行状态
systemctl --failed #显示启动失败的服务

注:*代表某个服务的名字,如http的服务名为httpd


例如在CentOS 7 上安装http

[root@CentOS7 ~]# yum -y install httpd
启动服务(等同于service httpd start)
systemctl start httpd.service
停止服务(等同于service httpd stop)
systemctl stop httpd.service
重启服务(等同于service httpd restart)
systemctl restart httpd.service
查看服务是否运行(等同于service httpd status)
systemctl status httpd.service
开机自启动服务(等同于chkconfig httpd on)
systemctl enable httpd.service
开机时禁用服务(等同于chkconfig httpd on)
systemctl disable httpd.service
查看服务是否开机启动 (等同于chkconfig --list)

来自:http://www.linuxidc.com/Linux/2014-11/109236.htm
分页: 12/246 第一页 上页 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 下页 最后页 [ 显示模式: 摘要 | 列表 ]