/*
* Blocked calculation 执行过程中, 信号 kill -INT xxx 被屏蔽, 所以程序没有反映
* 只有到信号被取消阻塞的时程序才会结束
* 信号屏蔽只是将信号加入到信号阻塞集合之中, 并没有丢弃, 一旦信号屏蔽取消, 信号就会发生作用
*/
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char **argv)
{
sigset_t intmask;
int i, repeat_factor = 10;
sigemptyset(&intmask);
sigaddset(&intmask, SIGINT); // 添加 block 或 unblock 的信号
// sigaddset(&intmask, SIGTERM);
while(1) {
sigprocmask(SIG_BLOCK, &intmask, NULL); // block
fprintf(stderr,"SIGINT signal blocked\n");
for(i = 0; i < repeat_factor; i++) {
sleep(1);
fprintf(stdout, "[%d] calculating...\n", i);
}
fprintf(stdout, "Blocked calculation is finished\n");
sigprocmask(SIG_UNBLOCK, &intmask, NULL); // unblock
fprintf(stdout, "SIGINT signal unblocked\n");
for(i = 0; i < repeat_factor; i++) {
sleep(1);
fprintf(stdout, "[%d] calculating...\n", i);
}
fprintf(stdout, "Unblocked calculation is finished\n");
}
exit(0);
}
2012年3月31日土曜日
2012年3月30日金曜日
[C 语言] 在循环中 fork 子进程
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
void CreateSubProcess(int num);
int main(int argc, char *argv[])
{
CreateSubProcess(5);
}
void CreateSubProcess(int num)
{
pid_t pid;
int i;
for(i = 0; i < num; i++) {
sleep(1);
pid = fork();
if(pid == 0 || pid == -1) // 子进程或错误时, 退出 for 循环继续执行下面的
break;
}
if(pid == -1) {
perror("fail to fork!\n");
exit(1);
} else if(pid == 0) {
printf("child pid = %d, parent pid = %d\n", getpid(), getppid());
} else {
printf("all child's parent pid = %d\n", getpid(), getpid());
}
exit(0);
}
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
void CreateSubProcess(int num);
int main(int argc, char *argv[])
{
CreateSubProcess(5);
}
void CreateSubProcess(int num)
{
pid_t pid;
int i;
for(i = 0; i < num; i++) {
sleep(1);
pid = fork();
if(pid == 0 || pid == -1) // 子进程或错误时, 退出 for 循环继续执行下面的
break;
}
if(pid == -1) {
perror("fail to fork!\n");
exit(1);
} else if(pid == 0) {
printf("child pid = %d, parent pid = %d\n", getpid(), getppid());
} else {
printf("all child's parent pid = %d\n", getpid(), getpid());
}
exit(0);
}
[C 语言] linux tcp socket 实例
1. 客户端
================================================================================
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#define BUFFSIZE 32
void Die(char *mess)
{
perror(mess);
exit(1);
}
int main(int argc, char *argv[])
{
int sock;
struct sockaddr_in echoserver;
char buffer[BUFFSIZE];
unsigned int echolen;
int received = 0;
if (argc != 4) {
fprintf(stderr, "USAGE: client <server_ip> <port> <word>\n");
exit(1);
}
/* Create the TCP socket */
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
Die("Failed to create socket");
}
/* Construct the server sockaddr_in structure */
memset(&echoserver, 0, sizeof(echoserver)); /* Clear struct */
echoserver.sin_family = AF_INET; /* Internet/IP */
echoserver.sin_addr.s_addr = inet_addr(argv[1]); /* IP address */
echoserver.sin_port = htons(atoi(argv[2])); /* server port */
/* Establish connection */
if (connect(sock,
(struct sockaddr *) &echoserver,
sizeof(echoserver)) < 0) {
Die("Failed to connect with server");
}
/* Send the word to the server */
echolen = strlen(argv[3]);
if (send(sock, argv[3], echolen, 0) != echolen) {
Die("Mismatch in number of sent bytes");
}
/* Receive the word back from the server */
fprintf(stdout, "Received: ");
while (received < echolen) {
int bytes = 0;
if ((bytes = recv(sock, buffer, BUFFSIZE-1, 0)) < 1) {
Die("Failed to receive bytes from server");
}
received += bytes;
buffer[bytes] = '\0'; /* Assure null terminated string */
fprintf(stdout, buffer);
}
fprintf(stdout, "\n");
close(sock);
exit(0);
}
================================================================================
2. 服务器
================================================================================
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#define MAXPENDING 1 /* Max connection requests */
#define BUFFSIZE 32
void Die(char *mess)
{
perror(mess);
exit(1);
}
void HandleClient(int sock)
{
char buffer[BUFFSIZE];
int received = -1;
/* Receive message */
if ((received = recv(sock, buffer, BUFFSIZE, 0)) < 0) {
Die("Failed to receive initial bytes from client");
}
/* Send bytes and check for more incoming data in loop */
while (received > 0) {
/* Send back received data */
if (send(sock, buffer, received, 0) != received) {
Die("Failed to send bytes to client");
}
/* Check for more data */
if ((received = recv(sock, buffer, BUFFSIZE, 0)) < 0) {
Die("Failed to receive additional bytes from client");
}
}
close(sock);
}
int main(int argc, char *argv[])
{
int serversock, clientsock, yes = 1;
struct sockaddr_in echoserver, echoclient;
if (argc != 2) {
fprintf(stderr, "USAGE: server <port>\n");
exit(1);
}
/* Create the TCP socket */
if ((serversock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
Die("Failed to create socket");
}
/* Construct the server sockaddr_in structure */
memset(&echoserver, 0, sizeof(echoserver)); /* Clear struct */
echoserver.sin_family = AF_INET; /* Internet/IP */
echoserver.sin_addr.s_addr = htonl(INADDR_ANY); /* Incoming addr */
echoserver.sin_port = htons(atoi(argv[1])); /* server port */
/* Set the reuse option to fix TIME_WAIT */
setsockopt(serversock,
SOL_SOCKET, SO_REUSEADDR, (const char *)&yes, sizeof(yes));
/* Bind the server socket */
if (bind(serversock, (struct sockaddr *) &echoserver,
sizeof(echoserver)) < 0) {
Die("Failed to bind the server socket");
}
/* Listen on the server socket */
if (listen(serversock, MAXPENDING) < 0) {
Die("Failed to listen on server socket");
}
/* Run until cancelled */
while (1) {
unsigned int clientlen = sizeof(echoclient);
/* Wait for client connection */
if ((clientsock = accept(serversock,
(struct sockaddr *) &echoclient,
&clientlen)) < 0) {
Die("Failed to accept client connection");
}
fprintf(stdout, "Client connected, ip: %s, port: %d\n",
inet_ntoa(echoclient.sin_addr), echoclient.sin_port);
HandleClient(clientsock);
}
}
================================================================================
================================================================================
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#define BUFFSIZE 32
void Die(char *mess)
{
perror(mess);
exit(1);
}
int main(int argc, char *argv[])
{
int sock;
struct sockaddr_in echoserver;
char buffer[BUFFSIZE];
unsigned int echolen;
int received = 0;
if (argc != 4) {
fprintf(stderr, "USAGE: client <server_ip> <port> <word>\n");
exit(1);
}
/* Create the TCP socket */
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
Die("Failed to create socket");
}
/* Construct the server sockaddr_in structure */
memset(&echoserver, 0, sizeof(echoserver)); /* Clear struct */
echoserver.sin_family = AF_INET; /* Internet/IP */
echoserver.sin_addr.s_addr = inet_addr(argv[1]); /* IP address */
echoserver.sin_port = htons(atoi(argv[2])); /* server port */
/* Establish connection */
if (connect(sock,
(struct sockaddr *) &echoserver,
sizeof(echoserver)) < 0) {
Die("Failed to connect with server");
}
/* Send the word to the server */
echolen = strlen(argv[3]);
if (send(sock, argv[3], echolen, 0) != echolen) {
Die("Mismatch in number of sent bytes");
}
/* Receive the word back from the server */
fprintf(stdout, "Received: ");
while (received < echolen) {
int bytes = 0;
if ((bytes = recv(sock, buffer, BUFFSIZE-1, 0)) < 1) {
Die("Failed to receive bytes from server");
}
received += bytes;
buffer[bytes] = '\0'; /* Assure null terminated string */
fprintf(stdout, buffer);
}
fprintf(stdout, "\n");
close(sock);
exit(0);
}
================================================================================
2. 服务器
================================================================================
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#define MAXPENDING 1 /* Max connection requests */
#define BUFFSIZE 32
void Die(char *mess)
{
perror(mess);
exit(1);
}
void HandleClient(int sock)
{
char buffer[BUFFSIZE];
int received = -1;
/* Receive message */
if ((received = recv(sock, buffer, BUFFSIZE, 0)) < 0) {
Die("Failed to receive initial bytes from client");
}
/* Send bytes and check for more incoming data in loop */
while (received > 0) {
/* Send back received data */
if (send(sock, buffer, received, 0) != received) {
Die("Failed to send bytes to client");
}
/* Check for more data */
if ((received = recv(sock, buffer, BUFFSIZE, 0)) < 0) {
Die("Failed to receive additional bytes from client");
}
}
close(sock);
}
int main(int argc, char *argv[])
{
int serversock, clientsock, yes = 1;
struct sockaddr_in echoserver, echoclient;
if (argc != 2) {
fprintf(stderr, "USAGE: server <port>\n");
exit(1);
}
/* Create the TCP socket */
if ((serversock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
Die("Failed to create socket");
}
/* Construct the server sockaddr_in structure */
memset(&echoserver, 0, sizeof(echoserver)); /* Clear struct */
echoserver.sin_family = AF_INET; /* Internet/IP */
echoserver.sin_addr.s_addr = htonl(INADDR_ANY); /* Incoming addr */
echoserver.sin_port = htons(atoi(argv[1])); /* server port */
/* Set the reuse option to fix TIME_WAIT */
setsockopt(serversock,
SOL_SOCKET, SO_REUSEADDR, (const char *)&yes, sizeof(yes));
/* Bind the server socket */
if (bind(serversock, (struct sockaddr *) &echoserver,
sizeof(echoserver)) < 0) {
Die("Failed to bind the server socket");
}
/* Listen on the server socket */
if (listen(serversock, MAXPENDING) < 0) {
Die("Failed to listen on server socket");
}
/* Run until cancelled */
while (1) {
unsigned int clientlen = sizeof(echoclient);
/* Wait for client connection */
if ((clientsock = accept(serversock,
(struct sockaddr *) &echoclient,
&clientlen)) < 0) {
Die("Failed to accept client connection");
}
fprintf(stdout, "Client connected, ip: %s, port: %d\n",
inet_ntoa(echoclient.sin_addr), echoclient.sin_port);
HandleClient(clientsock);
}
}
================================================================================
[C 语言] nslookup (gethostbyname)
/* Bare nslookup utility (w/ minimal error checking) */
#include <stdio.h> /* stderr, stdout */
#include <stdlib.h> /* exit() */
#include <unistd.h> /* close(), write() */
#include <netdb.h> /* hostent struct, gethostbyname() */
#include <arpa/inet.h> /* inet_ntoa() to format IP address */
#include <netinet/in.h> /* in_addr structure */
int
main(int argc, char **argv)
{
struct hostent *host; /* host information */
struct in_addr h_addr; /* Internet address */
if (argc != 2) {
fprintf(stderr, "USAGE: nslookup <inet_address>\n");
exit(1);
}
if ((host = gethostbyname(argv[1])) == NULL) {
fprintf(stderr, "(mini) nslookup failed on '%s'\n", argv[1]);
exit(1);
}
h_addr.s_addr = *((unsigned long *) host->h_addr_list[0]);
fprintf(stdout, "%s\n", inet_ntoa(h_addr));
exit(0);
}
#include <stdio.h> /* stderr, stdout */
#include <stdlib.h> /* exit() */
#include <unistd.h> /* close(), write() */
#include <netdb.h> /* hostent struct, gethostbyname() */
#include <arpa/inet.h> /* inet_ntoa() to format IP address */
#include <netinet/in.h> /* in_addr structure */
int
main(int argc, char **argv)
{
struct hostent *host; /* host information */
struct in_addr h_addr; /* Internet address */
if (argc != 2) {
fprintf(stderr, "USAGE: nslookup <inet_address>\n");
exit(1);
}
if ((host = gethostbyname(argv[1])) == NULL) {
fprintf(stderr, "(mini) nslookup failed on '%s'\n", argv[1]);
exit(1);
}
h_addr.s_addr = *((unsigned long *) host->h_addr_list[0]);
fprintf(stdout, "%s\n", inet_ntoa(h_addr));
exit(0);
}
2012年3月29日木曜日
[工具使用] gdb 调试后台进程
1. ps 查询子进程 PID
$ ps x | grep pgpool
26258 pts/1 S 0:00 /usr/local/pgpool312/bin/pgpool -n
26259 pts/1 S 0:00 pgpool: wait for connection request <= 找到子进程 PID
26262 pts/1 S 0:00 pgpool: PCP: wait for connection request
26263 pts/1 S 0:00 pgpool: worker process
26267 pts/1 S 0:00 gdb /usr/local/pgpool312/bin/pgpool 26259
28887 pts/2 R+ 0:00 grep pgpool
2. 启动 gdb, attach 子进程
$ gdb /usr/local/pgpool312/bin/pgpool 26259
或
$ gdb
$ gdb attach 26259
3. 显示 stack
$ gdb bt
4. 删除所有断点
$ gdb delete
5. 设置断点 (指定文件, 行号)
$ gdb b pool_process_query.c:243
6. 通过 pgpool 执行查询
$ psql -h localhost -p 9999 -c "select * from pgbench_accounts" -d postgres
7. 下一步
$ gdb n
8. 继续运行
$ gdb c
9. 显示变量内容
$ gdb p num_fds
$ gdb up
$ gdb down
$ ps x | grep pgpool
26258 pts/1 S 0:00 /usr/local/pgpool312/bin/pgpool -n
26259 pts/1 S 0:00 pgpool: wait for connection request <= 找到子进程 PID
26262 pts/1 S 0:00 pgpool: PCP: wait for connection request
26263 pts/1 S 0:00 pgpool: worker process
26267 pts/1 S 0:00 gdb /usr/local/pgpool312/bin/pgpool 26259
28887 pts/2 R+ 0:00 grep pgpool
2. 启动 gdb, attach 子进程
$ gdb /usr/local/pgpool312/bin/pgpool 26259
或
$ gdb
$ gdb attach 26259
3. 显示 stack
$ gdb bt
4. 删除所有断点
$ gdb delete
5. 设置断点 (指定文件, 行号)
$ gdb b pool_process_query.c:243
6. 通过 pgpool 执行查询
$ psql -h localhost -p 9999 -c "select * from pgbench_accounts" -d postgres
7. 下一步
$ gdb n
8. 继续运行
$ gdb c
9. 显示变量内容
$ gdb p num_fds
$ gdb up
$ gdb down
[C 语言] daemon 守护进程
daemon (守护) 程序编写规则:
1. 程序运行后调用 fork, 并让父进程退出, 子进程获得一个新的进程 ID, 但继承了父进程的进程组 ID
2. 调用 setsid 创建一个新的 session, 使自己成为新 session 和新进程组的 leader, 并使进程没有控制终端 (tty)
3. 改变当前工作目录至根目录, 以免影响可加载文件系统, 或者也可以改变到某些特定的目录
4. 设置文件创建 mask 为 0, 避免创建文件时权限的影响
5. 关闭不需要的打开文件描述符, 因为 daemon 程序在后台执行, 不需要于终端交互, 通常就关闭 STDIN, STDOUT 和 STDERR, 其它根据实际情况处理, 另一个问题是 daemon 程序不能和终端交互, 也就无法使用printf方法输出信息了, 可以使用 syslog 机制来实现信息的输出, 方便程序的调试
程序运行后使用 ps 命令查看
$ ps axj | grep a.out
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
1 10118 10118 10118 ? -1 Ss 505 0:00 ./a.out
例子:
================================================================================
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <syslog.h>
#include <signal.h>
int main(void)
{
if(daemon_init() == -1) {
printf("can't fork self/n");
exit(0);
}
openlog("daemontest", LOG_PID, LOG_USER);
syslog(LOG_INFO, "program started.");
signal(SIGTERM, sig_term); /* arrange to catch the signal */
while(1) {
sleep(1); /* put your main program here */
}
return(0);
}
int daemon_init(void)
{
pid_t pid;
if((pid = fork()) < 0)
return(-1);
else if(pid != 0)
exit(0); /* parent exit */
/* child continues */
setsid(); /* become session leader */
chdir("/"); /* change working directory */
umask(0); /* clear file mode creation mask */
close(0); /* close stdin */
close(1); /* close stdout */
close(2); /* close stderr */
return(0);
}
void sig_term(int signo)
{
if(signo == SIGTERM)
/* catched signal sent by kill(1) command */
{
syslog(LOG_INFO, "program terminated.");
closelog();
exit(0);
}
}
================================================================================
1. 程序运行后调用 fork, 并让父进程退出, 子进程获得一个新的进程 ID, 但继承了父进程的进程组 ID
2. 调用 setsid 创建一个新的 session, 使自己成为新 session 和新进程组的 leader, 并使进程没有控制终端 (tty)
3. 改变当前工作目录至根目录, 以免影响可加载文件系统, 或者也可以改变到某些特定的目录
4. 设置文件创建 mask 为 0, 避免创建文件时权限的影响
5. 关闭不需要的打开文件描述符, 因为 daemon 程序在后台执行, 不需要于终端交互, 通常就关闭 STDIN, STDOUT 和 STDERR, 其它根据实际情况处理, 另一个问题是 daemon 程序不能和终端交互, 也就无法使用printf方法输出信息了, 可以使用 syslog 机制来实现信息的输出, 方便程序的调试
程序运行后使用 ps 命令查看
$ ps axj | grep a.out
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
1 10118 10118 10118 ? -1 Ss 505 0:00 ./a.out
例子:
================================================================================
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <syslog.h>
#include <signal.h>
int main(void)
{
if(daemon_init() == -1) {
printf("can't fork self/n");
exit(0);
}
openlog("daemontest", LOG_PID, LOG_USER);
syslog(LOG_INFO, "program started.");
signal(SIGTERM, sig_term); /* arrange to catch the signal */
while(1) {
sleep(1); /* put your main program here */
}
return(0);
}
int daemon_init(void)
{
pid_t pid;
if((pid = fork()) < 0)
return(-1);
else if(pid != 0)
exit(0); /* parent exit */
/* child continues */
setsid(); /* become session leader */
chdir("/"); /* change working directory */
umask(0); /* clear file mode creation mask */
close(0); /* close stdin */
close(1); /* close stdout */
close(2); /* close stderr */
return(0);
}
void sig_term(int signo)
{
if(signo == SIGTERM)
/* catched signal sent by kill(1) command */
{
syslog(LOG_INFO, "program terminated.");
closelog();
exit(0);
}
}
================================================================================
[LINUX 基础] 显示部分行 (head tail sed)
1. 显示后 100 行
tail -n 100 filename
tail -n -100 filename
2. 显示从开头第 100 行开始的后面所有行
tail -n +100 filename
3. 显示开头 100 行
head -n 100 filename
head -n +100 filename
4. 从开头开始显示, 除去最后的 100 行
head -n 100 filename
5. 从第 3 行开始显示头 2 行
$ cat filename | tail -n +3 | head -n 2
6. 显示从第 2 行开始到第 3 行结束之间所有行
$ cat filename | head -n 3 | tail -n +2
$ sed -n '2,3p' filename
tail -n 100 filename
tail -n -100 filename
2. 显示从开头第 100 行开始的后面所有行
tail -n +100 filename
3. 显示开头 100 行
head -n 100 filename
head -n +100 filename
4. 从开头开始显示, 除去最后的 100 行
head -n 100 filename
5. 从第 3 行开始显示头 2 行
$ cat filename | tail -n +3 | head -n 2
6. 显示从第 2 行开始到第 3 行结束之间所有行
$ cat filename | head -n 3 | tail -n +2
$ sed -n '2,3p' filename
2012年3月28日水曜日
[LINUX 基础] diff 与 patch
diff
-r : ()递归, 将两个不同版本源代码目录中的所有对应文件进行比较, 包括子目录文件
-N : 确保补丁文件将正确地处理已经创建或删除文件的情况
-u : 统一格式创建补丁文件
patch
-p0: 针对于当前目录下的文件
-p1: 忽略掉 (补丁文件中的) 第一层目录, 从当前目录开始查找
-b : 备份要打补丁的原文件
-d : 当前工作目录设置为指定目录, 此时的 -p0 即代表此目录
-E : 如果发现了空文件, 那么就删除它
-R : 在补丁文件中的"新"文件和"旧"文件调换过来 (实际上就是给新版本打补丁, 让它变成老版本)
1. 单个文件打补丁
1-1. 制作 patch 文件 (形式: diff 旧版本 新版本)
$ diff –uN from-file to-file > to-file.patch
1-2. 给旧版本打补丁
$ patch -p0 -b < to-file.patch
1-3. 去除补丁, 恢复之前的旧版本
$ patch -p0 -RE < to-file.patch
2. 多文件
2-1. 制作 patch 文件
$ diff –uNr from-docu to-docu > to-docu.patch
2-2. 给旧版本打补丁
$ patch –p1 < to-docu.patch
2-3. 去除补丁, 恢复之前的旧版本
$ patch –R –p1
-r : ()递归, 将两个不同版本源代码目录中的所有对应文件进行比较, 包括子目录文件
-N : 确保补丁文件将正确地处理已经创建或删除文件的情况
-u : 统一格式创建补丁文件
patch
-p0: 针对于当前目录下的文件
-p1: 忽略掉 (补丁文件中的) 第一层目录, 从当前目录开始查找
-b : 备份要打补丁的原文件
-d : 当前工作目录设置为指定目录, 此时的 -p0 即代表此目录
-E : 如果发现了空文件, 那么就删除它
-R : 在补丁文件中的"新"文件和"旧"文件调换过来 (实际上就是给新版本打补丁, 让它变成老版本)
1. 单个文件打补丁
1-1. 制作 patch 文件 (形式: diff 旧版本 新版本)
$ diff –uN from-file to-file > to-file.patch
1-2. 给旧版本打补丁
$ patch -p0 -b < to-file.patch
1-3. 去除补丁, 恢复之前的旧版本
$ patch -p0 -RE < to-file.patch
2. 多文件
2-1. 制作 patch 文件
$ diff –uNr from-docu to-docu > to-docu.patch
2-2. 给旧版本打补丁
$ patch –p1 < to-docu.patch
2-3. 去除补丁, 恢复之前的旧版本
$ patch –R –p1
2012年3月26日月曜日
[项目管理] git 安装与使用
http://www.taocms.org/243.html
0-1. 分布式版本控制工具
0-2. 在一个不能连接网络的地方时, 仍然能够提交文件, 查看历史版本记录, 创建项目分支等
0-3. 仓库所在的目录就是你的日常工作目录, 没有服务器端和客户端之分
0-4. .git目录才是仓库, .git目录外的地方是你的工作目录
1. 安装 git 客户端
$ ./configure --prefix=/usr/local/git1794
$ make
$ sudo make install
2. [可选] 下载并安装 connect.c, 配置 ssh 通过 proxy
$ gcc connect -o connect
$ cat ~/.ssh/config
Host git.postgresql.org
ProxyCommand /home/go/bin/connect -S www.proxy.com %h %p
3. clone
3-1. 上传 /home/.ssh/id_rsa.pub 到 profile, 并且在相应 xxx 项目中登录帐号
http://www.postgresql.org/community/signup
3-2. clone 代码到本地
$ git clone ssh://git@git.postgresql.org/xxx.git
4. 设置 git 本地用户信息
4-1. /etc/gitconfig 文件: 系统中对所有用户都普遍适用的配置, 若使用 git config 时用 --system 选项, 读写的就是这个文件
4-2. ~/.gitconfig 文件: 用户目录下的配置文件只适用于该用户, 若使用 git config 时用 --global 选项, 读写的就是这个文件
4-3. 工作目录 (当前项目) 中的 .git/config 文件的: 仅仅针对当前项目有效
4-4. 每一个级别的配置都会覆盖上层的相同配置, .git/config 会覆盖 /etc/gitconfig 中的同名变量
$ rm -fv ~/.gitconfig
$ rm -fv ~/.git/config
$ cd ?/git/src
$ sh git_init.sh
$ git config --list ($ git var -l)
$ cat git_init.sh
#!/bin/bash
git config branch.master.rebase true
git config branch.autosetuprebase always
git config user.name "Go"
git config user.email go@gmail.com
git config --global user.name "Go"
git config --global user.email go@gmail.com
# git config --global http.proxy http://www.proxy.com:80
================================================================================
1. 新建项目
$ cd pjname
$ git init
2. 克隆项目镜像到本地
git clone git://github.com/schacon/grit.git
git clone git://github.com/schacon/grit.git mygrit <- 指定新名称
3. 检查当前文件状态
$ git status
4. 更新到本地
$ git pull
5. 提交更改到本地库
$ git commit -m 'comments'
6. 上传至服务器
$ git push
7. 删除文件
$ rm -fv test.txt
$ git rm test.txt
$ git rm log/\*.log <- 删除目录 log 下所有以 .log 结尾的文件
$ git rm \*~ <- 递归删除当前目录及其子目录中所有 ~ 结尾的文件
$ git commit
8. 添加文件
$ git add *.c *.java
$ git commit -m 'add comments'
9. 更新并覆盖本地文件
$ git checkout test.txt
10. 几个 git 地址
[socksify] 有代理服务器时使用 socks 来通信
$ [socksify] git clone git://git.postgresql.org/git/postgresql.git
$ [socksify] git clone git://git.postgresql.org/git/pgpool2.git
0-1. 分布式版本控制工具
0-2. 在一个不能连接网络的地方时, 仍然能够提交文件, 查看历史版本记录, 创建项目分支等
0-3. 仓库所在的目录就是你的日常工作目录, 没有服务器端和客户端之分
0-4. .git目录才是仓库, .git目录外的地方是你的工作目录
1. 安装 git 客户端
$ ./configure --prefix=/usr/local/git1794
$ make
$ sudo make install
2. [可选] 下载并安装 connect.c, 配置 ssh 通过 proxy
$ gcc connect -o connect
$ cat ~/.ssh/config
Host git.postgresql.org
ProxyCommand /home/go/bin/connect -S www.proxy.com %h %p
3. clone
3-1. 上传 /home/.ssh/id_rsa.pub 到 profile, 并且在相应 xxx 项目中登录帐号
http://www.postgresql.org/community/signup
3-2. clone 代码到本地
$ git clone ssh://git@git.postgresql.org/xxx.git
4. 设置 git 本地用户信息
4-1. /etc/gitconfig 文件: 系统中对所有用户都普遍适用的配置, 若使用 git config 时用 --system 选项, 读写的就是这个文件
4-2. ~/.gitconfig 文件: 用户目录下的配置文件只适用于该用户, 若使用 git config 时用 --global 选项, 读写的就是这个文件
4-3. 工作目录 (当前项目) 中的 .git/config 文件的: 仅仅针对当前项目有效
4-4. 每一个级别的配置都会覆盖上层的相同配置, .git/config 会覆盖 /etc/gitconfig 中的同名变量
$ rm -fv ~/.gitconfig
$ rm -fv ~/.git/config
$ cd ?/git/src
$ sh git_init.sh
$ git config --list ($ git var -l)
$ cat git_init.sh
#!/bin/bash
git config branch.master.rebase true
git config branch.autosetuprebase always
git config user.name "Go"
git config user.email go@gmail.com
git config --global user.name "Go"
git config --global user.email go@gmail.com
# git config --global http.proxy http://www.proxy.com:80
================================================================================
1. 新建项目
$ cd pjname
$ git init
2. 克隆项目镜像到本地
git clone git://github.com/schacon/grit.git
git clone git://github.com/schacon/grit.git mygrit <- 指定新名称
3. 检查当前文件状态
$ git status
4. 更新到本地
$ git pull
5. 提交更改到本地库
$ git commit -m 'comments'
6. 上传至服务器
$ git push
7. 删除文件
$ rm -fv test.txt
$ git rm test.txt
$ git rm log/\*.log <- 删除目录 log 下所有以 .log 结尾的文件
$ git rm \*~ <- 递归删除当前目录及其子目录中所有 ~ 结尾的文件
$ git commit
8. 添加文件
$ git add *.c *.java
$ git commit -m 'add comments'
9. 更新并覆盖本地文件
$ git checkout test.txt
10. 几个 git 地址
[socksify] 有代理服务器时使用 socks 来通信
$ [socksify] git clone git://git.postgresql.org/git/postgresql.git
$ [socksify] git clone git://git.postgresql.org/git/pgpool2.git
[Ruby] 日期函数
# utf-8
# ruby v1.9
require 'date'
YOUBI = ['Sun','Mon','Tues','Wed','Thur','Fri','Sat','Sun']
def usage(n)
puts "Usage: make_sche_month YYYY MM Name1 Name2"
exit n
end
if ARGV.size != 2 && ARGV.size != 4
usage 1
end
d = Date.new(ARGV[0].to_i, ARGV[1].to_i, 1)
if d == nil
usage 1
end
if ARGV[2] && ARGV[3]
PERSON = [ARGV[2], ARGV[3]]
else
PERSON = ['X','Y']
end
# print header
puts '|ym||xx:xx-xx:xx|xx:xx-xx:xx|comments|h'
month = d.month
token = 0
while true
break if month != d.month
if (d.cwday == 6)
puts "|#{d.mon}/#{d.day}|#{YOUBI[d.cwday]}|-|-||"
elsif (d.cwday == 7)
puts "|#{d.mon}/#{d.day}|#{YOUBI[d.cwday]}|-|-||"
# token = (token + 1) % 2
else
if (token == 0)
puts "|#{d.mon}/#{d.day}|#{YOUBI[d.cwday]}|#{PERSON[0]}|#{PERSON[1]}||"
else
puts "|#{d.mon}/#{d.day}|#{YOUBI[d.cwday]}|#{PERSON[1]}|#{PERSON[0]}||"
end
end
d = d.succ
end
# ruby v1.9
require 'date'
YOUBI = ['Sun','Mon','Tues','Wed','Thur','Fri','Sat','Sun']
def usage(n)
puts "Usage: make_sche_month YYYY MM Name1 Name2"
exit n
end
if ARGV.size != 2 && ARGV.size != 4
usage 1
end
d = Date.new(ARGV[0].to_i, ARGV[1].to_i, 1)
if d == nil
usage 1
end
if ARGV[2] && ARGV[3]
PERSON = [ARGV[2], ARGV[3]]
else
PERSON = ['X','Y']
end
# print header
puts '|ym||xx:xx-xx:xx|xx:xx-xx:xx|comments|h'
month = d.month
token = 0
while true
break if month != d.month
if (d.cwday == 6)
puts "|#{d.mon}/#{d.day}|#{YOUBI[d.cwday]}|-|-||"
elsif (d.cwday == 7)
puts "|#{d.mon}/#{d.day}|#{YOUBI[d.cwday]}|-|-||"
# token = (token + 1) % 2
else
if (token == 0)
puts "|#{d.mon}/#{d.day}|#{YOUBI[d.cwday]}|#{PERSON[0]}|#{PERSON[1]}||"
else
puts "|#{d.mon}/#{d.day}|#{YOUBI[d.cwday]}|#{PERSON[1]}|#{PERSON[0]}||"
end
end
d = d.succ
end
2012年3月25日日曜日
[JAVA] JDBC 数据库连接池
http://www.iteye.com/topic/96940
http://blog.sina.com.cn/s/blog_55d57a460100iq71.html
http://blog.csdn.net/mgoann/article/category/1086677
2012年3月22日木曜日
[JAVA] slf4j + log4j + log4jdbc
1. 下载并安装下列 jar 包
log4jdbc4-1.2.jar
log4j-1.2.16.jar
slf4j-api-1.6.4.jar
slf4j-log4j12-1.6.4.jar
相关数据库的 x.jdbc.jar
2. 配置文件及位置
2-1. 将 log4j.proerties 加入到 classpath 中
2-2. 若不在 classpath 中, 则使用 JVM 系统变量
-Dlog4j.configuration=file:/path/to/log4j.properties (Linux)
-Dlog4j.configuration=file:/C:/path/to/log4j.properties (Windows)
2-3. 或使用如下 java 代码加载
final static Logger logger = LoggerFactory.getLogger(JdbcSqlLogTest.class);
static {
PropertyConfigurator.configure("log4j.properties");
}
3. 使用
3-1. 编程方式
3-1-1. 修改代码中数据库驱动类名和连接字符串
// Class.forName("org.postgresql.Driver");
// Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:9120/go?user=go&password=go");
Class.forName("net.sf.log4jdbc.DriverSpy");
Connection conn = DriverManager.getConnection("jdbc:log4jdbc:postgresql://localhost:9120/go?user=go&password=go");
3-1-2. 包装正常的 Connection 数据库连接对象
Class.forName("org.postgresql.Driver");
Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:9120/go?user=go&password=go");
Connection connProxy = new net.sf.log4jdbc.ConnectionSpy(conn);
================================================================================
# log4j.proerties sample
#
# * DEBUG (lowest)
# * INFO
# * WARN (middle)
# * ERROR
# * FATAL (highest)
#
# * %p --The priority of the logging event (debug, warn)
# * %t --The name of the thread generating the event
# * %c --The category of the logging event
# * %m --message
# * %n --newline character
# * %d --date of the logging event ({yyyy-MM-dd HH:mm:ss,SSS})
# * %l --Outputs the source code location information
# * %C --Classname
# * %F --Filename
# * %L --Line number
# * %M --Methodname
# * %r --Number of milliseconds since the start of the vm
#
log4j.debug=false
log4j.rootLogger=ALL,stdout,mail
log4j.logger.logfile=ALL,logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Threshold=DEBUG
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss} %-5p [%F:%4L - %M] - %m%n
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.Threshold=DEBUG
log4j.appender.logfile.MaxFileSize=512KB
log4j.appender.logfile.MaxBackupIndex=10
log4j.appender.logfile.File=log/logdatei.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} %-5p [%c] - %m%n
log4j.appender.mail=org.apache.log4j.net.SMTPAppender
log4j.appender.mail.Threshold=OFF
log4j.appender.mail.BufferSize=32
log4j.appender.mail.SMTPHost=mail.gmx.net
log4j.appender.mail.SMTPUsername=qisbes@gmx.de
log4j.appender.mail.SMTPPassword=qis.bes
log4j.appender.mail.From=qisbes@gmx.de
log4j.appender.mail.to=ahrens@his.de
log4j.appender.mail.Subject=[DataImportExportTool] Error Alert
log4j.appender.mail.layout=org.apache.log4j.PatternLayout
log4j.appender.mail.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} [%t] %-5p %c %x - %m%n
######################################
# Log4JDBC - Database-Driver-Logging #
######################################
log4j.logger.jdbc.audit=INFO,jdbc
log4j.additivity.jdbc.audit=false
! Log only JDBC calls to ResultSet objects
log4j.logger.jdbc.resultset=INFO,jdbc
log4j.additivity.jdbc.resultset=true
! Log only the SQL that is executed.
log4j.logger.jdbc.sqlonly=DEBUG,sql
log4j.additivity.jdbc.sqlonly=true
! Log timing information about the SQL that is executed.
log4j.logger.jdbc.sqltiming=DEBUG,sqltiming
log4j.additivity.jdbc.sqltiming=true
! Log connection open/close events and connection number dump
log4j.logger.jdbc.connection=DEBUG,connection
log4j.additivity.jdbc.connection=true
! the appender used for the JDBC API layer call logging above, sql only
log4j.appender.sql=org.apache.log4j.FileAppender
log4j.appender.sql.File=log/sql.log
log4j.appender.sql.Append=false
log4j.appender.sql.layout=org.apache.log4j.PatternLayout
log4j.appender.sql.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} %m%n%n
! the appender used for the JDBC API layer call logging above, sql timing
log4j.appender.sqltiming=org.apache.log4j.FileAppender
log4j.appender.sqltiming.File=log/sqltiming.log
log4j.appender.sqltiming.Append=false
log4j.appender.sqltiming.layout=org.apache.log4j.PatternLayout
log4j.appender.sqltiming.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} %m%n
! the appender used for the JDBC API layer call logging above
log4j.appender.jdbc=org.apache.log4j.FileAppender
log4j.appender.jdbc.File=log/jdbc.log
log4j.appender.jdbc.Append=false
log4j.appender.jdbc.layout=org.apache.log4j.PatternLayout
log4j.appender.jdbc.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} %m%n
! the appender used for the JDBC Connection open and close events
log4j.appender.connection=org.apache.log4j.FileAppender
log4j.appender.connection.File=log/connection.log
log4j.appender.connection.Append=false
log4j.appender.connection.layout=org.apache.log4j.PatternLayout
log4j.appender.connection.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} %m%n
================================================================================
log4jdbc4-1.2.jar
log4j-1.2.16.jar
slf4j-api-1.6.4.jar
slf4j-log4j12-1.6.4.jar
相关数据库的 x.jdbc.jar
2. 配置文件及位置
2-1. 将 log4j.proerties 加入到 classpath 中
2-2. 若不在 classpath 中, 则使用 JVM 系统变量
-Dlog4j.configuration=file:/path/to/log4j.properties (Linux)
-Dlog4j.configuration=file:/C:/path/to/log4j.properties (Windows)
2-3. 或使用如下 java 代码加载
final static Logger logger = LoggerFactory.getLogger(JdbcSqlLogTest.class);
static {
PropertyConfigurator.configure("log4j.properties");
}
3. 使用
3-1. 编程方式
3-1-1. 修改代码中数据库驱动类名和连接字符串
// Class.forName("org.postgresql.Driver");
// Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:9120/go?user=go&password=go");
Class.forName("net.sf.log4jdbc.DriverSpy");
Connection conn = DriverManager.getConnection("jdbc:log4jdbc:postgresql://localhost:9120/go?user=go&password=go");
3-1-2. 包装正常的 Connection 数据库连接对象
Class.forName("org.postgresql.Driver");
Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:9120/go?user=go&password=go");
Connection connProxy = new net.sf.log4jdbc.ConnectionSpy(conn);
================================================================================
# log4j.proerties sample
#
# * DEBUG (lowest)
# * INFO
# * WARN (middle)
# * ERROR
# * FATAL (highest)
#
# * %p --The priority of the logging event (debug, warn)
# * %t --The name of the thread generating the event
# * %c --The category of the logging event
# * %m --message
# * %n --newline character
# * %d --date of the logging event ({yyyy-MM-dd HH:mm:ss,SSS})
# * %l --Outputs the source code location information
# * %C --Classname
# * %F --Filename
# * %L --Line number
# * %M --Methodname
# * %r --Number of milliseconds since the start of the vm
#
log4j.debug=false
log4j.rootLogger=ALL,stdout,mail
log4j.logger.logfile=ALL,logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Threshold=DEBUG
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss} %-5p [%F:%4L - %M] - %m%n
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.Threshold=DEBUG
log4j.appender.logfile.MaxFileSize=512KB
log4j.appender.logfile.MaxBackupIndex=10
log4j.appender.logfile.File=log/logdatei.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} %-5p [%c] - %m%n
log4j.appender.mail=org.apache.log4j.net.SMTPAppender
log4j.appender.mail.Threshold=OFF
log4j.appender.mail.BufferSize=32
log4j.appender.mail.SMTPHost=mail.gmx.net
log4j.appender.mail.SMTPUsername=qisbes@gmx.de
log4j.appender.mail.SMTPPassword=qis.bes
log4j.appender.mail.From=qisbes@gmx.de
log4j.appender.mail.to=ahrens@his.de
log4j.appender.mail.Subject=[DataImportExportTool] Error Alert
log4j.appender.mail.layout=org.apache.log4j.PatternLayout
log4j.appender.mail.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} [%t] %-5p %c %x - %m%n
######################################
# Log4JDBC - Database-Driver-Logging #
######################################
log4j.logger.jdbc.audit=INFO,jdbc
log4j.additivity.jdbc.audit=false
! Log only JDBC calls to ResultSet objects
log4j.logger.jdbc.resultset=INFO,jdbc
log4j.additivity.jdbc.resultset=true
! Log only the SQL that is executed.
log4j.logger.jdbc.sqlonly=DEBUG,sql
log4j.additivity.jdbc.sqlonly=true
! Log timing information about the SQL that is executed.
log4j.logger.jdbc.sqltiming=DEBUG,sqltiming
log4j.additivity.jdbc.sqltiming=true
! Log connection open/close events and connection number dump
log4j.logger.jdbc.connection=DEBUG,connection
log4j.additivity.jdbc.connection=true
! the appender used for the JDBC API layer call logging above, sql only
log4j.appender.sql=org.apache.log4j.FileAppender
log4j.appender.sql.File=log/sql.log
log4j.appender.sql.Append=false
log4j.appender.sql.layout=org.apache.log4j.PatternLayout
log4j.appender.sql.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} %m%n%n
! the appender used for the JDBC API layer call logging above, sql timing
log4j.appender.sqltiming=org.apache.log4j.FileAppender
log4j.appender.sqltiming.File=log/sqltiming.log
log4j.appender.sqltiming.Append=false
log4j.appender.sqltiming.layout=org.apache.log4j.PatternLayout
log4j.appender.sqltiming.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} %m%n
! the appender used for the JDBC API layer call logging above
log4j.appender.jdbc=org.apache.log4j.FileAppender
log4j.appender.jdbc.File=log/jdbc.log
log4j.appender.jdbc.Append=false
log4j.appender.jdbc.layout=org.apache.log4j.PatternLayout
log4j.appender.jdbc.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} %m%n
! the appender used for the JDBC Connection open and close events
log4j.appender.connection=org.apache.log4j.FileAppender
log4j.appender.connection.File=log/connection.log
log4j.appender.connection.Append=false
log4j.appender.connection.layout=org.apache.log4j.PatternLayout
log4j.appender.connection.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} %m%n
================================================================================
登録:
投稿 (Atom)