Unix/Linux命令行小技巧(2)- Linux上kill占用某端口的进程

Linux平台上kill占用某端口进程命令:

fuser -k port/tcp(udp)

举个例子:

[root@localhost redis-2.8.19]# ps -ef | grep redis
root     10049 35207  0 17:33 pts/7    00:00:00 ./src/redis-server *:6379
root     10116 35207  0 17:33 pts/7    00:00:00 grep redis             
[root@localhost redis-2.8.19]# fuser -k 6379/tcp
6379/tcp:            10049
[1]+  Killed                  ./src/redis-server

可以看到,占用6379端口的进程被杀死了。
技巧出处:https://twitter.com/nixcraft/status/162914646125330432

Unix/Linux命令行小技巧(1)- 显示运行进程的PID

Bash中定义如下函数(函数参数为程序名):

findpid() { ps axc|awk "{if (\$5==\"$1\") print \$1}"; }

执行效果:

[root@localhost ~]# findpid() { ps axc|awk "{if (\$5==\"$1\") print \$1}"; }
[root@localhost ~]# findpid tail
16049
25206
40701
48132

技巧出处:https://twitter.com/nixcraft/status/158835574508240896

在markdown文件标题输入“#”

由于markdown文件是以“#”作为标题符号的,所以如果标题内容本身包含“#”,就不能直接输出。举个例子,如果标题是“C#”,输入“#C#”的话,效果如下:

C

可以看到“#”没有输出。

解决方式有两种:
(1)利用HTML语法,用“#”表示“#”,即输入“#C#” ;
(2)利用“\”,输入“#C\#”(要注意在“\”和“#”后面有一个空格,否则输出效果为“C\”)。
效果如下:

C#

参考资料:
(1)How to output “#” in title in mardkown file?

在Linux上搭建D语言开发环境

本文介绍如何在Linux上搭建D语言的开发环境:

(1)编译器我选的是gdc,从官方网站下载适合机器的版本,直接解压缩就可以了(不要解压到系统root文件夹:”/“)。为了方便起见,可以把路径加到PATH环境变量:

export PATH=$PWD/x86_64-gdcproject-linux-gnu/bin:$PATH

接下来写个简单的“hello world”程序(hello.d):

import std.stdio;
void main()
{
    writeln("Hello World!");
}  

编译一下:

[root@localhost nan]# gdc hello.d -o hello
/usr/bin/ld: unrecognized option '-plugin'
/usr/bin/ld: use the --help option for usage information
collect2: error: ld returned 1 exit status

这个问题的解决办法是在编译时加上“-fno-use-linker-plugin”选项。再次编译:

[root@localhost nan]# gdc -fno-use-linker-plugin -g hello.d -o hello
[root@localhost nan]# 

成功!
运行一下:

[root@localhost nan]# ./hello
Hello World!

输出了“Hello World!”。

(2)使用gdb进行调试。
示例程序代码如下:

import std.stdio;

void main()
{
    int sum;
    int i;

    for (i = 1; i <= 10; i++)
    {
        sum += i;
    }

    writeln(sum);
}

编译时需要加上“-g”编译选项,产生调试信息:

gdc -fno-use-linker-plugin -g sum.d -o sum

开始调试:

[root@localhost nan]# gdb -q sum
Reading symbols from sum...done.
(gdb) start
Temporary breakpoint 1 at 0x4057bf: file sum.d, line 5.
Starting program: /home/nan/sum
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Temporary breakpoint 1, D main () at sum.d:5
5               int sum;
(gdb) n
6               int i;
(gdb)
8               for (i = 1; i <= 10; i++)
(gdb)
10                      sum += i;
(gdb)
8               for (i = 1; i <= 10; i++)
(gdb) p i
$1 = 1
(gdb) p sum
$2 = 1
(gdb) c
Continuing.
55
[Inferior 1 (process 41619) exited normally]

可以看到,和调试普通的C程序没什么区别。

