├── README.md ├── Web服务器 └── django.md ├── images ├── Linux_wiki.png ├── Network_Time_Protocol_servers_and_clients.png ├── autoreconf.jpg ├── openvpn.png └── tcp_state_machine.jpg ├── 安全 ├── iptables.md └── selinux.md ├── 性能调优 ├── iostat.md ├── lsof.md ├── mpstat.md ├── perf.md ├── sar.md ├── strace.md ├── top.md └── vmstat.md ├── 效率工具 ├── emacs.md ├── git.md ├── pssh_pdsh.md ├── screen.md ├── sublime.md ├── svn.md ├── tmux.md └── vim.md ├── 数据库 ├── mysql.md ├── nosql-compare.md └── redis.md ├── 服务 ├── Docker.md ├── MySQL.md ├── NTP.md ├── Nginx.md ├── apache.md ├── cron.md ├── dhcp.md ├── dns.md ├── kvm.md ├── openvpn.md ├── rsync.md ├── rsyslog.md └── ssh.md ├── 版本管理 ├── git.md └── svn.md ├── 系统 ├── awk.md ├── cut.md ├── grep.md ├── process.md ├── sed.md ├── sort.md ├── tar.md └── xargs.md ├── 编译 ├── autotools.md ├── gcc.md └── makefile.md └── 网络 ├── curl.md ├── dig.md ├── elinks.md ├── ifconfig.md ├── iftop.md ├── ip.md ├── nc.md ├── nmap.md ├── ping.md ├── route.md ├── ss.md ├── tcpdump.md └── wget.md /README.md: -------------------------------------------------------------------------------- 1 | ## 主页 2 | 3 | [http://linuxwiki.github.io/](http://linuxwiki.github.io/) 4 | 5 | ## 大纲 6 | 7 | ![linux wiki](images/Linux_wiki.png) 8 | 9 | -------------------------------------------------------------------------------- /Web服务器/django.md: -------------------------------------------------------------------------------- 1 | # Django 2 | 3 | uwsgi 配置模版: 4 | 5 | [uwsgi] 6 | procname-prefix = xxxxx # 进程前缀,方便 grep 区分 7 | chdir = /data/${proj_name} 8 | wsgi-file = ${proj_name}/wsgi.py 9 | socket = 127.0.0.1:${port} 10 | master = true 11 | workers = 2 12 | procname-master = uwsgi master 13 | procname = uwsgi worker 14 | vacuum = true 15 | daemonize2 = /data/log/uwsgi/${proj_name}.log 16 | pidfile = /var/run/${proj_name}.pid 17 | -------------------------------------------------------------------------------- /images/Linux_wiki.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linuxwiki/SourceWiki/f943f7bdcded1ee7dead75c7cd3b920565f62665/images/Linux_wiki.png -------------------------------------------------------------------------------- /images/Network_Time_Protocol_servers_and_clients.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linuxwiki/SourceWiki/f943f7bdcded1ee7dead75c7cd3b920565f62665/images/Network_Time_Protocol_servers_and_clients.png -------------------------------------------------------------------------------- /images/autoreconf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linuxwiki/SourceWiki/f943f7bdcded1ee7dead75c7cd3b920565f62665/images/autoreconf.jpg -------------------------------------------------------------------------------- /images/openvpn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linuxwiki/SourceWiki/f943f7bdcded1ee7dead75c7cd3b920565f62665/images/openvpn.png -------------------------------------------------------------------------------- /images/tcp_state_machine.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linuxwiki/SourceWiki/f943f7bdcded1ee7dead75c7cd3b920565f62665/images/tcp_state_machine.jpg -------------------------------------------------------------------------------- /安全/iptables.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /安全/selinux.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /性能调优/iostat.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /性能调优/lsof.md: -------------------------------------------------------------------------------- 1 | # lsof 2 | 3 | list open files 4 | 5 | 本文主要是介绍 `lsof` 相关使用方法,原文主要是 10 个例子的讲解,笔者翻译过程新增了一些实用案例,[英文原文地址](http://www.tecmint.com/10-lsof-command-examples-in-linux/) 。 6 | 7 | `lsof` 的意思是'列出打开的文件',用于找出哪些文件被哪些进程打开或是占用。我们都知道 Linux/UNIX 的理念就是一切皆文件(包括 pipes 管道、sockets、directories 目录、devices 设备等等)。使用 `lsof` 命令的原因之一就是,当一个磁盘不能被卸载时,借助 `lsof` 这个命令我们可以轻易的识别哪些文件正在被占用。 8 | 9 | ## 1、通过 `lsof` 命令列出所有打开的文件 10 | 11 | 在下面的例子中,它会以长列表的形式显示打开的文件,为了便于理解,它以 Command、PID、USER、FD、TYPE 分类 12 | 13 | ``` 14 | # lsof 15 | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME 16 | init 1 root cwd DIR 8,3 4096 2 / 17 | init 1 root rtd DIR 8,3 4096 2 / 18 | init 1 root txt REG 8,3 150352 527181 /sbin/init 19 | init 1 root mem REG 8,3 65928 654110 /lib64/libnss_files-2.12.so 20 | init 1 root 0u CHR 1,3 0t0 4021 /dev/null 21 | ``` 22 | 23 | 若不指定条件默认将显示所有进程打开的所有文件,`lsof` 输出各列信息的意义如下: 24 | 25 | - `COMMAND`:进程的名称 26 | - `PID`:进程标识符 27 | - `USER`:进程所有者 28 | - `FD`:文件描述符,应用程序通过文件描述符识别该文件。如 cwd、txt 等 29 | - `cwd` 表示应用程序的当前工作目录 30 | - `RTD` 根目录 31 | - `txt` txt类型文件是程序代码,应用程序二进制文件本身或共享库 32 | - `MEM` 内存映射文件 33 | - `u` 表示该文件被打开并处于读取/写入模式,而不是只读 ® 或只写 (w) 模式。 34 | - `W` 表示该应用程序具有对整个文件的写锁。该文件描述符用于确保每次只能打开一个应用程序实例。 35 | - `R` 读访问 36 | - 初始打开每个应用程序时,都具有三个文件描述符,从 0 到 2,分别表示标准输入、输出和错误流。所以大多数应用程序所打开的文件的 FD 都是从3开始。 37 | - `TYPE`:文件类型,如 DIR、REG 等 38 | - `DIR` 目录 39 | - `REG` 基本文件 40 | - `CHR` 字符特殊文件 41 | - `FIFO` 先进先出 42 | - `UNIX` unix 域套接字 43 | - `DEVICE`:指定磁盘的名称 44 | - `SIZE`:文件的大小 45 | - `NODE`:索引节点(文件在磁盘上的标识) 46 | - `NAME`:打开文件的确切名称 47 | 48 | ## 2、列出特定用户打开的文件 49 | 50 | 使用 `-u` 选项后接用户指定某个用户打开文件 51 | 52 | ``` 53 | # lsof -u apache 54 | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME 55 | httpd 6032 apache cwd DIR 8,3 4096 2 / 56 | httpd 6032 apache rtd DIR 8,3 4096 2 / 57 | httpd 6032 apache txt REG 8,3 354688 1605148 /usr/sbin/httpd 58 | httpd 6032 apache mem REG 8,3 65928 654110 /lib64/libnss_files-2.12.so 59 | ``` 60 | 61 | ## 3、查找特定端口运行的进程 62 | 63 | 使用 `-i` 选项来查找正在运行特定端口的进程 64 | 65 | ``` 66 | # lsof -i TCP:53 67 | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME 68 | named 16885 named 20u IPv4 61664 0t0 TCP localhost:domain (LISTEN) 69 | # lsof -i UDP:53 70 | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME 71 | named 16885 named 512u IPv4 61663 0t0 UDP localhost:domain 72 | # lsof -i:53 73 | named 16885 named 20u IPv4 61664 0t0 TCP localhost:domain (LISTEN) 74 | named 16885 named 512u IPv4 61663 0t0 UDP localhost:domain 75 | ``` 76 | 77 | ## 4、列出 ipv4 和 ipv6 的文件 78 | 79 | ``` 80 | # lsof -i 4 81 | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME 82 | sshd 1239 root 3u IPv4 10081 0t0 TCP *:ssh (LISTEN) 83 | # lsof -i 6 84 | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME 85 | sshd 1239 root 4u IPv6 10083 0t0 TCP *:ssh (LISTEN) 86 | ``` 87 | 88 | ## 5、列出 TCP 端口范围 1-1024 端口 89 | 90 | 列出打开 1-1024 端口所有正在运行的程序 91 | 92 | ``` 93 | # lsof -i TCP:1-1024 94 | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME 95 | sshd 1239 root 3u IPv4 10081 0t0 TCP *:ssh (LISTEN) 96 | sshd 1239 root 4u IPv6 10083 0t0 TCP *:ssh (LISTEN) 97 | httpd 2142 root 4u IPv6 13337 0t0 TCP *:http (LISTEN) 98 | ``` 99 | 100 | ## 6、通过脱字符排除某个用户 101 | 102 | ``` 103 | # lsof -u^root 104 | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME 105 | dbus-daem 1212 dbus cwd DIR 8,3 4096 2 / 106 | dbus-daem 1212 dbus rtd DIR 8,3 4096 2 / 107 | ``` 108 | 109 | ## 7、查找特定用户使用文件和命令 110 | 111 | ``` 112 | # lsof -i -u apache 113 | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME 114 | httpd 6032 apache txt REG 8,3 354688 1605148 /usr/sbin/httpd 115 | httpd 6032 apache mem REG 8,3 9488 271645 /usr/lib64/apr-util-1/apr_ldap-1.so 116 | ``` 117 | 118 | ## 8、列出所有网络连接 119 | 120 | ``` 121 | # lsof -i 122 | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME 123 | sshd 1239 root 3u IPv4 10081 0t0 TCP *:ssh (LISTEN) 124 | sshd 1239 root 4u IPv6 10083 0t0 TCP *:ssh (LISTEN) 125 | ``` 126 | 127 | ## 9、采用 pid 搜索 128 | 129 | ``` 130 | # lsof -p 1 131 | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME 132 | init 1 root cwd DIR 8,3 4096 2 / 133 | init 1 root rtd DIR 8,3 4096 2 / 134 | init 1 root txt REG 8,3 150352 527181 /sbin/init 135 | ``` 136 | 137 | ## 10、杀死某个特定用户的所有活动 138 | 139 | ``` 140 | # kill -9 `lsof -t -u named` 141 | ``` 142 | 143 | ### 补充: 144 | 145 | 查看谁在使用文件系统,在卸载文件系统时,如果某个文件系统中有任何打开文件,操作一般会失败 146 | 147 | ``` 148 | # lsof /mnt/ 149 | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME 150 | bash 16672 root cwd DIR 11,0 8192 1856 /mnt 151 | lsof 17041 root cwd DIR 11,0 8192 1856 /mnt 152 | lsof 17042 root cwd DIR 11,0 8192 1856 /mnt 153 | ``` 154 | 155 | 查看被删除的文件 156 | 157 | ``` 158 | # lsof | grep deleted --color 159 | console-k 1291 root txt REG 8,3 155008 1577669 /usr/sbin/console-kit-daemon.#prelink#.bXthE2 (deleted) 160 | tail 17553 root 3r REG 8,3 6 523317 /tmp/test2 (deleted) 161 | ``` 162 | 163 | ## 应用实例 164 | 165 | 以下两个实例分别引用其它博主的实例,笔者也在实际过程中遇到过,作用很大,所以引用过来 166 | 167 | ### 实例1 恢复删除的文件 168 | 169 | - 实例引用 [turbolinux](http://www.turbolinux.com.cn/turbo/wiki/doku.php?id=%E6%94%B6%E9%9B%86%E7%B3%BB%E7%BB%9F%E4%BF%A1%E6%81%AF:lsof) 170 | 171 | 当 Linux 计算机受到入侵时,常见的情况是日志文件被删除,以掩盖攻击者的踪迹。管理错误也可能导致意外删除重要的文件,比如在清理旧日志时,意外地删除了数据库的活动事务日志。有时可以通过 `lsof` 来恢复这些文件。 172 | 173 | 当进程打开了某个文件时,只要该进程保持打开该文件,即使将其删除,它依然存在于磁盘中。这意味着,进程并不知道文件已经被删除,它仍然可以向打开该文件时提供给它的文件描述符进行读取和写入。除了该进程之外,这个文件是不可见的,因为已经删除了其相应的目录索引节点。 174 | 175 | 在 /proc 目录下,其中包含了反映内核和进程树的各种文件。/proc 目录挂载的是在内存中所映射的一块区域,所以这些文件和目录并不存在于磁盘中,因此当我们对这些文件进行读取和写入时,实际上是在从内存中获取相关信息。大多数与 `lsof` 相关的信息都存储于以进程的 PID 命名的目录中,即 /proc/1234 中包含的是PID为1234 的进程的信息。每个进程目录中存在着各种文件,它们可以使得应用程序简单地了解进程的内存空间、文件描述符列表、指向磁盘上的文件的符号链接和其他系统信息。lsof 程序使用该信息和其他关于内核内部状态的信息来产生其输出。所以lsof 可以显示进程的文件描述符和相关的文件名等信息。也就是我们通过访问进程的文件描述符可以找到该文件的相关信息。 176 | 177 | 当系统中的某个文件被意外地删除了,只要这个时候系统中还有进程正在访问该文件,那么我们就可以通过 `lsof` 从 /proc 目录下恢复该文件的内容。 假如由于误操作将 `/var/log/messages` 文件删除掉了,那么这时要将 `/var/log/messages` 文件恢复的方法如下: 178 | 179 | 首先使用lsof来查看当前是否有进程打开 `/var/logmessages` 文件,如下: 180 | 181 | ``` 182 | # lsof |grep /var/log/messages 183 | syslogd 1283 root 2w REG 3,3 5381017 1773647 /var/log/messages (deleted) 184 | ``` 185 | 186 | 从上面的信息可以看到 PID 1283(syslogd)打开文件的文件描述符为 2。同时还可以看到 `/var/log/messages` 已经标记被删除了。因此我们可以在 /proc/1283/fd/2 (fd 下的每个以数字命名的文件表示进程对应的文件描述符)中查看相应的信息,如下: 187 | 188 | ``` 189 | # head -n 10 /proc/1283/fd/2 190 | Aug 4 13:50:15 holmes86 syslogd 1.4.1: restart. 191 | Aug 4 13:50:15 holmes86 kernel: klogd 1.4.1, log source = /proc/kmsg started. 192 | Aug 4 13:50:15 holmes86 kernel: Linux version 2.6.22.1-8 (root@everestbuilder.linux-ren.org) (gcc version 4.2.0) #1 SMP Wed Jul 18 11:18:32 EDT 2007 193 | Aug 4 13:50:15 holmes86 kernel: BIOS-provided physical RAM map: 194 | Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 0000000000000000 - 000000000009f000 (usable) 195 | Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 000000000009f000 - 00000000000a0000 (reserved) 196 | Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 0000000000100000 - 000000001f7d3800 (usable) 197 | Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 000000001f7d3800 - 0000000020000000 (reserved) 198 | Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 00000000e0000000 - 00000000f0007000 (reserved) 199 | Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 00000000f0008000 - 00000000f000c000 (reserved) 200 | ``` 201 | 202 | 从上面的信息可以看出,查看 /proc/1283/fd/2 就可以得到所要恢复的数据。如果可以通过文件描述符查看相应的数据,那么就可以使用 I/O 重定向将其复制到文件中,如: 203 | 204 | ``` 205 | cat /proc/1283/fd/2 > /var/log/messages 206 | ``` 207 | 208 | 对于许多应用程序,尤其是日志文件和数据库,这种恢复删除文件的方法非常有用。 209 | 210 | ### 应用实例2 磁盘剩余空间和 `du` 显示相差太大 211 | 212 | - 实例引用:[orz DBA](http://chenxu.yo2.cn/articles/lsof.html) 213 | 214 | 今天一同事说文件系统 /tmp 目录下空间用满了,当时 `du` 统计目录所有文件的时候却很小。听到这个现象,第一感觉就是应该有大文件被删除,但是这个文件可能依然被其他程序打开,导致这个文件不能被清除。登上服务器使用 `lsof` 看了一下,果然如此,具体排查过程如下: 215 | 216 | ``` 217 | $ df -h 218 | Filesystem Size Used Avail Use% Mounted on 219 | /dev/sda5 8.7G 7.9G 407M 96% /tmp 220 | $ sudo lsof | grep /tmp | sort -k7 -nr #注:其实直接lsof | grep deleted 即可 221 | sleep 18833 peien.htg 1w REG 8,5 8321143673 54 /tmp/netstat.log (deleted) 222 | netstat_2 13571 peien.htg 1w REG 8,5 8321143673 54 /tmp/netstat.log (deleted) 223 | ``` 224 | 225 | 上面 `lsof` 输出结果的第二列是 PID,倒数第三列是占用空间大小 226 | 227 | 可以看到文件 /tmp/netstat.log (deleted) 占用7个多G的空间,虽然被删除了,但是还是有进程打开它。 228 | 229 | 然后,用 PID 看看是哪个程序占用这个文件: 230 | 231 | ``` 232 | $ ps -ef | grep 13571 233 | 51717 13571 1 0 2011 ? 00:15:00 /bin/bash /tmp/netstat_20110829.sh 234 | 51717 21456 13571 0 09:40 ? 00:00:00 sleep 10 235 | zhuxu 21458 17014 0 09:40 pts/0 00:00:00 grep 13571 236 | ``` 237 | 238 | 将这个进程 KILL 掉后,就 OK 了: 239 | 240 | ``` 241 | $ sudo kill -9 13571 242 | $ df -h 243 | Filesystem Size Used Avail Use% Mounted on 244 | /dev/sda5 8.7G 56M 8.2G 1% /tmp 245 | ``` 246 | -------------------------------------------------------------------------------- /性能调优/mpstat.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /性能调优/perf.md: -------------------------------------------------------------------------------- 1 | 2 | # 1. 什么是 Perf # 3 | 4 | Perf is a profiler tool for Linux 2.6+ based systems that abstracts away CPU 5 | hardware differences in Linux performance measurements and presents a simple 6 | commandline interface. Perf is based on the perf_events interface exported by 7 | recent versions of the Linux kernel. 8 | 9 | The perf tool offers a rich set of commands to collect and analyze performance 10 | and trace data. 11 | 12 | usage: perf [--version] [--help] COMMAND [ARGS] 13 | 14 | The most commonly used perf commands are: 15 | annotate Read perf.data (created by perf record) and display annotated code 16 | archive Create archive with object files with build-ids found in perf.data file 17 | bench General framework for benchmark suites 18 | buildid-cache Manage build-id cache. 19 | buildid-list List the buildids in a perf.data file 20 | diff Read two perf.data files and display the differential profile 21 | evlist List the event names in a perf.data file 22 | inject Filter to augment the events stream with additional information 23 | kmem Tool to trace/measure kernel memory(slab) properties 24 | kvm Tool to trace/measure kvm guest os 25 | list List all symbolic event types 26 | lock Analyze lock events 27 | record Run a command and record its profile into perf.data 28 | report Read perf.data (created by perf record) and display the profile 29 | sched Tool to trace/measure scheduler properties (latencies) 30 | script Read perf.data (created by perf record) and display trace output 31 | stat Run a command and gather performance counter statistics 32 | test Runs sanity tests. 33 | timechart Tool to visualize total system behavior during a workload 34 | top System profiling tool. 35 | trace strace inspired tool 36 | probe Define new dynamic tracepoints 37 | 38 | See 'perf help COMMAND' for more information on a specific command. 39 | 40 | 41 | # 2. Perf 的功能 # 42 | 43 | + 评估程序对硬件资源的使用情况: 各级 Cache 访问次数、各级 Cache 丢失次数、流水线 44 | 停顿周期、前端总线访问次数 … … 45 | + 评估程序对操作系统资源的使用情况: 系统调用次数、Page Fault 次数、上下文切换次 46 | 数、任务迁移次数 … … 47 | + 评估内核性能: Benchmarks、调度器性能分析、系统行为记录与重演动态添加探测点 … … 48 | 49 | 50 | 51 | ## 2.1 Perf list ## 52 | 53 | 54 | 功能: 查看当前软硬件环境、支持的性能事件。 55 | 56 | 查看所有分类事件的个数: `perf list | awk -F: '/Tracepoint event/ { lib[$1]++ } END { for (l in lib) { printf " %-16s %d\n", l, lib[l] } }' | sort | column` 57 | 58 | These include: 59 | 60 | + block: block device I/O 61 | + ext3, ext4: file system operations 62 | + kmem: kernel memory allocation events 63 | + random: kernel random number generator events 64 | + sched: CPU scheduler events 65 | + syscalls: system call enter and exits 66 | + task: task events 67 | 68 | 69 | 性能事件分三类: 70 | 71 | 1. 硬件性能事件 72 | 2. 软件性能事件 73 | 3. tracepoint event 74 | 75 | 76 | ## 2.2 Perf stat ## 77 | 78 | 功能: 分析程序的整体性能. 79 | 80 | 示例: 81 | 82 | 1. `perf stat -e task-clock ./a.out` # 分析 task-clock 事件 83 | 2. `perf stat -p 31317` # 分析 31317 进程 84 | 3. `perf stat -t 31318` # 分析 31318 线程 85 | 4. `perf stat -r 5 ./a.out` # 分析 5 次就停止 86 | 5. `perf stat -d ./a.out` # 全面分析 87 | 88 | ## 2.3 Perf top ## 89 | 90 | 功能: 实时显示系统/进程的性能统计信息。 91 | 92 | 使用方法: `perf top ` 分析界面之后 `?` 可以查看快捷键。有用的是 `a`, 93 | 即: "annotate current symbol", 可以看到具体的指令。 94 | 95 | 示例: 96 | 97 | 1. `perf top -a -p 31317` # 分析整个 31317 进程的性能 98 | 2. `perf top -n -p 31317` # 显示事件数量 99 | 3. `perf top --show-total-period -p 31317` # 累计事件个数 100 | 4. `perf top -G` 101 | 102 | top 界面解释: 103 | 104 | + 第一列: 性能事件在整个检测域中占的比例,符号的 热度 105 | + 第二列: 符号所在 DSO(Dynamic Shared Object) 106 | + 第三列: DSO 类型(ELF可执行文件,动态链接库,内核,内核模块,VDSO 等) 107 | + 第四列: 符号名(函数名) 108 | 109 | 110 | ## 2.4 Perf record/report ## 111 | 112 | 功能: 113 | 114 | 1. record: 记录一段时间内系统/进程的性能事件,生成 perf.data 文件 115 | 2. report: 读取 perf.data 文件,并显示分析数据 116 | 117 | 使用: `perf record [] []` 118 | 119 | 示例: 120 | 121 | perf record -g -p 31655 # 记录一段时间的 zone_server 性能事件 122 | perf report # 得到分析结果 123 | perf report -n # 显示对应时间的调用次数 124 | perf report -v # 显示每个符号的地址 125 | perf report -g flat,5% # 126 | perf report -g graph,5% # 127 | perf report -g fractal,5% # 128 | 129 | 130 | ## 2.5 Perf timechart ## 131 | 132 | 功能: 将系统的运行状态以 SVG 图的形式输出。 133 | 134 | 1. 各处理器状态(run, idle) 135 | 2. 各进程的时间图谱(run, sleep, blocked ...) 136 | 137 | 示例: 138 | 139 | perf timechart record -p 31655 140 | 141 | ## 2.6 Perf script ## 142 | 143 | 功能: 查看 perf 数据文件 (perf.data) 144 | 145 | 示例: 146 | 147 | + `perf script -l` # 查看当前系统中可扩展脚本 148 | + `perf script syscall-count` # 查看系统调用被调度次数 149 | + `perf script sctop` # 实时查看各个系统调用被调用的次数 150 | 151 | ## 2.7 Perf kmem ## 152 | 153 | 功能: 针对内存子系统的分析工具。也可以用 `perf record -e kmem:* -p 630` 来统计内存分配、释放。 154 | 155 | ## 2.8 内核 tracepoint ## 156 | 157 | 暂无. 158 | 159 | # 3. 一些术语 ## 160 | 161 | **PMU** -- Performance Monitoring Unit,性能检测单元。 162 | 163 | **Tracepoints** -- Tracepoint 是散落在内核源代码中的一些 hook,一旦使用,它们便可以在 164 | 特定的代码被运行到时被触发,这一特性可以被各种 trace/debug 工具所使用。 165 | 166 | **page-fault** -- Linux的内存管理子系统采用了分页机制。当应用程序请求的页面尚未建立、 167 | 请求的页面不在内存中、请求的页面虽然在内存中,但尚未建立物理地址与虚拟 地址的映 168 | 射关系时,都会触发一次缺页异常(page-fault)。 169 | 170 | **task-clock** -- 应用程序真正占用处理器的时间,单位是毫秒。任务执行时间。Linux是多任 171 | 务分时操作系统中,一个任务不太可能在执行期间始终占据处理器。操作系统会根据调度策 172 | 略合理安排各个任务轮流使用处理器,每次调度会产生一次上下文切换。 173 | 174 | **cycle** -- 程序消耗的处理器周期数。 175 | 176 | **instructions** -- 程序执行期间产生的处理器指令数。 177 | 178 | **branches** -- 程序在执行期间遇到的分支指令数。绝大多数现在处理器都具有分支预测与OOO 179 | (Out-of-Order)执行机制,以充分利用 CPU 内部的资源,减少流水线停顿周期。当处理器遇 180 | 到分支指令时,正常来说,需要等待分支条件计算完毕才能知道后续指令该往何处跳转。这 181 | 就导致了在等待分支条件计算期间,流水线上出现若干周期的停顿(流水线Hazard)。 182 | 183 | 184 | # 4. 参考(扩展)资料 # 185 | 186 | + [Perf 在 Linux 程序性能评估中的应用(by淘宝承刚)]( http://kernel.taobao.org/images/5/52/Perf%E5%9C%A8Linux%E6%80%A7%E8%83%BD%E8%AF%84%E4%BC%B0%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8_v3.pdf) 187 | + [Linux 的系统级性能剖析工具‐perf(二)](http://kernel.taobao.org/images/3/31/Linux%E7%9A%84%E7%B3%BB%E7%BB%9F%E7%BA%A7%E6%80%A7%E8%83%BD%E5%89%96%E6%9E%90%E5%B7%A5%E5%85%B7-perf-2.pdf) 188 | + [Linux 的系统级性能剖析工具‐perf(三)](http://kernel.taobao.org/images/e/e4/Linux%E7%9A%84%E7%B3%BB%E7%BB%9F%E7%BA%A7%E6%80%A7%E8%83%BD%E5%89%96%E6%9E%90%E5%B7%A5%E5%85%B7-perf-3.pdf) 189 | + [Linux kernel profiling with perf](https://perf.wiki.kernel.org/index.php/Tutorial) 190 | + [Perf -- Linux下的系统性能调优工具,第 1 部分](http://www.ibm.com/developerworks/cn/linux/l-cn-perf1/) 191 | + [Perf -- Linux下的系统性能调优工具,第 2 部分](http://www.ibm.com/developerworks/cn/linux/l-cn-perf2/) 192 | + [perf Examples](http://www.brendangregg.com/perf.html) 193 | 194 | -------------------------------------------------------------------------------- /性能调优/sar.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /性能调优/strace.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /性能调优/top.md: -------------------------------------------------------------------------------- 1 | # top 2 | 3 | `top` 命令是 Linux 下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于 Windows 的任务管理器。 4 | 5 | ## 一、top 理论 6 | 7 | ``` bash 8 | # top 9 | top - 10:52:40 up 3 days, 52 min, 1 user, load average: 57.28, 112.40, 123.60 10 | Tasks: 99 total, 1 running, 98 sleeping, 0 stopped, 0 zombie 11 | Cpu(s): 19.5%us, 11.4%sy, 0.0%ni, 0.0%id, 65.7%wa, 0.0%hi, 3.4%si, 0.0%st 12 | Mem: 16435896k total, 16232468k used, 203428k free, 58004k buffers 13 | Swap: 1044476k total, 713552k used, 330924k free, 10052032k cached 14 | 15 | PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 16 | ... ... 17 | ``` 18 | 19 | 统计信息区前五行是系统整体的统计信息。第一行是任务队列信息,同 `uptime` 命令的执行结果。其内容如下: 20 | 21 | |内容 | 解释 22 | |:--- |:--- 23 | |10:52:40 | 当前时间 24 | |up 3 days, 52 min | 系统运行时间 25 | |1 users | 当前登录用户数 26 | |load average: 57.28, 112.40, 123.60 | 系统负载,即任务队列平均长度。分别为 1、5、15min 前到现在平均值。 27 | 28 | 第二、三行为进程和 CPU 的信息。当有多个 CPU 时,这些内容可能会超过两行。内容如下: 29 | 30 | | 内容 | 解释 31 | |:--- |:--- 32 | | Tasks:99 total | 进程总数[键入H可查看线程数] 33 | | 1 running, 98 sleeping, 0 stopped | 正在运行的进程、睡眠进程、停止的进程 34 | | 0 zombie | 僵尸进程数 35 | | Cpu(s): 19.5%us, 11.4%sy, | 用户空间占用CPU百分比、内核空间占用CPU百分比 36 | | 0.0%ni, 0.0%id, | 用户进程空间内改变进程优先级占用CPU、空闲CPU百分比 37 | | 65.7%wa, 0.0%hi, 3.4%si, 0.0%st | 等待IO的CPU时间百分比,最后三个是中断请求相关 38 | 39 | 倒数第 2、3 行为内存相关信息: 40 | 41 | |内容 | 解释 42 | |:--- |:--- 43 | |Mem: 16435896k total, 16232468k used, | 分别是物理内存总量、使用物理内存总量 44 | |203428k free, 58004k buffers | 空闲内存总量、用作内核缓存内存量 45 | |Swap: 1044476k total, 713552k used, | 分别是交换分区量、使用交换分区总量 46 | |330924k free, 10052032k cached | 空闲交换区总量、缓存交换区总量 47 | 48 | 49 | - buffe [Difference between buffer and cache](http://wiki.answers.com/Q/Difference_between_buffer_and_cache) 50 | 51 | >A data area, shared by hardware devices or program a process is called buffer. They are operated at different speeds or with different sets of priorities. The buffer allows each device or process to operate without holding up by the other. In order to a buffer to be effective, the size of the buffer needs to be considered by the buffer designer. Like a cache, a buffer is a "midpoint holding place" but does not exist so much to accelerate the speed of an activity as for supporting the coordination of separate activities. 52 | 53 | >This term is used not only in programming but in hardware as well. In programming, buffering sometimes needs to screen data from its final intended place so that it can be edited or processed before moving to a regular file or database. 54 | 55 | - cached 56 | 57 | >Cache memory is type of random access memory (RAM). Cache Memory can be accessed more quickly by the computer microprocessor than it can be accessed by regular RAM. Like microprocessor processes data, it looks first in the cache memory and if there, it finds the data from a previous reading of data, it does not need to do the more time consuming reading of data from larger memory. 58 | 59 | >Sometimes Cache memory is described in levels of closeness and convenience to the microprocessor. An L1 cache is on the same chip like the microprocessors. 60 | 61 | >In addition to cache memory, RAM itself is a cache memory for hard disk storage since all of RAM's contents come up to the hard disk initially when you turn on your computer and load the operating system that you are loading it into RAM and later when you start new applications and access new data. RAM also contains a special area called a disk cache that consists of the data most recently read in from the hard disk. 62 | 63 | 最后 1 行则是进程相关的资源占用信息: 64 | 65 | - `PID`:进程的ID 66 | - `USER`:进程所有者 67 | - `PR`:进程的优先级别,越小越优先被执行 68 | - `NI`:nice值。负值表示高优先级,正值表示低优先级 69 | - `VIRT`:进程占用的虚拟内存 70 | - `RES`:进程占用的物理内存 71 | - `SHR`:进程使用的共享内存 72 | - `S`:进程的状态。S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值为负数 73 | - `%CPU`:进程占用CPU的使用率 74 | - `%MEM`:进程使用的物理内存和总内存的百分比 75 | - `TIME+`:该进程启动后占用的总的CPU时间,即占用CPU使用时间的累加值。 76 | - `COMMAND`:进程启动命令名称 77 | 78 | ## 二、top 技巧 79 | 80 | 终端执行 `top` 命令之后【也可后接一些选项,比如 `top -p 1` 只监控init进程,`top -u root` 只显示 root 运行进程等等】,可以敲击如下按键,实现不同功能: 81 | 82 | - `h`:获取 `top` 的命令帮助 83 | - `1`(数字1):列出所有的单个 CPU 负载情况 84 | - `z`:`top` 显示颜色 85 | - `x`:类似高亮显示,在 `z` 模式下使用 86 | - `P`[大写]:按 CPU 占用高低顺序列出程序 87 | - `M`[大写]:按内存占用高低顺序列出程序 88 | - `c`:显示进程命令的全路径与参数 89 | - `H`:显示线程,默认只显示进程 90 | - `top` 默认按 cpu 占用排序,按F(大写)即可选择相应排序 91 | - `d`:`top` 默认刷新时间是 3s ,使用d键可自定义刷新时间 92 | - top 选择列排序[高到低]的方法[在`z`颜色和`x`高亮模式下显示效果明显]: 93 | - shift+<:左选 94 | - shift+>:右选 95 | - `f`:可以指定 `top` 显示的内容,如 ppid、swap 等都可以选择显示 96 | - 显示 `Swap` 利用率:按 `f` 键,然后按 `p` 键,回车即可看到 Swap 状态 97 | - `k`:输入k之后可以 kill 掉指定的进程 98 | - `A`:分类显示各种系统资源高的进程。可用于快速识别系统上的性能要求极高的任务,__推荐使用__ 99 | - `W`[大写]:将当前设置写入 `~/.toprc` 文件中。这是写 `top` 配置文件的推荐方法 100 | 101 | ## 三、参考 102 | 103 | - [鸟哥Linux私房菜](http://linux.vbird.org/) 104 | - [top - Process Activity Command](http://www.cyberciti.biz/tips/top-linux-monitoring-tools.html) 105 | - [Learning Linux Commands: top](http://how-to.linuxcareer.com/learning-linux-commands-top) 106 | -------------------------------------------------------------------------------- /性能调优/vmstat.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /效率工具/emacs.md: -------------------------------------------------------------------------------- 1 | # Emacs 教程 2 | 3 | 世界上有三中程序员,一种是用 Vim 的,一种是用 Emacs 的,另外一种是用其它编辑器的。本文介绍 Emacs 的基本使用。 4 | 5 | 我的 Emacs 配置: https://gitcafe.com/JerryZhang/emacs-config.git 6 | 7 | ## 一、安装 8 | 9 | wget https://github.com/mirrors/emacs/archive/emacs-24.3.92.zip 10 | unzip emacs-24.3.92.zip 11 | cd emacs-24.3.93 12 | ./autogen.sh 13 | ./configure --without-makeinfo 14 | make -j2 15 | sudo make install 16 | 17 | 添加 `alias em='env TERM=xterm-256color emacs -nw` 到 `~/.bashrc` 中,这样就可以直接用 `em` 打开 Emacs 了。 18 | 19 | ## 二、基本快捷键 20 | 21 | 这里列出在没有打开任何 mode 的情况下,原生 Emacs 所支持的快捷键。 22 | 23 | + `C-`: Ctrl 键 24 | + `M-`: Alt/ESC 键, 25 | + `S-`: Shift 键 26 | + `C-g` : 撤销命令(没事多摁几下,我都是没事摁着玩的) 27 | + `C-z` : 挂起 Emacs 28 | + `C-x C-c`: 关闭 Emacs 29 | 30 | ### 2.1 光标移动 31 | 32 | + `C-n` : 下一行 33 | + `C-p` : 上一行 34 | + `C-f` : 前进一个字符 35 | + `C-b` : 后退一个字符 36 | + `M-f` : 前进一个单词 37 | + `M-b` : 后退一个单词 38 | + `C-v` : 向下翻页 39 | + `M-v` : 向上翻页 40 | + `C-l` : 光标所在行移动到屏幕中央 41 | + `C-a` : 行首 42 | + `C-e` : 行尾 43 | + `M-a` : 句首 44 | + `M-e` : 句尾 45 | + `M-<` : 文件首 46 | + `M->` : 文件尾 47 | 48 | ### 2.2 文档编辑 49 | 50 | + `` : 向前删除一个字符 51 | + `C-d` `` : 向后删除一个字符,我一般用 `C-d` 52 | + `M-d` `M-` : 向后删除一个单词 53 | + `C-k` : 删除光标到行尾,删除一行用 `C-a, C-k` (Vim 中的 dd)。 54 | + `M-k` : 删除光标到句尾 55 | + `C-@` : 标记(Mark set), 标记之后配合光标移动快捷键,可以选中一个区域 56 | + `M-w` : 复制 57 | + `C-w` : 剪切 58 | + `C-y` : 粘贴 59 | + `C-/` : 撤销(UNDO) 60 | 61 | 大小写转换: 62 | 63 | + `M-l`: Convert following word to lower case (downcase-word). 64 | + `M-u`: Convert following word to upper case (upcase-word). 65 | + `M-c`: Capitalize the following word (capital-word). 66 | + `C-x C-l`: Convert region to lower case (downcase-region). 67 | + `C-x C-u`: Convert region to upper case (upcase-region). 68 | 69 | 块操作: 70 | 71 | + `C-x r k`: Kill the text of the region-rectangle, saving its contents as the “last killed rectangle” (kill-rectangle). 72 | + `C-x r M-w`: Save the text of the region-rectangle as the “last killed rectangle” (copy-rectangle-as-kill). 73 | + `C-x r d`: Delete the text of the region-rectangle (delete-rectangle). 74 | + `C-x r y`: Yank the last killed rectangle with its upper left corner at point (yank-rectangle). 75 | + `C-x r o`: Insert blank space to fill the space of the region-rectangle (open-rectangle). This pushes the previous contents of the region-rectangle to the right. 76 | + `C-x r N`: Insert line numbers along the left edge of the region-rectangle (rectangle-number-lines). This pushes the previous contents of the region-rectangle to the right. 77 | + `C-x r c`: Clear the region-rectangle by replacing all of its contents with spaces (clear-rectangle). 78 | + `M-x delete-whitespace-rectangle`: Delete whitespace in each of the lines on the specified rectangle, starting from the left edge column of the rectangle. 79 | + `C-x r t string `: Replace rectangle contents with string on each line (string-rectangle). 80 | + `M-x string-insert-rectangle string `: Insert string on each line of the rectangle. 81 | 82 | ### 2.3 搜索 83 | 84 | + `C-s` : 向前搜索 85 | + `C-r` : 向后操作 86 | + `C-g` : 回到搜索开始前的位置 87 | + `M-%` : 询问并替换 88 | 89 | ### 2.4 文件操作(缓冲区) 90 | 91 | Emacs 可以打开很多文件,一个文件可以理解成一个 buffer,你可以在多个文件中来回切换。 92 | 93 | + `C-x f` : 打开一个文件 -> `find-file` 94 | + `C-x s` : 保存 95 | + `C-x C-w` : 另存为 96 | + `C-x C-v` : 关闭当前缓冲区,并打开新文件 97 | + `C-x C-b` : 打开缓冲区列表 98 | + `C-x b` : 切回最近的 buffer -> `switch-to-buffer` 99 | + `C-x k` : 关闭当前缓冲区 100 | + `C-x C-b`, `d`, `x`: 关闭用 d 标记 buffer 101 | + `M-x find-file-at-point` , `M-x ffap` 102 | + `C-x 5 0` : `delete-frame` 103 | 104 | ### 2.5 窗口(WINDOWS)操作 105 | 106 | + `C-x 1` : 只保留当前窗口 107 | + `C-x 2` : 水平切分 108 | + `C-x 3` : 垂直切分 109 | + `C-x o` : 切换到另外一个窗口 110 | + `C-x 0` : 关闭当前窗口(并不是删除buffer) 111 | + `C-x 4 C-f` : 在另外一个窗口打开文件 -> `find-file-other-window` 112 | 113 | ### 2.6 查阅命令 114 | 115 | + `M-x man` : 116 | + `M-x info` : 所有的 Emacs 手册 117 | 118 | ### 2.7 代码编辑 119 | 120 | + `M-;` : 块注释 121 | 122 | ### 2.8 目录操作 123 | 124 | + `M-x dired` : 打开一个目录 125 | 126 | ### 2.9 书签 127 | 128 | + `C-x r m` : 设置一个书签 -> `bookmark-set` 129 | + `C-x r b` : 跳转到一个书签 -> `bookmark-jump` 130 | + `C-x r l` : 显示所有书签列表, 管理书签的方式和 `Direcd` 模式一样 131 | - `RET` : 打开一个书签 132 | - `p`: 前一个书签 133 | - `n`: 后一个书签 134 | - `s` : 保存当前书签到一个文件中 135 | - `o` : 在另外一个窗口中打开文件 136 | - `r` : 重命名书签 137 | - `d` : 标记要删除的书签 138 | - `x` : 执行删除动作 139 | - `u` : 撤销标记 140 | 141 | ### 2.10 Occur 142 | 143 | 把所有的搜索结果都列到一个名为 `*Occur*` buffer 中。使用 `M-s o` 调用 `occur` 函数,搜索当前文档。 144 | 145 | + `M-g n` : 下一个匹配项 146 | + `M-g p` : 上一个匹配项 147 | + `e` : 进入 `occur-edit-mode`,可以编辑搜索结果 148 | + `C-c C-c` : 退出编辑模式 149 | + `g` : 刷新搜索结果 150 | 151 | ### 2.11 Dired 152 | 153 | + `C-x d` : 选个一个目录,在当前窗口打开 154 | + `C-x 4 d` : 选一个目录,在另外一个目录打开 155 | + `i` : 打开子目录 156 | 157 | ### 2.12 版本控制(Version Control) 158 | 159 | + `C-x v v` , `M-x vc-next-action` : 提交当前文件 160 | + `C-x v =` , `M-x vc-diff` 161 | + `C-x v ~` , `M-x vc-revision-other-window`: 与指定版本做比较 162 | + `C-x v l` , `M-x vc-print-log` : 查看日志 163 | + `C-x v u` , `M-x vc-revert` 164 | + `C-x v C-h` : 查看所有可用的 vc 命令 165 | 166 | ## 三、通用定制 167 | 168 | 默认的 emacs 的快捷键有些不好用,比如 `c-x c-f` 时,没有任何提示。再如窗口切换使用 `c-x o`,当 buffer 多时,非常不方便,这一节介绍 emacs 通用的定制(不针对某种开发/编辑环境)。 169 | 170 | emacs 启动时会会从两个地方找配置文件: 171 | 172 | 1. `~/.emacs` 173 | 2. `~/.emacs.d` 174 | 175 | 因为隐藏文件多有不便,我目前的做法是从 gitcafe 上 clone 下来我的 emacs 配置以后,用 `ln -s` 添加一个软连接。 176 | 177 | 基本设置: 178 | 179 | (fset 'yes-or-no-p 'y-or-n-p) ;; 用 `y/n` 代替 `yes/no` 180 | (setq auto-save-default nil) 181 | (setq inhibit-startup-message t) 182 | (setq mouse-yank-at-point t) 183 | (setq make-backup-files nil) 184 | (setq create-lockfiles nil) 185 | (column-number-mode t) 186 | 187 | (setq-default indent-tabs-mode nil) 188 | (setq-default tab-width 4) 189 | (global-auto-revert-mode t) 190 | (add-hook 'before-save-hook 'delete-trailing-whitespace) 191 | (show-paren-mode t) ;; 匹配括号高亮显示 192 | (global-visual-line-mode 1) ;; 自动换行 193 | 194 | 行号: 195 | 196 | (setq linum-format "%3d|") 197 | ;;(global-linum-mode 1) 198 | (global-set-key (kbd "M-s l") 'global-linum-mode) 199 | 200 | 代码缩进参考线: 201 | 202 | (require 'fill-column-indicator) 203 | (setq fci-rule-color "#eee") 204 | (setq fci-rule-column 80) 205 | (define-globalized-minor-mode 206 | global-fci-mode fci-mode (lambda () (fci-mode 1))) 207 | (global-fci-mode 1) 208 | 209 | 常用快捷键: 210 | 211 | (global-set-key [(f2)] 'grep) 212 | (global-set-key [(f3)] 'eshell) 213 | (global-set-key [(f4)] 'insert-current-date-time) 214 | (global-set-key [(f5)] 'compile) 215 | 216 | 使用 M-(1,2,3...9)窗口切换(依赖于 windows-numbering 插件): 217 | 218 | (add-to-list 'load-path "~/.emacs.d/lisp/window-numbering.el") 219 | (require 'window-numbering) 220 | (setq window-numbering-assign-func 221 | (lambda () (when (equal (buffer-name) "*Calculator*") 9))) 222 | (window-numbering-mode 1) 223 | 224 | `C-a` 跳转到句首,而不是行首(目前我没用): 225 | 226 | (defun prelude-move-beginning-of-line (arg) 227 | "Move point back to indentation of beginning of line. 228 | 229 | Move point to the first non-whitespace character on this line. 230 | If point is already there, move to the beginning of the line. 231 | Effectively toggle between the first non-whitespace character and 232 | the beginning of the line. 233 | 234 | If ARG is not nil or 1, move forward ARG - 1 lines first. If 235 | point reaches the beginning or end of the buffer, stop there." 236 | (interactive "^p") 237 | (setq arg (or arg 1)) 238 | 239 | ;; Move lines first 240 | (when (/= arg 1) 241 | (let ((line-move-visual nil)) 242 | (forward-line (1- arg)))) 243 | 244 | (let ((orig-point (point))) 245 | (back-to-indentation) 246 | (when (= orig-point (point)) 247 | (move-beginning-of-line 1)))) 248 | 249 | (global-set-key (kbd "C-a") 'prelude-move-beginning-of-line) 250 | 251 | Tip: **`M-x eval-buffer` 可以使配置文件立即生效,调试非常方便。** 252 | 253 | ## 四、高级定制 254 | 255 | 这一节针对不同的应用,介绍一些插件: 256 | 257 | ### 4.1 代码参考线 258 | 259 | fill-column-indicator: https://github.com/alpaker/Fill-Column-Indicator 260 | 261 | (require 'fill-column-indicator) 262 | (setq fci-rule-color "#333") 263 | (setq fci-rule-column 80) 264 | (define-globalized-minor-mode 265 | global-fci-mode fci-mode (lambda () (fci-mode 1))) 266 | (global-fci-mode 1) 267 | 268 | ### 4.2 自动补全 269 | 270 | [auto-complete](https://github.com/auto-complete/auto-complete) 和 [yasnippet](https://github.com/capitaomorte/yasnippet). 271 | 272 | (require 'popup) 273 | 274 | (require 'auto-complete) 275 | (require 'auto-complete-config) 276 | (add-to-list 'ac-dictionary-directories 277 | "~/.emacs.d/auto-complete/dict") 278 | (ac-config-default) 279 | (add-to-list 'ac-modes 'protobuf-mode) 280 | 281 | (require 'yasnippet) 282 | (yas-global-mode 1) 283 | 284 | 285 | ### 4.3 相同符号高亮: [highlight-symbol](https://github.com/nschum/highlight-symbol.el) 286 | 287 | (require 'highlight-symbol) 288 | (global-set-key (kbd "M--") 'highlight-symbol-at-point) 289 | (global-set-key (kbd "M-n") 'highlight-symbol-next) 290 | (global-set-key (kbd "M-p") 'highlight-symbol-prev) 291 | 292 | Tips: **用这个做查找也挺不错的!** 293 | 294 | ### 4.4 Markdown: [markdown-mode](http://jblevins.org/projects/markdown-mode/) 295 | 296 | (autoload 'markdown-mode "~/.emacs.d/lisp/markdown-mode/markdown-mode.el" 297 | "Major mode for editing Markdown files" t) 298 | (setq auto-mode-alist 299 | (cons '("\\.md" . markdown-mode) auto-mode-alist)) 300 | (setq auto-mode-alist 301 | (cons '("\\.markdown" . markdown-mode) auto-mode-alist)) 302 | (setq auto-mode-alist 303 | (cons '("\\.txt" . markdown-mode) auto-mode-alist)) 304 | 305 | ### 4.5 Python: [python-mode]() 306 | 307 | (require 'python-mode) 308 | 309 | (add-hook 'python-mode-hook 310 | (lambda () 311 | (set (make-local-variable 'compile-command) 312 | (format "python %s" (file-name-nondirectory buffer-file-name))))) 313 | 314 | 315 | ### 4.6 Google Protobuf Buffer: [protobuf-mode](http://code.google.com/p/protobuf/source/browse/trunk/editors/protobuf-mode.el?r=227) 316 | 317 | (require 'protobuf-mode) 318 | (add-to-list 'auto-mode-alist '("\\.proto$" . protobuf-mode)) 319 | 320 | ### 4.7 C++开发定制: xcscope + etags + c++-mode 321 | 322 | ;; 编译与调试 323 | (global-set-key [(f5)] 'compile) 324 | 325 | (require 'xcscope) 326 | (cscope-setup) 327 | 328 | (global-set-key [(f9)] 'ff-find-other-file) 329 | 330 | (setq tab-stop-list ()) 331 | (loop for x downfrom 40 to 1 do 332 | (setq tab-stop-list (cons (* x 4) tab-stop-list))) 333 | 334 | (defconst my-c-style 335 | '( 336 | (c-tab-always-indent . t) 337 | (c-hanging-braces-alist . ((substatement-open after) 338 | (brace-list-open))) 339 | (c-hanging-colons-alist . ((member-init-intro before) 340 | (inher-intro)' 341 | (label after) 342 | (acecss-label after))) 343 | (c-cleanup-list . (scope-operator 344 | empty-defun-braces 345 | defun-close-semi)) 346 | (c-offsets-alist . ((arglist-close . c-lineup-arglist) 347 | (case-label . 4) 348 | (substatement-open . 0) 349 | (block-open . 0) 350 | (knr-argdecl-intro . -) 351 | (innamespace . -) 352 | (inline-open . 0) 353 | (inher-cont . c-lineup-multi-inher) 354 | (arglist-cont-nonempty . +) 355 | (template-args-cont . + ))) 356 | (c-echo-syntactic-information-p . t) 357 | ) 358 | "My C Programming Style") 359 | 360 | ;; offset customizations not in my-c-style 361 | (setq c-offsets-alist '((member-init-intro . ++))) 362 | 363 | ;; Customizations for all modes in CC Mode. 364 | (defun my-c-mode-common-hook () 365 | ;; add my personal style and set it for the current buffer 366 | (c-add-style "PERSONAL" my-c-style t) 367 | ;; other customizations 368 | (setq tab-width 4 369 | indent-tabs-mode nil) 370 | ;; we like auto-newline and hungry-delete 371 | ;; (c-toggle-auto-hungry-state 1) 372 | ;; key bindings for all supported languages. We can put these in 373 | ;; c-mode-base-map because c-mode-map, c++-mode-map, objc-mode-map, 374 | ;; java-mode-map, idl-mode-map, and pike-mode-map inherit from it. 375 | ) 376 | (add-hook 'c-mode-common-hook 'my-c-mode-common-hook) 377 | (add-hook 'c-mode-hook 'hs-minor-mode) 378 | 379 | (add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode)) 380 | 381 | ;; http://stackoverflow.com/questions/14668744/emacs-indent-for-c-class-method 382 | (defun vlad-cc-style() 383 | (c-set-offset 'inline-open '0) 384 | ) 385 | (add-hook 'c++-mode-hook 'vlad-cc-style) 386 | 387 | [xcscope.el](https://github.com/dkogan/xcscope.el) 使用: 388 | 389 | + cscope -r : 在根目录下递归生成数据库 390 | + C-c s a : Set initial directory; 391 | + C-c s A : Unset initial directory; 392 | + C-c s I : create list of files to index; 393 | + C-c s s : Find symbol; 394 | + C-c s d : Find global definition; 395 | + C-c s c : Find functions calling a function; 396 | + C-c s C : Find called functions (list functions called from a function); 397 | + C-c s t : Find text string; 398 | + C-c s e : Find egrep pattern; 399 | + C-c s f : Find a file; 400 | + C-c s i : Find files #including a file; 401 | + C-c s b : Display cscope buffer; 402 | 403 | etags 使用: 404 | 405 | 搭配 `find` 来生成 tags: 406 | 407 | find . -name '*.c' -o -name '*.cpp' -o -name '*.h' -print | etags - 408 | 409 | + `M-x visit-tags-table FILE ` : 选择tags文件 410 | + `M-. [TAG] ` : 访问标签 411 | + `M-*` : 返回 412 | + `C-u M-.` : 寻找标签的下一个定义 413 | 414 | 其它: 415 | 416 | + `F9` : 在头文件和对应源文件之间跳转: `(global-set-key [(f9)] 'ff-find-other-file)` 417 | 418 | ### 4.8 [谷歌翻译](https://github.com/atykhonov/google-translate.git) 419 | 420 | 421 | (add-to-list 'load-path "~/.emacs.d/lisp/google-translate") 422 | (require 'google-translate) 423 | (require 'google-translate-smooth-ui) 424 | (global-set-key "\C-ct" 'google-translate-smooth-translate) 425 | (setq google-translate-translation-directions-alist 426 | '(("en" . "zh-CN") ("zh-CN" . "en") )) 427 | 428 | `C-c t` 打开翻译,我指定了英->中,中->英两种翻译模式。 429 | 430 | ### 4.9 Expand region 431 | 432 | Github: [expand-region.el](https://github.com/magnars/expand-region.el) 433 | 434 | (require 'expand-region) 435 | (global-set-key (kbd "M-m") 'er/expand-region) 436 | (global-set-key (kbd "M-s s") 'er/mark-symbol) 437 | (global-set-key (kbd "M-s p") 'er/mark-outside-pairs) 438 | (global-set-key (kbd "M-s P") 'er/mark-inside-pairs) 439 | (global-set-key (kbd "M-s q") 'er/mark-outside-quotes) 440 | (global-set-key (kbd "M-s Q") 'er/mark-inside-quotes) 441 | (global-set-key (kbd "M-s m") 'er/mark-comment) 442 | (global-set-key (kbd "M-s f") 'er/mark-defun) 443 | 444 | 复制代码的时候很实用! 445 | 446 | ### 4.10 代码静态检查: flycheck 447 | 448 | (require 'flycheck) 449 | (add-hook 'after-init-hook #'global-flycheck-mode) 450 | 451 | ### 4.11 Helm 452 | 453 | github: [https://github.com/emacs-helm/helm](https://github.com/emacs-helm/helm) 454 | 455 | **极力推荐** 这个插件,Emacs 最强插件,没有之一,装了了没装完全是两个档次的 Emacs。 456 | 457 | wiki: https://github.com/emacs-helm/helm/wiki 458 | 459 | (require 'helm) 460 | (require 'helm-config) 461 | (require 'helm-eshell) 462 | 463 | (add-hook 'eshell-mode-hook 464 | #'(lambda () 465 | (define-key eshell-mode-map (kbd "C-c C-l") 'helm-eshell-history))) 466 | 467 | (global-set-key (kbd "C-c h") 'helm-command-prefix) 468 | (define-key helm-map (kbd "") 'helm-execute-persistent-action) 469 | (define-key helm-map (kbd "C-i") 'helm-execute-persistent-action) 470 | (define-key helm-map (kbd "C-z") 'helm-select-action) 471 | 472 | (when (executable-find "curl") 473 | (setq helm-google-suggest-use-curl-p t)) 474 | 475 | (setq helm-split-window-in-side-p t 476 | helm-move-to-line-cycle-in-source t 477 | helm-ff-search-library-in-sexp t 478 | helm-scroll-amount 8 479 | helm-ff-file-name-history-use-recentf t 480 | ) 481 | 482 | (global-set-key (kbd "M-x") 'helm-M-x) 483 | (global-set-key (kbd "M-y") 'helm-show-kill-ring) 484 | (global-set-key (kbd "C-x b") 'helm-mini) 485 | (global-set-key (kbd "C-c h o") 'helm-occur) 486 | (global-set-key (kbd "C-x C-f") 'helm-find-files) 487 | 488 | (setq helm-M-x-fuzzy-match t) 489 | ;;(helm-autoresize-mode 1) 490 | (helm-mode 1) 491 | 492 | (global-set-key [(f6)] 'helm-imenu) 493 | 494 | 495 | ### 4.last Emacs主题 496 | 497 | 把 主题 放到最后,是想告诉大家,使用 Emacs(或者其它任何工具) 时,不要花时间在这些炫酷的东西上面,还是要聚焦于实用和高效。Emacs24自带了几款主题(Emacs23没有的哦),使用 `M-x customize-theme` 回车可查看配色效果。 498 | 499 | 也可以在学习资源中的 Emacs Theme 中找一款自己喜欢的。 500 | 501 | ## 五、学习资源 502 | 503 | 一些学习资源推荐,也是本文档的参考资料。 504 | 505 | + [Emacs Mini Mannual](http://tuhdo.github.io/index.html) : Emacs Mini 手册 506 | + [Emacs Themes](http://emacsthemes.caisah.info/) : 主题集合 507 | + [MELPA](http://melpa.milkbox.net/) : 插件集合,同时也可以感受一下 Emacs 的强大 508 | + [GNU Emacs Manuals Online](http://www.gnu.org/software/emacs/manual/) : Emacs 官方手册 509 | + [Emacs Redux](http://emacsredux.com/) 510 | + [Emacs Markdown Mode](http://jblevins.org/projects/markdown-mode/) 511 | + [一年成为Emacs高手(像神一样使用编辑器)](https://github.com/redguardtoo/mastering-emacs-in-one-year-guide/blob/master/guide-zh.org) 512 | + [Emacs as a Python IDE](http://www.jesshamrick.com/2012/09/18/emacs-as-a-python-ide/) 513 | + [Emacs快速参考](http://jianlee.ylinux.org/Computer/Emacs/emacsBFE99F8FE883.html) 514 | + [Case Conversion Commands](http://www.gnu.org/software/emacs/manual/html_node/emacs/Case.html) 515 | + [曹乐: 在Emacs下用C/C++编程](http://www.caole.net/diary/emacs_write_cpp.html) 516 | -------------------------------------------------------------------------------- /效率工具/git.md: -------------------------------------------------------------------------------- 1 | # 分布式管理系统 Git 2 | 3 | ## 一、Git基础 4 | 5 | ### 1.1 环境配置 6 | 7 | + `git config user.name your_name` : 设置你的用户名, 提交会显示 8 | + `git config user.email your_email` : 设置你的邮箱 9 | + `git config core.quotepath false` : 解决中文文件名显示为数字问题 10 | 11 | ### 1.2 基本操作 12 | 13 | + `git init` : 初始化一个 git 仓库 14 | + `git add ` : 添加一个文件到 git 仓库中 15 | + `git commit -m "commit message"`: 提交到本地 16 | + `git push [remote-name] [branch-name]` : 把本地的提交记录推送到远端分支 17 | + `git pull`: 更新仓库 `git pull` = `git fetch` + `git merge` 18 | + `git checkout -- ` : 还原未暂存(staged)的文件 19 | + `git reset HEAD ...` : 取消暂存,那么还原一个暂存文件,应该是先 `reset` 后 `checkout` 20 | + `git stash` : 隐藏本地提交记录, 恢复的时候 `git stash pop`。这样可以在本地和远程有冲突的情况下,更新其他文件 21 | 22 | ### 1.3 分支 23 | 24 | + `git branch ` : 基于当前 commit 新建一个分支,但是不切换到新分支 25 | + `git checkout -b ` : 新建并切换分支 26 | + `git checkout ` : 切换分支 27 | + `git branch -d ` : 删除分支 28 | + `git push origin ` : 推送本地分支 29 | + `git checkout -b origin/` : 基于某个远程分支新建一个分支开发 30 | + `git checkout --track origin/` : 跟踪远程分支(创建跟踪远程分支,Git 在 `git push` 的时候不需要指定 `origin` 和 `branch-name` ,其实当我们 `clone` 一个 repo 到本地的时候,`master` 分支就是 origin/master 的跟踪分支,所以提交的时候直接 `git push`)。 31 | + `git push origin :` : 删除远程分支 32 | 33 | ### 1.4 标签 34 | 35 | + `git tag -a -m ` : 创建一个标签 36 | + `git tag` : 显示已有的标签 37 | + `git show tagname`: 显示某个标签的详细信息 38 | + `git checkout -b ` : 基于某个 tag 创建一个新的分支 39 | 40 | ### 1.5 补丁 41 | 42 | 先占个坑。 43 | 44 | ### 1.6 Git shortcuts/aliases 45 | 46 | git config --global alias.co checkout 47 | git config --global alias.br branch 48 | git config --global alias.ci commit 49 | git config --global alias.st status 50 | 51 | ## 二、知识点 52 | 53 | 基本命令让你快速的上手使用Git,知识点能让你更好的理解Git。 54 | 55 | ### 2.1 文件的几种状态 56 | 57 | + untracked: 未被跟踪的,没有纳入 Git 版本控制,使用 `git add ` 纳入版本控制 58 | + unmodified: 未修改的,已经纳入版本控制,但是没有修改过的文件 59 | + modified: 对纳入版本控制的文件做了修改,git 将标记为 modified 60 | + staged: 暂存的文件,简单理解: 暂存文件就是 add 之后,commit 之前的文件状态 61 | 62 | 理解这几种文件状态对于理解 Git 是非常关键的(至少可以看懂一些错误提示了)。 63 | 64 | ### 2.2 快照和差异 65 | 66 | 详细可看:[Pro Git: Git基础](http://iissnan.com/progit/html/zh/ch1_3.html)中有讲到 *直接记录快照,而非差异比较*,这里只讲我个人的理解。 67 | 68 | Git 关心的是文件数据整体的变化,其他版本管理系统(以svn为例)关心的某个具体文件的*差异*。这个差异是好理解的,也就是两个版本具体文件的不同点,比如某一行的某个字符发生了改变。 69 | 70 | Git 不保存文件提交前后的差异,不变的文件不会发生任何改变,对于变化的文件,前后两次提交则保存两个文件。举个例子: 71 | 72 | SVN: 73 | 74 | 1. 新建3个文件a, b, c,做第一次提交 -> `version1 : file_a file_b file_c` 75 | 2. 修改文件 b, 做第二次提交(真正提交的是 修改后的文件 b 和修改前的 `file_b` 的 diff) -> `version2: diff_b_2_1` 76 | 3. 当我要 checkout version2 的时候,实际上得到的是 `file_a file_b+diff_b_2_1 file_c` 77 | 78 | Git: 79 | 80 | 1. 新建3个文件a, b, c,做第一次提交 -> `version1 : file_a file_b file_c` 81 | 2. 修改文件 b (得到`file_b1`), 做第二次提交 -> `version2: file_a file_b1 file_c` 82 | 3. 当我要用 version2 的时候,实际上得到的是 `file_a file_b1 file_c` 83 | 84 | 上面的 `file_a file_b1 file_c` 就是 version2 的 *快照*。 85 | 86 | ### 2.3 Git数据结构 87 | 88 | Git的核心数是很简单的,就是一个链表(或者一棵树更准确一些?无所谓了),一旦你理解了它的基本数据结构,再去看Git,相信你有不同的感受。继续用上面的例子(所有的物理文件都对应一个 SHA-1 的值) 89 | 90 | 当我们做第一次提交时,数据结构是这样的: 91 | 92 | 93 | sha1_2_file_map: 94 | 28415f07ca9281d0ed86cdc766629fb4ea35ea38 => file_a 95 | ed5cfa40b80da97b56698466d03ab126c5eec5a9 => file_b 96 | 1b5ca12a6cf11a9b89dbeee2e5431a1a98ea5e39 => file_c 97 | 98 | commit_26b985d269d3a617af4064489199c3e0d4791bb5: 99 | base_info: 100 | Auther: "JerryZhang(chinajiezhang@gmail.com)" 101 | Date: "Tue Jul 15 19:19:22 2014 +0800" 102 | commit_content: "第一次提交" 103 | file_list: 104 | [1]: 28415f07ca9281d0ed86cdc766629fb4ea35ea38 105 | [2]: ed5cfa40b80da97b56698466d03ab126c5eec5a9 106 | [3]: 1b5ca12a6cf11a9b89dbeee2e5431a1a98ea5e39 107 | pre_commit: null 108 | next_commit: null 109 | 110 | 当修改了 `file_b`, 再提交一次时,数据结构应该是这样的: 111 | 112 | sha1_2_file_map: 113 | 28415f07ca9281d0ed86cdc766629fb4ea35ea38 => file_a 114 | ed5cfa40b80da97b56698466d03ab126c5eec5a9 => file_b 115 | 1b5ca12a6cf11a9b89dbeee2e5431a1a98ea5e39 => file_c 116 | 39015ba6f80eb9e7fdad3602ef2b1af0521eba89 => file_b1 117 | 118 | commit_26b985d269d3a617af4064489199c3e0d4791bb5: 119 | base_info: 120 | Auther: "JerryZhang(chinajiezhang@gmail.com)" 121 | Date: "Tue Jul 15 19:19:22 2014 +0800" 122 | commit_content: "第一次提交" 123 | file_list: 124 | [1]: 28415f07ca9281d0ed86cdc766629fb4ea35ea38 125 | [2]: ed5cfa40b80da97b56698466d03ab126c5eec5a9 126 | [3]: 1b5ca12a6cf11a9b89dbeee2e5431a1a98ea5e39 127 | pre_commit: commit_a08a57561b5c30b9c0bf33829349e14fad1f5cff 128 | next_commit: null 129 | 130 | commit_a08a57561b5c30b9c0bf33829349e14fad1f5cff: 131 | base_info: 132 | Auther: "JerryZhang(chinajiezhang@gmail.com)" 133 | Date: "Tue Jul 15 22:19:22 2014 +0800" 134 | commit_content: "更新文件b" 135 | file_list: 136 | [1]: 28415f07ca9281d0ed86cdc766629fb4ea35ea38 137 | [2]: 39015ba6f80eb9e7fdad3602ef2b1af0521eba89 138 | [3]: 1b5ca12a6cf11a9b89dbeee2e5431a1a98ea5e39 139 | pre_commit: null 140 | next_commit: commit_26b985d269d3a617af4064489199c3e0d4791bb5 141 | 142 | 当提交完第二次的时候,执行 `git log`,实际上就是从 `commit_a08a57561b5c30b9c0bf33829349e14fad1f5cff` 开始遍历然后打印 `base_info` 而已。 143 | 144 | 实际的 git 实际肯定要比上面的结构((的信息)的)要复杂的多,但是它的核心思想应该是就是,每一次提交就是一个新的结点。通过这个结点,我可以找到所有的快照文件。再思考一下,什么是分支?什么是 Tags,其实他们可能只是某次提交的引用而已(一个 `tag_head_node` 指向了某一次提交的node)。再思考怎么回退一个版本呢?指针偏移!依次类推,上面的基本命令都可以得到一个合理的解释。 145 | 146 | **理解git fetch 和 git pull的差异** 147 | 148 | 上面我们说过 `git pull` 等价于 `git fetch` 和 `git merge` 两条命令。当我们 `clone` 一个 repo 到本地时,就有了本地分支和远端分支的概念(假定我们只有一个主分支),本地分支是 `master`,远端分支是 `origin/master`。通过上面我们对 Git 数据结构的理解,`master` 和 `origin/master` 可以想成是指向最新 commit 结点的两个指针。刚 `clone` 下来的 repo,`master` 和 `origin/master` 指针指向同一个结点,我们在本地提交一次,`origin` 结点就更新一次,此时 `master` 和 `orgin/master` 就不再相同了。很有可能别人已经 commit 改 repo 很多次了,并且进行了提交。那么我们的本地的 `origin/master` 就不再是远程服务器上的最新的位置了。 `git fetch` 干的就是从服务器上同步服务器上最新的 `origin/master` 和一些服务器上新的记录/文件到本地。而 `git merge` 就是合并操作了(解决文件冲突)。`git push` 是把本地的 `origin/master` 和 `master` 指向相同的位置,并且推送到远程的服务器。 149 | 150 | *理论部分是我个人对 Git 的理解,难免有偏差,看看就可以了。* 151 | 152 | 153 | ## 三、参考资料 154 | 155 | + [Pro Git](http://iissnan.com/progit/) 156 | + [Git shortcuts/aliases - How to create](http://alvinalexander.com/git/git-shortcuts-aliases-long-commands-how-to-create) 157 | -------------------------------------------------------------------------------- /效率工具/pssh_pdsh.md: -------------------------------------------------------------------------------- 1 | # pssh && pdsh 2 | 3 | ## 一、pssh 4 | 5 | `pssh` 是一个 python 编写可以在多台服务器上执行命令的工具,同时支持拷贝文件,是同类工具中很出色的,类似 `pdsh` 。为方便操作,使用前请在各个服务器上配置好密钥认证访问。项目地址: [parallel-ssh](https://code.google.com/p/parallel-ssh/) 6 | 7 | ### 1.1、安装 8 | 9 | ``` 10 | wget http://parallel-ssh.googlecode.com/files/pssh-2.3.1.tar.gz 11 | tar zxvf pssh-2.3.1.tar.gz 12 | cd pssh-2.3.1/ 13 | python setup.py install 14 | ``` 15 | 16 | ### 1.2、pssh相关参数 17 | 18 | * `pssh` 在多个主机上并行地运行命令 19 | * -h 执行命令的远程主机列表,文件内容格式 [user@]host[:port] 20 | * 如 test@172.16.10.10:229 21 | * -H 执行命令主机,主机格式 user@ip:port 22 | * -l 远程机器的用户名 23 | * -p 一次最大允许多少连接 24 | * -P 执行时输出执行信息 25 | * -o 输出内容重定向到一个文件 26 | * -e 执行错误重定向到一个文件 27 | * -t 设置命令执行超时时间 28 | * -A 提示输入密码并且把密码传递给ssh(如果私钥也有密码也用这个参数) 29 | * -O 设置ssh一些选项 30 | * -x 设置ssh额外的一些参数,可以多个,不同参数间空格分开 31 | * -X 同-x,但是只能设置一个参数 32 | * -i 显示标准输出和标准错误在每台host执行完毕后 33 | 34 | ### 1.3、附加工具 35 | 36 | * `pscp` 传输文件到多个 hosts,类似 `scp` 37 | * pscp -h hosts.txt -l irb2 foo.txt /home/irb2/foo.txt 38 | * `pslurp` 从多台远程机器拷贝文件到本地 39 | * `pnuke` 并行在远程主机杀进程 40 | * pnuke -h hosts.txt -l irb2 java 41 | * `prsync` 使用rsync协议从本地计算机同步到远程主机 42 | * prsync -r -h hosts.txt -l irb2 foo /home/irb2/foo 43 | 44 | ### 1.4、使用实例 45 | 46 | 写入主机到文件中,语法为 `用户名@主机ip` 47 | 48 | ``` 49 | $ cat host.txt 50 | root@192.168.230.128 51 | wul@10.0.0.8 52 | ``` 53 | 54 | 推荐使用 `-i` 选项输出信息而不是 `-P` 选项,`-h` 指定定义主机组 55 | 56 | ``` 57 | $ pssh -i -h host.txt 'date' 58 | [1] 16:32:38 [SUCCESS] root@192.168.230.128 59 | Mon Aug 12 16:32:38 CST 2013 60 | [2] 16:32:38 [SUCCESS] wul@10.0.0.8 61 | Mon Aug 12 16:32:38 CST 2013 62 | ``` 63 | 64 | `-x` 选项:指定 ssh 的一些额外选项 65 | 66 | ``` 67 | $ pssh -x '-t -t -o StrictHostKeyChecking=no' -i -h host.txt date 68 | [1] 17:20:01 [SUCCESS] root@192.168.230.128 69 | Mon Aug 12 17:20:01 CST 2013 70 | Stderr: Connection to 192.168.230.128 closed. 71 | [2] 17:20:01 [SUCCESS] wul@10.0.0.8 72 | Mon Aug 12 17:20:01 CST 2013 73 | Stderr: Connection to 10.0.0.8 closed. 74 | ``` 75 | 76 | `-H` 选项:指定单个主机 77 | 78 | ``` 79 | $ pssh -x '-t -t -o StrictHostKeyChecking=no' -i -H 192.168.230.128 -H wul@10.0.0.8 date 80 | [1] 17:22:58 [SUCCESS] 192.168.230.128 81 | Mon Aug 12 17:22:58 CST 2013 82 | Stderr: Connection to 192.168.230.128 closed. 83 | [2] 17:22:58 [SUCCESS] wul@10.0.0.8 84 | Mon Aug 12 17:22:58 CST 2013 85 | Stderr: Connection to 10.0.0.8 closed. 86 | ``` 87 | 88 | ### 1.5、参考文档 89 | 90 | * [pssh](http://linux.die.net/man/1/pssh) 91 | * [pssh-howto](http://www.theether.org/pssh/docs/0.2.3/pssh-HOWTO.html) 92 | 93 | ## 二、pdsh 94 | 95 | `pdsh`(Parallel Distributed SHell) 可并行的执行对目标主机的操作,对于批量执行命令和分发任务有很大的帮助,在使用前需要配置 ssh 无密码登录,[点击下载](http://sourceforge.net/projects/pdsh/) 96 | 97 | 98 | ### 2.1、pdsh 基本用法 99 | 100 | ``` 101 | pdsh -h 102 | Usage: pdsh [-options] command ... 103 | -S return largest of remote command return values 104 | -h output usage menu and quit 获取帮助 105 | -V output version information and quit 查看版本 106 | -q list the option settings and quit 列出 `pdsh` 执行的一些信息 107 | -b disable ^C status feature (batch mode) 108 | -d enable extra debug information from ^C status 109 | -l user execute remote commands as user 指定远程使用的用户 110 | -t seconds set connect timeout (default is 10 sec) 指定超时时间 111 | -u seconds set command timeout (no default) 类似 `-t` 112 | -f n use fanout of n nodes 设置同时连接的目标主机的个数 113 | -w host,host,... set target node list on command line 指定主机,host 可以是主机名也可以是 ip 114 | -x host,host,... set node exclusion list on command line 排除某些或者某个主机 115 | -R name set rcmd module to name 指定 rcmd 的模块名,默认使用 ssh 116 | -N disable hostname: labels on output lines 输出不显示主机名或者 ip 117 | -L list info on all loaded modules and exit 列出 `pdsh` 加载的模块信息 118 | -a target all nodes 指定所有的节点 119 | -g groupname target hosts in dsh group "groupname" 指定 `dsh` 组名,编译安裝需要添加 -g 支持选项 `--with-dshgroups` 120 | -X groupname exclude hosts in dsh group "groupname" 排除组,一般和 -a 连用 121 | available rcmd modules: exec,xcpu,ssh (default: ssh) 可用的执行命令模块,默认为 ssh 122 | ``` 123 | 124 | ### 2.2、使用实例 125 | 126 | #### 2.2.1、单个主机测试 127 | 128 | ``` 129 | $ pdsh -w 192.168.0.231 -l root uptime 130 | 192.168.0.231: 16:16:11 up 32 days, 22:14, ? users, load average: 0.10, 0.14, 0.16 131 | ``` 132 | 133 | #### 2.2.2、多个主机测试 134 | 135 | ``` 136 | $ pdsh -w 192.168.0.[231-233] -l root uptime 137 | 192.168.0.233: 16:17:05 up 32 days, 22:17, ? users, load average: 0.13, 0.12, 0.10 138 | 192.168.0.232: 16:17:05 up 32 days, 22:17, ? users, load average: 0.45, 0.34, 0.27 139 | 192.168.0.231: 16:17:06 up 32 days, 22:15, ? users, load average: 0.09, 0.13, 0.15 140 | ``` 141 | 142 | #### 2.2.3、逗号分隔主机 143 | 144 | ``` 145 | $ pdsh -w 192.168.0.231,192.168.0.234 -l root uptime 146 | 192.168.0.234: 16:19:44 up 32 days, 22:19, ? users, load average: 0.17, 0.21, 0.20 147 | 192.168.0.231: 16:19:44 up 32 days, 22:17, ? users, load average: 0.29, 0.18, 0.16 148 | ``` 149 | 150 | #### 2.2.4、`-x` 排除某个主机 151 | 152 | ``` 153 | $ pdsh -w 192.168.0.[231-233] -x 192.168.0.232 -l root uptime 154 | 192.168.0.233: 16:18:24 up 32 days, 22:19, ? users, load average: 0.11, 0.12, 0.09 155 | 192.168.0.231: 16:18:25 up 32 days, 22:16, ? users, load average: 0.11, 0.13, 0.15 156 | ``` 157 | 158 | #### 2.2.5、主机组 159 | 160 | 对于 -g 组,把对应的主机写入到 `/etc/dsh/group/` 或 `~/.dsh/group/` 目录下的文件中即可,文件名就是对应组名 161 | 162 | ``` 163 | $ cat ~/.dsh/group/dsh-test 164 | 192.168.0.231 165 | 192.168.0.232 166 | 192.168.0.233 167 | 192.168.0.234 168 | ``` 169 | 170 | ``` 171 | $ pdsh -g dsh-test -l root uptime 172 | 192.168.0.232: 16:21:38 up 32 days, 22:22, ? users, load average: 0.01, 0.15, 0.21 173 | 192.168.0.231: 16:21:38 up 32 days, 22:19, ? users, load average: 0.17, 0.16, 0.16 174 | 192.168.0.234: 16:21:39 up 32 days, 22:21, ? users, load average: 0.15, 0.19, 0.19 175 | 192.168.0.233: 16:21:40 up 32 days, 22:22, ? users, load average: 0.15, 0.15, 0.10 176 | ``` 177 | 178 | #### 2.2.6、`dshbak` 格式化输出 179 | 180 | `pdsh` 的缺省输出格式为主机名加该主机的输出,在主机或输出多时会比较混乱,可以采用 `dshbak` 做一些格式化,让输出更清晰。 181 | 182 | ``` 183 | $ pdsh -g dsh-test -l root 'date' # 查看哪些主机时间不一样,主机一多,可读性不强 184 | 192.168.0.232: Wed Jun 19 16:24:40 CST 2013 185 | 192.168.0.231: Wed Jun 19 16:24:40 CST 2013 186 | 192.168.0.234: Wed Jun 19 16:24:40 CST 2013 187 | 192.168.0.233: Wed Jun 19 16:24:40 CST 2013 188 | ``` 189 | 190 | 使用 `dshbak` 之后可读性变得好了很多 191 | 192 | ``` 193 | $ pdsh -g dsh-test -l root 'date' | dshbak -c 194 | ---------------- 195 | 192.168.0.[231-232,234] 196 | ---------------- 197 | Wed Jun 19 16:24:18 CST 2013 198 | ---------------- 199 | 192.168.0.233 200 | ---------------- 201 | Wed Jun 19 16:24:19 CST 2013 202 | ``` 203 | 204 | ### 2.3、参考文档 205 | 206 | * [Using PDSH](https://code.google.com/p/pdsh/wiki/UsingPDSH) -------------------------------------------------------------------------------- /效率工具/screen.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /效率工具/sublime.md: -------------------------------------------------------------------------------- 1 | # Sublime Text2 2 | 3 | ## 设置 tab 为 4 个空格 4 | 5 | * Preferences/Settings - Default 6 | 7 | ``` 8 | // The number of spaces a tab is considered equal to 9 | "tab_size": 4, 10 | 11 | // Set to true to insert spaces when tab is pressed 12 | "translate_tabs_to_spaces": true, 13 | ``` 14 | 15 | ### Reference 16 | 17 | * [Settings](https://www.sublimetext.com/docs/2/settings.html) 18 | 19 | ## 设置 vim 模式 20 | 21 | * Preferences/Settings - Default 22 | 23 | ``` 24 | "ignored_packages": ["Vintage"] 25 | ``` 26 | 27 | to: 28 | 29 | ``` 30 | "ignored_packages": [] 31 | ``` 32 | 33 | * Preferences/Settings - User 34 | 35 | 默认打开文件进入 insert 模式,可设置默认打开文件为 command 模式 36 | 37 | add: 38 | 39 | ``` 40 | "vintage_start_in_command_mode": true 41 | ``` 42 | 43 | ### Reference 44 | 45 | * [Vintage Mode](https://www.sublimetext.com/docs/2/vintage.html) 46 | 47 | ## 列编辑模式 48 | 49 | * 鼠标右键 + Shift OR 鼠标中键 50 | * Add to selection: Ctrl 51 | 52 | ### Reference 53 | 54 | * [Column Selection](https://www.sublimetext.com/docs/2/column_selection.html) 55 | 56 | ## Markdown Preview 插件 57 | 58 | * Use Ctrl+Shift+P then Package Control: Install Package 59 | * Look for Markdown Preview and install it. 60 | 61 | ### Reference 62 | 63 | * [Markdown Preview](https://github.com/revolunet/sublimetext-markdown-preview) 64 | 65 | ## 撤销恢复 66 | 67 | * Ctrl+Z 撤销 68 | * Ctrl+Y 恢复撤销 69 | 70 | ## 查找替换 71 | 72 | * Ctrl+F 查找 73 | * Ctrl+H 替换 74 | 75 | ## Ctrl+P 76 | 77 | * Ctrl+P 快速跳转当前项目中的任意文件 78 | * Ctrl+P 输入 @ 快速跳转 [等同于 Ctrl+r] 79 | * Ctrl+P 输入 # 当前文件搜索 [等同于 Ctrl+f] 80 | * Ctrl+P 输入 : 跳转到指定行 81 | 82 | ## 命令调用 83 | 84 | * Ctrl+Shift+P 85 | * 命令调用,如之前 Markdown Preview 安装就调用了 Package Control: Install Package。 86 | 87 | ## Console 88 | 89 | * Ctrl+` 90 | 91 | -------------------------------------------------------------------------------- /效率工具/svn.md: -------------------------------------------------------------------------------- 1 | # 版本管理工具: SVN 2 | 3 | 本文由 [svn book 1.4](http://svndoc.iusesvn.com/svnbook/1.4) 整理而来。 4 | 5 | `svn help `: 查看子命令用法、参数及行为方式。 6 | 7 | ## 一、创建一个svn仓库 8 | 9 | + `svnadmin create /user/local/svn/newrepos`: 创建一个新的 repo 10 | + `svn import YourDir file:///usr/local/svn/newrepos/some/project -m "Init import"` : 把未版本化的文件导入版本库 11 | + `svn list file:///usr/local/svn/newrepos/some/project`: 查看文件列表 12 | + `svn export http://svn.example.com/svn/repos1` : 导出一份干净的仓库(没有.svn文件) 13 | 14 | ## 二、基本使用 15 | 16 | + `svn checkout ` : 检出到本地 17 | + `svn update` : 更新工作拷贝 18 | + `svn add foo` : 将文件、目录或者符号链添加到版本库(提交后生效) 19 | + `svn delete foo` : 将文件、目录或者符号链从版本库中移除(提交后生效) 20 | + `svn copy foo bar` : 拷贝 21 | + `svn move foo bar` : 重命名 22 | + `svn mkdir blort` : 等价于 `mkdir blort; svn add blort` 23 | + `svn status` : 浏览你所做的修改。`-v` 显示所有项目文件的状态;`-u` 显示是否过期。 24 | - `A item` : 预定加入到版本库的文件、目录或符号链的item 25 | - `C item` : 文件 item 发生冲突,在从服务器更新时与本地版本发生交跌,在你提交到版本库前,必须手工的解决冲突 26 | - `D item` : 文件、目录或是符号链 item 预定从版本库中删除 27 | - `M item` : 文件 item 的内容被修改了 28 | + `svn diff` : 查看详细的信息,`-r` 指定比较版本 29 | + `svn revert` : 取消本地修改 30 | + `svn resolved` : 解决完冲突后通知svn(当 update 有冲突时会生成 3 个临时文件: filename.mine, filename.rOLDREV, filename.rNEWREV,resolved 告诉 svn 删除那3个临时文件) 31 | + `svn commmit` : 提交修改, `-m` 添加描述修改信息 32 | + `svn log` : 查看日志,`-r` 显示某一个版本, `-v` 详细模式 33 | + `svn cat` : 取特定版本的某一个文件显示在当前屏幕,`-r` 显示指定版本 34 | + `svn list` : 显示一个目录在某一版本存在的文件 35 | + `svn cleanup` : 它查找工作拷贝中的所有遗留的日志文件,删除进程中工作拷贝的锁 36 | 37 | ## 三、高级使用 38 | 39 | ### 3.1 属性 40 | 41 | 属性不是版本化的,如果你修改,删除一个修订版本属性,SVN 没有办法恢复到以前的值。 42 | 43 | + `svn propset` : 添加和修改文件或目录的属性 44 | + `svn propedit` : 使用定制的编辑器程序来添加和修改属性 45 | + `svn proplist` : 列出路径上存在的所有属性名称 46 | + `svn propget` : 获取属性的值 47 | + `svn propdel` : 删除某个属性 48 | 49 | ### 3.2 忽略未版本控制的条目 50 | 51 | SVN 忽略方法和 git 不同,git 是在本地加一个 `.gitigore` 即可,SVN 是通过属性(svn:ignore)来实现的。 52 | 53 | `svn propedit svn:ignore work_dir` : 在工作目录 work_dir 下添加过滤文件 54 | 55 | ### 3.3 外部定义 56 | 57 | 引用场景:多个目录共享同一个目录。以游戏开发为例,UI、服务器、策划共享的数据表,这个时候就可以用到 *外部定义* 这个概念了。我理解外部定义就相当于 linux 下的软链接。 58 | 59 | 一个外部定义是一个本地路经到 URL 的影射—也有可能一个特定的修订版本—一些版本化的资源。在 SVN 你可以使用 `svn:externals` 属性来定义外部定义,你可以用 `svn propset` 或` svn propedit` 创建和修改这个属性。它可以设置到任何版本化的路经,它的值是一个多行的子目录,可选的修订版本标记和完全有效的 SVN 版本库 URL 的列表(相对于设置属性的版本化目录)。 60 | 61 | 可以使用 `--ignore-externals` 来忽略 externals。 62 | 63 | 64 | ## 四、分支与合并 65 | 66 | ### 4.1 分支创建与删除 67 | 68 | SVN 分支其实只是做了一份拷贝而已(svn copy), 但是它并不是物理意义上的拷贝(完全复制一份,可以理解成 Linux 的硬链接, *廉价复制* )。 69 | 70 | svn copy http://svn.example.com/repos/calc/trunk \ 71 | http://svn.example.com/repos/calc/branches/my-calc-branch \ 72 | -m "Creating a private branch of /calc/trunk." 73 | 74 | + `svn delete http://svn.example.com/repos/calc/branches/my-calc-branch -m "Removing obsolete branch of calc project."` : 删除一个分支 75 | 76 | ### 4.2 在分支上工作 77 | 78 | 再 `checkout` 一份呗。 79 | 80 | ### 4.3 合并分支 81 | 82 | svn diff -c 344 http://svn.example.com/repos/calc/trunk 83 | svn merge -c 344 http://svn.example.com/repos/calc/trunk 84 | 85 | 合并分支看似简单,其实是一件非常头疼的事情(尤其是大项目)。我宁愿去选择一些可视化的文本比较工作,比如 [BeyondCompare](http://www.scootersoftware.com/),可以为你省下太多事情了。 86 | 87 | [版本库管理](http://svndoc.iusesvn.com/svnbook/1.4/svn.reposadmin.html) 之后的章节感兴趣去看看(上面提供的命令足够应付大多数使用情况了) 88 | 89 | ## 五、知识点 90 | 91 | ### 5.1 四种文件状态(svn status) 92 | 93 | 1. 未修改且是当前的, 文件在工作目录里没有修改,在工作修订版本之后没有修改提交到版本库。svn commit操作不做任何事情,svn update不做任何事情。 94 | 2. 本地已修改且是当前的, 在工作目录已经修改,从基本修订版本之后没有修改提交到版本库。本地修改没有提交,因此svn commit会成功提交,svn update不做任何事情。 95 | 3. 未修改且不是当前的了, 这个文件在工作目录没有修改,但在版本库中已经修改了。这个文件最终将更新到最新版本,成为当时的公共修订版本。svn commit不做任何事情,svn update将会取得最新的版本到工作拷贝。 96 | 4. 本地已修改且不是最新的, 这个文件在工作目录和版本库都得到修改。一个svn commit将会失败,这个文件必须首先更新,svn update命令会合并公共和本地修改,如果Subversion不可以自动完成,将会让用户解决冲突。 97 | 98 | ### 5.2 修订版本关键字 99 | 100 | 这些关键字可以用来代替 `--revision(r)` 的数字参数,这会被 Subversion 解释到特定的修订版本号。 101 | 102 | + `HEAD` : 版本库中最新的(或者是 "最年轻的")版本。 103 | + `BASE` : 工作拷贝中一个条目的修订版本号,如果这个版本在本地修改了,则“BASE版本”就是这个条目在本地未修改的版本。 104 | + `COMMITTED` : 项目最近修改的修订版本,与BASE相同或更早。 105 | + `PREV` : 一个项目最后修改版本之前的那个版本,技术上可以认为是COMMITTED -1。 106 | 107 | ### 5.3 SVN 和 Git 108 | 109 | 我感觉 SVN 和 Git 设计的本质区别在于 SVN 核心点在于它的目录,而 Git 的核心点在于它的 Commit(结点)。这也就说明了 SVN 可以 checkout 某一个目录,Git 不行。SVN 的分支可以理解成一个目录,而 Git 的分支只不过是某个 Commit 上的快照而已。 110 | 111 | -------------------------------------------------------------------------------- /效率工具/tmux.md: -------------------------------------------------------------------------------- 1 | # tmux 2 | 3 | 对于终端复用工具这里推荐使用 `tmux`,当然此类工具比较好的还有 `screen` ,不过相对 [screen] (http://www.ibm.com/developerworks/cn/linux/l-cn-screen/) 这里我更倾向于推荐 `tmux` [强悍的分屏等]。 4 | 5 | 如果仅仅只是多标签的功能,那么 putty 结合一些工具也可以做到,或者干脆使用 xshell,当然 tmux 此类工具不仅仅是那么简单。另外一个选择使用 tmux/screen 工具的原因是,有时我们会经常需要 SSH 或者 telent 远程登录到 Linux 服务器,有一些任务需要长时间运行,比如系统备份、数据传输等。通常情况下我们都是开一个远程终端窗口,因为执行时间比较长,一般需要等待它执行完毕,在此过程中不能关闭窗口或者网络原因断开连接,断开之后就 Game Over 了。这个功能就有点类似 `nohup` 和 `setsid` 命令的实现了,而 `tmux/screen` 则集 `nohup/setsid` 和多标签于一身。 6 | 7 | ## 一、安装 8 | 9 | 安装的话这里就不过说明了,不同的 Linux 发行版相应的包管理机制不同,安装 `tmux` 包即可。 10 | 11 | ## 二、使用实例 12 | 13 | ### 2.1、几个名词 14 | 15 | `tmux` 主要包括以下几个模块: 16 | 17 | * session 18 | * 会话:一个服务器可以包含多个会话 19 | * window 20 | * 窗口:一个会话可以包含多个窗口 21 | * pane 22 | * 面板:一个窗口可以包含多个面板[强悍的分屏] 23 | 24 | ### 2.2、绑定快捷键 25 | 26 | 列出了 `tmux` 的几个基本模块之后,就要来点实实在在的干货了,和 `screen` 默认激活控制台的 `Ctrl+a` 不同,`tmux` 默认的是 `Ctrl+b`,使用快捷键之后就可以执行一些相应的指令了。当然如果你不习惯使用 `Ctrl+b`,也可以在 `~/.tmux` 文件中加入以下内容把快捷键变为 `Ctrl+a`: 27 | 28 | ``` 29 | # Set prefix key to Ctrl-a 30 | unbind-key C-b 31 | set-option -g prefix C-a 32 | ``` 33 | 34 | 以下所有的操作都是激活控制台之后,即键入 `Ctrl+b` 前提下才可以使用的命令 [这里假设快捷键没改,改了的话则用 `Ctrl+b` ]。 35 | 36 | ### 2.3、基本操作 37 | 38 | |操作 | 解释 | 39 | |:----- | :------------------------------------------------------------------------------- | 40 | |? | 列出所有快捷键;按 `q` 返回 | 41 | |d | 脱离当前会话,可暂时返回 Shell 界面,输入 `tmux attach` 能够重新进入之前会话 | 42 | |s | 选择并切换会话;在同时开启了多个会话时使用 | 43 | |D | 选择要脱离的会话;在同时开启了多个会话时使用 | 44 | |: | 进入命令行模式;此时可输入支持的命令,例如 kill-server 所有 tmux 会话 | 45 | |[ | 复制模式,光标移动到复制内容位置,空格键开始,方向键选择复制,回车确认,q/Esc 退出 | 46 | |] | 进入粘贴模式,粘贴之前复制的内容,按 q/Esc 退出 | 47 | |~ | 列出提示信息缓存;其中包含了之前 tmux 返回的各种提示信息 | 48 | |t | 显示当前的时间 | 49 | |Ctrl+z | 挂起当前会话 | 50 | 51 | 52 | 53 | ### 2.4、窗口操作 54 | 55 | |操作 | 解释 | 56 | |:----- | :------------------------------ | 57 | | c |创建新窗口 | 58 | | & |关闭当前窗口 | 59 | | 数字键 |切换到指定窗口 | 60 | | p |切换至上一窗口 | 61 | | n |切换至下一窗口 | 62 | | l |前后窗口间互相切换 | 63 | | w |通过窗口列表切换窗口 | 64 | | , |重命名当前窗口,便于识别 | 65 | | . |修改当前窗口编号,相当于重新排序 | 66 | | f |在所有窗口中查找关键词,便于窗口多了切换 | 67 | 68 | ### 2.5、面板操作: 69 | 70 | |操作 | 解释 | 71 | |:-------------- |:-------------------------------------------------------- | 72 | | " | 将当前面板上下分屏 | 73 | | % | 将当前面板左右分屏 | 74 | | x | 关闭当前分屏 | 75 | | ! | 将当前面板置于新窗口,即新建一个窗口,其中仅包含当前面板 | 76 | | Ctrl+方向键 | 以 1 个单元格为单位移动边缘以调整当前面板大小 | 77 | | Alt+方向键 | 以 5 个单元格为单位移动边缘以调整当前面板大小 | 78 | | 空格键 | 可以在默认面板布局中切换,试试就知道了 | 79 | | q | 显示面板编号 | 80 | | o | 选择当前窗口中下一个面板 | 81 | | 方向键 | 移动光标选择对应面板 | 82 | | { | 向前置换当前面板 | 83 | | } | 向后置换当前面板 | 84 | | Alt+o | 逆时针旋转当前窗口的面板 | 85 | | Ctrl+o | 顺时针旋转当前窗口的面板 | 86 | | z | tmux 1.8 新特性,最大化当前所在面板 | 87 | 88 | ## 三、.tmux.conf 基本配置 89 | 90 | 软件到手了,自己怎么舒服就怎么用。定制主要还是在于 `.tmux.conf` 配置文件的配置,以下列出我的配置文件: 91 | 92 | ``` 93 | # Set prefix key to Ctrl-a 94 | unbind-key C-b 95 | set-option -g prefix C-a 96 | bind-key C-a last-window # 方便切换,个人习惯 97 | bind-key a send-prefix 98 | # shell 下的 `Ctrl+a` 切换到行首在此配置下失效,此处设置之后 `Ctrl+a` 再按 a 即可切换至 shell 行首 99 | 100 | # reload settings # 重新读取加载配置文件 101 | bind R source-file ~/.tmux.conf \; display-message "Config reloaded..." 102 | 103 | # Ctrl-Left/Right cycles thru windows (no prefix) 104 | # 不使用 prefix 键,使用 Ctrl 和左右方向键方便切换窗口 105 | bind-key -n "C-Left" select-window -t :- 106 | bind-key -n "C-Right" select-window -t :+ 107 | 108 | # displays 109 | bind-key * list-clients 110 | 111 | set -g default-terminal "screen-256color" # use 256 colors 112 | set -g display-time 5000 # status line messages display 113 | set -g status-utf8 on # enable utf-8 114 | set -g history-limit 100000 # scrollback buffer n lines 115 | setw -g mode-keys vi # use vi mode 116 | 117 | # start window indexing at one instead of zero 使窗口从 1 开始,默认从 0 开始 118 | set -g base-index 1 119 | 120 | # key bindings for horizontal and vertical panes 121 | unbind % 122 | bind | split-window -h # 使用 | 竖屏,方便分屏 123 | unbind '"' 124 | bind - split-window -v # 使用 - 横屏,方便分屏 125 | 126 | # window title string (uses statusbar variables) 127 | set -g set-titles-string '#T' 128 | 129 | # status bar with load and time 130 | set -g status-bg blue 131 | set -g status-fg '#bbbbbb' 132 | set -g status-left-fg green 133 | set -g status-left-bg blue 134 | set -g status-right-fg green 135 | set -g status-right-bg blue 136 | set -g status-left-length 90 137 | set -g status-right-length 90 138 | set -g status-left '[#(whoami)]' 139 | set -g status-right '[#(date +" %m-%d %H:%M ")]' 140 | set -g status-justify "centre" 141 | set -g window-status-format '#I #W' 142 | set -g window-status-current-format ' #I #W ' 143 | setw -g window-status-current-bg blue 144 | setw -g window-status-current-fg green 145 | 146 | # pane border colors 147 | set -g pane-active-border-fg '#55ff55' 148 | set -g pane-border-fg '#555555' 149 | ``` 150 | 151 | 注:关于 256 colors 需要设置相应别名 `export ssh='TERM=xterm ssh'` 152 | 153 | ## 四、开启批量执行 154 | 155 | 如果已经修改 prefix 键位 `Ctrl+a`,则 `Ctrl+a` [默认 Ctrl+b ]后输入 `:set synchronize-panes` ,输入 :set sync [TAB] 键可自动补齐 156 | 157 | 取消批量执行模式重复之前操作即可 158 | 159 | ## 五、脚本化启动 160 | 161 | 把以下脚本内容加入到 `~/.bashrc`,即可每次登录进入到 `tmux` 162 | 163 | ``` 164 | tmux_init() 165 | { 166 | tmux new-session -s "kumu" -d -n "local" # 开启一个会话 167 | tmux new-window -n "other" # 开启一个窗口 168 | tmux split-window -h # 开启一个竖屏 169 | tmux split-window -v "top" # 开启一个横屏,并执行 top 命令 170 | tmux -2 attach-session -d # tmux -2 强制启用 256color,连接已开启的 tmux 171 | } 172 | 173 | # 判断是否已有开启的 tmux 会话,没有则开启 174 | if which tmux 2>&1 >/dev/null; then 175 | test -z "$TMUX" && (tmux attach || tmux_init) 176 | fi 177 | ``` 178 | 179 | ## 六、参考文档 180 | 181 | * [使用tmux](https://wiki.freebsdchina.org/software/t/tmux) 182 | * [archlinux tmux](https://wiki.archlinux.org/index.php/Tmux) 183 | * [Tankywoo tmux wiki](http://wiki.wutianqi.com/software/tmux.html) 184 | * [Tmux 使用心得小记 ](http://www.lovelin.info/blog/2012/10/25/tmuxshi-yong-xin-de-xiao-ji/) 185 | * [Tmux Openbsd Manual Pages](http://www.openbsd.org/cgi-bin/man.cgi?query=tmux&sektion=1) -------------------------------------------------------------------------------- /效率工具/vim.md: -------------------------------------------------------------------------------- 1 | # vim 2 | 3 | + 作者: [tankywoo](https://github.com/tankywoo) 4 | + 原文链接: [http://wiki.tankywoo.com/tool/vim.html](http://wiki.tankywoo.com/tool/vim.html) 5 | + 配置文件: [.vimrc](https://github.com/tankywoo/dotfiles/blob/master/.vimrc) 6 | 7 | 8 | ## 一、快捷键 9 | 10 | ### 1.1、Movement 11 | * `h` - Move *left* 12 | * `j` - Move *down* 13 | * `k` - Move *up* 14 | * `l` - Move *right* 15 | * `0` - Move to *beginging* of line, 也可以使用 `Home`. 16 | * `^` - 在有 tab 或 space 的代码行里, `0` 是移到最行首, 而 `^` 是移到代码行首 17 | * `$` - Move to *end* of line 18 | * `gg` - Move to *first* line of file 19 | * `G` - Move to *last* line of file 20 | * `ngg`- 移动到指定的第 n 行, 也可以用 `nG` 21 | * `w` - Move *forward* to next word 22 | * `b` - Move *backward* to next word 23 | * `%` - 在匹配的括号、块的首尾移动 24 | * `C-o`- 返回到上次移动前的位置, 也可以用两个单引号 `'` 25 | * `C-i`- 前进到后一次移动的位置 26 | * `f` - 后接字符,移动到当前行的下一个指定字符,然后按 `;` 继续搜索下一个 27 | * `F` - 同上,移动到上一个 28 | * `|` - 竖线,前接数字,移动到当前行的指定列,如 `30|` ,移动到当前行的第30列 29 | 30 | ### 1.2、Search 31 | * `*` - Search *forward* for word under cursor 32 | * `#` - Search *backward* for word under curor 33 | * `/word` - Search *forward* for *word*. Support *RE* 34 | * `?word` - Search *backward* for *word*. Support *RE* 35 | * `n` - Repeat the last `/` or `?` command 36 | * `N` - Repeat the last `/` or `?` command in opposite direction 37 | 38 | 在搜索后, 被搜索的单词都会高亮, 一般想取消那些高亮的单词, 可以再次搜索随便输入一些字母, 搜索不到自然就取消了. 另外也可以使用 `nohl` 取消这些被高亮的词. 39 | 40 | ### 1.3、Deletion 41 | * `x` - Delete character *forward*(under cursor), and remain in normal mode 42 | * `X` - Delete character *backward*(before cursor), and remain in normal mode 43 | * `r` - Replace single character under cursor, and remain in normal mode 44 | * `s` - Delete single character under cursor, and *switch* to insert mode 45 | * `shift+~` - 这个可以把光标下的单词转换为大写 / 小写, 并自动移到下一个字符 46 | * `dw` - Delete a *word* forward 47 | * `daw`- 上面的 `dw` 是删除一个单词的前向部分, 而这个是删除整个单词, 不论 cursor 是否在单词中间 48 | * `db` - Delete a *word* backward 49 | * `dd` - Delete *entire* current line 50 | * `D` - Delete until end of line 51 | 52 | 53 | ### 1.4、Yank & Put 54 | * `y` - Yank(copy) 55 | * `yy` - Yank current line 56 | * `nyy` - Yank `n` lines form current line 57 | * `p` - Put(paste) yanked text *below* current line 58 | * `P` - Put(paste) yanked text *above* current line 59 | 60 | ### 1.5、Insert Mode ### 61 | * `i` - Enter insert mode to the *left* of the cursor 62 | * `a` - Enter insert mode to the *right* of the cursor 63 | * `o` - Enter insert mode to the line *below* the current line 64 | * `O` - Enter insert mode to the line *above* the current line 65 | 66 | ### 1.6、Visual Mode 67 | * `v` - Enter visual mode, highlight characters 68 | * `V` - Enter visual mode, highlight lines 69 | * `C-v` - Enter visual mode, highlight block 70 | 71 | ### 1.7、Other 72 | * `u` - Undo 73 | * `U` - Undo all changes on current line 74 | * `C-r` - Redo 75 | 76 | ### 1.8、Read More 77 | 78 | * [A handy guide to Vim shortcuts](http://eastcoastefx.vaesite.com/vim) 79 | * [tuxfiles-vimcheat](http://www.tuxfiles.org/linuxhelp/vimcheat.html) 80 | * [What is your most productive shortcut with Vim?](http://stackoverflow.com/questions/1218390/what-is-your-most-productive-shortcut-with-vim) 81 | 82 | 83 | ## 二、技巧 84 | 85 | ### 2.1、shell 多行注释 86 | 87 | 命令行模式下,注释掉 line1 与 line2 之间的行 88 | 89 | line1,line2s/^/#/g 90 | 91 | 92 | ### 2.2、自动补全 93 | 94 | Ctrl+n Ctrl+p 95 | Ctrl+x Ctrl+?{....} 96 | 97 | ### 2.3、左右分割打开 help 文档 98 | 99 | 默认是上下分割来打开文档,但是对于宽屏,左右分割反而更加方便 100 | 101 | :vert help xxx 102 | 103 | 104 | ### 2.4、逐个替换 105 | 106 | 全文直接替换: 107 | 108 | :%s/old_str/new_str/g 109 | 110 | 加上参数c可以逐个替换,这样可以对每一个再确认: 111 | 112 | :%s/old_str/new_str/gc 113 | 114 | 115 | ### 2.5、关于 search/replace 中的换行符 116 | 117 | Search: 118 | 119 | `\n` is `newline`, `\r` is `CR`(carriage return = Ctrl-M = ^M) 120 | 121 | Replace: 122 | 123 | `\r` is newline, `\n` is a null byte(0x00) 124 | 125 | 比如字符串 test1,test2,test3 把逗号换成换行: 126 | 127 | %s/,/\r/g 128 | 129 | ### 2.6、结合 github 管理插件 Vundle 130 | 131 | * [Vundle](https://github.com/gmarik/Vundle.vim) 132 | 133 | 134 | ## 三、参考 ## 135 | 136 | * [How to replace a character for a newline in Vim?](http://stackoverflow.com/questions/71323/how-to-replace-a-character-for-a-newline-in-vim) 137 | * [Why is \r a newline for Vim?](http://stackoverflow.com/questions/71417/why-is-r-a-newline-for-vim) 138 | * [How can I add a string to the end of each line in Vim?](http://stackoverflow.com/questions/594448/how-can-i-add-a-string-to-the-end-of-each-line-in-vim) 139 | -------------------------------------------------------------------------------- /数据库/mysql.md: -------------------------------------------------------------------------------- 1 | # MySQL 2 | 3 | 本篇由我「印象笔记」的一些片段文章整理而成,参考了很多文章,但是把很多原文链接都忘掉了,在此对原作者表示歉意。 4 | 5 | ## 1. 安装 6 | 7 | + CentOS: `yum install msyql` 8 | + Ubuntu: `apt-get install mysql-server` 9 | + Mac: `brew install mysql` 10 | 11 | ## 2. 配置 12 | 13 | + 查找本机配置文件位置: `mysql --help | grep cnf` 14 | 15 | ## 3. 使用 16 | 17 | ### 3.1 登录 18 | 19 | `mysql -hhost -uuser_name -puser_password [db_name.table_name]` 20 | 21 | ### 3.2 权限 22 | 23 | + 查询所有用户: `select User from mysql.user` 24 | + 创建用户: `create user username identified by 'password'` 25 | + 删除用户: `delete from mysql.user where User="xxx` -> `flush privileges` 26 | + 授权: `grant all privileges on db_name.tablename to username` 27 | + 撤销权限: `REVOKE PRIVILEGES ON db_name.* FROM 'user_name'@'localhost';` 28 | + 创建用户并赋权限: `grant all privileges on db_name.* to news_user@'localhost' identified by 'news_password'`, `@` 后面是限制的主机,可以是 IP 或者 IP 段,`%`表示任何地方。 29 | + 查看用户权限: `SHOW GRANTS FOR user_name` 或者 `SELECT * FROM mysql.user WHERE user='user_name' \G` 30 | 31 | ### 3.3 数据类型 32 | 33 | ** BLOB 和 TEXT ** 34 | 35 | BLOB 四种类型: `TINYBLOB`, `BLOB`, `MEDIUMBLOB`, `LONGBLOB`。 36 | 37 | TEXT 四种类型: `TINYTEXT`, `TEXT`, `MEDIUMTEXT`, `LONGTEXT`。 38 | 39 | 区别: 40 | 41 | 1. BLOB 被视为二进制字符串, TEXT被视为非二进制字符串; 42 | 2. BLOB列没有字符集,并且排序和比较基于列值字节的数值值。TEXT列有一个字符集,并且根据字符集的校对规则对值进行排序和比较。 43 | 44 | ** BLOB 和 TEXT 与 VARBINARY 和 VARCHAR 的不同 ** 45 | 46 | 1. BLOB 和 TEXT 列不能有默认值 47 | 2. 当保存或检索 BLOB 和 TEXT 列的值时不删除尾部空格。(这与 VARBINARY 和 VARCHAR 列相同) 48 | 3. 对于 BLOB 和 TEXT 列的索引,必须指定索引前缀的长度。对于 CHAR 和 VARCHAR,前缀长度是可选的. 49 | 50 | ### 3.4 数据库 51 | 52 | + 建库: `CREATE DATABASES db_name [charset="utf8"]` 53 | + 删库: `DROP DATABASES db_name` 54 | + 查看当前使用的数据库: ` select database();` 55 | 56 | ### 3.4 数据表 57 | 58 | + 建表: `CREATE TABLE tbl_name ( [,.. ])` 59 | + 删表: `DROP TABLE tbl_name` 60 | + 显示表的结构: `desc tbl_name`, `show columns from tbl_name` 61 | + 增加列: `ALTER TABLE tbl_name ADD col_name TYPE` 62 | + 删除列: `ALTER TABLE tbl_name DROP col_name` 63 | + 修改列: `ALTER TABLE tbl_name MODIFY col_name TYPE` 64 | + 改变表的名字: `ALTER TABLE tbl_name RENAME new_tbl_name` 65 | + 总条目数: `SELECT COUNT(*) FROM tbl_name` 66 | + 查看建表语句: `SHOW CREATE TABLE tbl_name \G` 67 | 68 | 索引: 69 | 70 | + 查看索引: `show index from tblname` or `show keys from tblname` 71 | + 创建索引: 72 | 73 | ALTER TABLE table_name ADD INDEX index_name (column_list) 74 | ALTER TABLE table_name ADD UNIQUE (column_list) 75 | ALTER TABLE table_name ADD PRIMARY KEY (column_list) 76 | 77 | CREATE INDEX index_name ON table_name (column_list) 78 | CREATE UNIQUE INDEX index_name ON table_name (column_list) 79 | 80 | + 删除索引: 81 | 82 | DROP INDEX index_name ON table_name 83 | ALTER TABLE table_name DROP INDEX index_name 84 | ALTER TABLE table_name DROP PRIMARY KEY 85 | 86 | 87 | 查询记录: 88 | 89 | + `sql = "select * from 数据表 where 字段名=字段值 order by 字段名 [desc]"` 90 | + `sql = "select * from 数据表 where 字段名 like '%字段值%' order by 字段名 [desc]"` 91 | + `sql = "select top 10 * from 数据表 where 字段名 order by 字段名 [desc]"` 92 | + `sql = "select * from 数据表 where 字段名 in ('值1','值2','值3')"` 93 | + `sql = "select * from 数据表 where 字段名 between 值1 and 值2"` 94 | 95 | 更新数据记录: 96 | 97 | * `sql="update 数据表 set 字段名=字段值 where 条件表达式"` 98 | * `sql="update 数据表 set 字段1=值1,字段2=值2 字段n=值n where 条件表达式"` 99 | 100 | 删除数据记录: 101 | 102 | * `sql="delete from 数据表 where 条件表达式"` 103 | * `sql="delete from 数据表" (将数据表所有记录删除)` 104 | 105 | 添加数据记录: 106 | 107 | * `sql="insert into 数据表 (字段1,字段2,字段3 …) values (值1,值2,值3 …)"` 108 | * `sql="insert into 目标数据表 select * from 源数据表" (把源数据表的记录添加到目标数据表)` 109 | 110 | `DISTINCT` 使用: 111 | 112 | 位置: `DISTINCT` 只能放到开头,但是与其他查询函数一起使用的时候,没有位置限制: `select play_id, count(distinct(task_id)) from task;` 113 | 114 | 举例: 115 | 116 | + 在 count 计算不重复的记录的时候能用到: `SELECT COUNT( DISTINCT player_id ) FROM task; 就是计算表中 id 不同的记录有多少条` 117 | + 在需要返回记录不同的 id 的具体值的时候可以用: `SELECT DISTINCT player_id FROM task; 返回表中不同的 id 的具体的值` 118 | + 上面的 情况2 对于需要返回 mysql 表中 2 列以上的结果时会有歧义: `SELECT DISTINCT player_id, task_id FROM task;` 实际上返回的是 `player_id` 与 `task_id` 同时不相同的结果,也就是 DISTINCT 同时作用了两个字段,必须得 `player_id` 与 `task_id` 都相同的才被排除了, 与我们期望的结果不一样,我们期望的是 player\_id 不同被过滤, 在这种情况下,distinct 同时作用了两个字段,player\_id, task\_id。这时候可以考虑使用 `group_concat` 函数来进行排除,不过这个 mysql 函数是在 mysql4.1 以上才支持的 119 | + 其实还有另外一种解决方式, 就是使用 `SELECT player_id, task_id, count(DISTINCT player_id) FROM task` 虽然这样的返回结果多了一列无用的count数据(有时也许就需要这个数据) 120 | + 同时我们还可以利用下面的方式解决上面遇到的歧义问题通过 group by 分组: `select player_id, task_id from task group by player_id` 121 | 122 | ## 4. 函数 123 | 124 | 日期和时间函数: 125 | 126 | * `DAYOFWEEK(date)`: 返回日期 date 的星期索引(1=星期天,2=星期一, ……7=星期六) 127 | * `WEEKDAY(date)`: 返回 date 的星期索引(0=星期一,1=星期二, ……6= 星期天) 128 | * `DAYOFMONTH(date)`: 返回 date 的月份中日期,在 1 到 31 范围内 129 | * `DAYOFYEAR(date)`: 返回 date 在一年中的日数, 在 1 到 366 范围内 130 | * `DAYNAME(date)` : 返回 date 的星期名字 131 | * `MONTHNAME(date)` : 返回 date 的月份名字 132 | * `QUARTER(date)` : 返回 date 一年中的季度,范围 1 到 4 133 | * `WEEK(date)` 134 | * `WEEK(date,first)` : 对于星期天是一周的第一天的地方,有一个单个参数,返回 date 的周数,范围在 0 到 52。2 个参数形式 WEEK() 允许你指定星期是否开始于星期天或星期一。如果第二个参数是 0 ,星期从星期天开始,如果第二个参数是1,从星期一开始。 135 | * `YEAR(date)` : 返回 date 的年份,范围在 1000 到 9999。 136 | * `MINUTE(time)` : 返回 time 的分钟,范围是 0 到 59。 137 | * `SECOND(time)` : 回来 time 的秒数,范围是 0 到 59。 138 | * `PERIOD_ADD(P,N)` : 增加 N 个月到阶段 P (以格式YYMM或YYYYMM)。以格式 YYYYMM 返回值。注意阶段参数 P 不是日期值。 139 | * `PERIOD_DIFF(P1,P2)` : 返回在时期 P1 和 P2 之间月数,P1 和 P2应该以格式 YYMM 或 YYYYMM。注意,时期参数 P1 和 P2 不是日期值。 140 | * `DATE_ADD(date,INTERVAL expr type)`, `DATE_SUB(date,INTERVAL expr type)`, `ADDDATE(date,INTERVAL expr type)`, `SUBDATE(date,INTERVAL expr type)` 这些功能执行日期运算 141 | * `TO_DAYS(date)`: 给出一个日期 date,返回一个天数(从 0 年的天数)。 142 | * `FROM_DAYS(N)` : 给出一个天数 N,返回一个 DATE 值 143 | * `DATE_FORMAT(date,format)` : 根据 format 字符串格式化 date 值 144 | * `TIME_FORMAT(time,format)` : 这象上面的 DATE_FORMAT() 函数一样使用,但是 format 字符串只能包含处理小时、分钟和秒的那些格式修饰符。其他修饰符产生一个NULL值或 0。 145 | * `CURDATE()` 146 | * `CURRENT_DATE`: 以 'YYYY-MM-DD' 或 'YYYYMMDD' 格式返回今天日期值,取决于函数是在一个字符串还是数字上下文被使用。 147 | * `CURTIME()` 148 | * `CURRENT_TIME` : 以 'HH:MM:SS' 或 'HHMMSS' 格式返回当前时间值,取决于函数是在一个字符串还是在数字的上下文被使用。 149 | * `NOW()`, `SYSDATE()`,`CURRENT_TIMESTAMP`: 以'YYYY-MM-DD HH:MM:SS'或 'YYYYMMDDHHMMSS' 格式返回当前的日期和时间,取决于函数是在一个字符串还是在数字的上下文被使用。 150 | * `UNIX_TIMESTAMP()` 151 | * `UNIX_TIMESTAMP(date)` : 如果没有参数调用,返回一个 Unix 时间戳记(从'1970-01-01 00:00:00'GMT开始的秒数)。如果 UNIX_TIMESTAMP() 用一个 date 参数被调用,它返回从'1970-01-01 00:00:00' GMT开始的秒数值。date 可以是一个 DATE 字符串、一个 DATETIME 字符串、一个 TIMESTAMP 或以 YYMMDD 或 YYYYMMDD 格式的本地时间的一个数字。 152 | * `FROM_UNIXTIME(unix_timestamp)` : 以'YYYY-MM-DD HH:MM:SS' 或 `YYYYMMDDHHMMSS` 格式返回 unix_timestamp 参数所表示的值,取决于函数是在一个字符串还是或数字上下文中被使用。 153 | * `SEC_TO_TIME(seconds)` : 返回 `seconds` 参数,变换成小时、分钟和秒,值以 `HH:MM:SS` 或 `HHMMSS` 格式化,取决于函数是在一个字符串还是在数字上下文中被使用。 154 | * `TIME_TO_SEC(time)` : 返回 time 参数,转换成秒。 155 | 156 | 与 `GROUP BY` 子句一起使用的函数: 157 | 158 | * `COUNT(expr)` : 返回由一个 SELECT 语句检索出来的行的非 NULL 值的数目 159 | * `COUNT(DISTINCT expr,[expr...])` : 返回一个不同值的数目 160 | * `AVG(expr)` : 返回 expr 的平均值 161 | * `MIN(expr)`, `MAX(expr)` : 返回 expr 的最小或最大值。MIN() 和 MAX() 可以有一个字符串参数 162 | * `SUM(expr)` : 返回 expr 的和。注意,如果返回的集合没有行,它返回NULL 163 | 164 | 其他函数: 165 | 166 | * `DATABASE()` : 返回当前的数据库名字。 167 | * `USER()`, `SYSTEM_USER()`, `SESSION_USER()` : 返回当前 MySQL 用户名。 168 | * `PASSWORD(str)` : 从纯文本口令 str 计算一个口令字符串。该函数被用于为了在 user 授权表的 Password 列中存储口令而加密 MySQL 口令 169 | * `ENCRYPT(str[,salt])`: 使用 Unix crypt() 系统调用加密 str。salt 参数应该是一个有2个字符的字符串。(MySQL 3.22.16中,salt可以长于2个字符。) 170 | * `ENCODE(str,pass_str)` : 使用 pass_str 作为口令加密 str。为了解密结果,使用 DECODE()。结果是一个二进制字符串,如果你想要在列中保存它,使用一个 BLOB 列类型。 171 | * `DECODE(crypt_str,pass_str)` : 使用 `pass_str` 作为口令解密加密的字符串 `crypt_str`。crypt_str 应该是一个由 ENCODE()返回的字符串。 172 | * `MD5(string)` : 对字符串计算 MD5校验和。值作为一个32长的十六进制数字被返回可以,例如用作哈希(hash)键。 173 | * `LAST_INSERT_ID([expr])` : 返回被插入一个 AUTO_INCREMENT 列的最后一个自动产生的值 174 | * `FORMAT(X,D)` 格式化数字X为类似于格式 '#,###,###.##',四舍五入到D为小数。如果D为0,结果将没有小数点和小数部分。 175 | * `VERSION()` 返回表明MySQL服务器版本的一个字符串。 176 | 177 | ## 5. 导入导出 178 | 179 | ### 5.1 导出某个库 180 | 181 | mysqldump -h$host -u$user -p$password $database > xxx.sql 182 | 183 | ### 5.2 导出指定表 184 | 185 | mysqldump -h$host -u$user -p$password $database $table > xxx.sql 186 | 187 | ### 5.3 只导出表结构 188 | 189 | mysqldump -h$host -u$user -p$password $database --no-data > xxx.sql 190 | 191 | ### 5.4导入 192 | 193 | 导出的结果其实就是一连串的sql语句,所以导入只需要执行xxx.sql里的语句 194 | 195 | mysql -h$host -u$user -p$password $database < xxx.sql 196 | 197 | ## 6. Tips 198 | 199 | + 在控制台执行一条SQL语句: `mysql -h127.0.0.1 -uuser -ppassword db_name -e "select xxx from xxx" > aa.txt` 200 | + 控制台中文乱码: `set names 'utf8'` 201 | + Mysql 报错: Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC ... 解决方案: [innodb使用大字段text,blob的一些优化建议](http://hidba.org/?p=551)。 202 | + [Get record counts for all tables in MySQL database]( http://stackoverflow.com/questions/286039/get-record-counts-for-all-tables-in-mysql-database) 203 | 204 | ## 7. 扩展资料 205 | 206 | + [SQL truncate 、delete与drop区别](http://www.cnblogs.com/8765h/archive/2011/11/25/2374167.html) 207 | + [MYSQL数据库管理之权限管理](http://blog.chinaunix.net/uid-20639775-id-3249105.html) 208 | + [根据多年经验整理的《互联网MySQL开发规范》](http://blog.sina.com.cn/s/blog_1380b3f180102vsg5.html) 209 | -------------------------------------------------------------------------------- /数据库/nosql-compare.md: -------------------------------------------------------------------------------- 1 | # NoSQL 比较 2 | 3 | ## CouchDB 4 | 5 | + 所用语言: Erlang 6 | + 特点:DB一致性,易于使用 7 | + 使用许可: Apache 8 | + 协议: HTTP/REST 9 | + 双向数据复制, 10 | + 持续进行或临时处理, 11 | + 处理时带冲突检查, 12 | + 因此,采用的是master-master复制(见编注2) 13 | + MVCC – 写操作不阻塞读操作 14 | + 可保存文件之前的版本 15 | + Crash-only(可靠的)设计 16 | + 需要不时地进行数据压缩 17 | + 视图:嵌入式 映射/减少 18 | + 格式化视图:列表显示 19 | + 支持进行服务器端文档验证 20 | + 支持认证 21 | + 根据变化实时更新 22 | + 支持附件处理 23 | + 因此, CouchApps(独立的 js应用程序) 24 | + 需要 jQuery程序库 25 | 26 | 27 | 最佳应用场景:**适用于数据变化较少,执行预定义查询,进行数据统计的应用程序。适用于需要提供数据版本支持的应用程序。** 28 | 29 | 例如: CRM、CMS系统。 master-master复制对于多站点部署是非常有用的。 30 | 31 | ## Redis 32 | 33 | + 所用语言:C/C++ 34 | + 特点:运行异常快 35 | + 使用许可: BSD 36 | + 协议:类 Telnet 37 | + 有硬盘存储支持的内存数据库, 38 | + 但自2.0版本以后可以将数据交换到硬盘(注意, 2.4以后版本不支持该特性!) 39 | + Master-slave复制(见编注3) 40 | + 虽然采用简单数据或以键值索引的哈希表,但也支持复杂操作,例如 ZREVRANGEBYSCORE。 41 | + INCR & co (适合计算极限值或统计数据) 42 | + 支持 sets(同时也支持 union/diff/inter) 43 | + 支持列表(同时也支持队列;阻塞式 pop操作) 44 | + 支持哈希表(带有多个域的对象) 45 | + 支持排序 sets(高得分表,适用于范围查询) 46 | + Redis支持事务 47 | + 支持将数据设置成过期数据(类似快速缓冲区设计) 48 | + Pub/Sub允许用户实现消息机制 49 | 50 | 最佳应用场景: **适用于数据变化快且数据库大小可遇见(适合内存容量)的应用程序。** 51 | 52 | 例如:股票价格、数据分析、实时数据搜集、实时通讯。 53 | 54 | ## MongoDB 55 | 56 | + 所用语言:C++ 57 | + 特点:保留了SQL一些友好的特性(查询,索引)。 58 | + 使用许可: AGPL(发起者: Apache) 59 | + 协议: Custom, binary( BSON) 60 | + Master/slave复制(支持自动错误恢复,使用 sets 复制) 61 | + 内建分片机制 62 | + 支持 javascript表达式查询 63 | + 可在服务器端执行任意的 javascript函数 64 | + update-in-place支持比CouchDB更好 65 | + 在数据存储时采用内存到文件映射 66 | + 对性能的关注超过对功能的要求 67 | + 建议最好打开日志功能(参数 –journal) 68 | + 在32位操作系统上,数据库大小限制在约2.5Gb 69 | + 空数据库大约占 192Mb 70 | + 采用 GridFS存储大数据或元数据(不是真正的文件系统) 71 | 72 | 最佳应用场景:**适用于需要动态查询支持;需要使用索引而不是 map/reduce功能;需要对大数据库有性能要求;需要使用 CouchDB但因为数据改变太频繁而占满内存的应用程序。** 73 | 74 | 例如:你本打算采用 MySQL或 PostgreSQL,但因为它们本身自带的预定义栏让你望而却步。 75 | 76 | ## Riak 77 | 78 | + 所用语言:Erlang和C,以及一些Javascript 79 | + 特点:具备容错能力 80 | + 使用许可: Apache 81 | + 协议: HTTP/REST或者 custom binary 82 | + 可调节的分发及复制(N, R, W) 83 | + 用 JavaScript or Erlang在操作前或操作后进行验证和安全支持。 84 | + 使用JavaScript或Erlang进行 Map/reduce 85 | + 连接及连接遍历:可作为图形数据库使用 86 | + 索引:输入元数据进行搜索(1.0版本即将支持) 87 | + 大数据对象支持( Luwak) 88 | + 提供“开源”和“企业”两个版本 89 | + 全文本搜索,索引,通过 Riak搜索服务器查询( beta版) 90 | + 支持Masterless多站点复制及商业许可的 SNMP监控 91 | 92 | 最佳应用场景: **适用于想使用类似 Cassandra(类似Dynamo)数据库但无法处理 bloat及复杂性的情况。适用于你打算做多站点复制,但又需要对单个站点的扩展性,可用性及出错处理有要求的情况。** 93 | 94 | 例如:销售数据搜集,工厂控制系统;对宕机时间有严格要求;可以作为易于更新的 web服务器使用。 95 | 96 | 97 | ## Membase 98 | 99 | + 所用语言: Erlang和C 100 | + 特点:兼容 Memcache,但同时兼具持久化和支持集群 101 | + 使用许可: Apache 2.0 102 | + 协议:分布式缓存及扩展 103 | + 非常快速(200k+/秒),通过键值索引数据 104 | + 可持久化存储到硬盘 105 | + 所有节点都是唯一的( master-master复制) 106 | + 在内存中同样支持类似分布式缓存的缓存单元 107 | + 写数据时通过去除重复数据来减少 IO 108 | + 提供非常好的集群管理 web界面 109 | + 更新软件时软无需停止数据库服务 110 | + 支持连接池和多路复用的连接代理 111 | 112 | 最佳应用场景: **适用于需要低延迟数据访问,高并发支持以及高可用性的应用程序** 113 | 114 | ## Neo4j 115 | 116 | + 所用语言: Java 117 | + 特点:基于关系的图形数据库 118 | + 使用许可: GPL,其中一些特性使用 AGPL/商业许可 119 | + 协议: HTTP/REST(或嵌入在 Java中) 120 | + 可独立使用或嵌入到 Java应用程序 121 | + 图形的节点和边都可以带有元数据 122 | + 很好的自带web管理功能 123 | + 使用多种算法支持路径搜索 124 | + 使用键值和关系进行索引 125 | + 为读操作进行优化 126 | + 支持事务(用 Java api) 127 | + 使用 Gremlin图形遍历语言 128 | + 支持 Groovy脚本 129 | + 支持在线备份,高级监控及高可靠性支持使用 AGPL/商业许可 130 | 131 | 132 | 最佳应用场景:**适用于图形一类数据。这是 Neo4j与其他nosql数据库的最显著区别。** 133 | 134 | 例如:社会关系,公共交通网络,地图及网络拓谱 135 | 136 | ## Cassandra 137 | 138 | + 所用语言: Java 139 | + 特点:对大型表格和 Dynamo支持得最好 140 | + 使用许可: Apache 141 | + 协议: Custom, binary (节约型) 142 | + 可调节的分发及复制(N, R, W) 143 | + 支持以某个范围的键值通过列查询 144 | + 类似大表格的功能:列,某个特性的列集合 145 | + 写操作比读操作更快 146 | + 基于 Apache分布式平台尽可能地 Map/reduce 147 | + 我承认对 Cassandra有偏见,一部分是因为它本身的臃肿和复杂性,也因为 Java的问题(配置,出现异常,等等) 148 | 149 | 最佳应用场景:**当使用写操作多过读操作(记录日志)如果每个系统组建都必须用 Java编写(没有人因为选用 Apache的软件被解雇)** 150 | 151 | 例如:银行业,金融业(虽然对于金融交易不是必须的,但这些产业对数据库的要求会比它们更大)写比读更快,所以一个自然的特性就是实时数据分析 152 | 153 | ## HBase 154 | 155 | (配合 ghshephard使用) 156 | 157 | + 所用语言: Java 158 | + 特点:支持数十亿行X上百万列 159 | + 使用许可: Apache 160 | + 协议:HTTP/REST (支持 Thrift,见编注4) 161 | + 在 BigTable之后建模 162 | + 采用分布式架构 Map/reduce 163 | + 对实时查询进行优化 164 | + 高性能 Thrift网关 165 | + 通过在server端扫描及过滤实现对查询操作预判 166 | + 支持 XML, Protobuf, 和binary的HTTP 167 | + Cascading, hive, and pig source and sink modules 168 | + 基于 Jruby( JIRB)的shell 169 | + 对配置改变和较小的升级都会重新回滚 170 | + 不会出现单点故障 171 | + 堪比MySQL的随机访问性能 172 | 173 | 最佳应用场景:**适用于偏好BigTable:)并且需要对大数据进行随机、实时访问的场合。** 174 | 175 | 例如: Facebook消息数据库(更多通用的用例即将出现) 176 | 177 | 来源: 178 | 179 | 1. [8种Nosql数据库系统对比](http://blog.jobbole.com/1344/) 180 | 2. [英文出处](http://kkovacs.eu/cassandra-vs-mongodb-vs-couchdb-vs-redis) 181 | -------------------------------------------------------------------------------- /数据库/redis.md: -------------------------------------------------------------------------------- 1 | # Redis 2 | 3 | ## 资料 4 | 5 | + [redis快速入门详解](http://airjd.com/view/i80zyhkb000ec5j) 6 | + [Redis 命令参考](http://redisdoc.com/): 这个略厉害了 7 | -------------------------------------------------------------------------------- /服务/Docker.md: -------------------------------------------------------------------------------- 1 | # 轻量级虚拟化Docker 2 | 3 | ## 一、Docker 基本介绍 4 | 5 | Docker发端于一个名为dotcloud的开源项目;随着编写者不断挖掘它的潜力,它迅速变成了一个炙手可热的项目。它由GO语言编写的,并且只支持Linux。它基于Linux容器(LxC)来创建一个虚拟环境。Docker不会通过建立独有的操作系统、进程和对硬件进行模拟来创建属于自己的虚拟机。请注意:虚拟环境VE(Virtual Environment)和虚拟机(VM)很不一样。虚拟机是由虚拟工具或者模拟器(HyperV 、VMWare等)创建的,是一个全镜像的主机源,其中包括操作系统、硬盘调整、网络和虚拟进程。过于臃肿的结构吃掉了大量的硬盘空间同时拖慢了运行和开机速度。 6 | 7 | 一台VE就像是轻量级的VM,它在已有的内核关于底层硬件的镜像上建立一个可以用来运行应用的‘容器’。它也可以用来创建操作系统,因为所谓的操作系统也不过是一个跑在内核上的应用而已。可以把Docker想象成LxC的一个强化版,只是具有以下LxC所不具有的特性: 8 | 9 | - **强大的可移植性**:你可以使用Docker创造一个绑定了你所有你所需要的应用的对象。这个对象可以被转移并被安装在任何一个安装了 Docker 的 Linux 主机上。 10 | - **版本控制**: Docker自带git功能,能够跟踪一个容器的成功版本并记录下来,并且可以对不同的版本进行检测,提交新版本,回滚到任意的一个版本等功能等等。 11 | - **组件的可重用性**: Docker 允许创建或是套用一个已经存在的包。举个例子,如果你有许多台机器都需要安装 Apache 和 MySQL 数据库,你可以创建一个包含了这两个组件的‘基础镜像’。然后在创建新机器的时候使用这个镜像进行安装就行了。 12 | - **可分享的类库**:已经有上千个可用的容器被上传并被分享到一个共有仓库中[registry.hub.docker.com](https://registry.hub.docker.com/)。考虑到AWS对于不同环境下的调试和发布,这一做法是十分聪明的。 13 | 14 | > LxC是一个Linux提供的收容功能接口,通过LxC提供的API和简单的工具,使得Linux用户可以简单的创建和管理系统或者应用的空间。[LXC容器](http://www.ibm.com/developerworks/cn/linux/l-lxc-containers/) 15 | 16 | Docker 通常用于如下场景: 17 | 18 | web应用的自动化打包和发布; 19 | 自动化测试和持续集成、发布; 20 | 在服务型环境中部署和调整数据库或其他的后台应用; 21 | 从头编译或者扩展现有的OpenShift或Cloud Foundry平台来搭建自己的PaaS环境。 22 | 23 | Docker实践解决方案: 24 | 25 | - 隔离性:Docker在文件系统和网络级别隔离了应用。从这个意义上来讲很像在运行”真正的“虚拟机。 26 | - 重复性:用你喜欢的方式准备系统(登录并在所有软件里执行apt-get命令,或者使用Dockerfile),然后把修改提交到镜像中。你可以随意实例化若干个实例,或者把镜像传输到另一台机器,完全重现同样的设置。 27 | - 安全性:Docker容器比普通的进程隔离更为安全。Docker团队已经确定了一些安全问题,正在着手解决。 28 | - 资源约束:Docker现在能限制CPU的使用率和内存用量。目前还不能直接限制磁盘的使用情况。 29 | - 易于安装:Docker有一个Docker Index,这个仓库存储了现成的Docker镜像,你用一条命令就可以完成实例化。比如说,要使用Clojure REPL镜像,只要运行docker run -t -i zefhemel/clojure-repl命令就能自动获取并运行该镜像。 30 | - 易于移除:不需要应用了?销毁容器就行。 31 | - 升级、降级:和EC2VM一样:先启动应用的新版本,然后把负载均衡器切换到新的端口。 32 | - 快照、备份:Docker能提交镜像并给镜像打标签,和EC2上的快照不同,Docker是立即处理的。 33 | 34 | 参考文档: 35 | 36 | - [Docker Getting Start: Related Knowledge ](http://tiewei.github.io/cloud/Docker-Getting-Start/) 37 | - [谁是容器中的“战斗机”?Docker与Chef、LXC等容器对比](http://code.csdn.net/news/2819773) 38 | - [Docker:利用Linux容器实现可移植的应用部署](http://www.infoq.com/cn/articles/docker-containers) 39 | 40 | ## 二、docker 安装配置 41 | 42 | ### 2.1、Docker install 43 | 44 | Docker的安装非常简单,这里只介绍Ubuntu 14.04的安装,其他发行版本的安装可以参考官网手册。 45 | 46 | ``` bash 47 | $ sudo apt-get update 48 | $ sudo apt-get install docker.io 49 | $ sudo ln -sf /usr/bin/docker.io /usr/local/bin/docker 50 | ``` 51 | 52 | 获取当前docker版本 53 | 54 | ``` bash 55 | $ sudo docker version 56 | Client version: 1.1.1 57 | Client API version: 1.13 58 | Go version (client): go1.2.1 59 | Git commit (client): bd609d2 60 | Server version: 1.1.1 61 | Server API version: 1.13 62 | Go version (server): go1.2.1 63 | Git commit (server): bd609d2 64 | ``` 65 | 66 | - [Docker install on ubuntu](http://docs.docker.io/installation/ubuntulinux/) 67 | 68 | ## 三、Docker images 69 | 70 | - [Docker index](https://registry.hub.docker.com/) Docker镜像首页,包括官方镜像和其它公开镜像 71 | 72 | ### 3.1、Search index images 73 | 74 | ``` bash 75 | $ sudo docker search ubuntu 76 | ``` 77 | 78 | ### 3.2、Pull images 79 | 80 | ``` bash 81 | $ sudo docker pull ubuntu # remote index 获取ubuntu官方镜像 82 | $ sudo docker images # 查看当前镜像列表 83 | REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE 84 | ubuntu 13.10 5e019ab7bf6d 3 weeks ago 180 MB 85 | ubuntu saucy 5e019ab7bf6d 3 weeks ago 180 MB 86 | ubuntu 12.04 74fe38d11401 3 weeks ago 209.6 MB 87 | ... ... 88 | ``` 89 | 90 | ### 3.3、Running an interactive shell 91 | 92 | ``` bash 93 | $ sudo docker run -i -t ubuntu:14.04 /bin/bash 94 | ``` 95 | 96 | - docker run - 运行一个容器 97 | - -t - 分配一个(伪)tty (link is external) 98 | - -i - 交互模式(so we can interact with it) 99 | - ubuntu - 使用ubuntu基础镜像 100 | - /bin/bash - 运行bash shell 101 | 102 | 103 | __注:__ ubuntu会有多个版本,通过指定tag来启动特定的版本[image]:[tag] 104 | 105 | ``` bash 106 | $ sudo docker ps # 查看当前运行的容器, ps -a列出当前系统所有的容器 107 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 108 | 6c9129e9df10 ubuntu:14.04 /bin/bash 6 minutes ago Up 6 minutes cranky_babbage 109 | ``` 110 | 111 | ### 3.4、相关快捷键 112 | 113 | - 退出:`Ctrl-D` or `exit` 114 | - detach:`Ctrl-p + Ctrl-q` 115 | - attach: `docker attach CONTAINER ID` 116 | 117 | ## 四、docker常用命令 118 | 119 | ### 4.1、docker help 120 | 121 | ``` bash 122 | $ sudo docker # docker命令帮助 123 | Usage: docker [OPTIONS] COMMAND [arg...] 124 | -H=[unix:///var/run/docker.sock]: tcp://host:port to bind/connect to or unix://path/to/socket to use 125 | 126 | A self-sufficient runtime for linux containers. 127 | 128 | Commands: 129 | attach Attach to a running container # 当前shell下attach连接指定运行镜像 130 | build Build an image from a Dockerfile # 通过Dockerfile定制镜像 131 | commit Create a new image from a container's changes # 提交当前容器为新的镜像 132 | cp Copy files/folders from the containers filesystem to the host path 133 | # 从容器中拷贝指定文件或者目录到宿主机中 134 | diff Inspect changes on a container's filesystem # 查看docker容器变化 135 | events Get real time events from the server # 从docker服务获取容器实时事件 136 | export Stream the contents of a container as a tar archive 137 | # 导出容器的内容流作为一个tar归档文件[对应import] 138 | history Show the history of an image # 展示一个镜像形成历史 139 | images List images # 列出系统当前镜像 140 | import Create a new filesystem image from the contents of a tarball 141 | # 从tar包中的内容创建一个新的文件系统映像[对应export] 142 | info Display system-wide information # 显示系统相关信息 143 | inspect Return low-level information on a container # 查看容器详细信息 144 | kill Kill a running container # kill指定docker容器 145 | load Load an image from a tar archive # 从一个tar包中加载一个镜像[对应save] 146 | login Register or Login to the docker registry server 147 | # 注册或者登陆一个docker源服务器 148 | logs Fetch the logs of a container # 输出当前容器日志信息 149 | port Lookup the public-facing port which is NAT-ed to PRIVATE_PORT 150 | # 查看映射端口对应的容器内部源端口 151 | pause Pause all processes within a container # 暂停容器 152 | ps List containers # 列出容器列表 153 | pull Pull an image or a repository from the docker registry server 154 | # 从docker镜像源服务器拉取指定镜像或者库镜像 155 | push Push an image or a repository to the docker registry server 156 | # 推送指定镜像或者库镜像至docker源服务器 157 | restart Restart a running container # 重启运行的容器 158 | rm Remove one or more containers # 移除一个或者多个容器 159 | rmi Remove one or more images 160 | # 移除一个或多个镜像[无容器使用该镜像才可删除,否则需删除相关容器才可继续或-f强制删除] 161 | run Run a command in a new container 162 | # 在一个新的容器中运行一个命令 163 | save Save an image to a tar archive # 保存一个镜像为一个tar包[对应load] 164 | search Search for an image in the docker index # 在docker index中搜索镜像 165 | start Start a stopped containers # 启动容器 166 | stop Stop a running containers # 停止容器 167 | tag Tag an image into a repository # 给源中镜像打标签 168 | top Lookup the running processes of a container # 查看容器中运行的进程信息 169 | unpause Unpause a paused container # 取消暂停容器 170 | version Show the docker version information # 查看docker版本号 171 | wait Block until a container stops, then print its exit code 172 | # 截取容器停止时的退出状态值 173 | ``` 174 | 175 | 176 | docker选项帮助 177 | 178 | ``` bash 179 | $ sudo docker --help 180 | Usage of docker: 181 | --api-enable-cors=false Enable CORS headers in the remote API # 远程API中开启CORS头 182 | -b, --bridge="" Attach containers to a pre-existing network bridge # 桥接网络 183 | use 'none' to disable container networking 184 | --bip="" Use this CIDR notation address for the network bridge's IP, not compatible with -b 185 | # 和-b选项不兼容,具体没有测试过 186 | -d, --daemon=false Enable daemon mode # daemon模式 187 | -D, --debug=false Enable debug mode # debug模式 188 | --dns=[] Force docker to use specific DNS servers # 强制docker使用指定dns服务器 189 | --dns-search=[] Force Docker to use specific DNS search domains # 强制docker使用指定dns搜索域 190 | -e, --exec-driver="native" Force the docker runtime to use a specific exec driver # 强制docker运行时使用指定执行驱动器 191 | -G, --group="docker" Group to assign the unix socket specified by -H when running in daemon mode 192 | use '' (the empty string) to disable setting of a group 193 | -g, --graph="/var/lib/docker" Path to use as the root of the docker runtime # 容器运行的根目录路径 194 | -H, --host=[] The socket(s) to bind to in daemon mode # daemon模式下docker指定绑定方式[tcp or 本地socket] 195 | specified using one or more tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd. 196 | --icc=true Enable inter-container communication # 跨容器通信 197 | --ip="0.0.0.0" Default IP address to use when binding container ports # 指定监听地址,默认所有ip 198 | --ip-forward=true Enable net.ipv4.ip_forward # 开启转发 199 | --iptables=true Enable Docker's addition of iptables rules # 添加对应iptables规则 200 | --mtu=0 Set the containers network MTU # 设置网络mtu 201 | if no value is provided: default to the default route MTU or 1500 if no default route is available 202 | -p, --pidfile="/var/run/docker.pid" Path to use for daemon PID file # 指定pid文件位置 203 | -r, --restart=true Restart previously running containers # 重新启动以前运行的容器 204 | -s, --storage-driver="" Force the docker runtime to use a specific storage driver # 强制docker运行时使用指定存储驱动 205 | --selinux-enabled=false Enable selinux support # 开启selinux支持 206 | --storage-opt=[] Set storage driver options # 设置存储驱动选项 207 | --tls=false Use TLS; implied by tls-verify flags # 开启tls 208 | --tlscacert="/root/.docker/ca.pem" Trust only remotes providing a certificate signed by the CA given here 209 | --tlscert="/root/.docker/cert.pem" Path to TLS certificate file # tls证书文件位置 210 | --tlskey="/root/.docker/key.pem" Path to TLS key file # tls key文件位置 211 | --tlsverify=false Use TLS and verify the remote (daemon: verify client, client: verify daemon) # 使用tls并确认远程控制主机 212 | -v, --version=false Print version information and quit # 输出docker版本信息 213 | ``` 214 | 215 | #### 4.1.1、docker search 216 | 217 | 官方镜像源地址:[registry.hub.docker.com](https://registry.hub.docker.com/) 218 | 219 | ``` bash 220 | $ sudo docker search 221 | 222 | Usage: docker search TERM 223 | 224 | Search the docker index for images # 从docker镜像主页搜索镜像 225 | 226 | --automated=false Only show automated builds 227 | --no-trunc=false Don't truncate output 228 | -s, --stars=0 Only displays with at least xxx stars 229 | ``` 230 | 231 | 示例: 232 | 233 | ``` bash 234 | $ sudo docker search -s 100 ubuntu 235 | # 查找star数至少为100的镜像,找出只有官方镜像start数超过100,默认不加s选项找出所有相关ubuntu镜像 236 | NAME DESCRIPTION STARS OFFICIAL AUTOMATED 237 | ubuntu Official Ubuntu base image 425 [OK] 238 | ``` 239 | 240 | #### 4.1.2、docker info 241 | 242 | ``` bash 243 | $ sudo docker info 244 | Containers: 7 # 容器个数 245 | Images: 102 # 镜像个数 246 | Storage Driver: aufs # 存储驱动,默认aufs 247 | Root Dir: /var/lib/docker/aufs # 根目录 248 | Dirs: 116 249 | Execution Driver: native-0.2 # 执行驱动 250 | Kernel Version: 3.13.0-24-generic 251 | WARNING: No swap limit support 252 | ``` 253 | 254 | #### 4.1.3、docker pull && docker push 255 | 256 | ``` bash 257 | $ sudo docker pull # pull拉取镜像 258 | 259 | Usage: docker pull NAME[:TAG] 260 | 261 | Pull an image or a repository from the registry 262 | 263 | $ sudo docker push # push推送指定镜像 264 | 265 | Usage: docker push NAME[:TAG] 266 | 267 | Push an image or a repository to the registry 268 | ``` 269 | 270 | 示例: 271 | 272 | ``` bash 273 | $ sudo docker pull ubuntu # 下载官方ubuntu docker镜像,默认下载所有ubuntu官方库镜像 274 | $ sudo docker pull ubuntu:14.04 # 下载指定版本ubuntu官方镜像 275 | ``` 276 | 277 | ``` bash 278 | $ sudo docker push 192.168.0.100:5000/ubuntu 279 | # 推送镜像库到私有源[可注册docker官方账户,推送到官方自有账户] 280 | $ sudo docker push 192.168.0.100:5000/ubuntu:14.04 281 | # 推送指定镜像到私有源 282 | ``` 283 | 284 | #### 4.1.4、docker images 285 | 286 | 列出当前系统镜像 287 | 288 | ``` bash 289 | $ sudo docker images -h 290 | 291 | Usage: docker images [OPTIONS] [NAME] 292 | 293 | List images 294 | 295 | -a, --all=false Show all images (by default filter out the intermediate image layers) 296 | # -a显示当前系统的所有镜像,包括过渡层镜像,默认docker images显示最终镜像,不包括过渡层镜像 297 | -f, --filter=[] Provide filter values (i.e. 'dangling=true') 298 | --no-trunc=false Don't truncate output 299 | -q, --quiet=false Only show numeric IDs 300 | ``` 301 | 302 | 示例: 303 | 304 | ``` bash 305 | $ sudo docker images # 显示当前系统镜像,不包括过渡层镜像 306 | $ sudo docker images -a # 显示当前系统所有镜像,包括过渡层镜像 307 | $ sudo docker images ubuntu # 显示当前系统docker ubuntu库中的所有镜像 308 | REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE 309 | ubuntu 12.04 ebe4be4dd427 4 weeks ago 210.6 MB 310 | ubuntu 14.04 e54ca5efa2e9 4 weeks ago 276.5 MB 311 | ubuntu 14.04-ssh 6334d3ac099a 7 weeks ago 383.2 MB 312 | ``` 313 | 314 | #### 4.1.5、docker rmi 315 | 316 | 删除一个或者多个镜像 317 | 318 | ``` bash 319 | $ sudo docker rmi 320 | 321 | Usage: docker rmi IMAGE [IMAGE...] 322 | 323 | Remove one or more images 324 | 325 | -f, --force=false Force removal of the image # 强制移除镜像不管是否有容器使用该镜像 326 | --no-prune=false Do not delete untagged parents # 不要删除未标记的父镜像 327 | ``` 328 | 329 | #### 4.1.6、docker run 330 | 331 | ``` bash 332 | $ sudo docker run 333 | 334 | Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] 335 | 336 | Run a command in a new container 337 | 338 | -a, --attach=[] Attach to stdin, stdout or stderr. 339 | -c, --cpu-shares=0 CPU shares (relative weight) # 设置cpu使用权重 340 | --cidfile="" Write the container ID to the file # 把容器id写入到指定文件 341 | --cpuset="" CPUs in which to allow execution (0-3, 0,1) # cpu绑定 342 | -d, --detach=false Detached mode: Run container in the background, print new container id # 后台运行容器 343 | --dns=[] Set custom dns servers # 设置dns 344 | --dns-search=[] Set custom dns search domains # 设置dns域搜索 345 | -e, --env=[] Set environment variables # 定义环境变量 346 | --entrypoint="" Overwrite the default entrypoint of the image # ? 347 | --env-file=[] Read in a line delimited file of ENV variables # 从指定文件读取变量值 348 | --expose=[] Expose a port from the container without publishing it to your host # 指定对外提供服务端口 349 | -h, --hostname="" Container host name # 设置容器主机名 350 | -i, --interactive=false Keep stdin open even if not attached # 保持标准输出开启即使没有attached 351 | --link=[] Add link to another container (name:alias) # 添加链接到另外一个容器[这个会专门章节讲解] 352 | --lxc-conf=[] (lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1" 353 | -m, --memory="" Memory limit (format: , where unit = b, k, m or g) # 内存限制 354 | --name="" Assign a name to the container # 设置容器名 355 | --net="bridge" Set the Network mode for the container # 设置容器网络模式 356 | 'bridge': creates a new network stack for the container on the docker bridge 357 | 'none': no networking for this container 358 | 'container:': reuses another container network stack 359 | 'host': use the host network stack inside the container. Note: the host mode gives the container full access to local system services such as D-bus and is therefore considered insecure. 360 | -P, --publish-all=false Publish all exposed ports to the host interfaces # 自动映射容器对外提供服务的端口 361 | -p, --publish=[] Publish a container's port to the host # 指定端口映射 362 | format: ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort 363 | (use 'docker port' to see the actual mapping) 364 | --privileged=false Give extended privileges to this container # 提供更多的权限给容器 365 | --rm=false Automatically remove the container when it exits (incompatible with -d) # 如果容器退出自动移除和-d选项冲突 366 | --sig-proxy=true Proxify received signals to the process (even in non-tty mode). SIGCHLD is not proxied. # ? 367 | -t, --tty=false Allocate a pseudo-tty # 分配伪终端 368 | -u, --user="" Username or UID # 指定运行容器的用户uid或者用户名 369 | -v, --volume=[] Bind mount a volume (e.g., from the host: -v /host:/container, from docker: -v /container) 370 | # 挂载卷[这个会专门章节讲解] 371 | --volumes-from=[] Mount volumes from the specified container(s) # 从指定容器挂载卷 372 | -w, --workdir="" Working directory inside the container # 指定容器工作目录 373 | ``` 374 | 375 | 示例: 376 | 377 | ``` bash 378 | $ sudo docker images ubuntu 379 | REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE 380 | ubuntu 14.04 e54ca5efa2e9 4 weeks ago 276.5 MB 381 | ... ... 382 | $ sudo docker run -t -i -c 100 -m 512MB -h test1 -d --name="docker_test1" ubuntu /bin/bash 383 | # 创建一个cpu优先级为100,内存限制512MB,主机名为test1,名为docker_test1后台运行bash的容器 384 | a424ca613c9f2247cd3ede95adfbaf8d28400cbcb1d5f9b69a7b56f97b2b52e5 385 | $ sudo docker ps 386 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 387 | a424ca613c9f ubuntu:14.04 /bin/bash 6 seconds ago Up 5 seconds docker_test1 388 | $ sudo docker attach docker_test1 389 | root@test1:/# pwd 390 | / 391 | root@test1:/# exit 392 | exit 393 | ``` 394 | 395 | __关于cpu优先级:__ 396 | 397 | > By default all groups have 1024 shares. A group with 100 shares will get a ~10% portion of the CPU time: 398 | 399 | #### 4.1.7、docker start|stop|kill... ... 400 | 401 | docker `start`|`stop`|`kill`|`restart`|`pause`|`unpause`|`rm`|`commit`|`inspect`|`logs` 402 | 403 | * docker start CONTAINER [CONTAINER...] # 运行一个或多个停止的容器 404 | * docker stop CONTAINER [CONTAINER...] # 停掉一个或多个运行的容器 `-t`选项可指定超时时间 405 | * docker kill [OPTIONS] CONTAINER [CONTAINER...] # 默认kill发送SIGKILL信号 `-s`可以指定发送kill信号类型 406 | * docker restart [OPTIONS] CONTAINER [CONTAINER...] # 重启一个或多个运行的容器 `-t`选项可指定超时时间 407 | * docker pause CONTAINER # 暂停一个容器,方便commit 408 | * docker unpause CONTAINER # 继续暂停的容器 409 | * docker rm [OPTIONS] CONTAINER [CONTAINER...] # 移除一个或多个容器 410 | * -f, --force=false Force removal of running container 411 | * -l, --link=false Remove the specified link and not the underlying container 412 | * -v, --volumes=false Remove the volumes associated with the container 413 | * docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] # 提交指定容器为镜像 414 | * -a, --author="" Author (e.g., "John Hannibal Smith ") 415 | * -m, --message="" Commit message 416 | * -p, --pause=true Pause container during commit # 默认commit是暂停状态 417 | * docker inspect CONTAINER|IMAGE [CONTAINER|IMAGE...] # 查看容器或者镜像的详细信息 418 | * docker logs CONTAINER # 输出指定容器日志信息 419 | * -f, --follow=false Follow log output # 类似tail -f 420 | * -t, --timestamps=false Show timestamps 421 | * --tail="all" Output the specified number of lines at the end of logs (defaults to all logs) 422 | 423 | ### 4.2、参考文档 424 | 425 | * [Docker Run Reference](https://docs.docker.com/reference/run/) 426 | 427 | ## 五、docker端口映射 428 | 429 | ``` bash 430 | # Find IP address of container with ID 通过容器id获取ip 431 | $ sudo docker inspect | grep IPAddress | cut -d ’"’ -f 4 432 | ``` 433 | 434 | 无论如何,这些ip是基于本地系统的并且容器的端口非本地主机是访问不到的。此外,除了端口只能本地访问外,对于容器的另外一个问题是这些ip在容器每次启动的时候都会改变。 435 | 436 | Docker解决了容器的这两个问题,并且给容器内部服务的访问提供了一个简单而可靠的方法。Docker通过端口绑定主机系统的接口,允许非本地客户端访问容器内部运行的服务。为了简便的使得容器间通信,Docker提供了这种连接机制。 437 | 438 | ### 5.1、自动映射端口 439 | 440 | `-P`使用时需要指定`--expose`选项,指定需要对外提供服务的端口 441 | 442 | ``` bash 443 | $ sudo docker run -t -P --expose 22 --name server ubuntu:14.04 444 | ``` 445 | 446 | 使用`docker run -P`自动绑定所有对外提供服务的容器端口,映射的端口将会从没有使用的端口池中(49000..49900)自动选择,你可以通过`docker ps`、`docker inspect `或者`docker port `确定具体的绑定信息。 447 | 448 | ### 5.2、绑定端口到指定接口 449 | 450 | 基本语法 451 | 452 | ``` bash 453 | $ sudo docker run -p [([:[host_port]])|():][/udp] 454 | ``` 455 | 456 | 默认不指定绑定ip则监听所有网络接口。 457 | 458 | #### 5.2.1、绑定TCP端口 459 | 460 | ``` bash 461 | # Bind TCP port 8080 of the container to TCP port 80 on 127.0.0.1 of the host machine. 462 | $ sudo docker run -p 127.0.0.1:80:8080 463 | # Bind TCP port 8080 of the container to a dynamically allocated TCP port on 127.0.0.1 of the host machine. 464 | $ sudo docker run -p 127.0.0.1::8080 465 | # Bind TCP port 8080 of the container to TCP port 80 on all available interfaces of the host machine. 466 | $ sudo docker run -p 80:8080 467 | # Bind TCP port 8080 of the container to a dynamically allocated TCP port on all available interfaces 468 | $ sudo docker run -p 8080 469 | ``` 470 | 471 | #### 5.2.2、绑定UDP端口 472 | 473 | ``` bash 474 | # Bind UDP port 5353 of the container to UDP port 53 on 127.0.0.1 of the host machine. 475 | $ sudo docker run -p 127.0.0.1:53:5353/udp 476 | ``` 477 | 478 | ## 六、配置网络 479 | 480 | Docker uses Linux bridge capabilities to provide network connectivity to containers. The docker0 bridge interface is managed by Docker for this purpose. When the Docker daemon starts it : 481 | 482 | Dokcer通过使用Linux桥接提供容器之间的通信,docker0桥接接口的目的就是方便Docker管理。当Docker daemon启动时需要做以下操作: 483 | 484 | - creates the docker0 bridge if not present 如果docker0不存在则创建 485 | - searches for an IP address range which doesn’t overlap with an existing route 搜索一个与当前路由不冲突的ip段 486 | - picks an IP in the selected range 在确定的范围中选择ip 487 | - assigns this IP to the docker0 bridge 绑定ip到docker0 488 | 489 | ### 6.1、列出当前主机网桥 490 | 491 | ``` bash 492 | $ sudo brctl show # brctl工具依赖bridge-utils软件包 493 | bridge name bridge id STP enabled interfaces 494 | docker0 8000.000000000000 no 495 | ``` 496 | 497 | ### 6.2、查看当前docker0 ip 498 | 499 | ``` bash 500 | $ sudo ifconfig docker0 501 | docker0 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx 502 | inet addr:172.17.42.1 Bcast:0.0.0.0 Mask:255.255.0.0 503 | ``` 504 | 505 | 在容器运行时,每个容器都会分配一个特定的虚拟机口并桥接到docker0。每个容器都会配置同docker0 ip相同网段的专用ip地址,docker0 的IP地址被用于所有容器的默认网关。 506 | 507 | ### 6.3、运行一个容器 508 | 509 | ``` bash 510 | $ sudo docker run -t -i -d ubuntu /bin/bash 511 | 52f811c5d3d69edddefc75aff5a4525fc8ba8bcfa1818132f9dc7d4f7c7e78b4 512 | $ sudo brctl show 513 | bridge name bridge id STP enabled interfaces 514 | docker0 8000.fef213db5a66 no vethQCDY1N 515 | ``` 516 | 517 | 以上, docker0 扮演着52f811c5d3d6 container这个容器的虚拟接口vethQCDY1N interface桥接的角色。 518 | 519 | #### 6.3.1、使用特定范围的IP 520 | 521 | Docker会尝试寻找没有被主机使用的ip段,尽管它适用于大多数情况下,但是它不是万能的,有时候我们还是需要对ip进一步的规划。Docker允许你管理docker0桥接或者通过`-b`选项自定义桥接网卡,需要安装`bridge-utils`软件包。 522 | 523 | 基本步骤如下: 524 | 525 | - ensure Docker is stopped 确保docker的进程是停止的 526 | - create your own bridge (bridge0 for example) 创建自定义网桥 527 | - assign a specific IP to this bridge 给网桥分配特定的ip 528 | - start Docker with the -b=bridge0 parameter 以-b的方式指定网桥 529 | 530 | ``` bash 531 | # Stop Docker 532 | $ sudo service docker stop 533 | # Clean docker0 bridge and 534 | # add your very own bridge0 535 | $ sudo ifconfig docker0 down 536 | $ sudo brctl addbr bridge0 537 | $ sudo ifconfig bridge0 192.168.227.1 netmask 255.255.255.0 538 | # Edit your Docker startup file 539 | $ echo "DOCKER_OPTS=\"-b=bridge0\"" >> /etc/default/docker 540 | # Start Docker 541 | $ sudo service docker start 542 | # Ensure bridge0 IP is not changed by Docker 543 | $ sudo ifconfig bridge0 544 | bridge0 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx 545 | inet addr:192.168.227.1 Bcast:192.168.227.255 Mask:255.255.255.0 546 | # Run a container 547 | $ docker run -i -t ubuntu /bin/bash 548 | # Container IP in the 192.168.227/24 range 549 | root@261c272cd7d5:/# ifconfig eth0 550 | eth0 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx 551 | inet addr:192.168.227.5 Bcast:192.168.227.255 Mask:255.255.255.0 552 | # bridge0 IP as the default gateway 553 | root@261c272cd7d5:/# route -n 554 | Kernel IP routing table 555 | Destination Gateway Genmask Flags Metric Ref Use Iface 556 | 0.0.0.0 192.168.227.1 0.0.0.0 UG 0 0 0 eth0 557 | 192.168.227.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 558 | ``` 559 | 560 | ### 6.4、不同主机间容器通信 561 | 562 | 不同容器之间的通信可以借助于`pipework`这个工具: 563 | 564 | ``` bash 565 | $ git clone https://github.com/jpetazzo/pipework.git 566 | $ sudo cp -rp pipework/pipework /usr/local/bin/ 567 | ``` 568 | 569 | #### 6.4.1、安装相应依赖软件 570 | 571 | ``` bash 572 | $ sudo apt-get install arping bridge-utils -y 573 | ``` 574 | 575 | #### 6.4.2、桥接网络 576 | 577 | Ubuntu14.04 578 | 579 | ``` bash 580 | # cat /etc/network/interfaces 581 | auto lo 582 | iface lo inet loopback 583 | 584 | auto eth0 585 | iface eth0 inet manual 586 | 587 | auto br0 588 | iface br0 inet static 589 | address 10.0.128.219 590 | netmask 255.255.255.192 591 | gateway 10.0.128.254 592 | bridge_ports eth0 593 | bridge_stp off 594 | bridge_fd 0 595 | bridge_maxwait 0 596 | dns-nameservers 10.0.127.110 597 | dns-search intranet.123u.com 598 | ``` 599 | 600 | ##### 启动br0,使桥接生效 601 | 602 | ``` bash 603 | # ifup br0 604 | # Bash=$(docker run -i -d -t 10.0.128.219:5000/ubuntu:14.04 /bin/bash) 605 | # pipework br0 $Bash 10.0.128.223/26 606 | ``` 607 | 608 | ### 6.5、参考文档 609 | 610 | - [pipework readme](https://github.com/jpetazzo/pipework/blob/master/README.md) 611 | - [pipework-docker网络增强工具](http://peerxu.github.io/blog/2014/04/07/docker-with-openvswitch.html) 612 | 613 | ## 七、构建docker私有库 614 | 615 | 为方便管理,我们需要对官方的镜像做一些定制,我们可以构建私有的`docker registry` 616 | 617 | ### 7.1、快速构建 618 | 619 | The fastest way to get running: 620 | 621 | - install docker:`apt-get install docker.io` 622 | - run the registry: `docker run -p 5000:5000 registry` 623 | 624 | That will use the official image from the Docker index.[因为国内被墙的原因,速度比较慢,推荐第二种方式] 625 | 626 | ### 7.2、传统构建方式 627 | 628 | ``` bash 629 | $ sudo apt-get install build-essential python-dev libevent-dev python-pip liblzma-dev 630 | $ git clone https://github.com/dotcloud/docker-registry.git 631 | $ cd docker-registry/ 632 | $ cp config/config_sample.yml config/config.yml 633 | $ mkdir /data/registry -p 634 | $ pip install . 635 | ``` 636 | 637 | #### 7.2.1、启动 638 | 639 | ``` bash 640 | $ sudo gunicorn --access-logfile - --debug -k gevent -b 0.0.0.0:5000 \ 641 | -w 1 docker_registry.wsgi:application 642 | ``` 643 | 644 | 生产环境可以通过如`supervisord`创建8个workers,或者通过nginx和apache来管理,具体可以参考[docker-registry readme](https://github.com/dotcloud/docker-registry)。 645 | 646 | ``` bash 647 | $ sudo gunicorn -k gevent --max-requests 100 --graceful-timeout 3600 \ 648 | -t 3600 -b localhost:5000 -w 8 docker_registry.wsgi:application 649 | ``` 650 | 651 | #### 7.2.2、提交指定容器到私有库 652 | 653 | ``` bash 654 | $ docker tag 74fe38d11401 192.168.0.219:5000/ubuntu:12.04 655 | $ docker push 192.168.0.219:5000/ubuntu 656 | ``` 657 | 658 | ### 7.3、参考 659 | 660 | - [docker-registry readme](https://github.com/dotcloud/docker-registry) 661 | - [How to use your own Registry](http://blog.docker.io/2013/07/how-to-use-your-own-registry/) 662 | 663 | ## 八、容器数据管理 664 | 665 | docker管理数据的方式有两种: 666 | 667 | * 数据卷 668 | * 数据卷容器 669 | 670 | ### 8.1、数据卷 671 | 672 | 数据库是一个或多个容器专门指定绕过`Union File System`的目录,为持续性或共享数据提供一些有用的功能: 673 | 674 | * 数据卷可以在容器间共享和重用 675 | * 数据卷数据改变是直接修改的 676 | * 数据卷数据改变不会被包括在容器中 677 | * 数据卷是持续性的,直到没有容器使用它们 678 | 679 | #### 8.1.2、添加一个数据卷 680 | 681 | 你可以使用`-v`选项添加一个数据卷,或者可以使用多次`-v`选项为一个docker容器运行挂载多个数据卷。 682 | 683 | ``` bash 684 | $ sudo docker run --name data -v /data -t -i centos:6.4 /bin/bash 685 | # 创建数据卷绑定到到新建容器,新建容器中会创建/data数据卷 686 | bash-4.1# ls -ld /data/ 687 | drwxr-xr-x 2 root root 4096 Jul 23 06:59 /data/ 688 | bash-4.1# df -Th 689 | Filesystem Type Size Used Avail Use% Mounted on 690 | ... ... 691 | ext4 91G 4.6G 82G 6% /data 692 | ``` 693 | 694 | 创建的数据卷可以通过`docker inspect`获取宿主机对应路径 695 | 696 | ``` bash 697 | $ sudo docker inspect data 698 | ... ... 699 | "Volumes": { 700 | "/data": "/var/lib/docker/vfs/dir/151de401d268226f96d824fdf444e77a4500aed74c495de5980c807a2ffb7ea9" 701 | }, # 可以看到创建的数据卷宿主机路径 702 | "VolumesRW": { 703 | "/data1": true 704 | } 705 | ... ... 706 | ``` 707 | 708 | #### 8.1.3、挂载宿主机目录为一个数据卷 709 | 710 | `-v`选项除了可以创建卷,也可以挂载当前主机的一个目录到容器中。 711 | 712 | ``` bash 713 | $ sudo docker run --name web -v /source/:/web -t -i centos:6.4 /bin/bash 714 | bash-4.1# ls -ld /web/ 715 | drwxr-xr-x 2 root root 4096 Jul 23 06:59 /web/ 716 | bash-4.1# df -Th 717 | ... ... 718 | ext4 91G 4.6G 82G 6% /web 719 | bash-4.1# exit 720 | ``` 721 | 722 | 默认挂载卷是可读写的,可以在挂载时指定只读 723 | 724 | ``` bash 725 | $ sudo docker run --rm --name test -v /source/:/test:ro -t -i centos:6.4 /bin/bash 726 | ``` 727 | 728 | ### 8.2、创建和挂载一个数据卷容器 729 | 730 | 如果你有一些持久性的数据并且想在容器间共享,或者想用在非持久性的容器上,最好的方法是创建一个数据卷容器,然后从此容器上挂载数据。 731 | 732 | 创建数据卷容器 733 | 734 | ``` bash 735 | $ sudo docker run -t -i -d -v /test --name test centos:6.4 /bin/bash 736 | ``` 737 | 738 | 使用`--volumes-from`选项在另一个容器中挂载/test卷 739 | 740 | ``` bash 741 | $ sudo docker run -t -i -d --volumes-from test --name test1 centos:6.4 /bin/bash 742 | ``` 743 | 744 | 添加另一个容器 745 | 746 | ``` bash 747 | $ sudo docker run -t -i -d --volumes-from test --name test2 centos:6.4 /bin/bash 748 | ``` 749 | 750 | 也可以继承其它挂载有/test卷的容器 751 | 752 | ``` bash 753 | $ sudo docker run -t -i -d --volumes-from test1 --name test3 centos:6.4 /bin/bash 754 | ``` 755 | 756 | ### 8.3、备份、恢复或迁移数据卷 757 | 758 | ``` bash 759 | $ sudo docker run --volumes-from test -v $(pwd):/backup centos:6.4 tar cvf /backup/test.tar /test 760 | tar: Removing leading `/' from member names 761 | tar: /test/test.tar: file is the archive; not dumped 762 | /test/ 763 | /test/b 764 | /test/d 765 | /test/c 766 | /test/a 767 | ``` 768 | 769 | 启动一个新的容器并且从`test`容器中挂载卷。然后我们挂载当前目录`$(pwd)`到容器中为backup,然后备份卷数据为test.tar,即备份数据存放在当前宿主机的所在路径下。 770 | 771 | ``` bash 772 | $ ls # 当前目录下产生了test卷的备份文件test.tar 773 | test.tar 774 | ``` 775 | 776 | 你可以恢复给同一个容器或者另外的容器,新建容器并解压备份文件到新的容器数据卷: 777 | 778 | ``` bash 779 | $ sudo docker run -t -i -d -v /test --name test2 centos:6.4 /bin/bash 780 | $ sudo docker run --volumes-from test2 -v $(pwd):/backup centos:6.4 tar xvf /backup/test.tar 781 | # 恢复之前的文件到新建卷中 782 | test/ 783 | test/b 784 | test/d 785 | test/c 786 | test/a 787 | ``` 788 | 789 | ### 8.4、参考 790 | 791 | * [Managing Data in Containers](http://docs.docker.com/userguide/dockervolumes/#data-volumes) 792 | 793 | ## 九、链接容器 794 | 795 | 之前介绍过通过端口映射连接容器中对外提供的服务。这是你与运行在容器中的服务和应用进行交互的方式之一。在本节中,会介绍同网络端口方式访问一样好用的方式,即链接容器。docker容器具有一个链接系统允许多个容器连接在一起并且共享连接信息。docker链接将创建一个父子关系,其中父容器可以看到关于它子容器选择的信息。 796 | 797 | ### 9.1 容器命名 798 | 799 | 执行docker链接依赖容器的名称,在创建容器时,如果不指定容器的名字,则默认会自动创建一个名字。这种命名提供了两个很有用的功能: 800 | 801 | * 1、给容器命名方便记忆,如命名运行web应用的容器为`web` 802 | * 2、为docker容器提供一个参考,允许方便其他容器调用,如把容器`web`链接到容器`db` 803 | 804 | 可以通过`--name`选项给容器自定义命名: 805 | 806 | ``` bash 807 | $ sudo docker run -d -t -i --name bash centos:6.4 bash 808 | $ sudo docker ps -l 809 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 810 | 70be821b7804 centos:6.4 bash About a minute ago Up About a minute bash 811 | ``` 812 | 813 | 也可以通过`docker inspect`获取容器名 814 | 815 | ``` bash 816 | $ sudo docker inspect -f "{{ .Name }}" 70be821b7804 817 | /bash 818 | ``` 819 | 820 | 注:容器名称必须是唯一,意思是你只能命名一个叫`web`的容器。如果你想复用容器名,则必须在创建新的容器前通过`docker rm`删除旧的容器。 821 | 822 | ### 9.2 链接容器 823 | 824 | 链接允许容器间安全可见通信,使用`--link`选项创建链接。 825 | 826 | ``` bash 827 | $ sudo docker run -d -t -i --name test1 centos:6.4 bash 828 | ``` 829 | 830 | 创建一个容器链接到`test1`容器 831 | 832 | ``` bash 833 | $ sudo docker run -d -t -i --name test2 --link test1:test1 centos:6.4 bash 834 | ``` 835 | 836 | * `--link name:alias` 837 | 838 | ``` bash 839 | $ sudo docker ps 840 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 841 | 1966fe2a909c centos:6.4 bash 2 minutes ago Up 2 minutes test2 842 | 20f7f53b61df centos:6.4 bash 4 minutes ago Up 4 minutes test1,test2/test1 843 | ``` 844 | 845 | 从上面命令输出可以看出test2链接到test1容器的父/子关系。 846 | 847 | 848 | -------------------------------------------------------------------------------- /服务/MySQL.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /服务/NTP.md: -------------------------------------------------------------------------------- 1 | 2 | ## 一、简介 3 | 4 | Network Time Protocol(NTP) 是用来使计算机时间同步化的一种协议,它可以使计算机对其服务器或时钟源(如石英钟,GPS 等等)做同步化,它可以提供高精准度的时间校正(LAN 上与标准间差小于1毫秒,WAN上几十毫秒),且可使用加密确认的方式来防止恶毒的协议攻击。默认使用 `UDP 123端口` 5 | 6 | NTP 提供准确时间,首先需要一个准确的 UTC 时间来源,NTP 获得 UTC 的时间来源可以从原子钟、天文台、卫星,也可从 Internet 上获取。时间服务器按照 NTP 服务器的等级传播,根据离外部 UTC 源的远近将所有服务器归入不用的层 (Stratum) 中。Stratum-1 在顶层由外部 UTC 接入,stratum-1 的时间服务器为整个系统的基础,Stratum 的总数限制在 15 以内。下图为 NTP 层次图: 7 | 8 |
ntp
9 | 10 | ## 二、NTP Server 安装配置 11 | 12 | 关于 NTP 服务器的安装,根据不同版本安装方法也不同。REDHAT 系统则可以使用 yum 安装,Ubuntu 系列可以使用 `apt-get` 安装,这里不做具体的介绍,主要详细介绍配置文件的信息。 13 | 14 | 对于 Centos 过滤注释和空行后,ntp 配置文件内容如下 15 | 16 | ``` 17 | # grep -vE '^#|^$' /etc/ntp.conf 18 | driftfile /var/lib/ntp/drift 19 | restrict default kod nomodify notrap nopeer noquery 20 | restrict -6 default kod nomodify notrap nopeer noquery 21 | restrict 127.0.0.1 22 | restrict -6 ::1 23 | server 0.centos.pool.ntp.org 24 | server 1.centos.pool.ntp.org 25 | server 2.centos.pool.ntp.org 26 | includefile /etc/ntp/crypto/pw 27 | keys /etc/ntp/keys 28 | ``` 29 | 30 | ### 2.1 配置选项说明 31 | 32 | * `driftfile` 选项, 则指定了用来保存系统时钟频率偏差的文件。 ntpd 程序使用它来自动地补偿时钟的自然漂移, 从而使时钟即使在切断了外来时源的情况下, 仍能保持相当的准确度。另外,driftfile 选项也保存上一次响应所使用的 NTP 服务器的信息。 这个文件包含了 NTP 的内部信息, 它不应被任何其他进程修改。`无需更改` 33 | * `restrict default kod nomodify notrap nopeer noquery` 默认拒绝所有NTP客户端的操作 [ restrict <子网掩码>|<网段> [ignore|nomodiy|notrap|notrust|nknod ] 指定可以通信的IP地址和网段。如果没有指定选项,表示客户端访问NTP服务器没有任何限制 34 | * `ignore`: 关闭所有 NTP 服务 35 | * `nomodiy`: 表示客户端不能更改 NTP 服务器的时间参数,但可以通过 NTP 服务器进行时间同步 36 | * `notrust`: 拒绝没有通过认证的客户端 37 | * `knod`: kod 技术科阻止 "Kiss of Death" 包(一种 DOS 攻击)对服务器的破坏,使用 knod 开启功能 38 | * `nopeer`: 不与其它同一层的 NTP 服务器进行同步 39 | * `server [IP|FQDN|prefer]`指该服务器上层 NTP Server,使用 prefer 的优先级最高,没有使用 prefer 则按照配置文件顺序由高到低,默认情况下至少 15min 和上层 NTP 服务器进行时间校对 40 | * `fudge`: 可以指定本地 NTP Server 层,如 `fudge 127.0.0.1 stratum 9` 41 | * `broadcast 网段 子网掩码`: 指定 NTP 进行时间广播的网段,如`broadcast 192.168.1.255` 42 | * `logfile`: 可以指定 NTP Server 日志文件 43 | 44 | 几个与NTP相关的配置文件:` /usr/share/zoneinfo/`、`/etc/sysconfig/clock`、`/etc/localtime` 45 | 46 | * `/usr/share/zoneinfo/`: 存放时区文件目录 47 | * `/etc/sysconfig/clock`: 指定当前系统时区信息 48 | * `/etc/localtime`: 相应的时区文件 49 | 50 | 如果需要修改当前时区,则可以从 /usr/share/zoneinfo/ 目录拷贝相应时区文件覆盖 /etc/localtime 并修改 /etc/sysconfig/clock 即可 51 | 52 | ``` 53 | cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 54 | sed -i 's:ZONE=.*:ZONE="Asia/Shanghai":g' /etc/sysconfig/clock 55 | ``` 56 | 57 | ## 三、相关命令 58 | 59 | `ntpstat` 查看同步状态 60 | 61 | ``` 62 | # ntpstat 63 | synchronised to NTP server (192.168.0.18) at stratum 4 64 | time correct to within 88 ms # 表面时间校正 88ms 65 | polling server every 1024 s # 每隔 1024s 更新一次 66 | ``` 67 | 68 | `ntpq` 列出上层状态 69 | 70 | ``` 71 | # ntpq -np 72 | remote refid st t when poll reach delay offset jitter 73 | ============================================================================== 74 | *192.168.0.18 202.112.31.197 3 u 101 1024 377 14.268 0.998 0.143 75 | ``` 76 | 77 | 输出说明: 78 | 79 | * `remote`: NTP Server 80 | * `refid` : 参考的上层 ntp 地址 81 | * `st` : 层次 82 | * `when` : 上次更新时间距离现在时常 83 | * `poll` : 下次更新时间 84 | * `reach` : 更新次数 85 | * `delay` : 延迟 86 | * `offset`: 时间补偿结果 87 | * `jitter`: 与 BIOS 硬件时间差异 88 | 89 | `ntpdate` 同步当前时间: `ntpdate NTP服务器地址` 90 | 91 | ## 四、参考文档 92 | 93 | * [ NTP 百度百科](http://baike.baidu.com/view/60648.htm) 94 | * [ NTP 维基百科](http://en.wikipedia.org/wiki/Network_Time_Protocol) 95 | * 鸟哥 Linux 私房菜 96 | -------------------------------------------------------------------------------- /服务/Nginx.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /服务/apache.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /服务/cron.md: -------------------------------------------------------------------------------- 1 | ## 一、Cron 基础 2 | 3 | ### 1.1 什么是 cron, crond, crontab 4 | 5 | > **cron** is the general name for the service that runs scheduled actions. **crond** is the name of the daemon that runs in the background and reads **crontab** files. 6 | 7 | 简单理解:cron 是服务,crond 是守护进程, crontab 的 crond 的配置文件。 8 | 9 | ### 1.2 crontab 选项 10 | 11 | + `crontab -e` : Edit your crontab file, or create one if it doesn't already exist. # 推荐使用命令新增计划任务--语法检查 12 | + `crontab -l` : Display your crontab file. 13 | + `crontab -r` : Remove your crontab file. # 慎用 14 | + `crontab -u user` : Used in conjunction with other options, this option allows you to modify or view the crontab file of user. When available, only administrators can use this option. 15 | 16 | ### 1.3 crontab 格式 17 | 18 | minute(s) hour(s) day(s) month(s) weekday(s) command(s) 19 | 20 | ``` 21 | # Use the hash sign to prefix a comment 22 | # +—————- minute (0 – 59) 23 | # | +————- hour (0 – 23) 24 | # | | +———- day of month (1 – 31) 25 | # | | | +——- month (1 – 12) 26 | # | | | | +—- day of week (0 – 7) (Sunday=0 or 7) 27 | # | | | | | 28 | # * * * * * command to be executed 29 | ``` 30 | 31 | ## 二、使用举例 32 | 33 | 使用命令 `crontab -e` 编辑 crontab 文件。 34 | 35 | (1) 在每天的 7 点同步服务器时间 36 | 37 | 0 7 * * * ntpdate 192.168.1.112 38 | 39 | 40 | (2) 每两个小时执行一次 41 | 42 | 0 */2 * * * echo "2 minutes later" >> /tmp/output.txt 43 | 44 | (3) 每周五早上十点写周报 45 | 46 | 0 10 * * * 5 /home/jerryzhang/update_weekly.py 47 | 48 | (4) 每天 6, 12, 18 点执行一次命令 49 | 50 | 0 6,12,18 * * * /bin/echo hello 51 | 52 | (5) 每天 13, 14, 15, 16, 17 点执行一次命令 53 | 54 | 0 13-17 * * * /bin/echo hello 55 | 56 | __注:__ 57 | 58 | * 程序执行完毕,系统会给对应用户发送邮件,显示该程序执行内容,如果不想收到,可以重定向内容 `> /dev/null 2>&1` 59 | * 如果执行语句中有 `%` 号,需要使用反斜杠 '\' 转义 60 | 61 | ## 三、参考资料 62 | 63 | + [维基百科: Cron](http://zh.wikipedia.org/wiki/Cron) 64 | + [Difference between Cron and Crontab?](http://stackoverflow.com/questions/21789148/difference-between-cron-and-crontab) 65 | + [Cron and Crontab usage and examples](http://www.pantz.org/software/cron/croninfo.html) 66 | + [What are cron and crontab, and how do I use them?](https://kb.iu.edu/d/afiz) 67 | + [crontab实例+详解](http://88263188.blog.51cto.com/416252/291683) 68 | -------------------------------------------------------------------------------- /服务/dhcp.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /服务/dns.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /服务/kvm.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /服务/openvpn.md: -------------------------------------------------------------------------------- 1 | # OpenVPN 基本搭建实例 2 | 3 | OpenVPN 是一个用于创建虚拟专用网络加密通道的软件包,最早由 James Yonan 编写。OpenVPN 允许创建的 VPN 使用公开密钥、电子证书、或者用户名/密码来进行身份验证。 4 | 5 |
openvpn
6 | 7 | ## 一、准备软件 8 | 9 | 本例以 CentOS 6 为例 10 | 11 | * [ openvpn-2.3.1 ](http://swupdate.openvpn.org/community/releases/openvpn-2.3.1.tar.gz) 12 | * [ lzo-2.06 ](http://www.oberhumer.com/opensource/lzo/download/lzo-2.06.tar.gz) 13 | * [ 最新版本的 openvpn-2.3.1 官方不再集成 `easy-rsa` ] Note that easy-rsa is no longer bundled with OpenVPN source code archives. To get it, visit the easy-rsa page on GitHub, or download it from our Linux software repositories. 14 | 15 | ``` 16 | git clone https://github.com/OpenVPN/easy-rsa 17 | ``` 18 | 19 | ## 二、软件安装 20 | 21 | `openssl`、`openssl-devel`、`pam`、`pam-devel` 安装 22 | 23 | ``` 24 | yum install openssl openssl-devel pam pam-devel -y 25 | ``` 26 | 27 | `lzo-2.06` 安装,下载相应软件包编译安装即可 28 | 29 | ``` 30 | ./configure && make && make install 31 | ``` 32 | 33 | `openvpn-2.3.1` 安装,同上官网下载软件包编译安装 34 | 35 | ``` 36 | ./configure && make && make install 37 | ``` 38 | 39 | ## 三、相关配置 40 | 41 | Openvpn 的认证方式有很多种,这里介绍其中一种,key 认证登录方式 42 | 43 | ### 添加环境变量 44 | 45 | 在 `~/.barc_profile` 文件中加入如下内容,命名根据实际需求修改: 46 | 47 | ``` 48 | export D=/etc/openvpn 49 | export KEY_CONFIG=$D/openssl.cnf 50 | export KEY_DIR=$D/keys 51 | export KEY_SIZE=1024 52 | export KEY_COUNTRY=CN 53 | export KEY_PROVINCE=BJ 54 | export KEY_CITY=BJ 55 | export KEY_ORG=kumu 56 | export KEY_OU=kumu 57 | export KEY_NAME=kumu 58 | export KEY_EMAIL=root@kumu 59 | ``` 60 | 61 | 使新增环境变量生效并新建配置文件目录 `/etc/openvpn` 62 | 63 | ``` 64 | # source ~/.barc_profile 65 | # mkdir /etc/openvpn 66 | ``` 67 | 68 | __注__:也可修改 easy-rsa 中的 vars [/usr/local/src/openvpn/easy-rsa/easy-rsa/2.0/vars],`source` 生效 69 | 70 | ### 2.1 生成密钥 71 | 72 | 进入之前下载的 `easy-rsa` 目录 73 | 74 | __初始化 PKI、生成证书__: 75 | 76 | ``` 77 | # pwd 78 | /usr/local/src/openvpn/easy-rsa/easy-rsa/2.0 79 | # ls 80 | build-ca build-key build-key-server clean-all openssl-0.9.6.cnf pkitool vars 81 | build-dh build-key-pass build-req inherit-inter openssl-0.9.8.cnf revoke-full whichopensslcnf 82 | build-inter build-key-pkcs12 build-req-pass list-crl openssl-1.0.0.cnf sign-req 83 | # cp openssl-1.0.0.cnf /etc/openvpn/openssl.cnf 84 | # ./clean-all # 初始化,清除原有不需要的文件 85 | # ./build-ca # 一直回车即可 86 | Generating a 1024 bit RSA private key 87 | .......++++++ 88 | ............++++++ 89 | writing new private key to 'ca.key' 90 | ----- 91 | You are about to be asked to enter information that will be incorporated 92 | into your certificate request. 93 | What you are about to enter is what is called a Distinguished Name or a DN. 94 | There are quite a few fields but you can leave some blank 95 | For some fields there will be a default value, 96 | If you enter '.', the field will be left blank. 97 | ----- 98 | Country Name (2 letter code) [CN]: 99 | State or Province Name (full name) [BJ]: 100 | Locality Name (eg, city) [BJ]: 101 | Organization Name (eg, company) [kumu]: 102 | Organizational Unit Name (eg, section) [kumu]: 103 | Common Name (eg, your name or your server's hostname) [kumu CA]: 104 | Name []:kumu 105 | Email Address [root@kumu]: 106 | ``` 107 | 108 | __生成 Server 端证书 Server Key:__ 109 | 110 | ``` 111 | # ./build-key-server kumu_server # 一路回车,密码处填写密码 112 | Generating a 1024 bit RSA private key 113 | ....................................++++++ 114 | .........++++++ 115 | writing new private key to 'kumu_server.key' 116 | ----- 117 | You are about to be asked to enter information that will be incorporated 118 | into your certificate request. 119 | What you are about to enter is what is called a Distinguished Name or a DN. 120 | There are quite a few fields but you can leave some blank 121 | For some fields there will be a default value, 122 | If you enter '.', the field will be left blank. 123 | ----- 124 | Country Name (2 letter code) [CN]: 125 | State or Province Name (full name) [BJ]: 126 | Locality Name (eg, city) [BJ]: 127 | Organization Name (eg, company) [kumu]: 128 | Organizational Unit Name (eg, section) [kumu]: 129 | Common Name (eg, your name or your server's hostname) [kumu_server]: 130 | Name [kumu]: 131 | Email Address [root@kumu]: 132 | 133 | Please enter the following 'extra' attributes 134 | to be sent with your certificate request 135 | A challenge password []:123321 # 输入密码 136 | An optional company name []:kumu 137 | Using configuration from /etc/openvpn/openssl.cnf 138 | Check that the request matches the signature 139 | Signature ok 140 | The Subject's Distinguished Name is as follows 141 | countryName :PRINTABLE:'CN' 142 | stateOrProvinceName :PRINTABLE:'BJ' 143 | localityName :PRINTABLE:'BJ' 144 | organizationName :PRINTABLE:'kumu' 145 | organizationalUnitName:PRINTABLE:'kumu' 146 | commonName :T61STRING:'kumu_server' 147 | name :PRINTABLE:'kumu' 148 | emailAddress :IA5STRING:'root@kumu' 149 | Certificate is to be certified until May 11 22:54:08 2023 GMT (3650 days) 150 | Sign the certificate? [y/n]:y 151 | 152 | 153 | 1 out of 1 certificate requests certified, commit? [y/n]y 154 | Write out database with 1 new entries 155 | Data Base Updated 156 | ``` 157 | 158 | __生成 Client 端证书:__ 159 | 160 | ``` 161 | # ./build-key kumu_client1 # 一路回车,密码处填写密码 162 | Generating a 1024 bit RSA private key 163 | ..++++++ 164 | .....................++++++ 165 | writing new private key to 'kumu_client1.key' 166 | ----- 167 | You are about to be asked to enter information that will be incorporated 168 | into your certificate request. 169 | What you are about to enter is what is called a Distinguished Name or a DN. 170 | There are quite a few fields but you can leave some blank 171 | For some fields there will be a default value, 172 | If you enter '.', the field will be left blank. 173 | ----- 174 | Country Name (2 letter code) [CN]: 175 | State or Province Name (full name) [BJ]: 176 | Locality Name (eg, city) [BJ]: 177 | Organization Name (eg, company) [kumu]: 178 | Organizational Unit Name (eg, section) [kumu]: 179 | Common Name (eg, your name or your server's hostname) [kumu_client1]: 180 | Name [kumu]: 181 | Email Address [root@kumu]: 182 | 183 | Please enter the following 'extra' attributes 184 | to be sent with your certificate request 185 | A challenge password []:123321 186 | An optional company name []:kumu 187 | Using configuration from /etc/openvpn/openssl.cnf 188 | Check that the request matches the signature 189 | Signature ok 190 | The Subject's Distinguished Name is as follows 191 | countryName :PRINTABLE:'CN' 192 | stateOrProvinceName :PRINTABLE:'BJ' 193 | localityName :PRINTABLE:'BJ' 194 | organizationName :PRINTABLE:'kumu' 195 | organizationalUnitName:PRINTABLE:'kumu' 196 | commonName :T61STRING:'kumu_client1' 197 | name :PRINTABLE:'kumu' 198 | emailAddress :IA5STRING:'root@kumu' 199 | Certificate is to be certified until May 11 23:01:12 2023 GMT (3650 days) 200 | Sign the certificate? [y/n]:y 201 | 202 | 203 | 1 out of 1 certificate requests certified, commit? [y/n]y 204 | Write out database with 1 new entries 205 | Data Base Updated 206 | # ls /etc/openvpn/keys/ 207 | 01.pem ca.key index.txt.attr kumu_client1.crt kumu_server.crt openvpn-status.log 208 | 02.pem dh1024.pem index.txt.attr.old kumu_client1.csr kumu_server.csr serial 209 | ca.crt index.txt index.txt.old kumu_client1.key kumu_server.key serial.old 210 | ``` 211 | 212 | __注__:生成其他客户端证书以此类推,名字不相同即可 213 | 214 | __证书加密__: 215 | 216 | ``` 217 | # ./build-dh 218 | ./build-dh: line 7: dhparam: command not found 219 | ``` 220 | 221 | 出现如上问题,修改 `./build-dh` 命令中 `$OPENSSL` 为 `openssl` 即可,原因是默认 `/usr/local/src/openvpn/easy-rsa/easy-rsa/2.0/vars` 文件定义了 `OPENSSL=openssl` ,而笔者没有引用 `vars` 文件 222 | 223 | ``` 224 | # ./build-dh 225 | Generating DH parameters, 1024 bit long safe prime, generator 2 226 | This is going to take a long time 227 | ... ... 228 | # openvpn --genkey --secret /etc/openvpn/keys/ta.key # 生成加密 key 229 | ``` 230 | 231 | ### 2.2 Server 端配置文件修改 232 | 233 | ``` 234 | # pwd 235 | /usr/local/src/openvpn/openvpn-2.3.1/sample/sample-config-files 236 | # ls 237 | client.conf loopback-client openvpn-shutdown.sh server.conf tls-home.conf xinetd-server-config 238 | firewall.sh loopback-server openvpn-startup.sh static-home.conf tls-office.conf 239 | home.up office.up README static-office.conf xinetd-client-config 240 | # cp server.conf /etc/openvpn/ # 拷贝 Server 模板配置文件到配置目录 241 | ``` 242 | 243 | __Server 端配置文件内容如下:__ 244 | 245 | ``` 246 | # grep -vE '^;|^$|^#' /etc/openvpn/server.conf 247 | port 1194 248 | proto udp 249 | dev tun 250 | ca /etc/openvpn/keys/ca.crt 251 | cert /etc/openvpn/keys/kumu_server.crt 252 | key /etc/openvpn/keys/kumu_server.key # This file should be kept secret 253 | dh /etc/openvpn/keys/dh1024.pem 254 | server 10.8.0.0 255.255.255.0 255 | push "route 192.168.10.0 255.255.255.0" # 推送路由 256 | client-to-client 257 | keepalive 10 120 258 | tls-auth /etc/openvpn/keys/ta.key 0 # This file is secret 259 | comp-lzo 260 | persist-key 261 | persist-tun 262 | status /etc/openvpn/keys/openvpn-status.log 263 | verb 3 264 | ``` 265 | 266 | ### 2.3 开启路由转发和启动 Openvpn 267 | 268 | __开启路由转发:__ 269 | 270 | ``` 271 | echo 1 > /proc/sys/net/ipv4/ip_forward # 临时开启 272 | ``` 273 | 274 | 或者修改 /etc/sysctl.conf 中 `net.ipv4.ip_forward = 1`,执行 `sysctl -p` 永久生效 275 | 276 | __启动服务:__ 277 | 278 | ``` 279 | openvpn --config /etc/openvpn/server.conf --daemon 280 | ``` 281 | 282 | ### 2.4 Windows 客户端连接配置 283 | 284 | * 64 位安装 [openvpn-2.3.1-X86_64.exe](http://swupdate.openvpn.org/community/releases/openvpn-install-2.3.1-I001-x86_64.exe) 285 | * 32 位请安装 [openvpn-2.3.1-i686.exe](http://swupdate.openvpn.org/community/releases/openvpn-install-2.3.1-I001-i686.exe) 286 | 287 | 拷贝 Server 端生成的如下客户端证书到 Windows 软件安装目录 `OpenVPN\config` 下 288 | 289 | * kumu_client1.crt 290 | * kumu_client1.key 291 | * ca.key 292 | * ta.key 293 | 294 | 在 `OpenVPN\config` 目录中新建 Client 端配置文件 `client.ovpn` 295 | 296 | ``` 297 | client 298 | dev tun 299 | proto udp 300 | remote 10.2.0.110 1194 301 | resolv-retry infinite 302 | nobind 303 | persist-key 304 | persist-tun 305 | ca ca.crt 306 | cert kumu_client1.crt 307 | key kumu_client1.key 308 | ns-cert-type server 309 | tls-auth ta.key 1 310 | comp-lzo 311 | verb 3 312 | ``` 313 | 314 | Win7/Win8 以管理员身份启动 Openvpn Windows 客户端即可,基本的 Windows 安装这里不作介绍,如果正常,Openvpn Gui 客户端显示绿色,ping 测试无误,如下 315 | 316 | ``` 317 | C:\Users\kumu>ping 10.8.0.1 # 测试 VPN 318 | 319 | 正在 Ping 10.8.0.1 具有 32 字节的数据: 320 | 来自 10.8.0.1 的回复: 字节=32 时间<1ms TTL=64 321 | 来自 10.8.0.1 的回复: 字节=32 时间<1ms TTL=64 322 | ... ... 323 | C:\Users\kumu>ping 192.168.10.19 #测试内网 324 | 325 | 正在 Ping 192.168.10.19 具有 32 字节的数据: 326 | 来自 192.168.10.19 的回复: 字节=32 时间=1ms TTL=64 327 | 来自 192.168.10.19 的回复: 字节=32 时间=2ms TTL=64 328 | ... ... 329 | ``` 330 | 331 | ### 2.5 Linux 客户端配置 332 | 333 | __安装__参见 Server 端安装 334 | 335 | #### 相关配置 336 | 337 | ``` 338 | # mkdir /etc/openvpn 339 | # cp /usr/local/src/openvpn/openvpn-2.3.1/sample/sample-config-files/client.conf /etc/openvpn/ 340 | # grep -vE '^$|^#|^;' /etc/openvpn/client.conf 341 | client 342 | dev tun 343 | proto udp 344 | remote 10.2.0.110 1194 345 | resolv-retry infinite 346 | nobind 347 | persist-key 348 | persist-tun 349 | ca ca.crt 350 | cert kumu_client1.crt 351 | key kumu_client1.key 352 | ns-cert-type server 353 | tls-auth ta.key 1 354 | comp-lzo 355 | verb 3 356 | ``` 357 | 358 | 拷贝 Server 端生成的如下客户端证书到 Linux 客户端 /etc/openvpn 下(这里为了方便不再生成一套客户端证书了) 359 | 360 | * kumu_client1.crt 361 | * kumu_client1.key 362 | * ca.key 363 | * ta.key 364 | 365 | __启动 Openvpn 客户端服务:__ 366 | 367 | ``` 368 | openvpn --config /etc/openvpn/client.conf --daemon 369 | ``` 370 | 371 | #### 测试 372 | 373 | ``` 374 | # ifconfig tun0 375 | tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 376 | inet addr:10.8.0.6 P-t-P:10.8.0.5 Mask:255.255.255.255 377 | ... ... 378 | # route -n 379 | Kernel IP routing table 380 | Destination Gateway Genmask Flags Metric Ref Use Iface 381 | 10.8.0.5 0.0.0.0 255.255.255.255 UH 0 0 0 tun0 382 | 10.8.0.0 10.8.0.5 255.255.255.0 UG 0 0 0 tun0 383 | 192.168.10.0 10.8.0.5 255.255.255.0 UG 0 0 0 tun0 384 | ... ... 385 | # ping 192.168.10.19 386 | PING 192.168.10.19 (192.168.10.19) 56(84) bytes of data. 387 | 64 bytes from 192.168.10.19: icmp_seq=1 ttl=64 time=0.690 ms 388 | 64 bytes from 192.168.10.19: icmp_seq=2 ttl=64 time=1.21 ms 389 | ... ... 390 | ``` 391 | 392 | 393 | -------------------------------------------------------------------------------- /服务/rsync.md: -------------------------------------------------------------------------------- 1 | # rsync 2 | 3 | ## 一、rsync 基本介绍 4 | 5 | `rsync` 是类 unix 系统下的数据镜像备份工具,从软件的命名上就可以看出来了—— remote sync。它的特性如下: 6 | 7 | 8 | * 1、可以镜像保存整个目录树和文件系统 9 | * 2、可以很容易做到保持原来文件的权限、时间、软硬链接等等 10 | * 3、无须特殊权限即可安装 11 | * 4、优化的流程,文件传输效率高 12 | * 5、可以使用 rsh、ssh 等方式来传输文件,当然也可以通过直接的socket连接 13 | * 6、支持匿名传输 14 | 15 | 在使用 rsync 进行远程同步时,可以使用两种方式:__远程 Shell 方式__(用户验证由 ssh 负责)和 __C/S 方式__(即客户连接远程 rsync 服务器,用户验证由 rsync 服务器负责)。 16 | 17 | 无论本地同步目录还是远程同步数据,首次运行时将会把全部文件拷贝一次,以后再运行时将只拷贝有变化的文件(对于新文件)或文件的变化部分(对于原有文件)。 18 | 19 | ## 二、rsync 选项 20 | 21 | ``` 22 | Usage: rsync [OPTION]... SRC [SRC]... DEST 23 | or rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST 24 | or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST 25 | or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST 26 | or rsync [OPTION]... [USER@]HOST:SRC [DEST] 27 | or rsync [OPTION]... [USER@]HOST::SRC [DEST] 28 | or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST] 29 | The ':' usages connect via remote shell, while '::' & 'rsync://' usages connect 30 | to an rsync daemon, and require SRC or DEST to start with a module name. 31 | ``` 32 | 33 | __注:__ 在指定复制源时,路径是否有最后的 “/” 有不同的含义,例如: 34 | 35 | * /data :表示将整个 /data 目录复制到目标目录 36 | * /data/ :表示将 /data/ 目录中的所有内容复制到目标目录 37 | 38 | ### 2.1、常用选项 39 | 40 | * `-v` : Verbose (try -vv for more detailed information) # 详细模式显示 41 | * `-e` "ssh options" : specify the ssh as remote shell # 指定 ssh 作为远程 shell 42 | * `-a` : archive mode # 归档模式,表示以递归方式传输文件,并保持所有文件属性,等于 -rlptgoD 43 | * `-r`(--recursive) : 目录递归 44 | * `-l`(--links) :保留软链接 45 | * `-p`(--perms) :保留文件权限 46 | * `-t`(--times) :保留文件时间信息 47 | * `-g`(--group) :保留属组信息 48 | * `-o`(--owner) :保留文件属主信息 49 | * `-D`(--devices) :保留设备文件信息 50 | * `-z` : 压缩文件 51 | * `-h` : 以可读方式输出 52 | * `-H` : 复制硬链接 53 | * `-X` : 保留扩展属性 54 | * `-A` : 保留ACL属性 55 | * `-n` : 只测试输出而不正真执行命令,推荐使用,特别防止 `--delete` 误删除! 56 | * `--stats` : 输出文件传输的状态 57 | * `--progress` : 输出文件传输的进度 58 | * `––exclude=PATTERN` : 指定排除一个不需要传输的文件匹配模式 59 | * `––exclude-from=FILE` : 从 FILE 中读取排除规则 60 | * `––include=PATTERN` : 指定需要传输的文件匹配模式 61 | * `––include-from=FILE` : 从 FILE 中读取包含规则 62 | * `--numeric-ids` : 不映射 uid/gid 到 user/group 的名字 63 | * `-S, --sparse` : 对稀疏文件进行特殊处理以节省DST的空间 64 | * `--delete` : 删除 DST 中 SRC 没有的文件,也就是所谓的镜像 [mirror] 备份 65 | 66 | ## 三、远程 Shell 方式 67 | 68 | ``` 69 | rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST # 执行“推”操作 70 | or rsync [OPTION]... [USER@]HOST:SRC [DEST] # 执行“拉”操作 71 | ``` 72 | 73 | ## 四、rsync C/S 方式 74 | 75 | ``` 76 | rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST # 执行“推”操作 77 | or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST # 执行“推”操作 78 | or rsync [OPTION]... [USER@]HOST::SRC [DEST] # 执行“拉”操作 79 | or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST] # 执行“拉”操作 80 | ``` 81 | 82 | C/S 方式需要配置服务端,下面是一个配置文件示例: 83 | 84 | ``` 85 | # /etc/rsyncd.conf 86 | 87 | uid = root 88 | gid = root 89 | use chroot = yes 90 | 91 | [bak-data] 92 | path = /data/ 93 | comment = data backup 94 | numeric ids = yes 95 | read only = yes 96 | list = no 97 | auth users = data 98 | filter = merge /etc/.data-filter # 过滤规则 99 | secrets file = /etc/rsync-secret 100 | hosts allow = 192.168.80.0/24 172.16.0.10 101 | 102 | [bak-home] 103 | path = /home/ 104 | comment = home backup 105 | numeric ids = yes 106 | read only = yes 107 | list = no 108 | auth users = home,test 109 | exclude = .svn .git 110 | secrets file = /etc/rsync-secret 111 | hosts allow = 192.168.80.0/24 172.16.0.10 112 | ``` 113 | 114 | 密码文件和 filter 文件内容如下: 115 | 116 | ``` 117 | # cat /etc/rsync-secret 118 | data:123321 119 | home:123456 120 | test:654321 121 | # chmod 600 /etc/rsync-secret 122 | # cat /etc/.data-filter # 关于 filter 的规则文件需要多测试才能彻底明白 123 | + mysql56/*** 124 | - * 125 | # 以上规则表示匹配所有 mysql56 目录下的内容,其它都不同步 126 | ``` 127 | 128 | 关于filter的匹配规则可以参考[man手册](http://www.samba.org/ftp/rsync/rsyncd.conf.html): 129 | 130 | filter 131 | The daemon has its own filter chain that determines what files it will let the client access. This chain is not sent to the client and is independent of any filters the client may have specified. Files excluded by the daemon filter chain (daemon-excluded files) are treated as non-existent if the client tries to pull them, are skipped with an error message if the client tries to push them (triggering exit code 23), and are never deleted from the module. You can use daemon filters to prevent clients from downloading or tampering with private administrative files, such as files you may add to support uid/gid name translations. 132 | 133 | The daemon filter chain is built from the "filter", "include from", "include", "exclude from", and "exclude" parameters, in that order of priority. Anchored patterns are anchored at the root of the module. To prevent access to an entire subtree, for example, "/secret", you must exclude everything in the subtree; the easiest way to do this is with a triple-star pattern like "/secret/***". 134 | 135 | The "filter" parameter takes a space-separated list of daemon filter rules, though it is smart enough to know not to split a token at an internal space in a rule (e.g. "- /foo - /bar" is parsed as two rules). You may specify one or more merge-file rules using the normal syntax. Only one "filter" parameter can apply to a given module in the config file, so put all the rules you want in a single parameter. Note that per-directory merge-file rules do not provide as much protection as global rules, but they can be used to make --delete work better during a client download operation if the per-dir merge files are included in the transfer and the client requests that they be used. 136 | 137 | ## 五、一些命令 138 | 139 | ### 5.1、常用命令 140 | 141 | ``` 142 | RSYNC_PASSWORD=123321 rsync -havAEHXi -n --numeric-ids --delete --stats --progress [SRC] [DEST] 143 | ``` 144 | 145 | __注:__ 如果有稀疏文件,则添加 `-S` 选项可以提升传输性能。 146 | 147 | ### 5.2、ssh 端口非默认 22 同步 148 | 149 | 使用 ssh 方式传输时如果连接服务器 ssh 端口非标准,则需要通过 `-e` 选项指定: 150 | 151 | ``` 152 | RSYNC_PASSWORD=123321 rsync -havAEHXi -n --numeric-ids --delete --stats --progress -e "ssh -p 22222" [USER@]HOST:SRC [DEST] 153 | ``` 154 | 155 | ### 5.3、查看服务器同步资源 156 | 157 | ``` 158 | RSYNC_PASSWORD=123321 rsync --list-only data@192.168.80.150::bak-data 159 | 或 160 | RSYNC_PASSWORD=123321 rsync --list-only rsync://data@192.168.80.150/bak-data 161 | ``` 162 | 163 | ## 六、参考文档 164 | 165 | * [rsync man 手册](http://www.samba.org/ftp/rsync/rsyncd.conf.html) 166 | * [howtocn rsync文档](http://www.howtocn.org/rsync:use_rsync) 167 | * [使用 rsync 进行文件备份](http://blog.clanzx.net/2013/08/23/rsync-backup.html) 168 | 169 | --EOF-- -------------------------------------------------------------------------------- /服务/rsyslog.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /服务/ssh.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /版本管理/git.md: -------------------------------------------------------------------------------- 1 | 2 | 1. 入门和学习Git的最好资料是:[pro git](http://iissnan.com/progit/),本文档主要记录我们在开发、发布过程中一些常用的 Git 命令。 3 | 2. [Git 风格指南](https://github.com/aseaday/git-style-guide) 4 | 5 | ## 一、Git基础 6 | 7 | ### 1.1 环境配置 8 | 9 | + `git config user.name your_name` : 设置你的用户名, 提交会显示 10 | + `git config user.email your_email` : 设置你的邮箱 11 | + `git config core.quotepath false` : 解决中文文件名显示为数字问题 12 | + `git config --list` : 查看现有的配置 13 | 14 | 几个 alias 方便操作: 15 | 16 | git config --global alias.co checkout 17 | git config --global alias.br branch 18 | git config --global alias.ci commit 19 | git config --global alias.st status 20 | 21 | ### 1.2 基本操作 22 | 23 | + `git init` : 初始化一个 git 仓库 24 | + `git add ` : 添加一个文件到 git 仓库中 25 | + `git commit -m "commit message"`: 提交到本地 26 | + `git push [remote-name] [branch-name]` : 把本地的提交记录推送到远端分支 27 | + `git pull`: 更新仓库 `git pull` = `git fetch` + `git merge` 28 | + `git checkout -- ` : 还原未暂存(staged)的文件 29 | + `git reset HEAD ...` : 取消暂存,那么还原一个暂存文件,应该是先 `reset` 后 `checkout` 30 | + `git stash` : 隐藏本地提交记录, 恢复的时候 `git stash pop`。这样可以在本地和远程有冲突的情况下,更新其他文件 31 | + `git log --name-status` : 查看详细的 log 32 | 33 | ### 1.3 分支 34 | 35 | + `git branch ` : 基于当前 commit 新建一个分支,但是不切换到新分支 36 | + `git checkout -b ` : 新建并切换分支 37 | + `git checkout ` : 切换分支 38 | + `git branch -d ` : 删除分支 39 | + `git push origin ` : 推送本地分支 40 | + `git checkout -b origin/` : 基于某个远程分支新建一个分支开发 41 | + `git checkout --track origin/` : 跟踪远程分支(创建跟踪远程分支,Git 在 `git push` 的时候不需要指定 `origin` 和 `branch-name` ,其实当我们 `clone` 一个 repo 到本地的时候,`master` 分支就是 origin/master 的跟踪分支,所以提交的时候直接 `git push`)。 42 | + `git push origin :` : 删除远程分支 43 | 44 | **Tips**: 放弃所有本地提交/改动,强制更新: 45 | 46 | git fetch --all 47 | git reset --hard origin/master 48 | git pull 49 | 50 | ### 1.4 标签 51 | 52 | + `git tag -a -m ` : 创建一个标签 53 | + `git tag` : 显示已有的标签 54 | + `git show tagname`: 显示某个标签的详细信息 55 | + `git checkout -b ` : 基于某个 tag 创建一个新的分支 56 | 57 | ### 1.5 回退到某一次提交 58 | 59 | + step 1: 使用 `git log` 查看提交的 hash 值 60 | + step 2: `git reset --hard hash` 61 | 62 | 可在本地回退到某一次提交,撤掉回退 `git pull` 即可。 63 | 64 | 如果想回退到远端分支的某一次提交,需要强制推送到远端分支: `git push origin master -f`。 65 | 66 | ## 二、知识点 67 | 68 | 基本命令让你快速的上手使用Git,知识点能让你更好的理解Git。 69 | 70 | ### 2.1 文件的几种状态 71 | 72 | + untracked: 未被跟踪的,没有纳入 Git 版本控制,使用 `git add ` 纳入版本控制 73 | + unmodified: 未修改的,已经纳入版本控制,但是没有修改过的文件 74 | + modified: 对纳入版本控制的文件做了修改,git 将标记为 modified 75 | + staged: 暂存的文件,简单理解: 暂存文件就是 add 之后,commit 之前的文件状态 76 | 77 | 理解这几种文件状态对于理解 Git 是非常关键的(至少可以看懂一些错误提示了)。 78 | 79 | ### 2.2 快照和差异 80 | 81 | 详细可看:[Pro Git: Git基础](http://iissnan.com/progit/html/zh/ch1_3.html)中有讲到 *直接记录快照,而非差异比较*,这里只讲我个人的理解。 82 | 83 | Git 关心的是文件数据整体的变化,其他版本管理系统(以svn为例)关心的某个具体文件的*差异*。这个差异是好理解的,也就是两个版本具体文件的不同点,比如某一行的某个字符发生了改变。 84 | 85 | Git 不保存文件提交前后的差异,不变的文件不会发生任何改变,对于变化的文件,前后两次提交则保存两个文件。举个例子: 86 | 87 | SVN: 88 | 89 | 1. 新建3个文件a, b, c,做第一次提交 -> `version1 : file_a file_b file_c` 90 | 2. 修改文件 b, 做第二次提交(真正提交的是 修改后的文件 b 和修改前的 `file_b` 的 diff) -> `version2: diff_b_2_1` 91 | 3. 当我要 checkout version2 的时候,实际上得到的是 `file_a file_b+diff_b_2_1 file_c` 92 | 93 | Git: 94 | 95 | 1. 新建3个文件a, b, c,做第一次提交 -> `version1 : file_a file_b file_c` 96 | 2. 修改文件 b (得到`file_b1`), 做第二次提交 -> `version2: file_a file_b1 file_c` 97 | 3. 当我要用 version2 的时候,实际上得到的是 `file_a file_b1 file_c` 98 | 99 | 上面的 `file_a file_b1 file_c` 就是 version2 的 *快照*。 100 | 101 | ### 2.3 Git数据结构 102 | 103 | Git的核心数是很简单的,就是一个链表(或者一棵树更准确一些?无所谓了),一旦你理解了它的基本数据结构,再去看Git,相信你有不同的感受。继续用上面的例子(所有的物理文件都对应一个 SHA-1 的值) 104 | 105 | 当我们做第一次提交时,数据结构是这样的: 106 | 107 | 108 | sha1_2_file_map: 109 | 28415f07ca9281d0ed86cdc766629fb4ea35ea38 => file_a 110 | ed5cfa40b80da97b56698466d03ab126c5eec5a9 => file_b 111 | 1b5ca12a6cf11a9b89dbeee2e5431a1a98ea5e39 => file_c 112 | 113 | commit_26b985d269d3a617af4064489199c3e0d4791bb5: 114 | base_info: 115 | Auther: "JerryZhang(chinajiezhang@gmail.com)" 116 | Date: "Tue Jul 15 19:19:22 2014 +0800" 117 | commit_content: "第一次提交" 118 | file_list: 119 | [1]: 28415f07ca9281d0ed86cdc766629fb4ea35ea38 120 | [2]: ed5cfa40b80da97b56698466d03ab126c5eec5a9 121 | [3]: 1b5ca12a6cf11a9b89dbeee2e5431a1a98ea5e39 122 | pre_commit: null 123 | next_commit: null 124 | 125 | 当修改了 `file_b`, 再提交一次时,数据结构应该是这样的: 126 | 127 | sha1_2_file_map: 128 | 28415f07ca9281d0ed86cdc766629fb4ea35ea38 => file_a 129 | ed5cfa40b80da97b56698466d03ab126c5eec5a9 => file_b 130 | 1b5ca12a6cf11a9b89dbeee2e5431a1a98ea5e39 => file_c 131 | 39015ba6f80eb9e7fdad3602ef2b1af0521eba89 => file_b1 132 | 133 | commit_26b985d269d3a617af4064489199c3e0d4791bb5: 134 | base_info: 135 | Auther: "JerryZhang(chinajiezhang@gmail.com)" 136 | Date: "Tue Jul 15 19:19:22 2014 +0800" 137 | commit_content: "第一次提交" 138 | file_list: 139 | [1]: 28415f07ca9281d0ed86cdc766629fb4ea35ea38 140 | [2]: ed5cfa40b80da97b56698466d03ab126c5eec5a9 141 | [3]: 1b5ca12a6cf11a9b89dbeee2e5431a1a98ea5e39 142 | pre_commit: commit_a08a57561b5c30b9c0bf33829349e14fad1f5cff 143 | next_commit: null 144 | 145 | commit_a08a57561b5c30b9c0bf33829349e14fad1f5cff: 146 | base_info: 147 | Auther: "JerryZhang(chinajiezhang@gmail.com)" 148 | Date: "Tue Jul 15 22:19:22 2014 +0800" 149 | commit_content: "更新文件b" 150 | file_list: 151 | [1]: 28415f07ca9281d0ed86cdc766629fb4ea35ea38 152 | [2]: 39015ba6f80eb9e7fdad3602ef2b1af0521eba89 153 | [3]: 1b5ca12a6cf11a9b89dbeee2e5431a1a98ea5e39 154 | pre_commit: null 155 | next_commit: commit_26b985d269d3a617af4064489199c3e0d4791bb5 156 | 157 | 当提交完第二次的时候,执行 `git log`,实际上就是从 `commit_a08a57561b5c30b9c0bf33829349e14fad1f5cff` 开始遍历然后打印 `base_info` 而已。 158 | 159 | 实际的 git 实际肯定要比上面的结构((的信息)的)要复杂的多,但是它的核心思想应该是就是,每一次提交就是一个新的结点。通过这个结点,我可以找到所有的快照文件。再思考一下,什么是分支?什么是 Tags,其实他们可能只是某次提交的引用而已(一个 `tag_head_node` 指向了某一次提交的node)。再思考怎么回退一个版本呢?指针偏移!依次类推,上面的基本命令都可以得到一个合理的解释。 160 | 161 | **理解git fetch 和 git pull的差异** 162 | 163 | 上面我们说过 `git pull` 等价于 `git fetch` 和 `git merge` 两条命令。当我们 `clone` 一个 repo 到本地时,就有了本地分支和远端分支的概念(假定我们只有一个主分支),本地分支是 `master`,远端分支是 `origin/master`。通过上面我们对 Git 数据结构的理解,`master` 和 `origin/master` 可以想成是指向最新 commit 结点的两个指针。刚 `clone` 下来的 repo,`master` 和 `origin/master` 指针指向同一个结点,我们在本地提交一次,`origin` 结点就更新一次,此时 `master` 和 `orgin/master` 就不再相同了。很有可能别人已经 commit 改 repo 很多次了,并且进行了提交。那么我们的本地的 `origin/master` 就不再是远程服务器上的最新的位置了。 `git fetch` 干的就是从服务器上同步服务器上最新的 `origin/master` 和一些服务器上新的记录/文件到本地。而 `git merge` 就是合并操作了(解决文件冲突)。`git push` 是把本地的 `origin/master` 和 `master` 指向相同的位置,并且推送到远程的服务器。 164 | 165 | *理论部分是我个人对 Git 的理解,难免有偏差,看看就可以了。* 166 | 167 | -------------------------------------------------------------------------------- /版本管理/svn.md: -------------------------------------------------------------------------------- 1 | 本文由 [svn book 1.4](http://svndoc.iusesvn.com/svnbook/1.4) 整理而来。 2 | 3 | `svn help `: 查看子命令用法、参数及行为方式。 4 | 5 | ## 一、创建一个svn仓库 6 | 7 | + `svnadmin create /user/local/svn/newrepos`: 创建一个新的 repo 8 | + `svn import YourDir file:///usr/local/svn/newrepos/some/project -m "Init import"` : 把未版本化的文件导入版本库 9 | + `svn list file:///usr/local/svn/newrepos/some/project`: 查看文件列表 10 | + `svn export http://svn.example.com/svn/repos1` : 导出一份干净的仓库(没有.svn文件) 11 | 12 | ## 二、基本使用 13 | 14 | + `svn checkout ` : 检出到本地 15 | + `svn update` : 更新工作拷贝 16 | + `svn add foo` : 将文件、目录或者符号链添加到版本库(提交后生效) 17 | + `svn delete foo` : 将文件、目录或者符号链从版本库中移除(提交后生效) 18 | + `svn copy foo bar` : 拷贝 19 | + `svn move foo bar` : 重命名 20 | + `svn mkdir blort` : 等价于 `mkdir blort; svn add blort` 21 | + `svn status` : 浏览你所做的修改。`-v` 显示所有项目文件的状态;`-u` 显示是否过期。 22 | - `A item` : 预定加入到版本库的文件、目录或符号链的item 23 | - `C item` : 文件 item 发生冲突,在从服务器更新时与本地版本发生交跌,在你提交到版本库前,必须手工的解决冲突 24 | - `D item` : 文件、目录或是符号链 item 预定从版本库中删除 25 | - `M item` : 文件 item 的内容被修改了 26 | + `svn diff` : 查看详细的信息,`-r` 指定比较版本 27 | + `svn revert` : 取消本地修改 28 | + `svn resolved` : 解决完冲突后通知svn(当 update 有冲突时会生成 3 个临时文件: filename.mine, filename.rOLDREV, filename.rNEWREV,resolved 告诉 svn 删除那3个临时文件) 29 | + `svn commmit` : 提交修改, `-m` 添加描述修改信息 30 | + `svn log` : 查看日志,`-r` 显示某一个版本, `-v` 详细模式 31 | + `svn cat` : 取特定版本的某一个文件显示在当前屏幕,`-r` 显示指定版本 32 | + `svn list` : 显示一个目录在某一版本存在的文件 33 | + `svn cleanup` : 它查找工作拷贝中的所有遗留的日志文件,删除进程中工作拷贝的锁 34 | 35 | ## 三、高级使用 36 | 37 | ### 3.1 属性 38 | 39 | 属性不是版本化的,如果你修改,删除一个修订版本属性,SVN 没有办法恢复到以前的值。 40 | 41 | + `svn propset` : 添加和修改文件或目录的属性 42 | + `svn propedit` : 使用定制的编辑器程序来添加和修改属性 43 | + `svn proplist` : 列出路径上存在的所有属性名称 44 | + `svn propget` : 获取属性的值 45 | + `svn propdel` : 删除某个属性 46 | 47 | ### 3.2 忽略未版本控制的条目 48 | 49 | SVN 忽略方法和 git 不同,git 是在本地加一个 `.gitigore` 即可,SVN 是通过属性(svn:ignore)来实现的。 50 | 51 | `svn propedit svn:ignore work_dir` : 在工作目录 work_dir 下添加过滤文件 52 | 53 | 在个人目录下编辑 `.bash_profile` 文件, 添加 SVN\_EDITOR 环境变量, `export SVN_EDITOR=vim`. 54 | 55 | ### 3.3 外部定义 56 | 57 | 引用场景:多个目录共享同一个目录。以游戏开发为例,UI、服务器、策划共享的数据表,这个时候就可以用到 *外部定义* 这个概念了。我理解外部定义就相当于 linux 下的软链接。 58 | 59 | 一个外部定义是一个本地路经到 URL 的影射—也有可能一个特定的修订版本—一些版本化的资源。在 SVN 你可以使用 `svn:externals` 属性来定义外部定义,你可以用 `svn propset` 或` svn propedit` 创建和修改这个属性。它可以设置到任何版本化的路经,它的值是一个多行的子目录,可选的修订版本标记和完全有效的 SVN 版本库 URL 的列表(相对于设置属性的版本化目录)。 60 | 61 | 可以使用 `--ignore-externals` 来忽略 externals。 62 | 63 | 64 | ## 四、分支与合并 65 | 66 | ### 4.1 分支创建与删除 67 | 68 | SVN 分支其实只是做了一份拷贝而已(svn copy), 但是它并不是物理意义上的拷贝(完全复制一份,可以理解成 Linux 的硬链接, *廉价复制* )。 69 | 70 | svn copy http://svn.example.com/repos/calc/trunk \ 71 | http://svn.example.com/repos/calc/branches/my-calc-branch \ 72 | -m "Creating a private branch of /calc/trunk." 73 | 74 | + `svn delete http://svn.example.com/repos/calc/branches/my-calc-branch -m "Removing obsolete branch of calc project."` : 删除一个分支 75 | 76 | ### 4.2 在分支上工作 77 | 78 | 再 `checkout` 一份呗。 79 | 80 | ### 4.3 合并分支 81 | 82 | svn diff -c 344 http://svn.example.com/repos/calc/trunk 83 | svn merge -c 344 http://svn.example.com/repos/calc/trunk 84 | 85 | 合并分支看似简单,其实是一件非常头疼的事情(尤其是大项目)。我宁愿去选择一些可视化的文本比较工作,比如 [BeyondCompare](http://www.scootersoftware.com/),可以为你省下太多事情了。 86 | 87 | [版本库管理](http://svndoc.iusesvn.com/svnbook/1.4/svn.reposadmin.html) 之后的章节感兴趣去看看(上面提供的命令足够应付大多数使用情况了) 88 | 89 | ### 4.4 查看所有分支 90 | 91 | 1. 在根目录下 `svn info` 找到版本库根路径,比如: `https://10.0.128.1/svn/HotCode` 92 | 2. `svn ls https://10.0.128.1/svn/HotCode/branches` 就可以看到其他分支了 93 | 94 | ## 五、知识点 95 | 96 | ### 5.1 四种文件状态(svn status) 97 | 98 | 1. 未修改且是当前的, 文件在工作目录里没有修改,在工作修订版本之后没有修改提交到版本库。svn commit操作不做任何事情,svn update不做任何事情。 99 | 2. 本地已修改且是当前的, 在工作目录已经修改,从基本修订版本之后没有修改提交到版本库。本地修改没有提交,因此svn commit会成功提交,svn update不做任何事情。 100 | 3. 未修改且不是当前的了, 这个文件在工作目录没有修改,但在版本库中已经修改了。这个文件最终将更新到最新版本,成为当时的公共修订版本。svn commit不做任何事情,svn update将会取得最新的版本到工作拷贝。 101 | 4. 本地已修改且不是最新的, 这个文件在工作目录和版本库都得到修改。一个svn commit将会失败,这个文件必须首先更新,svn update命令会合并公共和本地修改,如果Subversion不可以自动完成,将会让用户解决冲突。 102 | 103 | ### 5.2 修订版本关键字 104 | 105 | 这些关键字可以用来代替 `--revision(r)` 的数字参数,这会被 Subversion 解释到特定的修订版本号。 106 | 107 | + `HEAD` : 版本库中最新的(或者是 "最年轻的)版本。 108 | + `BASE` : 工作拷贝中一个条目的修订版本号,如果这个版本在本地修改了,则“BASE版本”就是这个条目在本地未修改的版本。 109 | + `COMMITTED` : 项目最近修改的修订版本,与BASE相同或更早。 110 | + `PREV` : 一个项目最后修改版本之前的那个版本,技术上可以认为是COMMITTED -1。 111 | 112 | ### 5.3 SVN 和 Git 113 | 114 | 我感觉 SVN 和 Git 设计的本质区别在于 SVN 核心点在于它的目录,而 Git 的核心点在于它的 Commit(结点)。这也就说明了 SVN 可以 checkout 某一个目录,Git 不行。SVN 的分支可以理解成一个目录,而 Git 的分支只不过是某个 Commit 上的快照而已。 115 | 116 | ## 六、常见问题 117 | 118 | + [svn diff: file marked as binary type](http://stackoverflow.com/questions/2634043/svn-diff-file-marked-as-binary-type) 119 | -------------------------------------------------------------------------------- /系统/awk.md: -------------------------------------------------------------------------------- 1 | # AWK 2 | 3 | ## 一、awk 简介 4 | 5 | 最简单地说, AWK 是一种用于处理文本的编程语言工具。AWK 在很多方面类似于 shell 编程语言,尽管 AWK 具有完全属于其本身的语法。它的设计思想来源于 SNOBOL4 、sed 、Marc Rochkind 设计的有效性语言、语言工具 yacc 和 lex ,当然还从 C 语言中获取了一些优秀的思想。在最初创造 AWK 时,其目的是用于文本处理,并且这种语言的基础是,只要在输入数据中有模式匹配,就执行一系列指令。该实用工具扫描文件中的每一行,查找与命令行中所给定内容相匹配的模式。如果发现匹配内容,则进行下一个编程步骤。如果找不到匹配内容,则继续处理下一行。 6 | 7 | ## 二、空行、行号和计算 8 | 9 | ### 2.1 每行后面都添加一个空行 10 | 11 | awk 程序都是由一系列的 "匹配模式 { 执行动作 }" 语句所组成。在每个 "匹配模式——执行动作" 语句中,模式和动作都是可以被省略的。如果匹配模式被省略,那么预定的动作将会对输入文件的每一行执行。 12 | 13 | ``` 14 | awk '1; { print "" }' 15 | 等价于 # 如果动作被省略,那么默认就会执行{print } 16 | awk '1 {print } { print "" }' 17 | 等价于 # 动作只有在匹配模式值为真时执行,"1"永远为真 18 | awk '{print } { print "" }' 19 | ``` 20 | 21 | ### 2.2 添加空行的另外一种方法 22 | 23 | awk 中每条 print 语句后都默认会输出一个 ORS 变量(Output Record Seprator,即输出行分隔符,默认为换行符)。第一个不带参数的 print 语句等同于 print $0,其中 $0 代表整行内容的变量。第二个 print 语句什么也不输出,但是鉴于 print 语句后都会被自动加上 ORS 变量,这句的作用就是输出一个新行,遇事每行后面加空行的目的达到了。 24 | 25 | ``` 26 | awk ' BEGIN { ORS="\n\n" }; 1' 27 | # BEGIN 是特殊的模式,后面所接的内容,会在文件被读入前执行。 28 | # 这里对 ORS 变量进行重新定义,将一个换行符改成两个。"1",等价于 {print } 29 | ``` 30 | 31 | ### 2.3 在每一个非空的行后面添加空行 32 | 33 | ``` 34 | awk 'NF {print $0 "\n"}' 35 | ``` 36 | 37 | NF(number of fields),即本行被分割成的字段的数目。当遇到空行,NF 值为0,后面的匹配动作就不会被执行,这条语句可以理解为 "如果这一行可以分割成任意大于0的部分,那么输出当前行以及一个换行符"。 38 | 39 | ### 2.4 在每行后添加两个空行 40 | 41 | ``` 42 | awk '1; {print "\n"}' 43 | 等价于 44 | awk '{print ; print "\n"}' 45 | ``` 46 | 47 | -------------------------------------------------------------------------------- /系统/cut.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /系统/grep.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /系统/process.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /系统/sed.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /系统/sort.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /系统/tar.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /系统/xargs.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /编译/autotools.md: -------------------------------------------------------------------------------- 1 | **本文档整理自: [Autotools Tutorial: Part II](https://www.lrde.epita.fr/~adl/dl/autotools.pdf)。** 2 | 3 | ## 一、Hello World 4 | 5 | ### 1.1 创建文件 6 | 7 | *src/main.c* 8 | 9 | #include 10 | #include 11 | 12 | int main(void) 13 | { 14 | puts ("Hello World!"); 15 | puts ("This is " PACKAGE_STRING "."); 16 | return 0; 17 | } 18 | 19 | 20 | *configure.ac* 21 | 22 | AC_INIT([amhello], [1.0], [bug-report@address]) 23 | AM_INIT_AUTOMAKE([foreign -Wall -Werror]) 24 | AC_PROG_CC 25 | AC_CONFIG_HEADER([config.h]) 26 | AC_CONFIG_FILES([Makefile src/Makefile]) 27 | AC_OUTPUT 28 | 29 | *Makefile.am* 30 | 31 | SUBDIRS = src 32 | 33 | *src/Makefile.am* 34 | 35 | bin_PROGRAMS = hello 36 | hello_SOURCES = main.c 37 | 38 | 此时的文件结构为(`ls -R`): 39 | 40 | .: 41 | Makefile.am configure.ac src 42 | 43 | src: 44 | Makefile.am main.c 45 | 46 | 47 | ### 1.2 autoreconf --install 48 | 49 | $: autoreconf --install 50 | configure.ac:2: installing `./install-sh' 51 | configure.ac:2: installing `./missing' 52 | src/Makefile.am: installing `./depcomp' 53 | 54 | 此时的文件结构为(`ls -R`): 55 | 56 | .: 57 | Makefile.am aclocal.m4 config.h.in configure.ac install-sh src 58 | Makefile.in autom4te.cache configure depcomp missing 59 | 60 | autom4te.cache: 61 | output.0 output.1 requests traces.0 traces.1 62 | 63 | src: 64 | Makefile.am Makefile.in main.c 65 | 66 | + Makefile.in config.h.in configure* src/Makefile.in : expected configuration templates. 67 | + aclocal.m4 : denitions for third-party macros used in *configure.ac*. 68 | + depcomp* install-sh* missing* : auxiliary tools used during the build. 69 | + autom4te.cache/ autom4te.cache/* : Autotools cache files 70 | 71 | ### 1.3 `./configure` 72 | 73 | checking for a BSD-compatible install... /usr/bin/install -c 74 | checking whether build environment is sane... yes 75 | checking for a thread-safe mkdir -p... /bin/mkdir -p 76 | checking for gawk... gawk 77 | checking whether make sets $(MAKE)... yes 78 | checking for gcc... gcc 79 | ... 80 | configure: creating ./config.status 81 | config.status: creating Makefile 82 | config.status: creating src/Makefile 83 | config.status: creating config.h 84 | config.status: executing depfiles commands 85 | 86 | ### 1.4 `make` 87 | 88 | /usr/bin/make all-recursive 89 | make[1]: Entering directory `/home/zhangjie/TempFile/src' 90 | Making all in src 91 | make[2]: Entering directory `/home/zhangjie/TempFile/src/src' 92 | gcc -DHAVE_CONFIG_H -I. -I.. -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c 93 | mv -f .deps/main.Tpo .deps/main.Po 94 | gcc -g -O2 -o hello main.o 95 | make[2]: Leaving directory `/home/zhangjie/TempFile/src/src' 96 | make[2]: Entering directory `/home/zhangjie/TempFile/src' 97 | make[2]: Leaving directory `/home/zhangjie/TempFile/src' 98 | make[1]: Leaving directory `/home/zhangjie/TempFile/src' 99 | 100 | ### 1.5 编译、链接成功,运行程序: `src/hello` 101 | 102 | $: src/hello 103 | Hello World! 104 | This is amhello 1.0. 105 | 106 | ### 1.6 源码打包: `make distcheck` 107 | 108 | $: make distcheck 109 | ... 110 | ============================================= 111 | amhello-1.0 archives ready for distribution: 112 | amhello-1.0.tar.gz 113 | ============================================= 114 | 115 | ### 1.7 解包,查看文件内容 116 | 117 | $ tar ztf amhello-1.0.tar.gz 118 | amhello-1.0/ 119 | amhello-1.0/Makefile.am 120 | amhello-1.0/aclocal.m4 121 | amhello-1.0/configure.ac 122 | amhello-1.0/src/ 123 | amhello-1.0/src/Makefile.am 124 | amhello-1.0/src/main.c 125 | amhello-1.0/src/Makefile.in 126 | amhello-1.0/config.h.in 127 | amhello-1.0/Makefile.in 128 | amhello-1.0/missing 129 | amhello-1.0/configure 130 | amhello-1.0/depcomp 131 | amhello-1.0/install-sh 132 | 133 | ## 二、Autotools 核心介绍 134 | 135 | ### 2.1 GNU AutoConf 136 | 137 | + `autoconf` : Create *configure* from *configure.ac* . 138 | + `autoheader` : Create *config.h.in* from *configure.ac* . 139 | + `autoreconf` : Run all tools in the right order. 140 | + `autoscan` : Scan sources for common portability problems, and related macros missing from *configure.ac* . 141 | + `autoupdate` : Update obsolete macros in *configure.ac* . 142 | + `ifnames` : Gather identiers from all `#if/#ifdef/...` directives. 143 | + `autom4te` : The heart of Autoconf. It drives M4 and implements the 144 | features used by most of the above tools. Useful for 145 | creating more than just *configure* files. 146 | 147 | ### 2.2 GNU AutoMake 148 | 149 | + `automake` : Create *Makefile.in*s from *Makefile.am*s and *configure.ac* . 150 | + `aclocal` : Scan `configure.ac` for uses of third-party macros, and 151 | gather denitions in `aclocal.m4`. 152 | 153 | ### 2.3 autoreconf 154 | 155 | ![autoreconf](../images/autoreconf.jpg) 156 | 157 | 在实际应用中: 158 | 159 | + 没必要记住所有工具之间的关系; 160 | + 在初始化的时候,使用 `autoreconf --install`; 161 | + 修改输出(配置)文件的时候,重建规则; 162 | + 你需对解每个工具产生的错误都有一个粗糙的理解(至少要知道是谁产生的错误)。 163 | 164 | ## 三、Hello World 讲解 165 | 166 | ### 3.1 configure.ac 167 | 168 | AC_INIT([amhello], [1.0], [bug-report@address]) 169 | AM_INIT_AUTOMAKE([foreign -Wall -Werror]) 170 | AC_PROG_CC 171 | AC_CONFIG_HEADER([config.h]) 172 | AC_CONFIG_FILES([Makefile src/Makefile]) 173 | AC_OUTPUT 174 | 175 | + `AC_INIT`: Initialize *Autoconf*. Specify package's name, version number, and bug-report address. 176 | + `AM_INIT_AUTOMAKE`: Initialize *Automake*. Turn on all Automake warnning and report them as errors. This is a foreign package. 177 | + `AC_PROG_CC`: Check for a C compiler. 178 | + `AC_CONFIG_HEADER([config.h])`: Declare *config.h* as output header. 179 | + `AC_CONFIG_FILES`: Declare *Makefile* and *src/Makefile* as output files. 180 | + `AC_OUTPUT`: Actually output all declared files. 181 | 182 | ### 3.2 Makefile.am 183 | 184 | SUBDIRS = src 185 | 186 | + Build recursively in *src/* . 187 | + Nothing else is declared for the current directory.(The top-level *Makefile.am* is usually short.) 188 | 189 | ### 3.2 src/Makefile.am 190 | 191 | bin_PROGRAMS = hello 192 | hello_SOURCES = main.c 193 | 194 | + We are building some programs. 195 | + These programs will be installed in *bindir* (注意看下面tip的结构). 196 | + There is only one program to build: *hello*. 197 | + To create *hello*, just compile *main.c*. 198 | 199 | **tip**: Standard File System Hierarchy: 200 | 201 | ![](/attach/compile/sys_hierarchy.jpg) 202 | 203 | ## 四、使用 Autoconf 204 | 205 | ### 4.1 从 configure.ac 到 configure 和 config.h.in 206 | 207 | + "autoconf is a macro processor. 208 | + It converts *configure.ac*, which is a shell script using macro instructions, into *congfiure*, a full-fledged shell script. 209 | + Autoconf offers many macros to perform common conguration checks. 210 | + It is not uncommon to have a *configure.ac* without shell construct, using only macros. 211 | + While processing *configure.ac* it is also possible to trace the occurrences of macros. This is how "autoheader" creates *config.h.in* . It just looks for the macros that #define symbols. 212 | + The real macro processor actually is GNU M4. Autoconf offers some infrastructure on top of that, plus the pool of macros. 213 | 214 | ### 4.2 探索 M4 215 | 216 | *exmple.m4:* 217 | 218 | m4_define(NAME1, Harry) 219 | m4_define(NAME2, Sally) 220 | m4_define(MET, $1 met $2) 221 | MET(NAME1, NAME2) 222 | 223 | output: 224 | 225 | $: m4 -P example.m4 226 | # 空白 227 | # 空白 228 | # 空白 229 | Harry met Sally 230 | 231 | M4 是一个宏处理器,将输出拷贝到输出。可以内嵌,也可以用户自定义,除了宏展开以外,M4还有一些内建的函数,用来引用文件、执行Unix命令、文本操作、循环等。 232 | 233 | 这里不详细展开表述 M4,但是要记住 M4 是 Autoconf 的核心,Autoconf 只是封装了一些指令而已。 234 | 235 | ### 4.3 M4 基础上的 Autoconf 236 | 237 | + 在许多机器上, Auto = M4,和一些预定义的宏。 238 | + 引用是 `[` 和 `]` (而不是 `'` 和 `'`)。 239 | + 也因此在 Shell 中做比较使用 `test` ,而不是 `[` 。 240 | 241 | if test "$x" = "$y"; then ... 242 | 243 | + 使用 `AC_DEFUN` 定义宏。 244 | 245 | AC_DEFUN([NAME1], [Harry, Jr.]) 246 | AC_DEFUN([NAME2], [Sally]) 247 | AC_DEFUN([MET], [$1 met $2]) 248 | MET([NAME1], [NAME2]) 249 | 250 | 251 | ### 4.3 一个 configure.ac 的结构 252 | 253 | # Prelude 254 | AC_INIT([PACKAGE], [VERSION], [BUG-REPORT-ADDRESS]) 255 | AM_INIT_AUTOMAKE([foreign -Wall -Werror]) 256 | AC_PREREQ(VERSION) # Eg. AC_PREREQ([2.65]) 257 | AC_CONFIG_SRCDIR(FILE) # Eg. AC_CONFIG_SRCDIR([src/main.c]) 258 | AC_CONFIG_AUX_DIR(DIRECTORY) # mising, install-sh 等临时文件的目录 eg. AC_CONFIG_AUX_DIR([build-aux]) 259 | 260 | # Checks for programs. 261 | AC_PROG_CC 262 | AC_PROG_CXX 263 | AC_PROG_AWK 264 | AC_CHECK_PROGS(VAR, PROGS, [VAL-IF-NOT-FOUND]) # Dene VAR to the rst PROGS found, or to VAL-IF-NOT-FOUND otherwise. 265 | 266 | # Check for libraries. 267 | AC_CHECK_LIB(LIBRARY, FUNCT, [ACT-IF-FOUND], [ACT-IF-NOT]) # Check whether LIBRARY exists and contains FUNCT. AC CHECK HEADERS(HEADERS...)Execute ACT-IF-FOUND if it does, ACT-IF-NOT otherwise 268 | 269 | # Check for header files. 270 | AC_CHECK_HEADERS(HEADERS...) # Check for HEADERS and #define HAVE_HEADER_H for each header found. eg. AC_CHECK_HEADERS([sys/param.h unistd.h]) 271 | 272 | # Check for typedefs, structures, and compiler characteristics. 273 | 274 | # Check for library functions. 275 | 276 | # Output files. 277 | AC_CONFIG_HEADERS([config.h]) 278 | AC_CONFIG_FILES([Makefile src/Makefile ...]) 279 | AC_OUTPUT 280 | 281 | 282 | ## 五、使用 Automake 283 | 284 | ### 5.1 Automake 规则 285 | 286 | + Automake helps creating **portable** and **GNU-standard compliant* *Makefile*s. 287 | + You may be used to other kinds of build systems.(eg. no VPATH builds, but all objects go into *obj/*). 288 | + Do not use Automake if you do not like the GNU Build System: Automake will get in your way if you don't fit the mold. 289 | + "automake" creates **complex** *Makefile.in*s from simple *Makefile.am*s. 290 | + Consider *Makefile.in*s as internal details. 291 | + *Makele.am*s follow roughly the same syntax as *Makefile*s however they usually contains only variable denitions. 292 | + "automake"" creates build rules from these definitions. 293 | + It's OK to add extra *Makefile* rules in *Makefile.am*: "automake" will preserve them in the output. 294 | 295 | ### 5.2 在 *configure.ac* 中声明 Automake 296 | 297 | 语法: `AM_INIT_AUTOMAKE([OPTIONS...])])` . eg: `AM_INIT_AUTOMAKE([foreign -Wall -Werror])` . 298 | 299 | 选项: 300 | 301 | + `-Wall` : 关闭所有警告. 302 | + `-Werror` : 把警告当成错误. 303 | + `foreign` : 放宽 GNU 标准要求. 304 | + `1.11.1` : automake 的最小版本号 305 | + `dist-bzip2` : Also create tar.bz2 archives during `make dist` and `make distcheck`. 306 | + `tar-ustar` : Create tar archives using the ustar format. 307 | 308 | `AC_CONFIG_FILES(FILES...)` : Automake 为每一个有 *FILE*.am 的 *FILE* 生成一个 *FILE*.in 文件。 309 | 310 | eg: `AC_CONFIG_FILES([Makefile sub/Makefile])` 会生成 *Makefile.am* 和 *sub/Makefile.am*. 311 | 312 | ### 5.3 声明源文件 313 | 314 | bin_PROGRAMS = foo run-me 315 | foo_SOURCES = foo.c foo.h print.c print.h 316 | run_me_SOURCES = run.c run.h print.c 317 | 318 | + These programs will be installed in $(bindir). 319 | + The sources of each *program* go into *program*_SOURCES. 320 | + Non-alphanumeric characters are mapped to '_'. 321 | + Automake automatically computes the list of objects to build and link from these files. 322 | + Header files are not compiled. We list them only so they get distributed (Automake does not distribute files it does not know about). 323 | + It's OK to use the same source for two programs. 324 | + Compiler and linker are inferred from the extensions. 325 | 326 | ### 5.4 (静态)库 327 | 328 | lib_LIBRARIES = libfoo.a libbar.a 329 | libfoo_a_SOURCES = foo.c privfoo.h 330 | libbar_a_SOURCES = bar.c privbar.h 331 | include_HEADERS = foo.h bar.h 332 | 333 | + These libraries will be installed in $(libdir). 334 | + Library names must match lib*.a. 335 | + Public headers will be installed in $(includedir). 336 | + Private headers are not installed, like ordinary source files. 337 | 338 | ### 5.5 目录结构 339 | 340 | + 在每个目录下都要有一个 *Makefile* (也就是 *Makefile.am*)。 341 | + 所有的 *Makefile* 都要在 *configure.ac* 中声明. 342 | 343 | AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile src/dira/Makefile src/dirb/Makefile]) 344 | 345 | + 在顶层目录下运行 make. 346 | + *Makefile.am*s should fix the order in which to recurse directories using the *SUBDIRS* variable. 347 | 348 | file: Makefile.am 349 | SUBDIRS = lib src 350 | 351 | + The current directory is implicitly built after subdirectories. 352 | + You can put: .' where you want to override this. 353 | 354 | ### 5.6 $(srcdir) and VPATH Builds 355 | 356 | + Remember VPATH builds: a source file is not necessary in the current directory. 357 | + There are two twin trees: the **build tree**, and the **source tree**. 358 | + *Makefile* and objects files are in the build tree. 359 | + *Makefile.in*, *Makefile.am*, and source files are in the source tree. 360 | + If `./configure` is run in the current directory, the two trees are one. 361 | + In each *Makefile*, 'config.status' will define `$(srcdir)`: the path to the matching source directory. 362 | + When referring to sources files or targets in Automake variables, you do not have to worry about *source* vs. *build*, because 'make' will check both directories. 363 | + You may need `$(srcdir)` when specifying flags for tools, or writing custom commands. E.g., to tell the compiler to include headers from *dir/* , you should write `-I$(srcdir)/dir`, not `-Idir`. (`-Idir` would fetch headers from the build tree.) 364 | 365 | ### 5.7 Convenience Libraries 366 | 367 | *lib/Makefile.am*: 368 | 369 | noinst_LIBRARIES = libcompat.a 370 | libcompat_a_SOURCES = xalloc.c xalloc.h 371 | 372 | *src/Makefile.am*: 373 | 374 | bin_PROGRAMS = foo run-me 375 | foo_SOURCES = foo.c foo.h print.c print.h 376 | run_me_SOURCES = run.c run.h print.c 377 | run_me_LDADD = ../lib/libcompat.a 378 | run_me_CPPFLAGS = -I$(srcdir)/../lib 379 | 380 | + This is a convenience library, used only when building the package. 381 | + *LDADD* is added when linking all programs. 382 | + *AM_CPPFLAGS* contains additional preprocessor flags. 383 | + You can use per-target variables: they apply to a single program 384 | 385 | ### 5.8 Per-Target Flags 386 | 387 | Assuming foo is a program or library: 388 | 389 | + `foo_CFLAGS` : Additional C compiler flags. 390 | + `foo_CPPFLAGS` : Additional preprocessor flags (`-Is` and `-Ds`). 391 | + `foo_LDADD` : Additional link objects, `-ls` and `-Ls` (if *foo* is a program). 392 | + `foo_LIBADD` : Additional link objects, `-ls` and `-Ls` (if *foo* is a library). 393 | + `foo_LDFLAGS` : Additional linker flags. 394 | 395 | The default value for `foo_XXXFLAGS` is `$(AM_XXXFLAGS)`. 396 | 397 | Use plain file names to refer to libraries inside your package (keep `-ls` and `-Ls` for external libraries only). 398 | 399 | *src/Makefile.am*: 400 | 401 | bin_PROGRAMS = foo run-me 402 | foo_SOURCES = foo.c foo.h print.c print.h 403 | run_me_SOURCES = run.c run.h print.c 404 | run_me_CPPFLAGS = -I$(srcdir)/../lib 405 | run_me_LDADD = ../lib/libcompat.a $(EFENCELIB) 406 | 407 | ### 5.9 What Gets Distributed 408 | 409 | `make dist` and `make distcheck` create a tarball containing: 410 | 411 | + All sources declared using ... *SOURCES* 412 | + All headers declared using ... *HEADERS* 413 | + All scripts declared with *dist ... SCRIPTS* 414 | + All data les declared with *dist ... DATA* 415 | + ... 416 | + Common les such as *ChangeLog*, *NEWS*, etc. 417 | + See `automake --help` for a list of those files. 418 | + Extra les or directories listed into *EXTRA_DIST*. 419 | 420 | ### 5.10 扩展的 Automake 规则 421 | 422 | 略。 423 | 424 | -------------------------------------------------------------------------------- /编译/gcc.md: -------------------------------------------------------------------------------- 1 | ## 一、参数选项 2 | 3 | ### 1.1 编译,链接 4 | 5 | * -E filename.c: 预处理,不生成文件。可以查看一段代码预处理后的代码。 6 | * -C: 在预处理的时候,不删除注释信息,一般和 **-E: 使用,用来分析代码。 7 | * -S filename.c: 预处理、编译,生成汇编代码。 8 | * -c filename.c: 预处理、编译、汇编,生成目标文件。 9 | * -M: 生成文件关联的信息(也就是目标文件依赖的源代码)。 10 | * -MM: 和上面的那个一样,但是它将忽略由 #include 造成的依赖关系。 11 | * -llibrary: 指定编译所需的库。 12 | * -Ldir: 指定编译搜索库的路径。 13 | * -g: 在编译的时候产生调试信息。 14 | * -static: 禁止使用动态库。 15 | * -share: 尽量使用动态库。 16 | * -w: 不生成任何警告信息。 17 | * -Wall: 生成所有警告信息。 18 | * -pedantic-error: 允许发出ANSI C标准所列的全部错误信息 19 | * -werror: 把所有的告警信息转化为错误信息,并在告警发生时终止编译过程。 20 | * -o: 生成目标文件。eg: gcc -o hello.asm -S hello.c 21 | * -ansi: 关闭 gnu c 中与 ansi c 不兼容的特性, 激活 ansic的 专有特性(包括禁止一些 asm inline typeof 关键字, 以及 UNIX,vax 等预处理宏)。 22 | * fno-asm: 此选项实现 ansi 选项的功能的一部分,它禁止将 asm, inline 和 typeof 用作关键字。 23 | * -undef: 取消对任何非标准宏的定义。 24 | * -Idir: 指定头文件查找目录(如果没找到,再去缺省的目录中找)。 25 | * -nostdinc: 规定不在 g++ 指定的标准路经中搜索, 但仍在其他路径中搜索。 26 | * -nostdin C++: 规定不在 g++ 指定的标准路经中搜索, 但仍在其他路径中搜索。 27 | * -Wno-invalid-offsetof: -Wno-invalid-offsetof (C++ and Objective-C++ only), Suppress warnings from applying the ‘offsetof’ macro to a non-POD type. 28 | 29 | ### 1.2 优化选项 30 | 31 | * -O0: 关闭所有优选项,不做程序优化,默认等级。 32 | * -O1: 这是最基本的优化等级。编译器会在不花费太多编译时间的同时试图生成更快更小的代码。这些优化是非常基础的,但一般这些任务肯定能顺利完成。 33 | * -O2: O1的进阶。这是推荐的优化等级,除非你有特殊的需求。-O2会比-O1启用多一些标记。设置了-O2后,编译器会试图提高代码性能而不会增大体积和大量占用的编译时间。 34 | * -O3: 是最高最危险的优化等级。用这个选项会延长编译代码的时间,并且在使用gcc4.x的系统里不应全局启用。自从3.x版本以来gcc的行为已经有了极大地改变。在3.x,-O3生成的代码也只是比-O2快一点点而已,而gcc4.x中还未必更快。用-O3来编译所有的软件包将产生更大体积更耗内存的二进制文件,大大增加编译失败的机会或不可预知的程序行为(包括错误)。这样做将得不偿失,记住过犹不及。在gcc 4.x.中使用-O3是不推荐的。 35 | 36 | ## 二、参考资料 37 | 38 | * [GCC 编译优化指南](http://www.jinbuguo.com/linux/optimize_guide.html) 39 | * [GCC Command-Line Options](http://tigcc.ticalc.org/doc/comopts.html) 40 | * [GCC参数详解](http://www.cppblog.com/seman/archive/2005/11/30/1440.html) 41 | * [GCC编译选项分析](http://www.cnblogs.com/showna/articles/1013401.html) 42 | -------------------------------------------------------------------------------- /编译/makefile.md: -------------------------------------------------------------------------------- 1 | 内容系为陈皓当前写的一个系列: 跟我一起写 Makefile。顺便附上他的博客: 2 | 3 | + 陈皓的个人博客: [酷壳-CoolShell.cn——享受编程和技术所带来的快乐 – http://coolshell.cn](http://coolshell.cn/) 4 | + CSDN博客(旧的,已经不再更新): [陈皓专栏【空谷幽兰,心如皓月】](http://blog.csdn.net/haoel/article/details/2899) 5 | 6 | 目录: 7 | 8 | + [跟我一起写 Makefile(一)](http://blog.csdn.net/haoel/article/details/2886): 概述, 关于程序的编译和链接, Makefile 规则。 9 | + [跟我一起写 Makefile(二)](http://blog.csdn.net/haoel/article/details/2887): make 是如何工作的, Makefile 中使用变量,让 make 自动推导,清空目标文件的规则。 10 | + [跟我一起写 Makefile(三)](http://blog.csdn.net/haoel/article/details/2888): Makefile 里有什么?Makefile 的文件名,引用其他的 Makefile,环境变量 MAKEFILES,make 的工作方式。 11 | + [跟我一起写 Makefile(四)](http://blog.csdn.net/haoel/article/details/2889): 规则举例,规则的语法,在规则中使用通配符,文件搜索,伪目标。 12 | + [跟我一起写 Makefile(五)](http://blog.csdn.net/haoel/article/details/2890): 多目标,静态模式,自动生成依赖性。 13 | + [跟我一起写 Makefile(六)](http://blog.csdn.net/haoel/article/details/2891): 显示命令,命令执行,命令出错,嵌套执行make,定义命令包。 14 | + [跟我一起写 Makefile(七)](http://blog.csdn.net/haoel/article/details/2892): 变量的基础,变量中的变量,变量高级用法,追加变量值,override 指示符。 15 | + [跟我一起写 Makefile(八)](http://blog.csdn.net/haoel/article/details/2893): 多行变量,环境变量,目标变量,模式变量,使用条件判断。 16 | + [跟我一起写 Makefile(九)](http://blog.csdn.net/haoel/article/details/2894): 使用函数,函数的语法,字符串处理函数,文件名操作函数。 17 | + [跟我一起写 Makefile(十)](http://blog.csdn.net/haoel/article/details/2895): foreach 函数,if 函数,call 函数,origin 函数,shell 函数,控制 make 的函数。 18 | + [跟我一起写 Makefile(十一)](http://blog.csdn.net/haoel/article/details/2896): make 的运行,make 的退出码,指定 Makefile,指定目标,检查规则,make的参数。 19 | + [跟我一起写 Makefile(十二)](http://blog.csdn.net/haoel/article/details/2897): 隐含规则,使用隐含规则,隐含规则一览,隐含规则使用的变量,隐含规则链。 20 | + [跟我一起写 Makefile(十三)](http://blog.csdn.net/haoel/article/details/2898): 定义模式规则,模式规则介绍,模式规则示例,自动化变量,模式的匹配,重载内建隐含规则 21 | + [跟我一起写 Makefile(十四)](http://blog.csdn.net/haoel/article/details/2899): 使用make更新函数库文件,后序 22 | -------------------------------------------------------------------------------- /网络/curl.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /网络/dig.md: -------------------------------------------------------------------------------- 1 | # DNS 查询工具 -- dig|host|nslookup 2 | 3 | `nslookup`、`host` 和 `dig` 是三个 DNS 查询工具,以下会分别介绍它们的使用方法。 4 | 5 | ## 一、nslookup 6 | 7 | > nslookup is a tried and true program that has weathered the ages. nslookup has been deprecated and may be removed from future releases. There is not even a man page for this program. 8 | 9 | 因此,这里不过多介绍。 10 | 11 | ## 二、host 12 | 13 | `host` 命令和 `dig` 命令很相像,但是 `host` 命令的输出要更简洁,如下示例 14 | 15 | ``` 16 | # host www.google.com 17 | www.google.com has address 74.125.135.106 18 | ``` 19 | 20 | `host` 命令只输出给我们 `dig` 命令的 ANSWER section,相对 `dig` 提供的一些不必要的信息来说更简洁快速。也可指定 DNS Server 来查询,例如我想使用 Google DNS `8.8.8.8`,named 可以如下指定 21 | 22 | ``` 23 | # host www.google.com 8.8.8.8 24 | Using domain server: 25 | Name: 8.8.8.8 26 | Address: 8.8.8.8#53 27 | Aliases: 28 | 29 | www.google.com has address 173.194.72.147 30 | ``` 31 | 32 | ### `host` 反解析 33 | 34 | ``` 35 | # host 173.194.72.147 36 | 147.72.194.173.in-addr.arpa domain name pointer tf-in-f147.1e100.net. 37 | ``` 38 | 39 | ### 指定查询类型,使用 `-t` 选项 40 | 41 | ``` 42 | # host -t SOA google.com # 查询 SOA 记录信息 43 | google.com has SOA record ns1.google.com. dns-admin.google.com. 2013061100 7200 1800 1209600 300 44 | ``` 45 | 46 | ### 查询 `MX` 记录 47 | 48 | ``` 49 | $ host -t MX google.com 50 | google.com mail is handled by 10 aspmx.l.google.com. 51 | google.com mail is handled by 40 alt3.aspmx.l.google.com. 52 | google.com mail is handled by 20 alt1.aspmx.l.google.com. 53 | google.com mail is handled by 50 alt4.aspmx.l.google.com. 54 | google.com mail is handled by 30 alt2.aspmx.l.google.com. 55 | ``` 56 | 57 | ### `-C` 对比认证 DNS SOA 信息 58 | 59 | ``` 60 | # host -C google.com 61 | Nameserver 216.239.34.10: 62 | google.com has SOA record ns1.google.com. dns-admin.google.com. 2013061100 7200 1800 1209600 300 63 | Nameserver 216.239.36.10: 64 | google.com has SOA record ns1.google.com. dns-admin.google.com. 2013061100 7200 1800 1209600 300 65 | Nameserver 216.239.32.10: 66 | ... ... 67 | ``` 68 | 69 | ### 查询 DNS Server 软件版本信息 70 | 71 | ``` 72 | # host -c CH -t txt version.bind 10.10.10.2 73 | Using domain server: 74 | Name: 10.10.10.2 # 10.10.10.2 为 DNS Server 75 | Address: 10.10.10.2#53 76 | Aliases: 77 | 78 | version.bind descriptive text "9.8.1-P2" 79 | ``` 80 | 81 | ### host help 82 | 83 | ``` 84 | # host 85 | Usage: host [-aCdlriTwv] [-c class] [-N ndots] [-t type] [-W time] 86 | [-R number] [-m flag] hostname [server] 87 | -a is equivalent to -v -t ANY 88 | -c specifies query class for non-IN data # 搜索非网络数据时要指定要查找的类 89 | -C compares SOA records on authoritative nameservers 90 | -d is equivalent to -v 91 | -l lists all hosts in a domain, using AXFR 92 | -i IP6.INT reverse lookups 93 | -N changes the number of dots allowed before root lookup is done 94 | -r disables recursive processing 95 | -R specifies number of retries for UDP packets 96 | -s a SERVFAIL response should stop query 97 | -t specifies the query type # 指定要查询的记录类型 98 | -T enables TCP/IP mode 99 | -v enables verbose output # 输出更详细的信息 100 | -w specifies to wait forever for a reply 101 | -W specifies how long to wait for a reply 102 | -4 use IPv4 query transport only 103 | -6 use IPv6 query transport only 104 | -m set memory debugging flag (trace|record|usage) 105 | ``` 106 | 107 | ## 三、dig 108 | 109 | `dig` 也是一个很强大的命令,相对 host 来说输出较为繁杂,如下: 110 | 111 | ``` 112 | $ dig www.google.com 113 | ... ... 114 | 115 | ;; ANSWER SECTION: 116 | www.google.com. 297 IN A 74.125.135.106 117 | www.google.com. 297 IN A 74.125.135.104 118 | ... ... 119 | 120 | ;; AUTHORITY SECTION: 121 | google.com. 172796 IN NS ns3.google.com. 122 | google.com. 172796 IN NS ns1.google.com. 123 | google.com. 172796 IN NS ns4.google.com. 124 | google.com. 172796 IN NS ns2.google.com. 125 | 126 | ... ... 127 | ``` 128 | 129 | ### 查询 `MX` 记录 130 | 131 | ``` 132 | $ dig google.com MX | grep '^;; ANSWER SECTION:' -A 5 133 | ;; ANSWER SECTION: 134 | google.com. 368 IN MX 50 alt4.aspmx.l.google.com. 135 | google.com. 368 IN MX 40 alt3.aspmx.l.google.com. 136 | google.com. 368 IN MX 10 aspmx.l.google.com. 137 | google.com. 368 IN MX 30 alt2.aspmx.l.google.com. 138 | google.com. 368 IN MX 20 alt1.aspmx.l.google.com. 139 | ``` 140 | 141 | ### 查询 `SOA` 记录 142 | 143 | ``` 144 | $ dig google.com SOA | grep '^;; ANSWER SECTION:' -A 1 145 | ;; ANSWER SECTION: 146 | google.com. 85539 IN SOA ns1.google.com. dns-admin.google.com. 2013061100 7200 1800 1209600 300 147 | ``` 148 | 149 | ### 指定 DNS Server 查询 150 | 151 | ``` 152 | $ dig www.baidu.com @8.8.8.8 153 | ... ... 154 | ;; ANSWER SECTION: 155 | www.baidu.com. 1024 IN CNAME www.a.shifen.com. 156 | www.a.shifen.com. 166 IN A 119.75.217.56 157 | www.a.shifen.com. 166 IN A 119.75.218.77 158 | ... ... 159 | ``` 160 | 161 | ### `dig` 查询版本号 162 | 163 | ``` 164 | $ dig chaos txt version.bind 10.10.10.2 | grep '^;; ANSWER SECTION:' -A 1 165 | ;; ANSWER SECTION: 166 | version.bind. 0 CH TXT "9.8.1-P2" 167 | ``` 168 | 169 | ### `dig` 反解析 `-x` 170 | 171 | ``` 172 | $ dig -x 74.125.135.105 173 | ;; QUESTION SECTION: 174 | ;105.135.125.74.in-addr.arpa. IN PTR 175 | 176 | ;; ANSWER SECTION: 177 | 105.135.125.74.in-addr.arpa. 83205 IN PTR ni-in-f105.1e100.net. 178 | ``` 179 | 180 | ### 跟踪 `dig` 全过程 `+trace` 181 | 182 | ``` 183 | $ dig +trace www.google.com 184 | ``` -------------------------------------------------------------------------------- /网络/elinks.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /网络/ifconfig.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /网络/iftop.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /网络/ip.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /网络/nc.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /网络/nmap.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /网络/ping.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /网络/route.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /网络/ss.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | -------------------------------------------------------------------------------- /网络/tcpdump.md: -------------------------------------------------------------------------------- 1 | # tcpdump使用技巧 2 | 3 | 作者: 潜水大叔 4 | 5 | 一般情况下,非HTTP协议的网络分析,在服务器端用`tcpdump`比较多,在客户端用wireshark比较多,两个抓包软件的语法是一样的。 6 | 7 | ## 一、基本语法 8 | 9 | ### 1.1、过滤主机 10 | 11 | - 抓取所有经过eth1,目的或源地址是192.168.1.1的网络数据 12 | 13 | ```bash 14 | tcpdump -i eth1 host 192.168.1.1 15 | ``` 16 | 17 | - 指定源地址 18 | 19 | ```bash 20 | tcpdump -i eth1 src host 192.168.1.1 21 | ``` 22 | 23 | - 指定目的地址 24 | 25 | ```bash 26 | tcpdump -i eth1 dst host 192.168.1.1 27 | ``` 28 | 29 | ### 1.2、过滤端口 30 | 31 | - 抓取所有经过eth1,目的或源端口是25的网络数据 32 | 33 | ```bash 34 | tcpdump -i eth1 port 25 35 | ``` 36 | 37 | - 指定源端口 38 | 39 | ```bash 40 | tcpdump -i eth1 src port 25 41 | ``` 42 | 43 | - 指定目的端口 44 | 45 | ```bash 46 | tcpdump -i eth1 dst port 25 47 | ``` 48 | 49 | ### 1.3、网络过滤 50 | 51 | ```bash 52 | tcpdump -i eth1 net 192.168 53 | tcpdump -i eth1 src net 192.168 54 | tcpdump -i eth1 dst net 192.168 55 | ``` 56 | 57 | ### 1.4、协议过滤 58 | 59 | ```bash 60 | tcpdump -i eth1 arp 61 | tcpdump -i eth1 ip 62 | tcpdump -i eth1 tcp 63 | tcpdump -i eth1 udp 64 | tcpdump -i eth1 icmp 65 | ``` 66 | 67 | ### 1.5、常用表达式 68 | 69 | 非 : ! or "not" (去掉双引号) 70 | 且 : && or "and" 71 | 或 : || or "or" 72 | 73 | - 抓取所有经过eth1,目的地址是192.168.1.254或192.168.1.200端口是80的TCP数据 74 | 75 | ```bash 76 | tcpdump -i eth1 '((tcp) and (port 80) and ((dst host 192.168.1.254) or (dst host 192.168.1.200)))' 77 | ``` 78 | 79 | - 抓取所有经过eth1,目标MAC地址是00:01:02:03:04:05的ICMP数据 80 | 81 | ```bash 82 | tcpdump -i eth1 '((icmp) and ((ether dst host 00:01:02:03:04:05)))' 83 | ``` 84 | 85 | - 抓取所有经过eth1,目的网络是192.168,但目的主机不是192.168.1.200的TCP数据 86 | 87 | ```bash 88 | tcpdump -i eth1 '((tcp) and ((dst net 192.168) and (not dst host 192.168.1.200)))' 89 | ``` 90 | 91 | ## 二、高级包头过滤 92 | 93 | 首先了解如何从包头过滤信息 94 | 95 | ``` 96 | proto[x:y] : 过滤从x字节开始的y字节数。比如ip[2:2]过滤出3、4字节(第一字节从0开始排) 97 | proto[x:y] & z = 0 : proto[x:y]和z的与操作为0 98 | proto[x:y] & z !=0 : proto[x:y]和z的与操作不为0 99 | proto[x:y] & z = z : proto[x:y]和z的与操作为z 100 | proto[x:y] = z : proto[x:y]等于z 101 | ``` 102 | 103 | 操作符 : >, <, >=, <=, =, != 104 | 105 | ### 2.1、IP头 106 | 107 | ``` 108 | 0 1 2 3 109 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 110 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 111 | |Version| IHL |Type of Service| Total Length | 112 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 113 | | Identification |Flags| Fragment Offset | 114 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 115 | | Time to Live | Protocol | Header Checksum | 116 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 117 | | Source Address | 118 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 119 | | Destination Address | 120 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 121 | | Options | Padding | <-- optional 122 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 123 | | DATA ... | 124 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 125 | ``` 126 | 127 | 本文只针对IPv4。 128 | 129 | ### 2.2、IP选项设置了吗? 130 | 131 | “一般”的IP头是20字节,但IP头有选项设置,不能直接从偏移21字节处读取数据。IP头有个长度字段可以知道头长度是否大于20字节。 132 | 133 | ``` 134 | +-+-+-+-+-+-+-+-+ 135 | |Version| IHL | 136 | +-+-+-+-+-+-+-+-+ 137 | ``` 138 | 139 | 通常第一个字节的二进制值是:01000101,分成两个部分: 140 | 141 | 0100 = 4 表示IP版本 142 | 0101 = 5 表示IP头32 bit的块数,5 x 32 bits = 160 bits or 20 bytes 143 | 144 | 如果第一字节第二部分的值大于5,那么表示头有IP选项。 145 | 146 | 下面介绍两种过滤方法(第一种方法比较操蛋,可忽略): 147 | 148 | a. 比较第一字节的值是否大于01000101,这可以判断IPv4带IP选项的数据和IPv6的数据。 149 | 150 | 01000101十进制等于69,计算方法如下(小提示:用计算器更方便) 151 | 152 | ``` 153 | 0 : 0 \ 154 | 1 : 2^6 = 64 \ 第一部分 (IP版本) 155 | 0 : 0 / 156 | 0 : 0 / 157 | - 158 | 0 : 0 \ 159 | 1 : 2^2 = 4 \ 第二部分 (头长度) 160 | 0 : 0 / 161 | 1 : 2^0 = 1 / 162 | ``` 163 | 164 | 64 + 4 + 1 = 69 165 | 166 | 如果设置了IP选项,那么第一自己是01000110(十进制70),过滤规则: 167 | ```bash 168 | tcpdump -i eth1 'ip[0] > 69' 169 | ``` 170 | 171 | IPv6的数据也会匹配,看看第二种方法。 172 | 173 | b. 位操作 174 | 175 | 0100 0101 : 第一字节的二进制 176 | 0000 1111 : 与操作 177 | <========= 178 | 0000 0101 : 结果 179 | 180 | 正确的过滤方法 181 | 182 | ```bash 183 | tcpdump -i eth1 'ip[0] & 15 > 5' 184 | ``` 185 | 186 | 或者 187 | ```bash 188 | tcpdump -i eth1 'ip[0] & 0x0f > 5' 189 | ``` 190 | 191 | ### 2.3、分片标记 192 | 193 | 当发送端的MTU大于到目的路径链路上的MTU时就会被分片,这段话有点拗口,权威的请参考《TCP/IP详解》。唉,32借我的书没还,只能凑合写,大家记得看书啊。 194 | 195 | 分片信息在IP头的第七和第八字节: 196 | 197 | ``` 198 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 199 | |Flags| Fragment Offset | 200 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 201 | ``` 202 | 203 | Bit 0: 保留,必须是0 204 | Bit 1: (DF) 0 = 可能分片, 1 = 不分片 205 | Bit 2: (MF) 0 = 最后的分片, 1 = 还有分片 206 | 207 | Fragment Offset字段只有在分片的时候才使用。 208 | 209 | 要抓带DF位标记的不分片的包,第七字节的值应该是: 210 | 211 | 01000000 = 64 212 | 213 | ```bash 214 | tcpdump -i eth1 'ip[6] = 64' 215 | ``` 216 | 217 | ### 2.4、抓分片包 218 | 219 | - 匹配MF,分片包 220 | 221 | ```bash 222 | tcpdump -i eth1 'ip[6] = 32' 223 | ``` 224 | 225 | 最后分片包的开始3位是0,但是有Fragment Offset字段。 226 | 227 | - 匹配分片和最后分片 228 | 229 | ```bash 230 | tcpdump -i eth1 '((ip[6:2] > 0) and (not ip[6] = 64))' 231 | ``` 232 | 233 | 测试分片可以用下面的命令: 234 | 235 | ```bash 236 | ping -M want -s 3000 192.168.1.1 237 | ``` 238 | 239 | ### 2.5、匹配小TTL 240 | 241 | TTL字段在第九字节,并且正好是完整的一个字节,TTL最大值是255,二进制为11111111。 242 | 243 | 可以用下面的命令验证一下: 244 | 245 | ```bash 246 | $ ping -M want -s 3000 -t 256 192.168.1.200 247 | ping: ttl 256 out of range 248 | ``` 249 | 250 | ``` 251 | +-+-+-+-+-+-+-+-+ 252 | | Time to Live | 253 | +-+-+-+-+-+-+-+-+ 254 | ``` 255 | 256 | - 在网关可以用下面的命令看看网络中谁在使用traceroute 257 | 258 | ```bash 259 | tcpdump -i eth1 'ip[8] < 5' 260 | ``` 261 | 262 | ### 2.6、抓大于X字节的包 263 | 264 | - 大于600字节 265 | 266 | ```bash 267 | tcpdump -i eth1 'ip[2:2] > 600' 268 | ``` 269 | 270 | ### 2.7、更多的IP过滤 271 | 272 | 首先还是需要知道TCP基本结构,再次推荐《TCP/IP详解》,卷一就够看的了,避免走火入魔。 273 | 274 | - TCP头 275 | 276 | ``` 277 | 0 1 2 3 278 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 279 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 280 | | Source Port | Destination Port | 281 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 282 | | Sequence Number | 283 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 284 | | Acknowledgment Number | 285 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 286 | | Data | |C|E|U|A|P|R|S|F| | 287 | | Offset| Res. |W|C|R|C|S|S|Y|I| Window | 288 | | | |R|E|G|K|H|T|N|N| | 289 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 290 | | Checksum | Urgent Pointer | 291 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 292 | | Options | Padding | 293 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 294 | | data | 295 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 296 | ``` 297 | 298 | - 抓取源端口大于1024的TCP数据包 299 | 300 | ```bash 301 | tcpdump -i eth1 'tcp[0:2] > 1024' 302 | ``` 303 | 304 | - 匹配TCP数据包的特殊标记 305 | 306 | TCP标记定义在TCP头的第十四个字节 307 | 308 | ``` 309 | +-+-+-+-+-+-+-+-+ 310 | |C|E|U|A|P|R|S|F| 311 | |W|C|R|C|S|S|Y|I| 312 | |R|E|G|K|H|T|N|N| 313 | +-+-+-+-+-+-+-+-+ 314 | ``` 315 | 316 | 重复一下TCP三次握手,两个主机是如何勾搭的: 317 | 318 | 1. 源发送SYN 319 | 2. 目标回答SYN, ACK 320 | 3. 源发送ACK 321 | 322 | 没女朋友的童鞋要学习一下: 323 | 1. MM,你的手有空吗?-_- 324 | 2. 有空,你呢?\~_~ 325 | 3. 我也有空 \*_* 326 | 327 | 失败的loser是酱紫的: 328 | 1. MM,这是你掉的板砖吗?(SYN)  ̄▽ ̄ 329 | 2. 不是,找拍啊?(RST-ACK) ˋ﹏ˊ 330 | 331 | - 只抓SYN包,第十四字节是二进制的00000010,也就是十进制的2 332 | 333 | ```bash 334 | tcpdump -i eth1 'tcp[13] = 2' 335 | ``` 336 | 337 | - 抓SYN, ACK (00010010 or 18) 338 | 339 | ```bash 340 | tcpdump -i eth1 'tcp[13] = 18' 341 | ``` 342 | 343 | - 抓SYN或者SYN-ACK 344 | 345 | ```bash 346 | tcpdump -i eth1 'tcp[13] & 2 = 2' 347 | ``` 348 | 349 | 用到了位操作,就是不管ACK位是啥。 350 | 351 | - 抓PSH-ACK 352 | 353 | ```bash 354 | tcpdump -i eth1 'tcp[13] = 24' 355 | ``` 356 | 357 | - 抓所有包含FIN标记的包(FIN通常和ACK一起,表示幽会完了,回见) 358 | 359 | ```bash 360 | tcpdump -i eth1 'tcp[13] & 1 = 1' 361 | ``` 362 | 363 | - 抓RST(勾搭没成功,伟大的greatwall对她认为有敏感信息的连接发RST包,典型的棒打鸳鸯) 364 | 365 | ```bash 366 | tcpdump -i eth1 'tcp[13] & 4 = 4' 367 | ``` 368 | 369 | 下图详细描述了TCP各种状态的标记,方便分析。 370 | 371 | ![tcp_state_machine.jpg](../images/tcp_state_machine.jpg) 372 | 373 | 374 | ### 2.8、大叔注 375 | 376 | tcpdump考虑了一些数字恐惧症者的需求,提供了部分常用的字段偏移名字: 377 | 378 | icmptype (ICMP类型字段) 379 | icmpcode (ICMP符号字段) 380 | tcpflags (TCP标记字段) 381 | 382 | ICMP类型值有: 383 | 384 | icmp-echoreply, icmp-unreach, icmp-sourcequench, icmp-redirect, icmp-echo, icmp-routeradvert, icmp-routersolicit, icmp-timxceed, icmp-paramprob, icmp-tstamp, icmp-tstampreply, icmp-ireq, icmp-ireqreply, icmp-maskreq, icmp-maskreply 385 | 386 | TCP标记值: 387 | 388 | tcp-fin, tcp-syn, tcp-rst, tcp-push, tcp-push, tcp-ack, tcp-urg 389 | 390 | 这样上面按照TCP标记位抓包的就可以写直观的表达式了: 391 | 392 | - 只抓SYN包 393 | 394 | ```bash 395 | tcpdump -i eth1 'tcp[tcpflags] = tcp-syn' 396 | ``` 397 | 398 | - 抓SYN, ACK 399 | 400 | ```bash 401 | tcpdump -i eth1 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack != 0' 402 | ``` 403 | 404 | ### 2.9、抓SMTP数据 405 | 406 | ```bash 407 | tcpdump -i eth1 '((port 25) and (tcp[(tcp[12]>>2):4] = 0x4d41494c))' 408 | ``` 409 | 410 | 抓取数据区开始为"MAIL"的包,"MAIL"的十六进制为0x4d41494c。 411 | 412 | ### 2.10、抓HTTP GET数据 413 | 414 | ```bash 415 | tcpdump -i eth1 'tcp[(tcp[12]>>2):4] = 0x47455420' 416 | ``` 417 | 418 | "GET "的十六进制是47455420 419 | 420 | ### 2.11、抓SSH返回 421 | 422 | ```bash 423 | tcpdump -i eth1 'tcp[(tcp[12]>>2):4] = 0x5353482D' 424 | ``` 425 | 426 | "SSH-"的十六进制是0x5353482D 427 | 428 | ```bash 429 | tcpdump -i eth1 '(tcp[(tcp[12]>>2):4] = 0x5353482D) and (tcp[((tcp[12]>>2)+4):2] = 0x312E)' 430 | ``` 431 | 432 | 抓老版本的SSH返回信息,如"SSH-1.99.." 433 | 434 | ## 三、大叔注 435 | 436 | 如果是为了查看数据内容,建议用`tcpdump -s 0 -w filename`把数据包都保存下来,然后用wireshark的Follow TCP Stream/Follow UDP Stream来查看整个会话的内容。 437 | 438 | `-s 0`是抓取完整数据包,否则默认只抓68字节。 439 | 440 | 另外,用tcpflow也可以方便的获取TCP会话内容,支持tcpdump的各种表达式。 441 | 442 | ### 3.1、UDP头 443 | ``` 444 | 0 7 8 15 16 23 24 31 445 | +--------+--------+--------+--------+ 446 | | Source | Destination | 447 | | Port | Port | 448 | +--------+--------+--------+--------+ 449 | | | | 450 | | Length | Checksum | 451 | +--------+--------+--------+--------+ 452 | | | 453 | | DATA ... | 454 | +-----------------------------------+ 455 | ``` 456 | 457 | - 抓DNS请求数据 458 | 459 | ```bash 460 | tcpdump -i eth1 udp dst port 53 461 | ``` 462 | 463 | ### 3.2、其他 464 | 465 | `-c`参数对于运维人员来说也比较常用,因为流量比较大的服务器,靠人工CTRL+C还是抓的太多,甚至导致服务器宕机,于是可以用`-c`参数指定抓多少个包。 466 | 467 | ```bash 468 | time tcpdump -nn -i eth0 'tcp[tcpflags] = tcp-syn' -c 10000 > /dev/null 469 | ``` 470 | 471 | 上面的命令计算抓10000个SYN包花费多少时间,可以判断访问量大概是多少。 472 | 473 | ## 四、参考资料 474 | 475 | > [tcpdump advanced filters](http://www.wains.be/pub/networking/tcpdump_advanced_filters.txt) 476 | -------------------------------------------------------------------------------- /网络/wget.md: -------------------------------------------------------------------------------- 1 | COMING SOON ...... 2 | --------------------------------------------------------------------------------