参考资料:
(1)How to fix “unrecognized option ‘-plugin`” when using gdc to compile D program?
(2)GDC documentation and debugging problems

Redis从2.8.12版本开始支持“ROLE”命令

今天才知道,Redis2.8.12版本开始支持“ROLE”命令了。通过“ROLE”命令,可以得到当前Redis的角色是“master”,“slave”或者“sentinel”。回想我们一年前做Redis监控程序时,还要通过“info”命令得到整个Redis状态,然后再解析“Role”这个关键字,才能得到是什么角色,实在有点麻烦。如果有机会,应该升级一下监控程序,一旦发现是2.8.12版本,就直接用“ROLE”命令好了。

2014年终总结

2014年就要走完了,是时候总结一下了:
(1)chinadtrace:申请的第一个微信公众号,建立了第一个介绍DTrace的中文网站:http://chinadtrace.org/
(2)8月昆山之行:一场说走就走的旅行
(3)100个gdb小技巧:与hellogcc伙伴们合作的项目。历时半年,今天发布1.0版本。电子书下载地址
(4)公司被并购:将来适当的时候会详细写一下这段过程;
(5)拥有了属于自己的域名:https://nanxiao.me/
(6)为开源项目redisunixODBC贡献patch;
(7)十一之行:难忘的回家之旅
(8)在影院看了两部没白花钱的电影:《白日焰火》和《黄金时代》;
(9)阅读了几本还不错的书;
(10)享受到了4G网络。

100个gdb小技巧(v1.0).pdf

hellogcc于今年6月份开启《100个gdb小技巧》这个项目,我便参与其中。截至到这周末,一共收集了100个实用的gdb小技巧。我利用这个周末时间,把它制作成了一本pdf的电子书,方便大家下载和使用。当然,100不是终点,未来这个项目还会发展下去,还会有2.03.0的版本出来。Stay tuned!

P.S.:下载地址

unixODBC驱动链接的数据库客户端和程序直接链接的数据库客户端库一定要一致

这两天调试了一个诡异的问题,使用unixODBC连接MySQL数据库,最后程序core dumpMySQL client代码的fill_ird_data_lengths函数:

void fill_ird_data_lengths(DESC *ird, ulong *lengths, uint fields)
{
  ......
  assert(fields == ird->count);
}

fileds是一个很离谱的数,一看就像是内存值被破坏了。

经过艰苦的单步调试,最后查出的问题是unixODBC驱动链接的MySQL数据库客户端库和程序直接链接的MySQL数据库客户端库不一样(因为程序还没有完全改完,有一部分code还会直接调用MySQL数据库客户端库)。

这个坑一定要记住!

一键编译安装gcc

本文原载于我在hellogcc上的文章

今天看到一篇文章,作者通过一个shell脚本和一个Makefile,可以自动下载需要的所有安装包并且自动编译gcc

$ # Download the scripts using wget.
$ mkdir /opt/gcc-4.9.2
$ cd /opt/gcc-4.9.2
$ wget http://projects.joelinoff.com/gcc-4.9.2/bld.sh
$ wget http://projects.joelinoff.com/gcc-4.9.2/Makefile
$ chmod a+x bld.sh
$ make
[output snipped]
$ # The compiler is installed in /opt/gcc-4.9.2/rtf/bin

我试了一下,果然很方便。只要有一台可以联网的机器,就可以了。感兴趣的朋友可以试一试。

P.S.:
(1)编译libiconv时可能会有“'gets' undeclared here“错误,请参考这篇文章
(2)如果机器是64位的,但是缺少32位的库文件。这样在编译gcc时会出现错误:“configure: error: I suspect your system does not have 32-bit developement libraries (libc and headers). If you have them, rerun configure with --enable-multilib. If you do not have them, and want to build a 64-bit-only compiler, rerun configure with --disable-multilib.”。提示需要配置“--disable-multilib”。

ODBC中的三种变量类型

无论是使用ODBC的新手或老兵,看到SQLCHARSOL_C_CHARSQL_CHAR,可能都会有些糊涂。它们之间的区别到底是什么呢?

(1)第一种是ODBC定义的数据类型(像SQLCHAR):SQL开头,后面跟着一系列大写字符,但是没有下划线。这种数据类型定义在sqltypes.h中,比如:

typedef signed short int   SQLSMALLINT;
typedef SQLSMALLINT     SQLRETURN;

#if (ODBCVER >= 0x0300)
typedef void *                  SQLHANDLE; 
......
#endif

这种数据类型可以用来定义变量,ODBC API的变量类型都是这种类型:

#if (ODBCVER >= 0x0300)
    SQLRETURN  SQL_API SQLAllocHandle(SQLSMALLINT HandleType,
                                      SQLHANDLE InputHandle, SQLHANDLE *OutputHandle);
#endif

这样做的好处是ODBC提供了一套自己的变量类型,相当于封装了一层,使用者不用关心底层具体的变量类型实现细节。即使底层的变量类型做了修改,使用者的代码也不用做任何改动。
这种数据类型和C语言数据类型的映射如下:

ODBC 类型 C 类型
SQLCHAR char
SQLSCHAR signed char
SQLINTEGER long int

(2)第二种是C语言的数据类型编码(SQL_C_CHAR)。他们并不是真正的数据类型,而是针对上面提到的的ODBC定义的数据类型的编码,所以不能用来定义变量。他们可以用作ODBC API的参数。这种数据类型定义在sqlext.h中,比如:

#define SQL_C_CHAR    SQL_CHAR             /* CHAR, VARCHAR, DECIMAL, NUMERIC */
#define SQL_C_LONG    SQL_INTEGER          /* INTEGER                      */
#define SQL_C_SHORT   SQL_SMALLINT         /* SMALLINT                     */
#define SQL_C_FLOAT   SQL_REAL             /* REAL                         */
#define SQL_C_DOUBLE  SQL_DOUBLE           /* FLOAT, DOUBLE                */

这种数据类型和ODBC数据类型的映射如下:

整数编码 ODBC 类型
SQL_C_CHAR SQLCHAR
SQL_S_STINYINT SQLSCHAR
SQL_C_SLONG SQLINTEGER

(3)第三种是SQL数据类型编码。同第二种一样,他们也不是真正的数据类型,而是提供SQL数据类型和编程语言数据类型的关联,因为也是数字编码,所以也不能用来定义变量。他们可以用作ODBC API的参数。这种数据类型定义在sqlext.h中,比如:

#define SQL_C_CHAR    SQL_CHAR             /* CHAR, VARCHAR, DECIMAL, NUMERIC */
#define SQL_C_LONG    SQL_INTEGER          /* INTEGER                      */
#define SQL_C_SHORT   SQL_SMALLINT         /* SMALLINT                     */
#define SQL_C_FLOAT   SQL_REAL             /* REAL                         */
#define SQL_C_DOUBLE  SQL_DOUBLE           /* FLOAT, DOUBLE                */

这种数据类型和SQL数据类型的映射如下:

整数编码 SQL类型
SQL_CHAR Char(n)
SQL_VARCHAR Varchar(n)
SQL_SMALLINT Smallint