From 9429ee020a723588dc29a195899791f595dfdac2 Mon Sep 17 00:00:00 2001 From: YYforymj <243885526@qq.com> Date: Sat, 8 Apr 2017 19:16:20 +0800 Subject: [PATCH 01/52] Update 20110123 How debuggers work Part 1 - Basics.md --- sources/tech/20110123 How debuggers work Part 1 - Basics.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/tech/20110123 How debuggers work Part 1 - Basics.md b/sources/tech/20110123 How debuggers work Part 1 - Basics.md index f8ef81d966..f619092912 100644 --- a/sources/tech/20110123 How debuggers work Part 1 - Basics.md +++ b/sources/tech/20110123 How debuggers work Part 1 - Basics.md @@ -1,3 +1,4 @@ +YYforymj is Translating [How debuggers work: Part 1 - Basics][21] ============================================================ From 7b1627af7e7f2342d05ebe7a299ec3afaa1b0e7b Mon Sep 17 00:00:00 2001 From: YYforymj <243885526@qq.com> Date: Sun, 9 Apr 2017 12:59:38 +0800 Subject: [PATCH 02/52] Delete 20110123 How debuggers work Part 1 - Basics.md --- ...0123 How debuggers work Part 1 - Basics.md | 322 ------------------ 1 file changed, 322 deletions(-) delete mode 100644 sources/tech/20110123 How debuggers work Part 1 - Basics.md diff --git a/sources/tech/20110123 How debuggers work Part 1 - Basics.md b/sources/tech/20110123 How debuggers work Part 1 - Basics.md deleted file mode 100644 index f619092912..0000000000 --- a/sources/tech/20110123 How debuggers work Part 1 - Basics.md +++ /dev/null @@ -1,322 +0,0 @@ -YYforymj is Translating -[How debuggers work: Part 1 - Basics][21] -============================================================ - -This is the first part in a series of articles on how debuggers work. I'm still not sure how many articles the series will contain and what topics it will cover, but I'm going to start with the basics. - -### In this part - -I'm going to present the main building block of a debugger's implementation on Linux - the ptrace system call. All the code in this article is developed on a 32-bit Ubuntu machine. Note that the code is very much platform specific, although porting it to other platforms shouldn't be too difficult. - -### Motivation - -To understand where we're going, try to imagine what it takes for a debugger to do its work. A debugger can start some process and debug it, or attach itself to an existing process. It can single-step through the code, set breakpoints and run to them, examine variable values and stack traces. Many debuggers have advanced features such as executing expressions and calling functions in the debbugged process's address space, and even changing the process's code on-the-fly and watching the effects. - -Although modern debuggers are complex beasts [[1]][13], it's surprising how simple is the foundation on which they are built. Debuggers start with only a few basic services provided by the operating system and the compiler/linker, all the rest is just [a simple matter of programming][14]. - -### Linux debugging - ptrace - -The Swiss army knife of Linux debuggers is the ptrace system call [[2]][15]. It's a versatile and rather complex tool that allows one process to control the execution of another and to peek and poke at its innards [[3]][16]. ptrace can take a mid-sized book to explain fully, which is why I'm just going to focus on some of its practical uses in examples. - -Let's dive right in. - -### Stepping through the code of a process - -I'm now going to develop an example of running a process in "traced" mode in which we're going to single-step through its code - the machine code (assembly instructions) that's executed by the CPU. I'll show the example code in parts, explaining each, and in the end of the article you will find a link to download a complete C file that you can compile, execute and play with. - -The high-level plan is to write code that splits into a child process that will execute a user-supplied command, and a parent process that traces the child. First, the main function: - -``` -int main(int argc, char** argv) -{ - pid_t child_pid; - - if (argc < 2) { - fprintf(stderr, "Expected a program name as argument\n"); - return -1; - } - - child_pid = fork(); - if (child_pid == 0) - run_target(argv[1]); - else if (child_pid > 0) - run_debugger(child_pid); - else { - perror("fork"); - return -1; - } - - return 0; -} -``` - -Pretty simple: we start a new child process with fork [[4]][17]. The if branch of the subsequent condition runs the child process (called "target" here), and the else if branch runs the parent process (called "debugger" here). - -Here's the target process: - -``` -void run_target(const char* programname) -{ - procmsg("target started. will run '%s'\n", programname); - - /* Allow tracing of this process */ - if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) { - perror("ptrace"); - return; - } - - /* Replace this process's image with the given program */ - execl(programname, programname, 0); -} -``` - -The most interesting line here is the ptrace call. ptrace is declared thus (in sys/ptrace.h): - -``` -long ptrace(enum __ptrace_request request, pid_t pid, - void *addr, void *data); -``` - -The first argument is a  _request_ , which may be one of many predefined PTRACE_* constants. The second argument specifies a process ID for some requests. The third and fourth arguments are address and data pointers, for memory manipulation. The ptrace call in the code snippet above makes the PTRACE_TRACEMErequest, which means that this child process asks the OS kernel to let its parent trace it. The request description from the man-page is quite clear: - -> Indicates that this process is to be traced by its parent. Any signal (except SIGKILL) delivered to this process will cause it to stop and its parent to be notified via wait(). **Also, all subsequent calls to exec() by this process will cause a SIGTRAP to be sent to it, giving the parent a chance to gain control before the new program begins execution**. A process probably shouldn't make this request if its parent isn't expecting to trace it. (pid, addr, and data are ignored.) - -I've highlighted the part that interests us in this example. Note that the very next thing run_targetdoes after ptrace is invoke the program given to it as an argument with execl. This, as the highlighted part explains, causes the OS kernel to stop the process just before it begins executing the program in execl and send a signal to the parent. - -Thus, time is ripe to see what the parent does: - -``` -void run_debugger(pid_t child_pid) -{ - int wait_status; - unsigned icounter = 0; - procmsg("debugger started\n"); - - /* Wait for child to stop on its first instruction */ - wait(&wait_status); - - while (WIFSTOPPED(wait_status)) { - icounter++; - /* Make the child execute another instruction */ - if (ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0) < 0) { - perror("ptrace"); - return; - } - - /* Wait for child to stop on its next instruction */ - wait(&wait_status); - } - - procmsg("the child executed %u instructions\n", icounter); -} -``` - -Recall from above that once the child starts executing the exec call, it will stop and be sent the SIGTRAP signal. The parent here waits for this to happen with the first wait call. wait will return once something interesting happens, and the parent checks that it was because the child was stopped (WIFSTOPPED returns true if the child process was stopped by delivery of a signal). - -What the parent does next is the most interesting part of this article. It invokes ptrace with the PTRACE_SINGLESTEP request giving it the child process ID. What this does is tell the OS -  _please restart the child process, but stop it after it executes the next instruction_ . Again, the parent waits for the child to stop and the loop continues. The loop will terminate when the signal that came out of the wait call wasn't about the child stopping. During a normal run of the tracer, this will be the signal that tells the parent that the child process exited (WIFEXITED would return true on it). - -Note that icounter counts the amount of instructions executed by the child process. So our simple example actually does something useful - given a program name on the command line, it executes the program and reports the amount of CPU instructions it took to run from start to finish. Let's see it in action. - -### A test run - -I compiled the following simple program and ran it under the tracer: - -``` -#include - -int main() -{ - printf("Hello, world!\n"); - return 0; -} -``` - -To my surprise, the tracer took quite long to run and reported that there were more than 100,000 instructions executed. For a simple printf call? What gives? The answer is very interesting [[5]][18]. By default, gcc on Linux links programs to the C runtime libraries dynamically. What this means is that one of the first things that runs when any program is executed is the dynamic library loader that looks for the required shared libraries. This is quite a lot of code - and remember that our basic tracer here looks at each and every instruction, not of just the main function, but  _of the whole process_ . - -So, when I linked the test program with the -static flag (and verified that the executable gained some 500KB in weight, as is logical for a static link of the C runtime), the tracing reported only 7,000 instructions or so. This is still a lot, but makes perfect sense if you recall that libc initialization still has to run before main, and cleanup has to run after main. Besides, printf is a complex function. - -Still not satisfied, I wanted to see something  _testable_  - i.e. a whole run in which I could account for every instruction executed. This, of course, can be done with assembly code. So I took this version of "Hello, world!" and assembled it: - -``` -section .text - ; The _start symbol must be declared for the linker (ld) - global _start - -_start: - - ; Prepare arguments for the sys_write system call: - ; - eax: system call number (sys_write) - ; - ebx: file descriptor (stdout) - ; - ecx: pointer to string - ; - edx: string length - mov edx, len - mov ecx, msg - mov ebx, 1 - mov eax, 4 - - ; Execute the sys_write system call - int 0x80 - - ; Execute sys_exit - mov eax, 1 - int 0x80 - -section .data -msg db 'Hello, world!', 0xa -len equ $ - msg -``` - -Sure enough. Now the tracer reported that 7 instructions were executed, which is something I can easily verify. - -### Deep into the instruction stream - -The assembly-written program allows me to introduce you to another powerful use of ptrace - closely examining the state of the traced process. Here's another version of the run_debugger function: - -``` -void run_debugger(pid_t child_pid) -{ - int wait_status; - unsigned icounter = 0; - procmsg("debugger started\n"); - - /* Wait for child to stop on its first instruction */ - wait(&wait_status); - - while (WIFSTOPPED(wait_status)) { - icounter++; - struct user_regs_struct regs; - ptrace(PTRACE_GETREGS, child_pid, 0, ®s); - unsigned instr = ptrace(PTRACE_PEEKTEXT, child_pid, regs.eip, 0); - - procmsg("icounter = %u. EIP = 0x%08x. instr = 0x%08x\n", - icounter, regs.eip, instr); - - /* Make the child execute another instruction */ - if (ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0) < 0) { - perror("ptrace"); - return; - } - - /* Wait for child to stop on its next instruction */ - wait(&wait_status); - } - - procmsg("the child executed %u instructions\n", icounter); -} -``` - -The only difference is in the first few lines of the while loop. There are two new ptrace calls. The first one reads the value of the process's registers into a structure. user_regs_struct is defined in sys/user.h. Now here's the fun part - if you look at this header file, a comment close to the top says: - -``` -/* The whole purpose of this file is for GDB and GDB only. - Don't read too much into it. Don't use it for - anything other than GDB unless know what you are - doing. */ -``` - -Now, I don't know about you, but it makes  _me_  feel we're on the right track :-) Anyway, back to the example. Once we have all the registers in regs, we can peek at the current instruction of the process by calling ptrace with PTRACE_PEEKTEXT, passing it regs.eip (the extended instruction pointer on x86) as the address. What we get back is the instruction [[6]][19]. Let's see this new tracer run on our assembly-coded snippet: - -``` -$ simple_tracer traced_helloworld -[5700] debugger started -[5701] target started. will run 'traced_helloworld' -[5700] icounter = 1\. EIP = 0x08048080\. instr = 0x00000eba -[5700] icounter = 2\. EIP = 0x08048085\. instr = 0x0490a0b9 -[5700] icounter = 3\. EIP = 0x0804808a. instr = 0x000001bb -[5700] icounter = 4\. EIP = 0x0804808f. instr = 0x000004b8 -[5700] icounter = 5\. EIP = 0x08048094\. instr = 0x01b880cd -Hello, world! -[5700] icounter = 6\. EIP = 0x08048096\. instr = 0x000001b8 -[5700] icounter = 7\. EIP = 0x0804809b. instr = 0x000080cd -[5700] the child executed 7 instructions -``` - -OK, so now in addition to icounter we also see the instruction pointer and the instruction it points to at each step. How to verify this is correct? By using objdump -d on the executable: - -``` -$ objdump -d traced_helloworld - -traced_helloworld: file format elf32-i386 - -Disassembly of section .text: - -08048080 <.text>: - 8048080: ba 0e 00 00 00 mov $0xe,%edx - 8048085: b9 a0 90 04 08 mov $0x80490a0,%ecx - 804808a: bb 01 00 00 00 mov $0x1,%ebx - 804808f: b8 04 00 00 00 mov $0x4,%eax - 8048094: cd 80 int $0x80 - 8048096: b8 01 00 00 00 mov $0x1,%eax - 804809b: cd 80 int $0x80 -``` - -The correspondence between this and our tracing output is easily observed. - -### Attaching to a running process - -As you know, debuggers can also attach to an already-running process. By now you won't be surprised to find out that this is also done with ptrace, which can get the PTRACE_ATTACH request. I won't show a code sample here since it should be very easy to implement given the code we've already gone through. For educational purposes, the approach taken here is more convenient (since we can stop the child process right at its start). - -### The code - -The complete C source-code of the simple tracer presented in this article (the more advanced, instruction-printing version) is available [here][20]. It compiles cleanly with -Wall -pedantic --std=c99 on version 4.4 of gcc. - -### Conclusion and next steps - -Admittedly, this part didn't cover much - we're still far from having a real debugger in our hands. However, I hope it has already made the process of debugging at least a little less mysterious. ptrace is truly a versatile system call with many abilities, of which we've sampled only a few so far. - -Single-stepping through the code is useful, but only to a certain degree. Take the C "Hello, world!" sample I demonstrated above. To get to main it would probably take a couple of thousands of instructions of C runtime initialization code to step through. This isn't very convenient. What we'd ideally want to have is the ability to place a breakpoint at the entry to main and step from there. Fair enough, and in the next part of the series I intend to show how breakpoints are implemented. - -### References - -I've found the following resources and articles useful in the preparation of this article: - -* [Playing with ptrace, Part I][11] -* [How debugger works][12] - - - -[1] I didn't check but I'm sure the LOC count of gdb is at least in the six-figures range. - -[2] Run man 2 ptrace for complete enlightment. - -[3] Peek and poke are well-known system programming jargon for directly reading and writing memory contents. - -[4] This article assumes some basic level of Unix/Linux programming experience. I assume you know (at least conceptually) about fork, the exec family of functions and Unix signals. - -[5] At least if you're as obsessed with low-level details as I am :-) - -[6] A word of warning here: as I noted above, a lot of this is highly platform specific. I'm making some simplifying assumptions - for example, x86 instructions don't have to fit into 4 bytes (the size of unsigned on my 32-bit Ubuntu machine). In fact, many won't. Peeking at instructions meaningfully requires us to have a complete disassembler at hand. We don't have one here, but real debuggers do. - - --------------------------------------------------------------------------------- - -via: http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1 - -作者:[Eli Bendersky ][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://eli.thegreenplace.net/ -[1]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id1 -[2]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id2 -[3]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id3 -[4]:http://www.jargon.net/jargonfile/p/peek.html -[5]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id4 -[6]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id5 -[7]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id6 -[8]:http://eli.thegreenplace.net/tag/articles -[9]:http://eli.thegreenplace.net/tag/debuggers -[10]:http://eli.thegreenplace.net/tag/programming -[11]:http://www.linuxjournal.com/article/6100?page=0,1 -[12]:http://www.alexonlinux.com/how-debugger-works -[13]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id7 -[14]:http://en.wikipedia.org/wiki/Small_matter_of_programming -[15]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id8 -[16]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id9 -[17]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id10 -[18]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id11 -[19]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id12 -[20]:https://github.com/eliben/code-for-blog/blob/master/2011/simple_tracer.c -[21]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1 From 6e8b2f41eb801d210f53ed8c11e0882720a9e58f Mon Sep 17 00:00:00 2001 From: YYforymj <243885526@qq.com> Date: Sun, 9 Apr 2017 13:01:19 +0800 Subject: [PATCH 03/52] Create How debuggers work: Part 1 - Basics --- .../tech/How debuggers work: Part 1 - Basics | 346 ++++++++++++++++++ 1 file changed, 346 insertions(+) create mode 100644 translated/tech/How debuggers work: Part 1 - Basics diff --git a/translated/tech/How debuggers work: Part 1 - Basics b/translated/tech/How debuggers work: Part 1 - Basics new file mode 100644 index 0000000000..9288fea970 --- /dev/null +++ b/translated/tech/How debuggers work: Part 1 - Basics @@ -0,0 +1,346 @@ +[调试器的工作原理:第一篇-基础][21] +============================================================ + +这是调试器工作原理系列文章的第一篇,我不确定这个系列会有多少篇文章,会涉及多少话题,但我仍会从这篇基础开始。 + +### 这一篇会讲什么 + +我将为大家展示 Linux 中调试器的主要构成模块 - ptrace 系统调用。这篇文章所有代码都是基于 32 位 Ubuntu 操作系统.值得注意的是,尽管这些代码是平台相关的,将他们移植到其他平台应该并不困难。 + +### 缘由 + +为了理解我们要做什么,让我们先考虑下调试器为了完成调试都需要什么资源。调试器可以开始一个进程并调试这个进程,又或者将自己同某个已经存在的进程关联起来。调试器能够单步执行代码,设定断点并且将程序执行到断点,检查变量的值并追踪堆栈。许多调试器有着更高级的特性,例如在调试器的地址空间内执行表达式或者调用函数,甚至可以在进程执行过程中改变代码并观察效果。 + +尽管现代的调试器都十分的复杂 [[1]][13],但他们的工作的原理却是十分的简单。调试器的基础是操作系统与编译器 / 链接器提供的一些基础服务,其余的部分只是[简单的编程][14]。 + +### Linux 的调试 - ptrace + +Linux 调试器中的瑞士军刀便是 ptrace 系统调用 [[2]][15]。这是一种复杂却强大的工具,可以允许一个进程控制另外一个进程并从内部替换被控制进程的内核镜像的值[[3]][16].。 + +接下来会深入分析。 + +### 执行进程的代码 + +我将编写一个示例,实现一个在“跟踪”模式下运行的进程。在这个模式下,我们将单步执行进程的代码,就像机器码(汇编代码)被 CPU 执行时一样。我将分段展示、讲解示例代码,在文章的末尾也有完整 c 文件的下载链接,你可以编译、执行或者随心所欲的更改。 + +更进一步的计划是实现一段代码,这段代码可以创建可执行用户自定义命令的子进程,同时父进程可以跟踪子进程。首先是主函数: + +``` +int main(int argc, char** argv) +{ + pid_t child_pid; + + if (argc < 2) { + fprintf(stderr, "Expected a program name as argument\n"); + return -1; + } + + child_pid = fork(); + if (child_pid == 0) + run_target(argv[1]); + else if (child_pid > 0) + run_debugger(child_pid); + else { + perror("fork"); + return -1; + } + + return 0; +} +``` + +看起来相当的简单:我们用 fork 命令创建了一个新的子进程。if 语句的分支执行子进程(这里称之为“target”),else if 的分支执行父进程(这里称之为“debugger”)。 + +下面是 target 进程的代码: + +``` +void run_target(const char* programname) +{ + procmsg("target started. will run '%s'\n", programname); + + /* Allow tracing of this process */ + if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) { + perror("ptrace"); + return; + } + + /* Replace this process's image with the given program */ + execl(programname, programname, 0); +} +``` + +这段代码中最值得注意的是 ptrace 调用。在 "sys/ptrace.h" 中,ptrace 是如下定义的: + +``` +long ptrace(enum __ptrace_request request, pid_t pid, + void *addr, void *data); +``` + +第一个参数是 _request_,这是许多预定义的 PTRACE_* 常量中的一个。第二个参数为请求分配进程 ID。第三个与第四个参数是地址与数据指针,用于操作内存。上面代码段中的ptrace调用发起了 PTRACE_TRACEME 请求,这意味着该子进程请求系统内核让其父进程跟踪自己。帮助页面上对于 request 的描述很清楚: + +> 意味着该进程被其父进程跟踪。任何传递给该进程的信号(除了 SIGKILL)都将通过 wait() 方法阻塞该进程并通知其父进程。**此外,该进程的之后所有调用 exec() 动作都将导致 SIGTRAP 信号发送到此进程上,使得父进程在新的程序执行前得到取得控制权的机会**。如果一个进程并不需要它的的父进程跟踪它,那么这个进程不应该发送这个请求。(pid,addr 与 data 暂且不提) + +我高亮了这个例子中我们需要注意的部分。在 ptrace 调用后,run_target 接下来要做的就是通过 execl 传参并调用。如同高亮部分所说明,这将导致系统内核在 execl 创建进程前暂时停止,并向父进程发送信号。 + +是时候看看父进程做什么了。 + +``` +void run_debugger(pid_t child_pid) +{ + int wait_status; + unsigned icounter = 0; + procmsg("debugger started\n"); + + /* Wait for child to stop on its first instruction */ + wait(&wait_status); + + while (WIFSTOPPED(wait_status)) { + icounter++; + /* Make the child execute another instruction */ + if (ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0) < 0) { + perror("ptrace"); + return; + } + + /* Wait for child to stop on its next instruction */ + wait(&wait_status); + } + + procmsg("the child executed %u instructions\n", icounter); +} +``` + +如前文所述,一旦子进程调用了 exec,子进程会停止并被发送 SIGTRAP 信号。父进程会等待该过程的发生并在第一个 wait() 处等待。一旦上述事件发生了,wait() 便会返回,由于子进程停止了父进程便会收到信号(如果子进程由于信号的发送停止了,WIFSTOPPED 就会返回 true)。 + +父进程接下来的动作就是整篇文章最需要关注的部分了。父进程会将 PTRACE_SINGLESTEP 与子进程ID作为参数调用 ptrace 方法。这就会告诉操作系统,“请恢复子进程,但在它执行下一条指令前阻塞”。周而复始地,父进程等待子进程阻塞,循环继续。当 wait() 中传出的信号不再是子进程的停止信号时,循环终止。在跟踪器(父进程)运行期间,这将会是被跟踪进程(子进程)传递给跟踪器的终止信号(如果子进程终止 WIFEXITED 将返回 true)。 + +icounter 存储了子进程执行指令的次数。这么看来我们小小的例子也完成了些有用的事情 - 在命令行中指定程序,它将执行该程序并记录它从开始到结束所需要的 cpu 指令数量。接下来就让我们这么做吧。 + +### 测试 + +我编译了下面这个简单的程序并利用跟踪器运行它: + +``` +#include + +int main() +{ + printf("Hello, world!\n"); + return 0; +} + +``` + +令我惊讶的是,跟踪器花了相当长的时间,并报告整个执行过程共有超过 100,000 条指令执行。仅仅是一条输出语句?什么造成了这种情况?答案很有趣[[5]][18]。Linux 的 gcc 默认会动态的将程序与 c 的运行时库动态地链接。这就意味着任何程序运行前的第一件事是需要动态库加载器去查找程序运行所需要的共享库。这些代码的数量很大 - 别忘了我们的跟踪器要跟踪每一条指令,不仅仅是主函数的,而是“整个过程中的指令”。 + +所以当我将测试程序使用静态编译时(通过比较,可执行文件会多出 500 KB 左右的大小,这部分是 C 运行时库的静态链接),跟踪器提示只有大概 7000 条指令被执行。这个数目仍然不小,但是考虑到在主函数执行前 libc 的初始化以及主函数执行后的清除代码,这个数目已经是相当不错了。此外,printf 也是一个复杂的函数。 + +仍然不满意的话,我需要的是“可以测试”的东西 - 例如可以完整记录每一个指令运行的程序执行过程。这当然可以通过汇编代码完成。所以我找到了这个版本的“Hello, world!”并编译了它。 + + +``` +section .text + ; The _start symbol must be declared for the linker (ld) + global _start + +_start: + + ; Prepare arguments for the sys_write system call: + ; - eax: system call number (sys_write) + ; - ebx: file descriptor (stdout) + ; - ecx: pointer to string + ; - edx: string length + mov edx, len + mov ecx, msg + mov ebx, 1 + mov eax, 4 + + ; Execute the sys_write system call + int 0x80 + + ; Execute sys_exit + mov eax, 1 + int 0x80 + +section .data +msg db 'Hello, world!', 0xa +len equ $ - msg +``` + + +当然,现在跟踪器提示 7 条指令被执行了,这样一来很容易区分他们。 + + +### 深入指令流 + + +上面那个汇编语言编写的程序使得我可以向你介绍 ptrace 的另外一个强大的用途 - 详细显示被跟踪进程的状态。下面是 run_debugger 函数的另一个版本: + +``` +void run_debugger(pid_t child_pid) +{ + int wait_status; + unsigned icounter = 0; + procmsg("debugger started\n"); + + /* Wait for child to stop on its first instruction */ + wait(&wait_status); + + while (WIFSTOPPED(wait_status)) { + icounter++; + struct user_regs_struct regs; + ptrace(PTRACE_GETREGS, child_pid, 0, ®s); + unsigned instr = ptrace(PTRACE_PEEKTEXT, child_pid, regs.eip, 0); + + procmsg("icounter = %u. EIP = 0x%08x. instr = 0x%08x\n", + icounter, regs.eip, instr); + + /* Make the child execute another instruction */ + if (ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0) < 0) { + perror("ptrace"); + return; + } + + /* Wait for child to stop on its next instruction */ + wait(&wait_status); + } + + procmsg("the child executed %u instructions\n", icounter); +} +``` + + +不同仅仅存在于 while 循环的开始几行。这个版本里增加了两个新的 ptrace 调用。第一条将进程的寄存器值读取进了一个结构体中。 sys/user.h 定义有 user_regs_struct。如果你查看头文件,头部的注释这么写到: + +``` +/* The whole purpose of this file is for GDB and GDB only. + Don't read too much into it. Don't use it for + anything other than GDB unless know what you are + doing. */ +``` + +``` +/* 这个文件只为了GDB而创建 + 不用详细的阅读.如果你不知道你在干嘛, + 不要在除了 GDB 以外的任何地方使用此文件 */ +``` + + +不知道你做何感想,但这让我觉得我们找对地方了。回到例子中,一旦我们在 regs 变量中取得了寄存器的值,我们就可以通过将 PTRACE_PEEKTEXT 作为参数、 regs.eip(x86 上的扩展指令指针)作为地址,调用 ptrace ,读取当前进程的当前指令。下面是新跟踪器所展示出的调试效果: + +``` +$ simple_tracer traced_helloworld +[5700] debugger started +[5701] target started. will run 'traced_helloworld' +[5700] icounter = 1\. EIP = 0x08048080\. instr = 0x00000eba +[5700] icounter = 2\. EIP = 0x08048085\. instr = 0x0490a0b9 +[5700] icounter = 3\. EIP = 0x0804808a. instr = 0x000001bb +[5700] icounter = 4\. EIP = 0x0804808f. instr = 0x000004b8 +[5700] icounter = 5\. EIP = 0x08048094\. instr = 0x01b880cd +Hello, world! +[5700] icounter = 6\. EIP = 0x08048096\. instr = 0x000001b8 +[5700] icounter = 7\. EIP = 0x0804809b. instr = 0x000080cd +[5700] the child executed 7 instructions +``` + + +现在,除了 icounter,我们也可以观察到指令指针与它每一步所指向的指令。怎么来判断这个结果对不对呢?使用 objdump -d 处理可执行文件: + +``` +$ objdump -d traced_helloworld + +traced_helloworld: file format elf32-i386 + +Disassembly of section .text: + +08048080 <.text>: + 8048080: ba 0e 00 00 00 mov $0xe,%edx + 8048085: b9 a0 90 04 08 mov $0x80490a0,%ecx + 804808a: bb 01 00 00 00 mov $0x1,%ebx + 804808f: b8 04 00 00 00 mov $0x4,%eax + 8048094: cd 80 int $0x80 + 8048096: b8 01 00 00 00 mov $0x1,%eax + 804809b: cd 80 int $0x80 +``` + + +这个结果和我们跟踪器的结果就很容易比较了。 + + +### 将跟踪器关联到正在运行的进程 + + +如你所知,调试器也能关联到已经运行的进程。现在你应该不会惊讶,ptrace 通过 以PTRACE_ATTACH 为参数调用也可以完成这个过程。这里我不会展示示例代码,通过上文的示例代码应该很容易实现这个过程。出于学习目的,这里使用的方法更简便(因为我们在子进程刚开始就可以让它停止)。 + + +### 代码 + + +上文中的简单的跟踪器(更高级的,可以打印指令的版本)的完整c源代码可以在[这里][20]找到。它是通过 4.4 版本的 gcc 以 -Wall -pedantic --std=c99 编译的。 + + +### 结论与计划 + + +诚然,这篇文章并没有涉及很多内容 - 我们距离亲手完成一个实际的调试器还有很长的路要走。但我希望这篇文章至少可以使得调试这件事少一些神秘感。ptrace 是功能多样的系统调用,我们目前只展示了其中的一小部分。 + + +单步调试代码很有用,但也只是在一定程度上有用。上面我通过c的“Hello World!”做了示例。为了执行主函数,可能需要上万行代码来初始化c的运行环境。这并不是很方便。最理想的是在main函数入口处放置断点并从断点处开始分步执行。为此,在这个系列的下一篇,我打算展示怎么实现断点。 + + + +### 参考 + + +撰写此文时参考了如下文章 + +* [Playing with ptrace, Part I][11] +* [How debugger works][12] + + + +[1] 我没有检查,但我确信 gdb 的代码行数至少有六位数。 + +[2] 使用 man 2 ptrace 命令可以了解更多。 + +[3] Peek and poke 在系统编程中是很知名的叫法,指的是直接读写内存内容。 + +[4] 这篇文章假定读者有一定的 Unix/Linux 编程经验。我假定你知道(至少了解概念)fork,exec 族函数与 Unix 信号。 + +[5] 至少你同我一样痴迷与机器/汇编语言。 + +[6] 警告:如同我上面所说,文章很大程度上是平台相关的。我简化了一些设定 - 例如,x86指令集不需要调整到 4 字节(我的32位 Ubuntu unsigned int 是 4 字节)。事实上,许多平台都不需要。从内存中读取指令需要预先安装完整的反汇编器。我们这里没有,但实际的调试器是有的。 + + +-------------------------------------------------------------------------------- + +via: http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1 + +作者:[Eli Bendersky ][a] +译者:[译者ID](https://github.com/YYforymj) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://eli.thegreenplace.net/ +[1]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id1 +[2]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id2 +[3]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id3 +[4]:http://www.jargon.net/jargonfile/p/peek.html +[5]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id4 +[6]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id5 +[7]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id6 +[8]:http://eli.thegreenplace.net/tag/articles +[9]:http://eli.thegreenplace.net/tag/debuggers +[10]:http://eli.thegreenplace.net/tag/programming +[11]:http://www.linuxjournal.com/article/6100?page=0,1 +[12]:http://www.alexonlinux.com/how-debugger-works +[13]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id7 +[14]:http://en.wikipedia.org/wiki/Small_matter_of_programming +[15]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id8 +[16]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id9 +[17]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id10 +[18]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id11 +[19]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id12 +[20]:https://github.com/eliben/code-for-blog/blob/master/2011/simple_tracer.c +[21]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1 From db97b9e8b057fc4ec875cb028c68e9df0ad76f74 Mon Sep 17 00:00:00 2001 From: YYforymj <243885526@qq.com> Date: Sun, 9 Apr 2017 13:07:13 +0800 Subject: [PATCH 04/52] Delete How debuggers work: Part 1 - Basics --- .../tech/How debuggers work: Part 1 - Basics | 346 ------------------ 1 file changed, 346 deletions(-) delete mode 100644 translated/tech/How debuggers work: Part 1 - Basics diff --git a/translated/tech/How debuggers work: Part 1 - Basics b/translated/tech/How debuggers work: Part 1 - Basics deleted file mode 100644 index 9288fea970..0000000000 --- a/translated/tech/How debuggers work: Part 1 - Basics +++ /dev/null @@ -1,346 +0,0 @@ -[调试器的工作原理:第一篇-基础][21] -============================================================ - -这是调试器工作原理系列文章的第一篇,我不确定这个系列会有多少篇文章,会涉及多少话题,但我仍会从这篇基础开始。 - -### 这一篇会讲什么 - -我将为大家展示 Linux 中调试器的主要构成模块 - ptrace 系统调用。这篇文章所有代码都是基于 32 位 Ubuntu 操作系统.值得注意的是,尽管这些代码是平台相关的,将他们移植到其他平台应该并不困难。 - -### 缘由 - -为了理解我们要做什么,让我们先考虑下调试器为了完成调试都需要什么资源。调试器可以开始一个进程并调试这个进程,又或者将自己同某个已经存在的进程关联起来。调试器能够单步执行代码,设定断点并且将程序执行到断点,检查变量的值并追踪堆栈。许多调试器有着更高级的特性,例如在调试器的地址空间内执行表达式或者调用函数,甚至可以在进程执行过程中改变代码并观察效果。 - -尽管现代的调试器都十分的复杂 [[1]][13],但他们的工作的原理却是十分的简单。调试器的基础是操作系统与编译器 / 链接器提供的一些基础服务,其余的部分只是[简单的编程][14]。 - -### Linux 的调试 - ptrace - -Linux 调试器中的瑞士军刀便是 ptrace 系统调用 [[2]][15]。这是一种复杂却强大的工具,可以允许一个进程控制另外一个进程并从内部替换被控制进程的内核镜像的值[[3]][16].。 - -接下来会深入分析。 - -### 执行进程的代码 - -我将编写一个示例,实现一个在“跟踪”模式下运行的进程。在这个模式下,我们将单步执行进程的代码,就像机器码(汇编代码)被 CPU 执行时一样。我将分段展示、讲解示例代码,在文章的末尾也有完整 c 文件的下载链接,你可以编译、执行或者随心所欲的更改。 - -更进一步的计划是实现一段代码,这段代码可以创建可执行用户自定义命令的子进程,同时父进程可以跟踪子进程。首先是主函数: - -``` -int main(int argc, char** argv) -{ - pid_t child_pid; - - if (argc < 2) { - fprintf(stderr, "Expected a program name as argument\n"); - return -1; - } - - child_pid = fork(); - if (child_pid == 0) - run_target(argv[1]); - else if (child_pid > 0) - run_debugger(child_pid); - else { - perror("fork"); - return -1; - } - - return 0; -} -``` - -看起来相当的简单:我们用 fork 命令创建了一个新的子进程。if 语句的分支执行子进程(这里称之为“target”),else if 的分支执行父进程(这里称之为“debugger”)。 - -下面是 target 进程的代码: - -``` -void run_target(const char* programname) -{ - procmsg("target started. will run '%s'\n", programname); - - /* Allow tracing of this process */ - if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) { - perror("ptrace"); - return; - } - - /* Replace this process's image with the given program */ - execl(programname, programname, 0); -} -``` - -这段代码中最值得注意的是 ptrace 调用。在 "sys/ptrace.h" 中,ptrace 是如下定义的: - -``` -long ptrace(enum __ptrace_request request, pid_t pid, - void *addr, void *data); -``` - -第一个参数是 _request_,这是许多预定义的 PTRACE_* 常量中的一个。第二个参数为请求分配进程 ID。第三个与第四个参数是地址与数据指针,用于操作内存。上面代码段中的ptrace调用发起了 PTRACE_TRACEME 请求,这意味着该子进程请求系统内核让其父进程跟踪自己。帮助页面上对于 request 的描述很清楚: - -> 意味着该进程被其父进程跟踪。任何传递给该进程的信号(除了 SIGKILL)都将通过 wait() 方法阻塞该进程并通知其父进程。**此外,该进程的之后所有调用 exec() 动作都将导致 SIGTRAP 信号发送到此进程上,使得父进程在新的程序执行前得到取得控制权的机会**。如果一个进程并不需要它的的父进程跟踪它,那么这个进程不应该发送这个请求。(pid,addr 与 data 暂且不提) - -我高亮了这个例子中我们需要注意的部分。在 ptrace 调用后,run_target 接下来要做的就是通过 execl 传参并调用。如同高亮部分所说明,这将导致系统内核在 execl 创建进程前暂时停止,并向父进程发送信号。 - -是时候看看父进程做什么了。 - -``` -void run_debugger(pid_t child_pid) -{ - int wait_status; - unsigned icounter = 0; - procmsg("debugger started\n"); - - /* Wait for child to stop on its first instruction */ - wait(&wait_status); - - while (WIFSTOPPED(wait_status)) { - icounter++; - /* Make the child execute another instruction */ - if (ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0) < 0) { - perror("ptrace"); - return; - } - - /* Wait for child to stop on its next instruction */ - wait(&wait_status); - } - - procmsg("the child executed %u instructions\n", icounter); -} -``` - -如前文所述,一旦子进程调用了 exec,子进程会停止并被发送 SIGTRAP 信号。父进程会等待该过程的发生并在第一个 wait() 处等待。一旦上述事件发生了,wait() 便会返回,由于子进程停止了父进程便会收到信号(如果子进程由于信号的发送停止了,WIFSTOPPED 就会返回 true)。 - -父进程接下来的动作就是整篇文章最需要关注的部分了。父进程会将 PTRACE_SINGLESTEP 与子进程ID作为参数调用 ptrace 方法。这就会告诉操作系统,“请恢复子进程,但在它执行下一条指令前阻塞”。周而复始地,父进程等待子进程阻塞,循环继续。当 wait() 中传出的信号不再是子进程的停止信号时,循环终止。在跟踪器(父进程)运行期间,这将会是被跟踪进程(子进程)传递给跟踪器的终止信号(如果子进程终止 WIFEXITED 将返回 true)。 - -icounter 存储了子进程执行指令的次数。这么看来我们小小的例子也完成了些有用的事情 - 在命令行中指定程序,它将执行该程序并记录它从开始到结束所需要的 cpu 指令数量。接下来就让我们这么做吧。 - -### 测试 - -我编译了下面这个简单的程序并利用跟踪器运行它: - -``` -#include - -int main() -{ - printf("Hello, world!\n"); - return 0; -} - -``` - -令我惊讶的是,跟踪器花了相当长的时间,并报告整个执行过程共有超过 100,000 条指令执行。仅仅是一条输出语句?什么造成了这种情况?答案很有趣[[5]][18]。Linux 的 gcc 默认会动态的将程序与 c 的运行时库动态地链接。这就意味着任何程序运行前的第一件事是需要动态库加载器去查找程序运行所需要的共享库。这些代码的数量很大 - 别忘了我们的跟踪器要跟踪每一条指令,不仅仅是主函数的,而是“整个过程中的指令”。 - -所以当我将测试程序使用静态编译时(通过比较,可执行文件会多出 500 KB 左右的大小,这部分是 C 运行时库的静态链接),跟踪器提示只有大概 7000 条指令被执行。这个数目仍然不小,但是考虑到在主函数执行前 libc 的初始化以及主函数执行后的清除代码,这个数目已经是相当不错了。此外,printf 也是一个复杂的函数。 - -仍然不满意的话,我需要的是“可以测试”的东西 - 例如可以完整记录每一个指令运行的程序执行过程。这当然可以通过汇编代码完成。所以我找到了这个版本的“Hello, world!”并编译了它。 - - -``` -section .text - ; The _start symbol must be declared for the linker (ld) - global _start - -_start: - - ; Prepare arguments for the sys_write system call: - ; - eax: system call number (sys_write) - ; - ebx: file descriptor (stdout) - ; - ecx: pointer to string - ; - edx: string length - mov edx, len - mov ecx, msg - mov ebx, 1 - mov eax, 4 - - ; Execute the sys_write system call - int 0x80 - - ; Execute sys_exit - mov eax, 1 - int 0x80 - -section .data -msg db 'Hello, world!', 0xa -len equ $ - msg -``` - - -当然,现在跟踪器提示 7 条指令被执行了,这样一来很容易区分他们。 - - -### 深入指令流 - - -上面那个汇编语言编写的程序使得我可以向你介绍 ptrace 的另外一个强大的用途 - 详细显示被跟踪进程的状态。下面是 run_debugger 函数的另一个版本: - -``` -void run_debugger(pid_t child_pid) -{ - int wait_status; - unsigned icounter = 0; - procmsg("debugger started\n"); - - /* Wait for child to stop on its first instruction */ - wait(&wait_status); - - while (WIFSTOPPED(wait_status)) { - icounter++; - struct user_regs_struct regs; - ptrace(PTRACE_GETREGS, child_pid, 0, ®s); - unsigned instr = ptrace(PTRACE_PEEKTEXT, child_pid, regs.eip, 0); - - procmsg("icounter = %u. EIP = 0x%08x. instr = 0x%08x\n", - icounter, regs.eip, instr); - - /* Make the child execute another instruction */ - if (ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0) < 0) { - perror("ptrace"); - return; - } - - /* Wait for child to stop on its next instruction */ - wait(&wait_status); - } - - procmsg("the child executed %u instructions\n", icounter); -} -``` - - -不同仅仅存在于 while 循环的开始几行。这个版本里增加了两个新的 ptrace 调用。第一条将进程的寄存器值读取进了一个结构体中。 sys/user.h 定义有 user_regs_struct。如果你查看头文件,头部的注释这么写到: - -``` -/* The whole purpose of this file is for GDB and GDB only. - Don't read too much into it. Don't use it for - anything other than GDB unless know what you are - doing. */ -``` - -``` -/* 这个文件只为了GDB而创建 - 不用详细的阅读.如果你不知道你在干嘛, - 不要在除了 GDB 以外的任何地方使用此文件 */ -``` - - -不知道你做何感想,但这让我觉得我们找对地方了。回到例子中,一旦我们在 regs 变量中取得了寄存器的值,我们就可以通过将 PTRACE_PEEKTEXT 作为参数、 regs.eip(x86 上的扩展指令指针)作为地址,调用 ptrace ,读取当前进程的当前指令。下面是新跟踪器所展示出的调试效果: - -``` -$ simple_tracer traced_helloworld -[5700] debugger started -[5701] target started. will run 'traced_helloworld' -[5700] icounter = 1\. EIP = 0x08048080\. instr = 0x00000eba -[5700] icounter = 2\. EIP = 0x08048085\. instr = 0x0490a0b9 -[5700] icounter = 3\. EIP = 0x0804808a. instr = 0x000001bb -[5700] icounter = 4\. EIP = 0x0804808f. instr = 0x000004b8 -[5700] icounter = 5\. EIP = 0x08048094\. instr = 0x01b880cd -Hello, world! -[5700] icounter = 6\. EIP = 0x08048096\. instr = 0x000001b8 -[5700] icounter = 7\. EIP = 0x0804809b. instr = 0x000080cd -[5700] the child executed 7 instructions -``` - - -现在,除了 icounter,我们也可以观察到指令指针与它每一步所指向的指令。怎么来判断这个结果对不对呢?使用 objdump -d 处理可执行文件: - -``` -$ objdump -d traced_helloworld - -traced_helloworld: file format elf32-i386 - -Disassembly of section .text: - -08048080 <.text>: - 8048080: ba 0e 00 00 00 mov $0xe,%edx - 8048085: b9 a0 90 04 08 mov $0x80490a0,%ecx - 804808a: bb 01 00 00 00 mov $0x1,%ebx - 804808f: b8 04 00 00 00 mov $0x4,%eax - 8048094: cd 80 int $0x80 - 8048096: b8 01 00 00 00 mov $0x1,%eax - 804809b: cd 80 int $0x80 -``` - - -这个结果和我们跟踪器的结果就很容易比较了。 - - -### 将跟踪器关联到正在运行的进程 - - -如你所知,调试器也能关联到已经运行的进程。现在你应该不会惊讶,ptrace 通过 以PTRACE_ATTACH 为参数调用也可以完成这个过程。这里我不会展示示例代码,通过上文的示例代码应该很容易实现这个过程。出于学习目的,这里使用的方法更简便(因为我们在子进程刚开始就可以让它停止)。 - - -### 代码 - - -上文中的简单的跟踪器(更高级的,可以打印指令的版本)的完整c源代码可以在[这里][20]找到。它是通过 4.4 版本的 gcc 以 -Wall -pedantic --std=c99 编译的。 - - -### 结论与计划 - - -诚然,这篇文章并没有涉及很多内容 - 我们距离亲手完成一个实际的调试器还有很长的路要走。但我希望这篇文章至少可以使得调试这件事少一些神秘感。ptrace 是功能多样的系统调用,我们目前只展示了其中的一小部分。 - - -单步调试代码很有用,但也只是在一定程度上有用。上面我通过c的“Hello World!”做了示例。为了执行主函数,可能需要上万行代码来初始化c的运行环境。这并不是很方便。最理想的是在main函数入口处放置断点并从断点处开始分步执行。为此,在这个系列的下一篇,我打算展示怎么实现断点。 - - - -### 参考 - - -撰写此文时参考了如下文章 - -* [Playing with ptrace, Part I][11] -* [How debugger works][12] - - - -[1] 我没有检查,但我确信 gdb 的代码行数至少有六位数。 - -[2] 使用 man 2 ptrace 命令可以了解更多。 - -[3] Peek and poke 在系统编程中是很知名的叫法,指的是直接读写内存内容。 - -[4] 这篇文章假定读者有一定的 Unix/Linux 编程经验。我假定你知道(至少了解概念)fork,exec 族函数与 Unix 信号。 - -[5] 至少你同我一样痴迷与机器/汇编语言。 - -[6] 警告:如同我上面所说,文章很大程度上是平台相关的。我简化了一些设定 - 例如,x86指令集不需要调整到 4 字节(我的32位 Ubuntu unsigned int 是 4 字节)。事实上,许多平台都不需要。从内存中读取指令需要预先安装完整的反汇编器。我们这里没有,但实际的调试器是有的。 - - --------------------------------------------------------------------------------- - -via: http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1 - -作者:[Eli Bendersky ][a] -译者:[译者ID](https://github.com/YYforymj) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://eli.thegreenplace.net/ -[1]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id1 -[2]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id2 -[3]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id3 -[4]:http://www.jargon.net/jargonfile/p/peek.html -[5]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id4 -[6]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id5 -[7]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id6 -[8]:http://eli.thegreenplace.net/tag/articles -[9]:http://eli.thegreenplace.net/tag/debuggers -[10]:http://eli.thegreenplace.net/tag/programming -[11]:http://www.linuxjournal.com/article/6100?page=0,1 -[12]:http://www.alexonlinux.com/how-debugger-works -[13]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id7 -[14]:http://en.wikipedia.org/wiki/Small_matter_of_programming -[15]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id8 -[16]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id9 -[17]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id10 -[18]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id11 -[19]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id12 -[20]:https://github.com/eliben/code-for-blog/blob/master/2011/simple_tracer.c -[21]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1 From a995b4b2762426581f245eea81a5cb47870fec40 Mon Sep 17 00:00:00 2001 From: YYforymj <243885526@qq.com> Date: Sun, 9 Apr 2017 13:10:16 +0800 Subject: [PATCH 05/52] Create 20110123 How debuggers work Part 1 - Basics.md --- ...0123 How debuggers work Part 1 - Basics.md | 346 ++++++++++++++++++ 1 file changed, 346 insertions(+) create mode 100644 translated/tech/20110123 How debuggers work Part 1 - Basics.md diff --git a/translated/tech/20110123 How debuggers work Part 1 - Basics.md b/translated/tech/20110123 How debuggers work Part 1 - Basics.md new file mode 100644 index 0000000000..9288fea970 --- /dev/null +++ b/translated/tech/20110123 How debuggers work Part 1 - Basics.md @@ -0,0 +1,346 @@ +[调试器的工作原理:第一篇-基础][21] +============================================================ + +这是调试器工作原理系列文章的第一篇,我不确定这个系列会有多少篇文章,会涉及多少话题,但我仍会从这篇基础开始。 + +### 这一篇会讲什么 + +我将为大家展示 Linux 中调试器的主要构成模块 - ptrace 系统调用。这篇文章所有代码都是基于 32 位 Ubuntu 操作系统.值得注意的是,尽管这些代码是平台相关的,将他们移植到其他平台应该并不困难。 + +### 缘由 + +为了理解我们要做什么,让我们先考虑下调试器为了完成调试都需要什么资源。调试器可以开始一个进程并调试这个进程,又或者将自己同某个已经存在的进程关联起来。调试器能够单步执行代码,设定断点并且将程序执行到断点,检查变量的值并追踪堆栈。许多调试器有着更高级的特性,例如在调试器的地址空间内执行表达式或者调用函数,甚至可以在进程执行过程中改变代码并观察效果。 + +尽管现代的调试器都十分的复杂 [[1]][13],但他们的工作的原理却是十分的简单。调试器的基础是操作系统与编译器 / 链接器提供的一些基础服务,其余的部分只是[简单的编程][14]。 + +### Linux 的调试 - ptrace + +Linux 调试器中的瑞士军刀便是 ptrace 系统调用 [[2]][15]。这是一种复杂却强大的工具,可以允许一个进程控制另外一个进程并从内部替换被控制进程的内核镜像的值[[3]][16].。 + +接下来会深入分析。 + +### 执行进程的代码 + +我将编写一个示例,实现一个在“跟踪”模式下运行的进程。在这个模式下,我们将单步执行进程的代码,就像机器码(汇编代码)被 CPU 执行时一样。我将分段展示、讲解示例代码,在文章的末尾也有完整 c 文件的下载链接,你可以编译、执行或者随心所欲的更改。 + +更进一步的计划是实现一段代码,这段代码可以创建可执行用户自定义命令的子进程,同时父进程可以跟踪子进程。首先是主函数: + +``` +int main(int argc, char** argv) +{ + pid_t child_pid; + + if (argc < 2) { + fprintf(stderr, "Expected a program name as argument\n"); + return -1; + } + + child_pid = fork(); + if (child_pid == 0) + run_target(argv[1]); + else if (child_pid > 0) + run_debugger(child_pid); + else { + perror("fork"); + return -1; + } + + return 0; +} +``` + +看起来相当的简单:我们用 fork 命令创建了一个新的子进程。if 语句的分支执行子进程(这里称之为“target”),else if 的分支执行父进程(这里称之为“debugger”)。 + +下面是 target 进程的代码: + +``` +void run_target(const char* programname) +{ + procmsg("target started. will run '%s'\n", programname); + + /* Allow tracing of this process */ + if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) { + perror("ptrace"); + return; + } + + /* Replace this process's image with the given program */ + execl(programname, programname, 0); +} +``` + +这段代码中最值得注意的是 ptrace 调用。在 "sys/ptrace.h" 中,ptrace 是如下定义的: + +``` +long ptrace(enum __ptrace_request request, pid_t pid, + void *addr, void *data); +``` + +第一个参数是 _request_,这是许多预定义的 PTRACE_* 常量中的一个。第二个参数为请求分配进程 ID。第三个与第四个参数是地址与数据指针,用于操作内存。上面代码段中的ptrace调用发起了 PTRACE_TRACEME 请求,这意味着该子进程请求系统内核让其父进程跟踪自己。帮助页面上对于 request 的描述很清楚: + +> 意味着该进程被其父进程跟踪。任何传递给该进程的信号(除了 SIGKILL)都将通过 wait() 方法阻塞该进程并通知其父进程。**此外,该进程的之后所有调用 exec() 动作都将导致 SIGTRAP 信号发送到此进程上,使得父进程在新的程序执行前得到取得控制权的机会**。如果一个进程并不需要它的的父进程跟踪它,那么这个进程不应该发送这个请求。(pid,addr 与 data 暂且不提) + +我高亮了这个例子中我们需要注意的部分。在 ptrace 调用后,run_target 接下来要做的就是通过 execl 传参并调用。如同高亮部分所说明,这将导致系统内核在 execl 创建进程前暂时停止,并向父进程发送信号。 + +是时候看看父进程做什么了。 + +``` +void run_debugger(pid_t child_pid) +{ + int wait_status; + unsigned icounter = 0; + procmsg("debugger started\n"); + + /* Wait for child to stop on its first instruction */ + wait(&wait_status); + + while (WIFSTOPPED(wait_status)) { + icounter++; + /* Make the child execute another instruction */ + if (ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0) < 0) { + perror("ptrace"); + return; + } + + /* Wait for child to stop on its next instruction */ + wait(&wait_status); + } + + procmsg("the child executed %u instructions\n", icounter); +} +``` + +如前文所述,一旦子进程调用了 exec,子进程会停止并被发送 SIGTRAP 信号。父进程会等待该过程的发生并在第一个 wait() 处等待。一旦上述事件发生了,wait() 便会返回,由于子进程停止了父进程便会收到信号(如果子进程由于信号的发送停止了,WIFSTOPPED 就会返回 true)。 + +父进程接下来的动作就是整篇文章最需要关注的部分了。父进程会将 PTRACE_SINGLESTEP 与子进程ID作为参数调用 ptrace 方法。这就会告诉操作系统,“请恢复子进程,但在它执行下一条指令前阻塞”。周而复始地,父进程等待子进程阻塞,循环继续。当 wait() 中传出的信号不再是子进程的停止信号时,循环终止。在跟踪器(父进程)运行期间,这将会是被跟踪进程(子进程)传递给跟踪器的终止信号(如果子进程终止 WIFEXITED 将返回 true)。 + +icounter 存储了子进程执行指令的次数。这么看来我们小小的例子也完成了些有用的事情 - 在命令行中指定程序,它将执行该程序并记录它从开始到结束所需要的 cpu 指令数量。接下来就让我们这么做吧。 + +### 测试 + +我编译了下面这个简单的程序并利用跟踪器运行它: + +``` +#include + +int main() +{ + printf("Hello, world!\n"); + return 0; +} + +``` + +令我惊讶的是,跟踪器花了相当长的时间,并报告整个执行过程共有超过 100,000 条指令执行。仅仅是一条输出语句?什么造成了这种情况?答案很有趣[[5]][18]。Linux 的 gcc 默认会动态的将程序与 c 的运行时库动态地链接。这就意味着任何程序运行前的第一件事是需要动态库加载器去查找程序运行所需要的共享库。这些代码的数量很大 - 别忘了我们的跟踪器要跟踪每一条指令,不仅仅是主函数的,而是“整个过程中的指令”。 + +所以当我将测试程序使用静态编译时(通过比较,可执行文件会多出 500 KB 左右的大小,这部分是 C 运行时库的静态链接),跟踪器提示只有大概 7000 条指令被执行。这个数目仍然不小,但是考虑到在主函数执行前 libc 的初始化以及主函数执行后的清除代码,这个数目已经是相当不错了。此外,printf 也是一个复杂的函数。 + +仍然不满意的话,我需要的是“可以测试”的东西 - 例如可以完整记录每一个指令运行的程序执行过程。这当然可以通过汇编代码完成。所以我找到了这个版本的“Hello, world!”并编译了它。 + + +``` +section .text + ; The _start symbol must be declared for the linker (ld) + global _start + +_start: + + ; Prepare arguments for the sys_write system call: + ; - eax: system call number (sys_write) + ; - ebx: file descriptor (stdout) + ; - ecx: pointer to string + ; - edx: string length + mov edx, len + mov ecx, msg + mov ebx, 1 + mov eax, 4 + + ; Execute the sys_write system call + int 0x80 + + ; Execute sys_exit + mov eax, 1 + int 0x80 + +section .data +msg db 'Hello, world!', 0xa +len equ $ - msg +``` + + +当然,现在跟踪器提示 7 条指令被执行了,这样一来很容易区分他们。 + + +### 深入指令流 + + +上面那个汇编语言编写的程序使得我可以向你介绍 ptrace 的另外一个强大的用途 - 详细显示被跟踪进程的状态。下面是 run_debugger 函数的另一个版本: + +``` +void run_debugger(pid_t child_pid) +{ + int wait_status; + unsigned icounter = 0; + procmsg("debugger started\n"); + + /* Wait for child to stop on its first instruction */ + wait(&wait_status); + + while (WIFSTOPPED(wait_status)) { + icounter++; + struct user_regs_struct regs; + ptrace(PTRACE_GETREGS, child_pid, 0, ®s); + unsigned instr = ptrace(PTRACE_PEEKTEXT, child_pid, regs.eip, 0); + + procmsg("icounter = %u. EIP = 0x%08x. instr = 0x%08x\n", + icounter, regs.eip, instr); + + /* Make the child execute another instruction */ + if (ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0) < 0) { + perror("ptrace"); + return; + } + + /* Wait for child to stop on its next instruction */ + wait(&wait_status); + } + + procmsg("the child executed %u instructions\n", icounter); +} +``` + + +不同仅仅存在于 while 循环的开始几行。这个版本里增加了两个新的 ptrace 调用。第一条将进程的寄存器值读取进了一个结构体中。 sys/user.h 定义有 user_regs_struct。如果你查看头文件,头部的注释这么写到: + +``` +/* The whole purpose of this file is for GDB and GDB only. + Don't read too much into it. Don't use it for + anything other than GDB unless know what you are + doing. */ +``` + +``` +/* 这个文件只为了GDB而创建 + 不用详细的阅读.如果你不知道你在干嘛, + 不要在除了 GDB 以外的任何地方使用此文件 */ +``` + + +不知道你做何感想,但这让我觉得我们找对地方了。回到例子中,一旦我们在 regs 变量中取得了寄存器的值,我们就可以通过将 PTRACE_PEEKTEXT 作为参数、 regs.eip(x86 上的扩展指令指针)作为地址,调用 ptrace ,读取当前进程的当前指令。下面是新跟踪器所展示出的调试效果: + +``` +$ simple_tracer traced_helloworld +[5700] debugger started +[5701] target started. will run 'traced_helloworld' +[5700] icounter = 1\. EIP = 0x08048080\. instr = 0x00000eba +[5700] icounter = 2\. EIP = 0x08048085\. instr = 0x0490a0b9 +[5700] icounter = 3\. EIP = 0x0804808a. instr = 0x000001bb +[5700] icounter = 4\. EIP = 0x0804808f. instr = 0x000004b8 +[5700] icounter = 5\. EIP = 0x08048094\. instr = 0x01b880cd +Hello, world! +[5700] icounter = 6\. EIP = 0x08048096\. instr = 0x000001b8 +[5700] icounter = 7\. EIP = 0x0804809b. instr = 0x000080cd +[5700] the child executed 7 instructions +``` + + +现在,除了 icounter,我们也可以观察到指令指针与它每一步所指向的指令。怎么来判断这个结果对不对呢?使用 objdump -d 处理可执行文件: + +``` +$ objdump -d traced_helloworld + +traced_helloworld: file format elf32-i386 + +Disassembly of section .text: + +08048080 <.text>: + 8048080: ba 0e 00 00 00 mov $0xe,%edx + 8048085: b9 a0 90 04 08 mov $0x80490a0,%ecx + 804808a: bb 01 00 00 00 mov $0x1,%ebx + 804808f: b8 04 00 00 00 mov $0x4,%eax + 8048094: cd 80 int $0x80 + 8048096: b8 01 00 00 00 mov $0x1,%eax + 804809b: cd 80 int $0x80 +``` + + +这个结果和我们跟踪器的结果就很容易比较了。 + + +### 将跟踪器关联到正在运行的进程 + + +如你所知,调试器也能关联到已经运行的进程。现在你应该不会惊讶,ptrace 通过 以PTRACE_ATTACH 为参数调用也可以完成这个过程。这里我不会展示示例代码,通过上文的示例代码应该很容易实现这个过程。出于学习目的,这里使用的方法更简便(因为我们在子进程刚开始就可以让它停止)。 + + +### 代码 + + +上文中的简单的跟踪器(更高级的,可以打印指令的版本)的完整c源代码可以在[这里][20]找到。它是通过 4.4 版本的 gcc 以 -Wall -pedantic --std=c99 编译的。 + + +### 结论与计划 + + +诚然,这篇文章并没有涉及很多内容 - 我们距离亲手完成一个实际的调试器还有很长的路要走。但我希望这篇文章至少可以使得调试这件事少一些神秘感。ptrace 是功能多样的系统调用,我们目前只展示了其中的一小部分。 + + +单步调试代码很有用,但也只是在一定程度上有用。上面我通过c的“Hello World!”做了示例。为了执行主函数,可能需要上万行代码来初始化c的运行环境。这并不是很方便。最理想的是在main函数入口处放置断点并从断点处开始分步执行。为此,在这个系列的下一篇,我打算展示怎么实现断点。 + + + +### 参考 + + +撰写此文时参考了如下文章 + +* [Playing with ptrace, Part I][11] +* [How debugger works][12] + + + +[1] 我没有检查,但我确信 gdb 的代码行数至少有六位数。 + +[2] 使用 man 2 ptrace 命令可以了解更多。 + +[3] Peek and poke 在系统编程中是很知名的叫法,指的是直接读写内存内容。 + +[4] 这篇文章假定读者有一定的 Unix/Linux 编程经验。我假定你知道(至少了解概念)fork,exec 族函数与 Unix 信号。 + +[5] 至少你同我一样痴迷与机器/汇编语言。 + +[6] 警告:如同我上面所说,文章很大程度上是平台相关的。我简化了一些设定 - 例如,x86指令集不需要调整到 4 字节(我的32位 Ubuntu unsigned int 是 4 字节)。事实上,许多平台都不需要。从内存中读取指令需要预先安装完整的反汇编器。我们这里没有,但实际的调试器是有的。 + + +-------------------------------------------------------------------------------- + +via: http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1 + +作者:[Eli Bendersky ][a] +译者:[译者ID](https://github.com/YYforymj) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://eli.thegreenplace.net/ +[1]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id1 +[2]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id2 +[3]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id3 +[4]:http://www.jargon.net/jargonfile/p/peek.html +[5]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id4 +[6]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id5 +[7]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id6 +[8]:http://eli.thegreenplace.net/tag/articles +[9]:http://eli.thegreenplace.net/tag/debuggers +[10]:http://eli.thegreenplace.net/tag/programming +[11]:http://www.linuxjournal.com/article/6100?page=0,1 +[12]:http://www.alexonlinux.com/how-debugger-works +[13]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id7 +[14]:http://en.wikipedia.org/wiki/Small_matter_of_programming +[15]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id8 +[16]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id9 +[17]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id10 +[18]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id11 +[19]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id12 +[20]:https://github.com/eliben/code-for-blog/blob/master/2011/simple_tracer.c +[21]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1 From 6da289fa220815427612a2eea1dbbd66e9d74dbf Mon Sep 17 00:00:00 2001 From: YYforymj <243885526@qq.com> Date: Sun, 9 Apr 2017 13:11:38 +0800 Subject: [PATCH 06/52] Delete 20110123 How debuggers work Part 1 - Basics.md --- ...0123 How debuggers work Part 1 - Basics.md | 346 ------------------ 1 file changed, 346 deletions(-) delete mode 100644 translated/tech/20110123 How debuggers work Part 1 - Basics.md diff --git a/translated/tech/20110123 How debuggers work Part 1 - Basics.md b/translated/tech/20110123 How debuggers work Part 1 - Basics.md deleted file mode 100644 index 9288fea970..0000000000 --- a/translated/tech/20110123 How debuggers work Part 1 - Basics.md +++ /dev/null @@ -1,346 +0,0 @@ -[调试器的工作原理:第一篇-基础][21] -============================================================ - -这是调试器工作原理系列文章的第一篇,我不确定这个系列会有多少篇文章,会涉及多少话题,但我仍会从这篇基础开始。 - -### 这一篇会讲什么 - -我将为大家展示 Linux 中调试器的主要构成模块 - ptrace 系统调用。这篇文章所有代码都是基于 32 位 Ubuntu 操作系统.值得注意的是,尽管这些代码是平台相关的,将他们移植到其他平台应该并不困难。 - -### 缘由 - -为了理解我们要做什么,让我们先考虑下调试器为了完成调试都需要什么资源。调试器可以开始一个进程并调试这个进程,又或者将自己同某个已经存在的进程关联起来。调试器能够单步执行代码,设定断点并且将程序执行到断点,检查变量的值并追踪堆栈。许多调试器有着更高级的特性,例如在调试器的地址空间内执行表达式或者调用函数,甚至可以在进程执行过程中改变代码并观察效果。 - -尽管现代的调试器都十分的复杂 [[1]][13],但他们的工作的原理却是十分的简单。调试器的基础是操作系统与编译器 / 链接器提供的一些基础服务,其余的部分只是[简单的编程][14]。 - -### Linux 的调试 - ptrace - -Linux 调试器中的瑞士军刀便是 ptrace 系统调用 [[2]][15]。这是一种复杂却强大的工具,可以允许一个进程控制另外一个进程并从内部替换被控制进程的内核镜像的值[[3]][16].。 - -接下来会深入分析。 - -### 执行进程的代码 - -我将编写一个示例,实现一个在“跟踪”模式下运行的进程。在这个模式下,我们将单步执行进程的代码,就像机器码(汇编代码)被 CPU 执行时一样。我将分段展示、讲解示例代码,在文章的末尾也有完整 c 文件的下载链接,你可以编译、执行或者随心所欲的更改。 - -更进一步的计划是实现一段代码,这段代码可以创建可执行用户自定义命令的子进程,同时父进程可以跟踪子进程。首先是主函数: - -``` -int main(int argc, char** argv) -{ - pid_t child_pid; - - if (argc < 2) { - fprintf(stderr, "Expected a program name as argument\n"); - return -1; - } - - child_pid = fork(); - if (child_pid == 0) - run_target(argv[1]); - else if (child_pid > 0) - run_debugger(child_pid); - else { - perror("fork"); - return -1; - } - - return 0; -} -``` - -看起来相当的简单:我们用 fork 命令创建了一个新的子进程。if 语句的分支执行子进程(这里称之为“target”),else if 的分支执行父进程(这里称之为“debugger”)。 - -下面是 target 进程的代码: - -``` -void run_target(const char* programname) -{ - procmsg("target started. will run '%s'\n", programname); - - /* Allow tracing of this process */ - if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) { - perror("ptrace"); - return; - } - - /* Replace this process's image with the given program */ - execl(programname, programname, 0); -} -``` - -这段代码中最值得注意的是 ptrace 调用。在 "sys/ptrace.h" 中,ptrace 是如下定义的: - -``` -long ptrace(enum __ptrace_request request, pid_t pid, - void *addr, void *data); -``` - -第一个参数是 _request_,这是许多预定义的 PTRACE_* 常量中的一个。第二个参数为请求分配进程 ID。第三个与第四个参数是地址与数据指针,用于操作内存。上面代码段中的ptrace调用发起了 PTRACE_TRACEME 请求,这意味着该子进程请求系统内核让其父进程跟踪自己。帮助页面上对于 request 的描述很清楚: - -> 意味着该进程被其父进程跟踪。任何传递给该进程的信号(除了 SIGKILL)都将通过 wait() 方法阻塞该进程并通知其父进程。**此外,该进程的之后所有调用 exec() 动作都将导致 SIGTRAP 信号发送到此进程上,使得父进程在新的程序执行前得到取得控制权的机会**。如果一个进程并不需要它的的父进程跟踪它,那么这个进程不应该发送这个请求。(pid,addr 与 data 暂且不提) - -我高亮了这个例子中我们需要注意的部分。在 ptrace 调用后,run_target 接下来要做的就是通过 execl 传参并调用。如同高亮部分所说明,这将导致系统内核在 execl 创建进程前暂时停止,并向父进程发送信号。 - -是时候看看父进程做什么了。 - -``` -void run_debugger(pid_t child_pid) -{ - int wait_status; - unsigned icounter = 0; - procmsg("debugger started\n"); - - /* Wait for child to stop on its first instruction */ - wait(&wait_status); - - while (WIFSTOPPED(wait_status)) { - icounter++; - /* Make the child execute another instruction */ - if (ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0) < 0) { - perror("ptrace"); - return; - } - - /* Wait for child to stop on its next instruction */ - wait(&wait_status); - } - - procmsg("the child executed %u instructions\n", icounter); -} -``` - -如前文所述,一旦子进程调用了 exec,子进程会停止并被发送 SIGTRAP 信号。父进程会等待该过程的发生并在第一个 wait() 处等待。一旦上述事件发生了,wait() 便会返回,由于子进程停止了父进程便会收到信号(如果子进程由于信号的发送停止了,WIFSTOPPED 就会返回 true)。 - -父进程接下来的动作就是整篇文章最需要关注的部分了。父进程会将 PTRACE_SINGLESTEP 与子进程ID作为参数调用 ptrace 方法。这就会告诉操作系统,“请恢复子进程,但在它执行下一条指令前阻塞”。周而复始地,父进程等待子进程阻塞,循环继续。当 wait() 中传出的信号不再是子进程的停止信号时,循环终止。在跟踪器(父进程)运行期间,这将会是被跟踪进程(子进程)传递给跟踪器的终止信号(如果子进程终止 WIFEXITED 将返回 true)。 - -icounter 存储了子进程执行指令的次数。这么看来我们小小的例子也完成了些有用的事情 - 在命令行中指定程序,它将执行该程序并记录它从开始到结束所需要的 cpu 指令数量。接下来就让我们这么做吧。 - -### 测试 - -我编译了下面这个简单的程序并利用跟踪器运行它: - -``` -#include - -int main() -{ - printf("Hello, world!\n"); - return 0; -} - -``` - -令我惊讶的是,跟踪器花了相当长的时间,并报告整个执行过程共有超过 100,000 条指令执行。仅仅是一条输出语句?什么造成了这种情况?答案很有趣[[5]][18]。Linux 的 gcc 默认会动态的将程序与 c 的运行时库动态地链接。这就意味着任何程序运行前的第一件事是需要动态库加载器去查找程序运行所需要的共享库。这些代码的数量很大 - 别忘了我们的跟踪器要跟踪每一条指令,不仅仅是主函数的,而是“整个过程中的指令”。 - -所以当我将测试程序使用静态编译时(通过比较,可执行文件会多出 500 KB 左右的大小,这部分是 C 运行时库的静态链接),跟踪器提示只有大概 7000 条指令被执行。这个数目仍然不小,但是考虑到在主函数执行前 libc 的初始化以及主函数执行后的清除代码,这个数目已经是相当不错了。此外,printf 也是一个复杂的函数。 - -仍然不满意的话,我需要的是“可以测试”的东西 - 例如可以完整记录每一个指令运行的程序执行过程。这当然可以通过汇编代码完成。所以我找到了这个版本的“Hello, world!”并编译了它。 - - -``` -section .text - ; The _start symbol must be declared for the linker (ld) - global _start - -_start: - - ; Prepare arguments for the sys_write system call: - ; - eax: system call number (sys_write) - ; - ebx: file descriptor (stdout) - ; - ecx: pointer to string - ; - edx: string length - mov edx, len - mov ecx, msg - mov ebx, 1 - mov eax, 4 - - ; Execute the sys_write system call - int 0x80 - - ; Execute sys_exit - mov eax, 1 - int 0x80 - -section .data -msg db 'Hello, world!', 0xa -len equ $ - msg -``` - - -当然,现在跟踪器提示 7 条指令被执行了,这样一来很容易区分他们。 - - -### 深入指令流 - - -上面那个汇编语言编写的程序使得我可以向你介绍 ptrace 的另外一个强大的用途 - 详细显示被跟踪进程的状态。下面是 run_debugger 函数的另一个版本: - -``` -void run_debugger(pid_t child_pid) -{ - int wait_status; - unsigned icounter = 0; - procmsg("debugger started\n"); - - /* Wait for child to stop on its first instruction */ - wait(&wait_status); - - while (WIFSTOPPED(wait_status)) { - icounter++; - struct user_regs_struct regs; - ptrace(PTRACE_GETREGS, child_pid, 0, ®s); - unsigned instr = ptrace(PTRACE_PEEKTEXT, child_pid, regs.eip, 0); - - procmsg("icounter = %u. EIP = 0x%08x. instr = 0x%08x\n", - icounter, regs.eip, instr); - - /* Make the child execute another instruction */ - if (ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0) < 0) { - perror("ptrace"); - return; - } - - /* Wait for child to stop on its next instruction */ - wait(&wait_status); - } - - procmsg("the child executed %u instructions\n", icounter); -} -``` - - -不同仅仅存在于 while 循环的开始几行。这个版本里增加了两个新的 ptrace 调用。第一条将进程的寄存器值读取进了一个结构体中。 sys/user.h 定义有 user_regs_struct。如果你查看头文件,头部的注释这么写到: - -``` -/* The whole purpose of this file is for GDB and GDB only. - Don't read too much into it. Don't use it for - anything other than GDB unless know what you are - doing. */ -``` - -``` -/* 这个文件只为了GDB而创建 - 不用详细的阅读.如果你不知道你在干嘛, - 不要在除了 GDB 以外的任何地方使用此文件 */ -``` - - -不知道你做何感想,但这让我觉得我们找对地方了。回到例子中,一旦我们在 regs 变量中取得了寄存器的值,我们就可以通过将 PTRACE_PEEKTEXT 作为参数、 regs.eip(x86 上的扩展指令指针)作为地址,调用 ptrace ,读取当前进程的当前指令。下面是新跟踪器所展示出的调试效果: - -``` -$ simple_tracer traced_helloworld -[5700] debugger started -[5701] target started. will run 'traced_helloworld' -[5700] icounter = 1\. EIP = 0x08048080\. instr = 0x00000eba -[5700] icounter = 2\. EIP = 0x08048085\. instr = 0x0490a0b9 -[5700] icounter = 3\. EIP = 0x0804808a. instr = 0x000001bb -[5700] icounter = 4\. EIP = 0x0804808f. instr = 0x000004b8 -[5700] icounter = 5\. EIP = 0x08048094\. instr = 0x01b880cd -Hello, world! -[5700] icounter = 6\. EIP = 0x08048096\. instr = 0x000001b8 -[5700] icounter = 7\. EIP = 0x0804809b. instr = 0x000080cd -[5700] the child executed 7 instructions -``` - - -现在,除了 icounter,我们也可以观察到指令指针与它每一步所指向的指令。怎么来判断这个结果对不对呢?使用 objdump -d 处理可执行文件: - -``` -$ objdump -d traced_helloworld - -traced_helloworld: file format elf32-i386 - -Disassembly of section .text: - -08048080 <.text>: - 8048080: ba 0e 00 00 00 mov $0xe,%edx - 8048085: b9 a0 90 04 08 mov $0x80490a0,%ecx - 804808a: bb 01 00 00 00 mov $0x1,%ebx - 804808f: b8 04 00 00 00 mov $0x4,%eax - 8048094: cd 80 int $0x80 - 8048096: b8 01 00 00 00 mov $0x1,%eax - 804809b: cd 80 int $0x80 -``` - - -这个结果和我们跟踪器的结果就很容易比较了。 - - -### 将跟踪器关联到正在运行的进程 - - -如你所知,调试器也能关联到已经运行的进程。现在你应该不会惊讶,ptrace 通过 以PTRACE_ATTACH 为参数调用也可以完成这个过程。这里我不会展示示例代码,通过上文的示例代码应该很容易实现这个过程。出于学习目的,这里使用的方法更简便(因为我们在子进程刚开始就可以让它停止)。 - - -### 代码 - - -上文中的简单的跟踪器(更高级的,可以打印指令的版本)的完整c源代码可以在[这里][20]找到。它是通过 4.4 版本的 gcc 以 -Wall -pedantic --std=c99 编译的。 - - -### 结论与计划 - - -诚然,这篇文章并没有涉及很多内容 - 我们距离亲手完成一个实际的调试器还有很长的路要走。但我希望这篇文章至少可以使得调试这件事少一些神秘感。ptrace 是功能多样的系统调用,我们目前只展示了其中的一小部分。 - - -单步调试代码很有用,但也只是在一定程度上有用。上面我通过c的“Hello World!”做了示例。为了执行主函数,可能需要上万行代码来初始化c的运行环境。这并不是很方便。最理想的是在main函数入口处放置断点并从断点处开始分步执行。为此,在这个系列的下一篇,我打算展示怎么实现断点。 - - - -### 参考 - - -撰写此文时参考了如下文章 - -* [Playing with ptrace, Part I][11] -* [How debugger works][12] - - - -[1] 我没有检查,但我确信 gdb 的代码行数至少有六位数。 - -[2] 使用 man 2 ptrace 命令可以了解更多。 - -[3] Peek and poke 在系统编程中是很知名的叫法,指的是直接读写内存内容。 - -[4] 这篇文章假定读者有一定的 Unix/Linux 编程经验。我假定你知道(至少了解概念)fork,exec 族函数与 Unix 信号。 - -[5] 至少你同我一样痴迷与机器/汇编语言。 - -[6] 警告:如同我上面所说,文章很大程度上是平台相关的。我简化了一些设定 - 例如,x86指令集不需要调整到 4 字节(我的32位 Ubuntu unsigned int 是 4 字节)。事实上,许多平台都不需要。从内存中读取指令需要预先安装完整的反汇编器。我们这里没有,但实际的调试器是有的。 - - --------------------------------------------------------------------------------- - -via: http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1 - -作者:[Eli Bendersky ][a] -译者:[译者ID](https://github.com/YYforymj) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://eli.thegreenplace.net/ -[1]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id1 -[2]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id2 -[3]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id3 -[4]:http://www.jargon.net/jargonfile/p/peek.html -[5]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id4 -[6]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id5 -[7]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id6 -[8]:http://eli.thegreenplace.net/tag/articles -[9]:http://eli.thegreenplace.net/tag/debuggers -[10]:http://eli.thegreenplace.net/tag/programming -[11]:http://www.linuxjournal.com/article/6100?page=0,1 -[12]:http://www.alexonlinux.com/how-debugger-works -[13]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id7 -[14]:http://en.wikipedia.org/wiki/Small_matter_of_programming -[15]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id8 -[16]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id9 -[17]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id10 -[18]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id11 -[19]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id12 -[20]:https://github.com/eliben/code-for-blog/blob/master/2011/simple_tracer.c -[21]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1 From 6746c4694ba0be1b28bdf8bf61d0a75164138891 Mon Sep 17 00:00:00 2001 From: YYforymj <243885526@qq.com> Date: Sun, 9 Apr 2017 13:13:01 +0800 Subject: [PATCH 07/52] Translated MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 翻译完成 --- ...0123 How debuggers work Part 1 - Basics.md | 346 ++++++++++++++++++ 1 file changed, 346 insertions(+) create mode 100644 translated/tech/20110123 How debuggers work Part 1 - Basics.md diff --git a/translated/tech/20110123 How debuggers work Part 1 - Basics.md b/translated/tech/20110123 How debuggers work Part 1 - Basics.md new file mode 100644 index 0000000000..9288fea970 --- /dev/null +++ b/translated/tech/20110123 How debuggers work Part 1 - Basics.md @@ -0,0 +1,346 @@ +[调试器的工作原理:第一篇-基础][21] +============================================================ + +这是调试器工作原理系列文章的第一篇,我不确定这个系列会有多少篇文章,会涉及多少话题,但我仍会从这篇基础开始。 + +### 这一篇会讲什么 + +我将为大家展示 Linux 中调试器的主要构成模块 - ptrace 系统调用。这篇文章所有代码都是基于 32 位 Ubuntu 操作系统.值得注意的是,尽管这些代码是平台相关的,将他们移植到其他平台应该并不困难。 + +### 缘由 + +为了理解我们要做什么,让我们先考虑下调试器为了完成调试都需要什么资源。调试器可以开始一个进程并调试这个进程,又或者将自己同某个已经存在的进程关联起来。调试器能够单步执行代码,设定断点并且将程序执行到断点,检查变量的值并追踪堆栈。许多调试器有着更高级的特性,例如在调试器的地址空间内执行表达式或者调用函数,甚至可以在进程执行过程中改变代码并观察效果。 + +尽管现代的调试器都十分的复杂 [[1]][13],但他们的工作的原理却是十分的简单。调试器的基础是操作系统与编译器 / 链接器提供的一些基础服务,其余的部分只是[简单的编程][14]。 + +### Linux 的调试 - ptrace + +Linux 调试器中的瑞士军刀便是 ptrace 系统调用 [[2]][15]。这是一种复杂却强大的工具,可以允许一个进程控制另外一个进程并从内部替换被控制进程的内核镜像的值[[3]][16].。 + +接下来会深入分析。 + +### 执行进程的代码 + +我将编写一个示例,实现一个在“跟踪”模式下运行的进程。在这个模式下,我们将单步执行进程的代码,就像机器码(汇编代码)被 CPU 执行时一样。我将分段展示、讲解示例代码,在文章的末尾也有完整 c 文件的下载链接,你可以编译、执行或者随心所欲的更改。 + +更进一步的计划是实现一段代码,这段代码可以创建可执行用户自定义命令的子进程,同时父进程可以跟踪子进程。首先是主函数: + +``` +int main(int argc, char** argv) +{ + pid_t child_pid; + + if (argc < 2) { + fprintf(stderr, "Expected a program name as argument\n"); + return -1; + } + + child_pid = fork(); + if (child_pid == 0) + run_target(argv[1]); + else if (child_pid > 0) + run_debugger(child_pid); + else { + perror("fork"); + return -1; + } + + return 0; +} +``` + +看起来相当的简单:我们用 fork 命令创建了一个新的子进程。if 语句的分支执行子进程(这里称之为“target”),else if 的分支执行父进程(这里称之为“debugger”)。 + +下面是 target 进程的代码: + +``` +void run_target(const char* programname) +{ + procmsg("target started. will run '%s'\n", programname); + + /* Allow tracing of this process */ + if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) { + perror("ptrace"); + return; + } + + /* Replace this process's image with the given program */ + execl(programname, programname, 0); +} +``` + +这段代码中最值得注意的是 ptrace 调用。在 "sys/ptrace.h" 中,ptrace 是如下定义的: + +``` +long ptrace(enum __ptrace_request request, pid_t pid, + void *addr, void *data); +``` + +第一个参数是 _request_,这是许多预定义的 PTRACE_* 常量中的一个。第二个参数为请求分配进程 ID。第三个与第四个参数是地址与数据指针,用于操作内存。上面代码段中的ptrace调用发起了 PTRACE_TRACEME 请求,这意味着该子进程请求系统内核让其父进程跟踪自己。帮助页面上对于 request 的描述很清楚: + +> 意味着该进程被其父进程跟踪。任何传递给该进程的信号(除了 SIGKILL)都将通过 wait() 方法阻塞该进程并通知其父进程。**此外,该进程的之后所有调用 exec() 动作都将导致 SIGTRAP 信号发送到此进程上,使得父进程在新的程序执行前得到取得控制权的机会**。如果一个进程并不需要它的的父进程跟踪它,那么这个进程不应该发送这个请求。(pid,addr 与 data 暂且不提) + +我高亮了这个例子中我们需要注意的部分。在 ptrace 调用后,run_target 接下来要做的就是通过 execl 传参并调用。如同高亮部分所说明,这将导致系统内核在 execl 创建进程前暂时停止,并向父进程发送信号。 + +是时候看看父进程做什么了。 + +``` +void run_debugger(pid_t child_pid) +{ + int wait_status; + unsigned icounter = 0; + procmsg("debugger started\n"); + + /* Wait for child to stop on its first instruction */ + wait(&wait_status); + + while (WIFSTOPPED(wait_status)) { + icounter++; + /* Make the child execute another instruction */ + if (ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0) < 0) { + perror("ptrace"); + return; + } + + /* Wait for child to stop on its next instruction */ + wait(&wait_status); + } + + procmsg("the child executed %u instructions\n", icounter); +} +``` + +如前文所述,一旦子进程调用了 exec,子进程会停止并被发送 SIGTRAP 信号。父进程会等待该过程的发生并在第一个 wait() 处等待。一旦上述事件发生了,wait() 便会返回,由于子进程停止了父进程便会收到信号(如果子进程由于信号的发送停止了,WIFSTOPPED 就会返回 true)。 + +父进程接下来的动作就是整篇文章最需要关注的部分了。父进程会将 PTRACE_SINGLESTEP 与子进程ID作为参数调用 ptrace 方法。这就会告诉操作系统,“请恢复子进程,但在它执行下一条指令前阻塞”。周而复始地,父进程等待子进程阻塞,循环继续。当 wait() 中传出的信号不再是子进程的停止信号时,循环终止。在跟踪器(父进程)运行期间,这将会是被跟踪进程(子进程)传递给跟踪器的终止信号(如果子进程终止 WIFEXITED 将返回 true)。 + +icounter 存储了子进程执行指令的次数。这么看来我们小小的例子也完成了些有用的事情 - 在命令行中指定程序,它将执行该程序并记录它从开始到结束所需要的 cpu 指令数量。接下来就让我们这么做吧。 + +### 测试 + +我编译了下面这个简单的程序并利用跟踪器运行它: + +``` +#include + +int main() +{ + printf("Hello, world!\n"); + return 0; +} + +``` + +令我惊讶的是,跟踪器花了相当长的时间,并报告整个执行过程共有超过 100,000 条指令执行。仅仅是一条输出语句?什么造成了这种情况?答案很有趣[[5]][18]。Linux 的 gcc 默认会动态的将程序与 c 的运行时库动态地链接。这就意味着任何程序运行前的第一件事是需要动态库加载器去查找程序运行所需要的共享库。这些代码的数量很大 - 别忘了我们的跟踪器要跟踪每一条指令,不仅仅是主函数的,而是“整个过程中的指令”。 + +所以当我将测试程序使用静态编译时(通过比较,可执行文件会多出 500 KB 左右的大小,这部分是 C 运行时库的静态链接),跟踪器提示只有大概 7000 条指令被执行。这个数目仍然不小,但是考虑到在主函数执行前 libc 的初始化以及主函数执行后的清除代码,这个数目已经是相当不错了。此外,printf 也是一个复杂的函数。 + +仍然不满意的话,我需要的是“可以测试”的东西 - 例如可以完整记录每一个指令运行的程序执行过程。这当然可以通过汇编代码完成。所以我找到了这个版本的“Hello, world!”并编译了它。 + + +``` +section .text + ; The _start symbol must be declared for the linker (ld) + global _start + +_start: + + ; Prepare arguments for the sys_write system call: + ; - eax: system call number (sys_write) + ; - ebx: file descriptor (stdout) + ; - ecx: pointer to string + ; - edx: string length + mov edx, len + mov ecx, msg + mov ebx, 1 + mov eax, 4 + + ; Execute the sys_write system call + int 0x80 + + ; Execute sys_exit + mov eax, 1 + int 0x80 + +section .data +msg db 'Hello, world!', 0xa +len equ $ - msg +``` + + +当然,现在跟踪器提示 7 条指令被执行了,这样一来很容易区分他们。 + + +### 深入指令流 + + +上面那个汇编语言编写的程序使得我可以向你介绍 ptrace 的另外一个强大的用途 - 详细显示被跟踪进程的状态。下面是 run_debugger 函数的另一个版本: + +``` +void run_debugger(pid_t child_pid) +{ + int wait_status; + unsigned icounter = 0; + procmsg("debugger started\n"); + + /* Wait for child to stop on its first instruction */ + wait(&wait_status); + + while (WIFSTOPPED(wait_status)) { + icounter++; + struct user_regs_struct regs; + ptrace(PTRACE_GETREGS, child_pid, 0, ®s); + unsigned instr = ptrace(PTRACE_PEEKTEXT, child_pid, regs.eip, 0); + + procmsg("icounter = %u. EIP = 0x%08x. instr = 0x%08x\n", + icounter, regs.eip, instr); + + /* Make the child execute another instruction */ + if (ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0) < 0) { + perror("ptrace"); + return; + } + + /* Wait for child to stop on its next instruction */ + wait(&wait_status); + } + + procmsg("the child executed %u instructions\n", icounter); +} +``` + + +不同仅仅存在于 while 循环的开始几行。这个版本里增加了两个新的 ptrace 调用。第一条将进程的寄存器值读取进了一个结构体中。 sys/user.h 定义有 user_regs_struct。如果你查看头文件,头部的注释这么写到: + +``` +/* The whole purpose of this file is for GDB and GDB only. + Don't read too much into it. Don't use it for + anything other than GDB unless know what you are + doing. */ +``` + +``` +/* 这个文件只为了GDB而创建 + 不用详细的阅读.如果你不知道你在干嘛, + 不要在除了 GDB 以外的任何地方使用此文件 */ +``` + + +不知道你做何感想,但这让我觉得我们找对地方了。回到例子中,一旦我们在 regs 变量中取得了寄存器的值,我们就可以通过将 PTRACE_PEEKTEXT 作为参数、 regs.eip(x86 上的扩展指令指针)作为地址,调用 ptrace ,读取当前进程的当前指令。下面是新跟踪器所展示出的调试效果: + +``` +$ simple_tracer traced_helloworld +[5700] debugger started +[5701] target started. will run 'traced_helloworld' +[5700] icounter = 1\. EIP = 0x08048080\. instr = 0x00000eba +[5700] icounter = 2\. EIP = 0x08048085\. instr = 0x0490a0b9 +[5700] icounter = 3\. EIP = 0x0804808a. instr = 0x000001bb +[5700] icounter = 4\. EIP = 0x0804808f. instr = 0x000004b8 +[5700] icounter = 5\. EIP = 0x08048094\. instr = 0x01b880cd +Hello, world! +[5700] icounter = 6\. EIP = 0x08048096\. instr = 0x000001b8 +[5700] icounter = 7\. EIP = 0x0804809b. instr = 0x000080cd +[5700] the child executed 7 instructions +``` + + +现在,除了 icounter,我们也可以观察到指令指针与它每一步所指向的指令。怎么来判断这个结果对不对呢?使用 objdump -d 处理可执行文件: + +``` +$ objdump -d traced_helloworld + +traced_helloworld: file format elf32-i386 + +Disassembly of section .text: + +08048080 <.text>: + 8048080: ba 0e 00 00 00 mov $0xe,%edx + 8048085: b9 a0 90 04 08 mov $0x80490a0,%ecx + 804808a: bb 01 00 00 00 mov $0x1,%ebx + 804808f: b8 04 00 00 00 mov $0x4,%eax + 8048094: cd 80 int $0x80 + 8048096: b8 01 00 00 00 mov $0x1,%eax + 804809b: cd 80 int $0x80 +``` + + +这个结果和我们跟踪器的结果就很容易比较了。 + + +### 将跟踪器关联到正在运行的进程 + + +如你所知,调试器也能关联到已经运行的进程。现在你应该不会惊讶,ptrace 通过 以PTRACE_ATTACH 为参数调用也可以完成这个过程。这里我不会展示示例代码,通过上文的示例代码应该很容易实现这个过程。出于学习目的,这里使用的方法更简便(因为我们在子进程刚开始就可以让它停止)。 + + +### 代码 + + +上文中的简单的跟踪器(更高级的,可以打印指令的版本)的完整c源代码可以在[这里][20]找到。它是通过 4.4 版本的 gcc 以 -Wall -pedantic --std=c99 编译的。 + + +### 结论与计划 + + +诚然,这篇文章并没有涉及很多内容 - 我们距离亲手完成一个实际的调试器还有很长的路要走。但我希望这篇文章至少可以使得调试这件事少一些神秘感。ptrace 是功能多样的系统调用,我们目前只展示了其中的一小部分。 + + +单步调试代码很有用,但也只是在一定程度上有用。上面我通过c的“Hello World!”做了示例。为了执行主函数,可能需要上万行代码来初始化c的运行环境。这并不是很方便。最理想的是在main函数入口处放置断点并从断点处开始分步执行。为此,在这个系列的下一篇,我打算展示怎么实现断点。 + + + +### 参考 + + +撰写此文时参考了如下文章 + +* [Playing with ptrace, Part I][11] +* [How debugger works][12] + + + +[1] 我没有检查,但我确信 gdb 的代码行数至少有六位数。 + +[2] 使用 man 2 ptrace 命令可以了解更多。 + +[3] Peek and poke 在系统编程中是很知名的叫法,指的是直接读写内存内容。 + +[4] 这篇文章假定读者有一定的 Unix/Linux 编程经验。我假定你知道(至少了解概念)fork,exec 族函数与 Unix 信号。 + +[5] 至少你同我一样痴迷与机器/汇编语言。 + +[6] 警告:如同我上面所说,文章很大程度上是平台相关的。我简化了一些设定 - 例如,x86指令集不需要调整到 4 字节(我的32位 Ubuntu unsigned int 是 4 字节)。事实上,许多平台都不需要。从内存中读取指令需要预先安装完整的反汇编器。我们这里没有,但实际的调试器是有的。 + + +-------------------------------------------------------------------------------- + +via: http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1 + +作者:[Eli Bendersky ][a] +译者:[译者ID](https://github.com/YYforymj) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://eli.thegreenplace.net/ +[1]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id1 +[2]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id2 +[3]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id3 +[4]:http://www.jargon.net/jargonfile/p/peek.html +[5]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id4 +[6]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id5 +[7]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id6 +[8]:http://eli.thegreenplace.net/tag/articles +[9]:http://eli.thegreenplace.net/tag/debuggers +[10]:http://eli.thegreenplace.net/tag/programming +[11]:http://www.linuxjournal.com/article/6100?page=0,1 +[12]:http://www.alexonlinux.com/how-debugger-works +[13]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id7 +[14]:http://en.wikipedia.org/wiki/Small_matter_of_programming +[15]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id8 +[16]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id9 +[17]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id10 +[18]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id11 +[19]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1#id12 +[20]:https://github.com/eliben/code-for-blog/blob/master/2011/simple_tracer.c +[21]:http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1 From 349c6b9fdbd6781ff173d6b952a062d2ee8e1a4e Mon Sep 17 00:00:00 2001 From: ictlyh Date: Sun, 9 Apr 2017 15:36:37 +0800 Subject: [PATCH 08/52] Translated tech/20170210 How to Make Vim Editor as Bash-IDE Using bash-support Plugin in Linux.md --- ...-IDE Using bash-support Plugin in Linux.md | 297 ------------------ ...-IDE Using bash-support Plugin in Linux.md | 296 +++++++++++++++++ 2 files changed, 296 insertions(+), 297 deletions(-) delete mode 100644 sources/tech/20170210 How to Make Vim Editor as Bash-IDE Using bash-support Plugin in Linux.md create mode 100644 translated/tech/20170210 How to Make Vim Editor as Bash-IDE Using bash-support Plugin in Linux.md diff --git a/sources/tech/20170210 How to Make Vim Editor as Bash-IDE Using bash-support Plugin in Linux.md b/sources/tech/20170210 How to Make Vim Editor as Bash-IDE Using bash-support Plugin in Linux.md deleted file mode 100644 index b7ff7cb5bd..0000000000 --- a/sources/tech/20170210 How to Make Vim Editor as Bash-IDE Using bash-support Plugin in Linux.md +++ /dev/null @@ -1,297 +0,0 @@ -ictlyh Translating -How to Make ‘Vim Editor’ as Bash-IDE Using ‘bash-support’ Plugin in Linux -============================================================ - -An IDE ([Integrated Development Environment][1]) is simply a software that offers much needed programming facilities and components in a single program, to maximize programmer productivity. IDEs put forward a single program in which all development can be done, enabling a programmer to write, modify, compile, deploy and debug programs. - -In this article, we will describe how to [install and configure Vim editor][2] as a Bash-IDE using bash-support vim plug-in. - -#### What is bash-support.vim plug-in? - -bash-support is a highly-customizable vim plug-in, which allows you to insert: file headers, complete statements, comments, functions, and code snippets. It also enables you to perform syntax checking, make a script executable, start a debugger simply with a keystroke; do all this without closing the editor. - -It generally makes bash scripting fun and enjoyable through organized and consistent writing/insertion of file content using shortcut keys (mappings). - -The current version plug-in is 4.3, version 4.0 was a rewriting of version 3.12.1; versions 4.0 or better, are based on a comprehensively new and more powerful template system, with changed template syntax unlike previous versions. - -### How To Install Bash-support Plug-in in Linux - -Start by downloading the latest version of bash-support plug-in using the command below: - -``` -$ cd Downloads -$ curl http://www.vim.org/scripts/download_script.php?src_id=24452 >bash-support.zip -``` - -Then install it as follows; create the `.vim` directory in your home folder (in case it doesn’t exist), move into it and extract the contents of bash-support.zip there: - -``` -$ mkdir ~/.vim -$ cd .vim -$ unzip ~/Downloads/bash-support.zip -``` - -Next, activate it from the `.vimrc` file: - -``` -$ vi ~/.vimrc -``` - -By inserting the line below: - -``` -filetype plug-in on -set number #optionally add this to show line numbers in vim -``` - -### How To Use Bash-support plug-in with Vim Editor - -To simplify its usage, the frequently used constructs as well as certain operations can be inserted/performed with key mappings respectively. The mappings are described in ~/.vim/doc/bashsupport.txt and ~/.vim/bash-support/doc/bash-hotkeys.pdf or ~/.vim/bash-support/doc/bash-hotkeys.tex files. - -##### Important: - -1. All mappings (`(\)+charater(s)` combination) are filetype specific: they are only work with ‘sh’ files, in order to avoid conflicts with mappings from other plug-ins. -2. Typing speed matters-when using key mapping, the combination of a leader `('\')` and the following character(s) will only be recognized for a short time (possibly less than 3 seconds – based on assumption). - -Below are certain remarkable features of this plug-in that we will explain and learn how to use: - -#### How To Generate an Automatic Header for New Scripts - -Look at the sample header below, to have this header created automatically in all your new bash scripts, follow the steps below. - -[ - ![Script Sample Header Options](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) -][3] - -Script Sample Header Options - -Start by setting your personal details (author name, author reference, organization, company etc). Use the map `\ntw` inside a Bash buffer (open a test script as the one below) to start the template setup wizard. - -Select option (1) to setup the personalization file, then press [Enter]. - -``` -$ vi test.sh -``` -[ - ![Set Personalizations in Scripts File](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) -][4] - -Set Personalizations in Scripts File - -Afterwards, hit [Enter] again. Then select the option (1) one more time to set the location of the personalization file and hit [Enter]. - -[ - ![Set Personalization File Location](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) -][5] - -Set Personalization File Location - -The wizard will copy the template file .vim/bash-support/rc/personal.templates to .vim/templates/personal.templates and open it for editing, where you can insert your details. - -Press `i` to insert the appropriate values within the single quotes as shown in the screenshot. - -[ - ![Add Info in Script Header](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) -][6] - -Add Info in Script Header - -Once you have set the correct values, type `:wq` to save and exit the file. Close the Bash test script, open another script to check the new configuration. The file header should now have your personal details similar to that in the screen shot below: - -``` -$ test2.sh -``` -[ - ![Auto Adds Header to Script](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) -][7] - -Auto Adds Header to Script - -#### Make Bash-support Plug-in Help Accessible - -To do this, type the command below on the Vim command line and press [Enter], it will create a file .vim/doc/tags: - -``` -:helptags $HOME/.vim/doc/ -``` -[ - ![Add Plugin Help in Vi Editor](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) -][8] - -Add Plugin Help in Vi Editor - -#### How To Insert Comments in Shell Scripts - -To insert a framed comment, type `\cfr` in normal mode: - -[ - ![Add Comments to Scripts](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) -][9] - -Add Comments to Scripts - -#### How To Insert Statements in a Shell Script - -The following are key mappings for inserting statements (`n` – normal mode, `i` – insert mode): - -1. `\sc` – case in … esac (n, I) -2. `\sei` – elif then (n, I) -3. `\sf` – for in do done (n, i, v) -4. `\sfo` – for ((…)) do done (n, i, v) -5. `\si` – if then fi (n, i, v) -6. `\sie` – if then else fi (n, i, v) -7. `\ss` – select in do done (n, i, v) -8. `\su` – until do done (n, i, v) -9. `\sw` – while do done (n, i, v) -10. `\sfu` – function (n, i, v) -11. `\se` – echo -e “…” (n, i, v) -12. `\sp` – printf “…” (n, i, v) -13. `\sa` – array element, ${.[.]} (n, i, v) and many more array features. - -#### Insert a Function and Function Header - -Type `\sfu` to add a new empty function, then add the function name and press [Enter] to create it. Afterwards, add your function code. - -[ - ![Insert New Function in Script](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) -][10] - -Insert New Function in Script - -To create a header for the function above, type `\cfu`, enter name of the function, click [Enter] and fill in the appropriate values (name, description, parameters and returns): - -[ - ![Create Header Function in Script](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) -][11] - -Create Header Function in Script - -#### More Examples of Adding Bash Statements - -Below is an example showing insertion of an if statement using `\si`: - -[ - ![Add Insert Statement to Script](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) -][12] - -Add Insert Statement to Script - -Next example showing addition of an echo statement using `\se`: - -[ - ![Add echo Statement to Script](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) -][13] - -Add echo Statement to Script - -#### How To Use Run Operation in Vi Editor - -The following is a list of some run operations key mappings: - -1. `\rr` – update file, run script (n, I) -2. `\ra` – set script cmd line arguments (n, I) -3. `\rc` – update file, check syntax (n, I) -4. `\rco` – syntax check options (n, I) -5. `\rd` – start debugger (n, I) -6. `\re` – make script executable/not exec.(*) (in) - -#### Make Script Executable - -After writing script, save it and type `\re` to make it executable by pressing [Enter]. - -[ - ![Make Script Executable](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) -][14] - -Make Script Executable - -#### How To Use Predefined Code Snippets To a Bash Script - -Predefined code snippets are files that contain already written code meant for a specific purpose. To add code snippets, type `\nr` and `\nw` to read/write predefined code snippets. Issue the command that follows to list default code snippets: - -``` -$ .vim/bash-support/codesnippets/ -``` -[ - ![List of Code Snippets](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) -][15] - -List of Code Snippets - -To use a code snippet such as free-software-comment, type `\nr` and use auto-completion feature to select its name, and press [Enter]: - -[ - ![Add Code Snippet to Script](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) -][16] - -Add Code Snippet to Script - -#### Create Custom Predefined Code Snippets - -It is possible to write your own code snippets under ~/.vim/bash-support/codesnippets/. Importantly, you can also create your own code snippets from normal script code: - -1. choose the section of code that you want to use as a code snippet, then press `\nw`, and closely give it a filename. -2. to read it, type `\nr` and use the filename to add your custom code snippet. - -#### View Help For the Built-in and Command Under the Cursor - -To display help, in normal mode, type: - -1. `\hh` – for built-in help -2. `\hm` – for a command help - -[ - ![View Built-in Command Help](http://www.tecmint.com/wp-content/uploads/2017/02/View-Built-in-Command-Help.png) -][17] - -View Built-in Command Help - -For more reference, read through the file : - -``` -~/.vim/doc/bashsupport.txt #copy of online documentation -~/.vim/doc/tags -``` - -Visit the Bash-support plug-in Github repository: [https://github.com/WolfgangMehner/bash-support][18] -Visit Bash-support plug-in on the Vim Website: [http://www.vim.org/scripts/script.php?script_id=365][19] - -That’s all for now, in this article, we described the steps of installing and configuring Vim as a Bash-IDE in Linux using bash-support plug-in. Check out the other exciting features of this plug-in, and do share them with us in the comments. - --------------------------------------------------------------------------------- - -作者简介: - -Aaron Kili is a Linux and F.O.S.S enthusiast, an upcoming Linux SysAdmin, web developer, and currently a content creator for TecMint who loves working with computers and strongly believes in sharing knowledge. - --------------------------------------------------------------------------------- - -via: http://www.tecmint.com/use-vim-as-bash-ide-using-bash-support-in-linux/ - -作者:[Aaron Kili][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://www.tecmint.com/author/aaronkili/ - -[1]:http://www.tecmint.com/best-linux-ide-editors-source-code-editors/ -[2]:http://www.tecmint.com/vi-editor-usage/ -[3]:http://www.tecmint.com/wp-content/uploads/2017/02/Script-Header-Options.png -[4]:http://www.tecmint.com/wp-content/uploads/2017/02/Set-Personalization-in-Scripts.png -[5]:http://www.tecmint.com/wp-content/uploads/2017/02/Set-Personalization-File-Location.png -[6]:http://www.tecmint.com/wp-content/uploads/2017/02/Add-Info-in-Script-Header.png -[7]:http://www.tecmint.com/wp-content/uploads/2017/02/Auto-Adds-Header-to-Script.png -[8]:http://www.tecmint.com/wp-content/uploads/2017/02/Add-Plugin-Help-in-Vi-Editor.png -[9]:http://www.tecmint.com/wp-content/uploads/2017/02/Add-Comments-to-Scripts.png -[10]:http://www.tecmint.com/wp-content/uploads/2017/02/Insert-New-Function-in-Script.png -[11]:http://www.tecmint.com/wp-content/uploads/2017/02/Create-Header-Function-in-Script.png -[12]:http://www.tecmint.com/wp-content/uploads/2017/02/Add-Insert-Statement-to-Script.png -[13]:http://www.tecmint.com/wp-content/uploads/2017/02/Add-echo-Statement-to-Script.png -[14]:http://www.tecmint.com/wp-content/uploads/2017/02/make-script-executable.png -[15]:http://www.tecmint.com/wp-content/uploads/2017/02/list-of-code-snippets.png -[16]:http://www.tecmint.com/wp-content/uploads/2017/02/Add-Code-Snippet-to-Script.png -[17]:http://www.tecmint.com/wp-content/uploads/2017/02/View-Built-in-Command-Help.png -[18]:https://github.com/WolfgangMehner/bash-support -[19]:http://www.vim.org/scripts/script.php?script_id=365 diff --git a/translated/tech/20170210 How to Make Vim Editor as Bash-IDE Using bash-support Plugin in Linux.md b/translated/tech/20170210 How to Make Vim Editor as Bash-IDE Using bash-support Plugin in Linux.md new file mode 100644 index 0000000000..05461e5ce8 --- /dev/null +++ b/translated/tech/20170210 How to Make Vim Editor as Bash-IDE Using bash-support Plugin in Linux.md @@ -0,0 +1,296 @@ +在 Linux 如何用 ‘bash-support’ 插件将 Vim 编辑器打造成一个 Bash-IDE +============================================================ + +IDE([集成开发环境][1])就是一个软件,它为了最大化程序员生产效率,提供了很多编程所需的设施和组件。 IDE 将所有开发集中到一个程序中,使得程序员可以编写、修改、编译、部署以及调试程序。 + +在这篇文章中,我们会介绍如何通过使用 bash-support vim 插件将[Vim 编辑器安装和配置][2] 为一个 Bash-IDE。 + +#### 什么是 bash-support.vim 插件? + +bash-support 是一个高度定制化的 vim 插件,它允许你插入:文件头、补全语句、注释、函数、以及代码块。它也使你可以进行语法检查、使脚本可执行、通过一次按键启动调试器;完成所有的这些而不需要关闭编辑器。 + +它使用快捷键(映射),通过有组织、一致的文件内容编写/插入,使得 bash 脚本变得有趣和愉快。 + +插件当前版本是 4.3,版本 4.0 重写了版本 3.12.1,4.0 及之后的版本基于一个全新的、更强大的、和之前版本模板语法不同的模板系统。 + +### 如何在 Linux 中安装 Bash-support 插件 + +用下面的命令下载最新版本的 bash-support 插件: + +``` +$ cd Downloads +$ curl http://www.vim.org/scripts/download_script.php?src_id=24452 >bash-support.zip +``` + +按照如下步骤安装;在你的主目录创建 `.vim` 目录(如果它不存在的话),进入该目录并提取 bash-support.zip 内容: + +``` +$ mkdir ~/.vim +$ cd .vim +$ unzip ~/Downloads/bash-support.zip +``` + +下一步,在 `.vimrc` 文件中激活它: + +``` +$ vi ~/.vimrc +``` + +通过插入下面一行: + +``` +filetype plug-in on +set number #optionally add this to show line numbers in vim +``` + +### 如何在 Vim 编辑器中使用 Bash-support 插件 + +为了简化使用,通常使用的结构和特定操作可以分别通过键映射插入/执行。 ~/.vim/doc/bashsupport.txt 和 ~/.vim/bash-support/doc/bash-hotkeys.pdf 或者 ~/.vim/bash-support/doc/bash-hotkeys.tex 文件中介绍了映射。 + +##### 重要: + +1. 所有映射(`(\)+charater(s)` 组合)都是针对特定文件类型的:为了避免和其它插件的映射冲突,它们只适用于 ‘sh’ 文件。 +2. 使用键映射的时候打字速度也有关系,引导符 `('\')` 和后面字符的组合要在特定短时间内才能识别出来(很可能少于 3 秒 - 基于假设)。 + +下面我们会介绍和学习使用这个插件一些显著的功能: + +#### 如何为新脚本自动生成文件头 + +看下面的事例文件头,为了要在你所有的新脚本中自动创建该文件头,请按照以下步骤操作。 + +[ + ![脚本事例文件头选项](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) +][3] + +脚本事例文件头选项 + +首先设置你的个人信息(作者名称、作者参考、组织、公司等)。在一个 Bash 缓冲区(像下面这样打开一个测试脚本)中使用映射 `\ntw` 启动模板设置向导。 + +选中选项(1)设置个性化文件,然后按回车键。 + +``` +$ vi test.sh +``` +[ + ![在脚本文件中设置个性化信息](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) +][4] + +在脚本文件中设置个性化信息 + +之后,再次输入回车键。然后再一次选中选项(1)设置个性化文件的路径并输入回车。 + +[ + ![设置个性化文件路径](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) +][5] + +设置个性化文件路径 + +设置向导会把目标文件 .vim/bash-support/rc/personal.templates 拷贝到 .vim/templates/personal.templates,打开并编辑它,在这里你可以输入你的信息。 + +按 `i` 键像截图那样在一个单引号中插入合适的值。 + +[ + ![在脚本文件头添加信息](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) +][6] + +在脚本文件头添加信息 + +一旦你设置了正确的值,输入 `:wq` 保存并退出文件。关闭 Bash 测试脚本,打开另一个脚本来测试新的配置。现在文件头中应该有和下面截图类似的你的个人信息: + +``` +$ test2.sh +``` +[ + ![自动添加文件头到脚本](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) +][7] + +自动添加文件头到脚本 + +#### 使 Bash-support 插件帮助信息可访问 + +为此,在 Vim 命令行输入下面的命令并按回车键,它会创建 .vim/doc/tags 文件: + +``` +:helptags $HOME/.vim/doc/ +``` +[ + ![在 Vi 编辑器添加插件帮助](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) +][8] + +在 Vi 编辑器添加插件帮助 + +#### 如何在 Shell 脚本中插入注释 + +要插入一个块注释,在普通模式下输入 `\cfr`: + +[ + ![添加注释到脚本](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) +][9] + +添加注释到脚本 + +#### 如何在 Shell 脚本中插入语句 + +下面是一些用于插入语句的键映射(`n` – 普通模式, `i` – 插入模式): + +1. `\sc` – case in … esac (n, I) +2. `\sei` – elif then (n, I) +3. `\sf` – for in do done (n, i, v) +4. `\sfo` – for ((…)) do done (n, i, v) +5. `\si` – if then fi (n, i, v) +6. `\sie` – if then else fi (n, i, v) +7. `\ss` – select in do done (n, i, v) +8. `\su` – until do done (n, i, v) +9. `\sw` – while do done (n, i, v) +10. `\sfu` – function (n, i, v) +11. `\se` – echo -e “…” (n, i, v) +12. `\sp` – printf “…” (n, i, v) +13. `\sa` – 数组元素, ${.[.]} (n, i, v) 和其它更多的数组功能。 + +#### 插入一个函数和函数头 + +输入 `\sfu` 添加一个新的空函数,然后添加函数名并按回车键创建它。之后,添加你的函数代码。 + +[ + ![在脚本中插入新函数](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) +][10] + +在脚本中插入新函数 + +为了给上面的函数创建函数头,输入 `\cfu`,输入函数名称,按回车键并填入合适的值(名称、介绍、参数、返回值): + +[ + ![在脚本中创建函数头](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) +][11] + +在脚本中创建函数头 + +#### 更多关于添加 Bash 语句的例子 + +下面是一个使用 `\si` 插入一条 if 语句的例子: + +[ + ![在脚本中插入语句](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) +][12] + +在脚本中插入语句 + +下面的例子显示使用 `\se` 添加一条 echo 语句: + +[ + ![在脚本中添加 echo 语句](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) +][13] + +在脚本中添加 echo 语句 + +#### 如何在 Vi 编辑器中使用运行操作 + +下面是一些运行操作键映射的列表: + +1. `\rr` – 更新文件,运行脚本 (n, I) +2. `\ra` – 设置脚本命令行参数 (n, I) +3. `\rc` – 更新文件,检查语法 (n, I) +4. `\rco` – 语法检查选项 (n, I) +5. `\rd` – 启动调试器 (n, I) +6. `\re` – 使脚本可/不可执行(*) (in) + +#### 使脚本可执行 + +编写完脚本后,保存它然后输入 `\re` 和回车键使它可执行。 + +[ + ![使脚本可执行](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) +][14] + +使脚本可执行 + +#### 如何在 Bash 脚本中使用预定义代码片段 + +预定义代码片段是为了特定目的包含了已写好代码的文件。为了添加代码段,输入 `\nr` 和 `\nw` 读/写预定义代码段。输入下面的命令列出默认的代码段: + +``` +$ .vim/bash-support/codesnippets/ +``` +[ + ![代码段列表](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) +][15] + +代码段列表 + +为了使用代码段,例如 free-software-comment,输入 `\nr` 并使用自动补全功能选择它的名称,然后输入回车键: + +[ + ![添加代码段到脚本](http://www.tecmint.com/wp-content/plugins/lazy-load/images/1x1.trans.gif) +][16] + +添加代码段到脚本 + +#### 创建自定义预定义代码段 + +可以在  ~/.vim/bash-support/codesnippets/ 目录下编写你自己的代码段。另外,你还可以从你正常的脚本代码中创建你自己的代码段: + +1. 选择你想作为代码段的部分代码,然后输入  `\nw` 并给它一个相近的文件名。 +2. 要读入它,只需要输入  `\nr` 然后使用文件名就可以添加你自定义的代码段。 + +#### 在当前光标处查看内建和命令帮助 + +要显示帮助,在普通模式下输入: + +1. `\hh` – 内建帮助 +2. `\hm` – 命令帮助 + +[ + ![查看内建命令帮助](http://www.tecmint.com/wp-content/uploads/2017/02/View-Built-in-Command-Help.png) +][17] + +查看内建命令帮助 + +更多参考资料,可以查看文件: + +``` +~/.vim/doc/bashsupport.txt #copy of online documentation +~/.vim/doc/tags +``` + +访问 Bash-support 插件 GitHub 仓库:[https://github.com/WolfgangMehner/bash-support][18] +在 Vim 网站访问 Bash-support 插件:[http://www.vim.org/scripts/script.php?script_id=365][19] + +就是这些啦,在这篇文章中,我们介绍了在 Linux 中使用 Bash-support 插件安装和配置 Vim 为一个 Bash-IDE 的步骤。快去发现这个插件其它令人兴奋的功能吧,一定要在评论中和我们分享哦。 + +-------------------------------------------------------------------------------- + +作者简介: + +Aaron Kili 是一个 Linux 和 F.O.S.S 爱好者、Linux 系统管理员、网络开发人员,现在也是 TecMint 的内容创作者,她喜欢和电脑一起工作,坚信共享知识。 + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/use-vim-as-bash-ide-using-bash-support-in-linux/ + +作者:[Aaron Kili][a] +译者:[ictlyh](https://github.com/ictlyh) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.tecmint.com/author/aaronkili/ + +[1]:http://www.tecmint.com/best-linux-ide-editors-source-code-editors/ +[2]:http://www.tecmint.com/vi-editor-usage/ +[3]:http://www.tecmint.com/wp-content/uploads/2017/02/Script-Header-Options.png +[4]:http://www.tecmint.com/wp-content/uploads/2017/02/Set-Personalization-in-Scripts.png +[5]:http://www.tecmint.com/wp-content/uploads/2017/02/Set-Personalization-File-Location.png +[6]:http://www.tecmint.com/wp-content/uploads/2017/02/Add-Info-in-Script-Header.png +[7]:http://www.tecmint.com/wp-content/uploads/2017/02/Auto-Adds-Header-to-Script.png +[8]:http://www.tecmint.com/wp-content/uploads/2017/02/Add-Plugin-Help-in-Vi-Editor.png +[9]:http://www.tecmint.com/wp-content/uploads/2017/02/Add-Comments-to-Scripts.png +[10]:http://www.tecmint.com/wp-content/uploads/2017/02/Insert-New-Function-in-Script.png +[11]:http://www.tecmint.com/wp-content/uploads/2017/02/Create-Header-Function-in-Script.png +[12]:http://www.tecmint.com/wp-content/uploads/2017/02/Add-Insert-Statement-to-Script.png +[13]:http://www.tecmint.com/wp-content/uploads/2017/02/Add-echo-Statement-to-Script.png +[14]:http://www.tecmint.com/wp-content/uploads/2017/02/make-script-executable.png +[15]:http://www.tecmint.com/wp-content/uploads/2017/02/list-of-code-snippets.png +[16]:http://www.tecmint.com/wp-content/uploads/2017/02/Add-Code-Snippet-to-Script.png +[17]:http://www.tecmint.com/wp-content/uploads/2017/02/View-Built-in-Command-Help.png +[18]:https://github.com/WolfgangMehner/bash-support +[19]:http://www.vim.org/scripts/script.php?script_id=365 From 73a0d0cd0de545e93c5d2cff666158e3aa3ba357 Mon Sep 17 00:00:00 2001 From: ictlyh Date: Sun, 9 Apr 2017 17:18:38 +0800 Subject: [PATCH 09/52] Translating 4 tech blogs --- .../tech/20170201 Building your own personal cloud with Cozy.md | 1 + ... Server Using SSL TLS for Secure File Transfer in CentOS 7.md | 1 + sources/tech/20170321 Writing a Linux Debugger Part 1 Setup.md | 1 + .../tech/20170324 Writing a Linux Debugger Part 2 Breakpoints.md | 1 + 4 files changed, 4 insertions(+) diff --git a/sources/tech/20170201 Building your own personal cloud with Cozy.md b/sources/tech/20170201 Building your own personal cloud with Cozy.md index 0afd5596a7..120ae79647 100644 --- a/sources/tech/20170201 Building your own personal cloud with Cozy.md +++ b/sources/tech/20170201 Building your own personal cloud with Cozy.md @@ -1,3 +1,4 @@ +ictlyh Translating Building your own personal cloud with Cozy ============================================================ diff --git a/sources/tech/20170215 How to Secure a FTP Server Using SSL TLS for Secure File Transfer in CentOS 7.md b/sources/tech/20170215 How to Secure a FTP Server Using SSL TLS for Secure File Transfer in CentOS 7.md index 06d9e51430..ed5736e090 100644 --- a/sources/tech/20170215 How to Secure a FTP Server Using SSL TLS for Secure File Transfer in CentOS 7.md +++ b/sources/tech/20170215 How to Secure a FTP Server Using SSL TLS for Secure File Transfer in CentOS 7.md @@ -1,3 +1,4 @@ +ictlyh Translating How to Secure a FTP Server Using SSL/TLS for Secure File Transfer in CentOS 7 ============================================================ diff --git a/sources/tech/20170321 Writing a Linux Debugger Part 1 Setup.md b/sources/tech/20170321 Writing a Linux Debugger Part 1 Setup.md index b2b08e66ed..d17aa9f3af 100644 --- a/sources/tech/20170321 Writing a Linux Debugger Part 1 Setup.md +++ b/sources/tech/20170321 Writing a Linux Debugger Part 1 Setup.md @@ -1,3 +1,4 @@ +ictlyh Translating Writing a Linux Debugger Part 1: Setup ============================================================ diff --git a/sources/tech/20170324 Writing a Linux Debugger Part 2 Breakpoints.md b/sources/tech/20170324 Writing a Linux Debugger Part 2 Breakpoints.md index 4c8cb966c5..b952dc30fc 100644 --- a/sources/tech/20170324 Writing a Linux Debugger Part 2 Breakpoints.md +++ b/sources/tech/20170324 Writing a Linux Debugger Part 2 Breakpoints.md @@ -1,3 +1,4 @@ +icltyh Translating Writing a Linux Debugger Part 2: Breakpoints ============================================================ From 33972d252213abb4df72c9943e5506a8f71d598c Mon Sep 17 00:00:00 2001 From: wxy Date: Sun, 9 Apr 2017 21:45:17 +0800 Subject: [PATCH 10/52] PRF:20170225 Microsoft Office Online gets better - on Linux too.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @XYenChi 翻译的很好,可见你的英语和中文水平不错,有部分理解我认为有误,有修改,请参看~ 另外,文件应该放到 translated 的对应子目录下~ --- ...ffice Online gets better - on Linux too.md | 102 +++++++++--------- 1 file changed, 50 insertions(+), 52 deletions(-) diff --git a/translated/20170225 Microsoft Office Online gets better - on Linux too.md b/translated/20170225 Microsoft Office Online gets better - on Linux too.md index 7b8834ee02..5293dd5b08 100644 --- a/translated/20170225 Microsoft Office Online gets better - on Linux too.md +++ b/translated/20170225 Microsoft Office Online gets better - on Linux too.md @@ -1,119 +1,117 @@ -XYenChi is translating -# 微软 Office 在线版变得更好 - linux上亦然 +微软 Office 在线版变得更好 - 在 Linux 上亦然 +============= -对于 linux 用户,影响 linux 使用体验的主要因素之一便是缺少微软 office 套装。如果你非得靠office 谋生,而它被绝大多数人使用,你可能不能承受使用开源产品的代价。理解矛盾之所在了吗? +对于 linux 用户,影响 linux 使用体验的主要因素之一便是缺少微软 Office 套装。如果你非得靠 Office 谋生,而它被绝大多数人使用,你可能不能承受使用开源产品的代价。理解矛盾之所在了吗? -的确, LibreOffice 是一个 [很棒的][1] 免费程序,但如果你的客户, 顾客或老板需要 Word 和 Excel 文件呢? 你确定能 [承担任何失误][2] 在转换这些文件从ODT或别的格式到DOCX之类时的错误或小问题 , 反之亦然。这是一系列难办的问题。 不幸的是,在技术在层面上对大多数人linux超出了能力范围。当然,不是绝对 。 +的确, LibreOffice 是一个 [很棒的][1] 自由程序,但如果你的客户、顾客或老板需要 Word 和 Excel 文件呢? 你确定能 [承担任何][2] 将这些文件从 ODT 或别的格式转换到 DOCX 之类时的失误、错误或小问题吗, 反之亦然。这是一系列难办的问题。 不幸的是,在技术在层面上对大多数人而言,Linux 超出了能力范围。当然,这不是绝对。 - ![Teaser](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-teaser.png) +![Teaser](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-teaser.png) -### 加入微软 Office 在线, 加入 Linux +### 加入微软 Office 在线, 加入 Linux -众所周知,微软拥有自己的云 office 服务多年。通过当今任何浏览器都可以使用使得它很棒且具有意义,这意味着 linux 也能使用!我前阵子刚测试了这个[方法][3]并且它表现出色。我能够轻松使用这个产品,以原本的格式保存文件或是转换我 ODF 格式的文件,这真的很棒。 +众所周知,微软拥有自己的 Office 云服务多年。通过任何现代浏览器都可以使用使得它很棒且具有意义,并且这意味着在 Linux 上也能使用!我前阵子刚测试了这个[方法][3]并且它表现出色。我能够轻松使用这个产品,以原本的格式保存文件,或是转换为我的 ODF 格式,这真的很棒。 -我决定再次使用这个套装看看它在过去几年的进步以及是否依旧对 Linux 友好。我使用 [Fedora 25][4](一种操作系统)作为例子。我同时做这些去测试 [SoftMaker Office 2016][5]. 听起来有趣,也确实如此 +我决定再次使用这个套装看看它在过去几年的进步以及是否依旧对 Linux 友好。我使用 [Fedora 25][4] 作为例子。我同时也去测试了 [SoftMaker Office 2016][5]。 听起来有趣,也确实如此。 ### 第一印象 -我得说我很高兴。office 不需要任何特别的插件。没有Silverlight 或 Flash 之类的东西。 单纯而大量的 HTML 和 Javascript 。 同时,交互界面反映及其迅速。唯一我不喜欢的就是 Word 文档的灰色背景,它让人很快感到疲劳。除了这个,整个套装工作流畅,没有延迟、奇怪之处及意料之外的错误。接下来让我们放慢脚步。 +我得说,我感到很高兴。Office 不需要任何特别的插件。没有 Silverlight 或 Flash 之类的东西。 单纯而大量的 HTML 和 Javascript 。 同时,交互界面反应极其迅速。唯一我不喜欢的就是 Word 文档的灰色背景,它让人很快感到疲劳。除了这个,整个套装工作流畅,没有延迟、行为古怪之处及意料之外的错误。接下来让我们放慢脚步。 -这个套装倒是需要你登录在线账户或者手机号——不必是 Live 或 Hotmail 邮箱。任何邮箱都可以。如果你有微软 [手机][6], 那么你可以用相同的账户并且可以同步你的数据。账户也会免费分配 5GB OneDrive 的储存空间。这很有条理,不是优秀或令人超级兴奋而是非常得当 +这个套装需要你用在线账户或者手机号登录——不必是 Live 或 Hotmail 邮箱。任何邮箱都可以。如果你有微软 [手机][6], 那么你可以用相同的账户并且可以同步你的数据。账户也会免费分配 5GB OneDrive 的储存空间。这很有条理,不是优秀或令人超级兴奋而是非常得当。 - ![微软 Office, 欢迎页面](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-welcome-page.jpg) +![微软 Office, 欢迎页面](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-welcome-page.jpg) -你可以使用各种各样的程序, 包括必需的三件套 - Word, Excel 和 Powerpoint, bu并且其他的东西也供使用, 包括一些新奇事物.文档自动保存, 但你也可以下载备份和转换成其他格式,像PDF和ODF。 +你可以使用各种各样的程序,包括必需的三件套 - Word、Excel 和 Powerpoint,并且其它的东西也可使用,包括一些新奇事物。文档会自动保存,但你也可以下载副本并转换成其它格式,比如 PDF 和 ODF。 -对我来说这简直完美。分享一个自己的小故事。我用 LibreOffice 写一本 [新奇的][7]书,之后当我需要将它们送去出版社编辑或者校对,我需要把它们转换成 DOCX 格式。唉,这需要微软 office。从我的 [Linux 问题解决大全][8]得知,我得一开始就使用Word,因为有一堆工作要与授权使用专有解决方案的编辑合作完成。没有任何情面可讲,只有出于对冷酷的金钱和商业的考量。错误是不容许接受的。 +对我来说这简直完美。分享一个自己的小故事。我用 LibreOffice 写一本 [奇幻类的][7]书,之后当我需要将它们送去出版社编辑或者校对,我需要把它们转换成 DOCX 格式。唉,这需要微软 office。从我的 [Linux 问题解决大全][8]得知,我得一开始就使用 Word,因为有一堆工作要与我的编辑合作完成,而他们使用专有软件。没有任何情面可讲,只有出于对冷酷的金钱和商业的考量。错误是不容许接受的。 - ![Word, 新文档](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-word-new.png) +![Word, 新文档](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-word-new.png) -使用 office 在线版在特殊场合能给很多人自由空间。 偶尔使用Word、Excel等,不需要购买整个完整的套装。如果你是 LibreOffice 的忠实粉丝,也可以暗地里将微软 Office 当作消遣而不必感到愧疚。有人传给你一个 Word 或 PPT 文件,你可以上传然后在线操作它们,然后转换成所需要的。这样的话你就可以在线生成你的工作,发送给要求严格的人,同时自己留一个 ODF 格式的备份,有需要的话就用 LibreOffice 操作。虽然这种方法的灵活性很是实用,但这不应该成为你的主要手段。对于 Linux 用户,这给予了很多他们平时所没有的自由,毕竟即使你想用微软 Office 也不好安装。 +使用 Office 在线版能给很多偶尔需要使用的人以自由空间。偶尔使用 Word、Excel 等,不需要购买整个完整的套装。如果你表面上是 LibreOffice 的忠实粉丝,你也可以暗地里“加入微软 Office 负心者俱乐部”而不必感到愧疚。有人传给你一个 Word 或 PPT 文件,你可以上传然后在线操作它们,然后转换成所需要的。这样的话你就可以在线生成你的工作,发送给那些严格要求的人,同时自己留一个 ODF 格式的备份,有需要的话就用 LibreOffice 操作。虽然这种方法的灵活性很是实用,但这不应该成为你的主要手段。对于 Linux 用户,这给予了很多他们平时所没有的自由,毕竟即使你想用微软 Office 也不好安装。 - ![另存为,转换选项](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-save-as.jpg) +![另存为,转换选项](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-save-as.jpg) -### 特性, 选项, 工具 +### 特性、选项、工具 -我开始琢磨一个文档——考虑到这其中各种细枝末节。用一种或三种风格写作,链接文本,嵌入图片,加上脚注,评论自己的文章甚至作为一个多重人格的极客巧妙地回复自己的评论。 +我开始琢磨一个文档——考虑到这其中各种细枝末节。写点文本,用一种或三种风格,链接某些文本,嵌入图片,加上脚注,评论自己的文章甚至作为一个多重人格的极客巧妙地回复自己的评论。 -除了灰色背景——我们得学会很好地完成一项无趣工作,即便是像臭鼬工厂那样的工作方式,因为浏览器里没有选项调整背景颜色——其实也还好。 +除了灰色背景——我们得学会很好地完成一项无趣工作,即便是像臭鼬工厂那样的工作方式,因为浏览器里没有选项调整背景颜色——其实也还好啦。 -Skype 也整合到了其中,你可以沟通合作。色相,非常整洁。鼠标右键可以选择一些快捷操作,包括链接、评论和翻译。改进的地方还有不少,它没有给我想要的,翻译有差错。 +Skype 甚至也整合到了其中,你可以边沟通边协作,或者在协作中倾听。其色调相当一致。鼠标右键可以选择一些快捷操作,包括链接、评论和翻译。不过需要改进的地方还有不少,它并没有给我想要的,翻译有差错。 - ![Skype active](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-skype-active.jpg) +![Skype active](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-skype-active.jpg) - ![右键选项](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-right-click.png) +![右键选项](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-right-click.png) - ![右键选项,更多](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-right-click-more.jpg) +![右键选项,更多](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-right-click-more.jpg) - ![翻译, 不准确](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-translations.png) +![翻译,不准确](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-translations.png) -你也可以加入图片——包括默认嵌入必应搜索筛选图片基于他们的监听和再分配权。这很棒,特别是当你想要创作而又想避免版权纷争时。 +你也可以加入图片——包括默认嵌入的必应搜索可以基于它们的许可证和分发权来筛选图片。这很棒,特别是当你想要创作文档而又想避免版权纷争时。 - ![图片, 在线搜索](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-images.jpg) +![图片,在线搜索](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-images.jpg) -### 更多评论、追踪 +### 关于追踪多说几句 -说老实话,很实用,在线使用使得更改和编辑被默认追踪,所以你就有基本的版本控制功能。不过如果直接关闭不保存的话,阶段性的编辑会遗失。 +说老实话,很实用。这个产品基于在线使用使得默认情况下可以跟踪更改和编辑,所以你就有了基本的版本控制功能。不过如果直接关闭而不保存的话,阶段性的编辑会遗失。 - ![评论](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-comments.jpg) +![评论](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-comments.jpg) - ![编译活动图标](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-edit-activity.png) +![编译活动日志](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-edit-activity.png) -看到一个错误——如果你试着在 Linux 上编辑 Word 或 Excel 文件,会被提示你很调皮,因为这明显是个不支持的操作。 +看到一个错误——如果你试着在 Linux 上(本地)编辑 Word 或 Excel 文件,会被提示你很调皮,因为这明显是个不支持的操作。 - ![编辑错误](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-edit-error.jpg) +![编辑错误](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-edit-error.jpg) -### Excel and friends +### Excel -实际工作流程不止使用 Word。我也使用 Excel,众所周知,它包含了很多整齐有效的模板之类的。好用而且在更新单元格和公式时没有任何延迟,涵盖了你所需要的大多数功能。 +实际工作流程不止使用 Word。我也使用 Excel,众所周知,它包含了很多整齐有效的模板之类的。好用而且在更新单元格和公式时没有任何延迟,它涵盖了你所需要的大多数功能。 - ![Excel, 有趣的模板](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-excel.jpg) + ![Excel,有趣的模板](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-excel.jpg) ![空白电子表格](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-excel-new-spreadsheet.jpg) - ![Excel,预算模板](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-excel-budget.jpg) + ![Excel,预算模板](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-excel-budget.jpg) ### OneDrive -在这里你可以新建文件夹和文件、移动文件、给你的朋友(如果你有的话)和同事们分享文件。5 GB 免费,当然,收费增容。总的来说,做的不错。在更新和展示内容上会花费一定时间。打开了的文档不能被删除,这可能看起来像一个漏洞,但从计算机角度来看是完美的体验。 +在这里你可以新建文件夹和文件、移动文件、给你的朋友(如果你需要的话)和同事们分享文件。5 GB 免费,当然,收费增容。总的来说,做的不错。在更新和展示内容上会花费一定时间。打开了的文档不能被删除,这可能看起来像一个漏洞,但从计算机角度来看是完美的体验。 - ![OneDrive](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-onedrive.jpg) +![OneDrive](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-onedrive.jpg) ### 帮助 -如果你感到疑惑——比如被人工智能戏耍,可以向 Redmond Borg ship 的云智囊团寻求帮助。 虽然这种方式不那么直接,但至少好用,结果往往也能令人满意T。 +如果你感到疑惑——比如被人工智能戏耍,可以向微软的云智囊团寻求帮助。 虽然这种方式不那么直接,但至少好用,结果往往也能令人满意。 - ![能做什么, 交互式的帮助](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-what-to-do.png) +![能做什么, 交互式的帮助](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-what-to-do.png) ### 问题 -在我三个小时的摸索中,我只遇到了两个小问题。一是文件编辑的时候浏览器会有警告(黄色三角),提醒我不安全的因素加载了建议使用 HTTPS 会话。二是创建 Excel 文件失败,只出现过一次。 +在我三个小时的摸索中,我只遇到了两个小问题。一是文件编辑的时候浏览器会有警告(黄色三角),提醒我在 HTTPS 会话中加载了不安全的元素。二是创建 Excel 文件失败,只出现过一次。 - ![文件创建失败](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-error.jpg) +![文件创建失败](http://www.dedoimedo.com/images/computers-years/2017-1/ms-office-online-error.jpg) ### 结论 -微软 Office 在线版是一个优秀的产品,与我两年前测试相比较,它变得更好了。外观出色,表现良好,使用期间错误很少,完美兼容,甚至对于 Linux 用户,使之具有个人意义和商业价值。我不能说它是自 VHS (Video Home System,家用录像系统)最好的,但一定是很棒的,它架起了 Linux 用户与微软 Office 之间的桥梁,解决了 Linux 用户长期以来的问题,方便且很好的支持 ODF 。 +微软 Office 在线版是一个优秀的产品,与我两年前测试相比较,它变得更好了。外观出色,表现良好,使用期间错误很少,完美兼容,甚至对于 Linux 用户,使之具有个人意义和商业价值。我不能说它是自 VHS (Video Home System,家用录像系统)出现以来最好的东西,但一定是很棒的,它架起了 Linux 用户与微软 Office 之间的桥梁,解决了 Linux 用户长期以来的问题,方便且很好的支持 ODF 。 + +现在我们来让事情变得更有趣些,如果你喜欢云概念的事物,那你可能对 [Open365][9] 感兴趣,这是一个基于 LibreOfiice 的办公软件,加上额外的邮件客户端和图像处理软件,还有 20 GB 的免费存储空间。最重要的是,你可以用浏览器同时完成这一切,只需要多开几个窗口。 -现在我们来让事情变得更有趣些,如果你喜欢云概念的事物,那你可能对[Open365][9]感兴趣, 一个基于 LibreOfiice 的办公软件, 加上额外的邮件客户端和图像处理软件,还有 20 GB 的免费存储空间。最重要的是,你可以用浏览器同时完成这一切,只需要多开几个窗口。 回到微软,如果你是 Linux 用户,如今可能确实需要微软 Office 产品。在线 Office 套装无疑是更方便的使用方法——或者至少不需要更改操作系统。它免费、优雅、透明度高。值得一提的是,你可以把思维游戏放在一边,享受你的云端生活。 -干杯 +干杯~ -------------------------------------------------------------------------------- - 作者简介: -我的名字是 Igor Ljubuncic. 38 岁左右, 已婚已育.现在是一家云技术公司的首席工程师,一个新的领域。直到 2015 年初,我作为团队中的一名操作系统工程师就职于世界上最大的信息技术公司之一 。开发新的 Linux 解决方案、完善内核、入侵 linux 进程。在这之前,我是创新设计团队的技术指导,致力于高性能计算环境的创新解决方案。还有一些像系统专家、系统程序员之类的新奇的名字。这些全是我的爱好,直到2008年,变成了工作,还有什么能比这更令人满意呢? -从 2004 到 2008,我作为物理学家在医学影像行业谋生。我专攻解决问题和发展算法,后来大量使用 Matlab 处理信号和图像。另外我认证了很多工程计算方法,包括 MEDIC Six Sigma Green Belt, 实验设计 和数据化工程。 +我的名字是 Igor Ljubuncic. 38 岁左右,已婚未育。现在是一家云技术公司的首席工程师,这是一个新的领域。到 2015 年初之前,我作为团队中的一名系统工程师就职于世界上最大的信息技术公司之一,开发新的 Linux 解决方案、完善内核、研究 linux。在这之前,我是创新设计团队的技术指导,致力于高性能计算环境的创新解决方案。还有一些像系统专家、系统程序员之类的新奇的名字。这些全是我的爱好,直到 2008 年,变成了工作,还有什么能比这更令人满意呢? -我也开始写作,包括 Linux 上新鲜的技术性的工作。彼此包括。 +从 2004 到 2008,我作为物理学家在医学影像行业谋生。我专攻解决问题和发展算法,后来大量使用 Matlab 处理信号和图像。另外我考了很多工程计算方法的认证,包括 MEDIC Six Sigma Green Belt,实验设计和数据化工程。 -请看我完整的开源项目清单、出版物、专利,下拉。 +我也开始写书,包括奇幻类和 Linux 上的技术性工作。彼此交融。 -完整的奖励和提名请看那边。 ------------- @@ -122,7 +120,7 @@ via: http://www.dedoimedo.com/computers/office-online-linux-better.html 作者:[Igor Ljubuncic][a] 译者:[XYenChi](https://github.com/XYenChi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 32b93718bc1c62319619e3a4ed22570528b9a3e7 Mon Sep 17 00:00:00 2001 From: wxy Date: Sun, 9 Apr 2017 22:16:55 +0800 Subject: [PATCH 11/52] PUB:20170225 Microsoft Office Online gets better - on Linux too.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @XYenChi 干的不错! --- ...20170225 Microsoft Office Online gets better - on Linux too.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated => published}/20170225 Microsoft Office Online gets better - on Linux too.md (100%) diff --git a/translated/20170225 Microsoft Office Online gets better - on Linux too.md b/published/20170225 Microsoft Office Online gets better - on Linux too.md similarity index 100% rename from translated/20170225 Microsoft Office Online gets better - on Linux too.md rename to published/20170225 Microsoft Office Online gets better - on Linux too.md From 0fc1177226f62fccfeeea187986050b02ec68b08 Mon Sep 17 00:00:00 2001 From: jasminepeng Date: Sun, 9 Apr 2017 22:39:56 +0800 Subject: [PATCH 12/52] =?UTF-8?q?=E6=A0=A1=E5=AF=B9=E5=AE=8C=E6=AF=95=20@G?= =?UTF-8?q?HLandy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 校对完毕 谢谢 --- ...0324 A formal spec for GitHub Flavored Markdown.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/translated/tech/20170324 A formal spec for GitHub Flavored Markdown.md b/translated/tech/20170324 A formal spec for GitHub Flavored Markdown.md index e7ab53d901..7a9658abf3 100644 --- a/translated/tech/20170324 A formal spec for GitHub Flavored Markdown.md +++ b/translated/tech/20170324 A formal spec for GitHub Flavored Markdown.md @@ -38,7 +38,6 @@ ### 迁移 变更我们用户的内容堆栈以兼容 CommonMark 规范,并不同于转换我们用来解析 Markdown 的库那样容易:目前我们在遇到最根本的障碍就是由于一些不常用语法 (LCTT 译注:原文是 the Corner,作为名词的原意为角落、偏僻处、窘境,这应该是指那些不常用语法),CommonMark 规范 (以及有歧义的 Markdown 原文) 可能会以一种意想不到的方式来渲染一些老旧的 Markdown 内容。 -the fundamental roadblock we encountered here is that the corner cases that CommonMark specifies (and that the original Markdown documentation left ambiguous) could cause some old Markdown content to render in unexpected ways. 通过综合分析 GitHub 中大量的 Markdown 语料库,我们断定现存的用户内容只有不到 1% 会受到新版本实现的影响:我们是通过同时使用新 (`cmark`,兼容 CommonMark 规范) 旧 (Sundown) 版本的库来渲染大量的 Markdown 文档、标准化 HTML 结果、分析它们的不同点,最后才得到这一个数据的。 @@ -56,11 +55,11 @@ the fundamental roadblock we encountered here is that the corner cases that Comm 除了转换之外,这还是一个高效的标准化过程,并且我们对此信心满满,毕竟完成这一任务的是我们在五年前就使用过的解析器。因此,所有的现存文档在保留其原始语意的情况下都能够进行明确的解析。 -一旦升级 Sundown 来标准化输入文档并充分测试之后,我们就会做好开启转换进程的准备。最开始的一步,就是在新的 `cmark` 实现上为所有的用户内容进行反置转换,以便确保我们能有一个有限的分界点来进行过渡。我们将为网站上这几个月内所有 **新的** 用户评论启用 CommonMark,这一过程不会引起任何人注意的 —— 他们这是一个关于 CommonMark 团队出色工作的圣约,通过一个最具现实世界用法的方式来正式规范 Markdown 语言。 +一旦升级 Sundown 来标准化输入文档并充分测试之后,我们就会做好开启转换进程的准备。最开始的一步,就是在新的 `cmark` 实现上为所有新用户内容进行反置转换,以便确保我们能有一个有限的分界点来进行过渡。实际上,几个月前我们就为网站上所有 **新的** 用户评论启用了 CommonMark,这一过程几乎没有引起任何人注意 —— 这是关于 CommonMark 团队出色工作的证明,通过一个最具现实世界用法的方式来正式规范 Markdown 语言。 -在后端,我们开启 MySQL 转换来升级替代用户的 Markdown 内容。在所有的评论进行标准化之后,在将其写回到数据库之前,我们将使用新实现来进行渲染并与旧实现的渲染结果进行对比,以确保 HTML 输出结果视觉可鉴以及用户数据在任何情况下都不被破坏。总而言之,只有不到 1% 的输入文档会受到表彰进程的修改,这符合我们的的期望,同时再次证明 CommonMark 规范能够呈现语言的真实用法。 +在后端,我们开启 MySQL 转换来升级替代所有 Markdown 用户内容。在所有的评论进行标准化之后,在将其写回到数据库之前,我们将使用新实现来进行渲染并与旧实现的渲染结果进行对比,以确保 HTML 输出结果视觉上感觉相同,并且用户数据在任何情况下都不会被破坏。总而言之,只有不到 1% 的输入文档会受到标准进程的修改,这符合我们的的期望,同时再次证明 CommonMark 规范能够呈现语言的真实用法。 -整个过程会持续好几天,最后的结果是网站上所有的 Markdown 用户内容会得到全面升级以符合新的 Markdown 标准,同时确保所有的最终渲染输出效果都对用户视觉可辩。 +整个过程会持续好几天,最后的结果是网站上所有的 Markdown 用户内容会得到全面升级以符合新的 Markdown 标准,同时确保所有的最终渲染输出效果对用户视觉上感觉相同。 #### 结论 @@ -68,11 +67,11 @@ the fundamental roadblock we encountered here is that the corner cases that Comm 能够让在 GitHub 上的所有 Markdown 内容符合一个动态变化且使用的标准,同时还可以为我的用户提供一个关于 GFM 如何进行解析和渲染 [清晰且权威的参考说明][19],我们是相当激动的。 -我们还将致力于 CommonMark 规范,一直到在它正式发布之前消沉最后一个 bug。我们也希望 GitHub.com 在 1.0 规范发布之后可以进行完美兼容。 +我们还将致力于 CommonMark 规范,一直到在它正式发布之前消除最后一个 bug。我们也希望 GitHub.com 在 1.0 规范发布之后可以进行完美兼容。 作为结束,以下为想要学习 CommonMark 规范或则自己来编写实现的朋友提供一些有用的链接。 -* [CommonMark 主页][1],可以了解该项目该多信息 +*   [CommonMark 主页][1],可以了解本项目更多信息 * [CommonMark 论坛讨论区][2],可以提出关于该规范的的问题和更改建议 * [CommonMark 规范][3] * [使用 C 语言编写的参考实现][4] From 74e833c35f7fb67e9fb4b08557c6b9746f0de5f5 Mon Sep 17 00:00:00 2001 From: geekpi Date: Mon, 10 Apr 2017 09:15:38 +0800 Subject: [PATCH 13/52] translating --- sources/tech/20170330 5 open source RSS feed readers.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20170330 5 open source RSS feed readers.md b/sources/tech/20170330 5 open source RSS feed readers.md index e3766c05a8..2c2e87de13 100644 --- a/sources/tech/20170330 5 open source RSS feed readers.md +++ b/sources/tech/20170330 5 open source RSS feed readers.md @@ -1,3 +1,5 @@ +translating---geekpi + 5 open source RSS feed readers ============================================================ From fb7f073e756ae410149fafc7d7c70f7d2c2b9883 Mon Sep 17 00:00:00 2001 From: geekpi Date: Mon, 10 Apr 2017 10:46:11 +0800 Subject: [PATCH 14/52] translated --- ...20170330 5 open source RSS feed readers.md | 104 ------------------ ...20170330 5 open source RSS feed readers.md | 101 +++++++++++++++++ 2 files changed, 101 insertions(+), 104 deletions(-) delete mode 100644 sources/tech/20170330 5 open source RSS feed readers.md create mode 100644 translated/tech/20170330 5 open source RSS feed readers.md diff --git a/sources/tech/20170330 5 open source RSS feed readers.md b/sources/tech/20170330 5 open source RSS feed readers.md deleted file mode 100644 index 2c2e87de13..0000000000 --- a/sources/tech/20170330 5 open source RSS feed readers.md +++ /dev/null @@ -1,104 +0,0 @@ -translating---geekpi - -5 open source RSS feed readers -============================================================ - - ![RSS feed](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/rss_feed.png?itok=FHLEh-fZ "RSS feed") ->Image by : [Rob McDonald][2] on Flickr. Modified by Opensource.com. [CC BY-SA 2.0][3]. - -### Do you use an RSS reader regularly? - -
   
- -When Google Reader was discontinued four years ago, many "technology experts" called it the end of RSS feeds. - -And it's true that for some people, social media and other aggregation tools are filling a need that feed readers for RSS, Atom, and other syndication formats once served. But old technologies never really die just because new technologies come along, particularly if the new technology does not perfectly replicate all of the use cases of the old one. The target audience for a technology might change a bit, and the tools people use to consume the technology might change, too. - -But RSS is no more gone than email, JavaScript, SQL databases, the command line, or any number of other technologies that various people told me more than a decade ago had numbered days. (Is it any wonder that vinyl album sales just hit a [25-year peak][4] last year?) One only has to look at the success of online feed reader site Feedly to understand that there's still definitely a market for RSS readers. - -The truth is, RSS and related feed formats are just more versatile than anything in wide usage that has attempted to replace it. There is no other easy was for me as a consumer to read a wide variety of publications, formatted in a client of my choosing, where I am virtually guaranteed to see every item that is published, while simultaneously not being shown a bunch of articles I have already read. And as a publisher, it's a simple format that most any publishing software I already use will support out of the box, letting me reach more people and easily distribute many types of documents. - -So no, RSS is not dead. Long live RSS! We last looked at [open source RSS reader][5] options in 2013, and it's time for an update. Here are some of my top choices for open source RSS feed readers in 2017, each a little different in its approach. - -### Miniflux - -[Miniflux][6] is an absolutely minimalist web-based RSS reader, but don't confuse its intentionally light approach with laziness on the part of the developers; it is purposefully built to be a simple and efficient design. The philosophy of Miniflux seems to be to keep the application out of the way so that the reader can focus on the content, something many of us can appreciate in a world of bloated web applications. - -But lightweight doesn't mean void of features; its responsive design looks good across any device, and allows for theming, an API interface, multiple languages, bookmark pinning, and more. - -Miniflux's [source code][7] can be found on GitHub under the [GPLv3 Affero][8] license.  If you don't want to set up your own self-hosted version, a paid hosting plan is available for $15/year. - -### RSSOwl - -[RSSOwl][9] is a cross-platform desktop feed reader. Written in Java, it is reminiscent of many popular desktop email clients in style and feel. It features powerful filtering and search capabilities, customizable notifications, and labels and bins for sorting your feeds. If you're used to using Thunderbird or other desktop readers for email, you'll feel right at home in RSSOwl. - -You can find the source code for [RSSOwl][10] on GitHub under the [Eclipse Public License][11]. - -### Tickr - -[Tickr][12] is a slightly different entry in this mix. It's a Linux desktop client, but it's not your traditional browse-and-read format. Instead, it slides your feed's headlines across a bar on your desktop like a news ticker; it's a great choice for news junkies who want to get the latest from a variety of sources. Clicking on a headline will open it in your browser of choice. It's not a dedicated reading client like the rest of the applications on this list, but if you're more interested in skimming headlines than reading every article, it's a good pick. - -Tickr's source code and binaries can be found on the project's [website][13] under a GPL license. - -### Tiny Tiny RSS - -It would be difficult to build a list of modern RSS readers without including [Tiny Tiny RSS][14]. It's among the most popular self-hosted web-based readers, and it's chocked full of features: OPML import and export, keyboard shortcuts, sharing features, a themeable interface, an infrastructure for plug-ins, filtering capabilities, and lots more. - -Tiny Tiny RSS also hosts an official [Android client][15], for those hoping to read on the go. - -Both the [web][16] and [Android][17] source code for Tiny Tiny RSS can be found on GitLab under a [GPLv3 license][18]. - -### Winds - -[Winds][19] is a modern looking self-hosted web feed reader, built on React. It makes use of a hosted machine learning personalization API called Stream, with the intent of helping you find more content that might be of interest to you based on your current interests. An online demo is available so you can [try it out][20] before you download. It's a new project, just a few months old, and so perhaps too soon to evaluate whether it's up to replace my daily feed reader yet, but it's certainly a project I'm watching with interest. - -You can find the [source code][21] for Winds on GitHub under an [MIT][22] license. - -* * * - -These are most definitely not the only options out there. RSS is a relatively easy-to-parse, well-documented format, and so there are many, many different feed readers out there built to suit just about every taste. Here's a [big list][23] of self-hosted open source feed readers you might consider in addition to the ones we listed. We hope you'll share with us what your favorite RSS reader is in the comments below. - --------------------------------------------------------------------------------- - -作者简介: - -Jason Baker - Jason is passionate about using technology to make the world more open, from software development to bringing sunlight to local governments. Linux desktop enthusiast. Map/geospatial nerd. Raspberry Pi tinkerer. Data analysis and visualization geek. Occasional coder. Cloud nativist. Follow him on Twitter. - - --------------- - -via: https://opensource.com/article/17/3/rss-feed-readers - -作者:[ Jason Baker][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://opensource.com/users/jason-baker -[1]:https://opensource.com/article/17/3/rss-feed-readers?rate=2sJrLq0K3QPQCznBId7K1Qrt3QAkwhQ435UyP77B5rs -[2]:https://www.flickr.com/photos/evokeartdesign/6002000807 -[3]:https://creativecommons.org/licenses/by/2.0/ -[4]:https://www.theguardian.com/music/2017/jan/03/record-sales-vinyl-hits-25-year-high-and-outstrips-streaming -[5]:https://opensource.com/life/13/6/open-source-rss -[6]:https://miniflux.net/ -[7]:https://github.com/miniflux/miniflux -[8]:https://github.com/miniflux/miniflux/blob/master/LICENSE -[9]:http://www.rssowl.org/ -[10]:https://github.com/rssowl/RSSOwl -[11]:https://github.com/rssowl/RSSOwl/blob/master/LICENSE -[12]:https://www.open-tickr.net/ -[13]:https://www.open-tickr.net/download.php -[14]:https://tt-rss.org/gitlab/fox/tt-rss/wikis/home -[15]:https://tt-rss.org/gitlab/fox/tt-rss-android -[16]:https://tt-rss.org/gitlab/fox/tt-rss/tree/master -[17]:https://tt-rss.org/gitlab/fox/tt-rss-android/tree/master -[18]:https://tt-rss.org/gitlab/fox/tt-rss-android/blob/master/COPYING -[19]:https://winds.getstream.io/ -[20]:https://winds.getstream.io/app/getting-started -[21]:https://github.com/GetStream/Winds -[22]:https://github.com/GetStream/Winds/blob/master/LICENSE.md -[23]:https://github.com/Kickball/awesome-selfhosted#feed-readers -[24]:https://opensource.com/user/19894/feed -[25]:https://opensource.com/article/17/3/rss-feed-readers#comments -[26]:https://opensource.com/users/jason-baker diff --git a/translated/tech/20170330 5 open source RSS feed readers.md b/translated/tech/20170330 5 open source RSS feed readers.md new file mode 100644 index 0000000000..023b82a780 --- /dev/null +++ b/translated/tech/20170330 5 open source RSS feed readers.md @@ -0,0 +1,101 @@ +5 个开源 RSS 订阅阅读器 +============================================================ + + ![RSS feed](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/rss_feed.png?itok=FHLEh-fZ "RSS feed") +>Image by : [Rob McDonald][2] on Flickr. Modified by Opensource.com. [CC BY-SA 2.0][3]. + +### 你平时使用 RSS 阅读器么? + +
   
+ +四年前当 Google Reader 宣布停止的时候,许多“技术专家”声称 RSS 订阅将会结束。 + +对于某些人而言,社交媒体和其他聚合工具满足了 RSS、Atom 以及其他格式阅读器的需求。但是老技术绝对不会因为新技术而死,特别是如果新技术不能完全覆盖旧技术的所有使用情况。技术的目标受众可能会有所改变,人们使用这个技术的工具也可能会改变。 + +但是,RSS 并不比像 email、JavaScript、SQL 数据库、命令行或者十几年前告诉我的其他技术已经多了多少天。(黑胶专辑的销售额去年刚刚达到了[ 25 年的顶峰][4]奇怪么?)只要看看在线 Feed 阅读器网站 Feedly 的成功,就能了解 RSS 阅读器仍然有市场。 + +事实是,RSS 和相关的 Feed 格式比任何尝试替换它更为广泛地使用。作为一名读者没有其他简单的方法可以以我选择的客户端格式化显示不同的出版物,我实际上看到的是所有发行的内容,而不会显示所有我已经阅读过的内容。作为发行商,这是一种简单的格式,我使用过的大多数发行软件都是开箱即用的,它可以让我被更多的人看到,并且可以简单地分发许多文档格式。 + +所以 RSS 没有死。RSS 长存!我们最后一次是在 2013 年回顾了[开源 RSS 阅读器][5]选择,现在是更新的时候了。这里是 2017 年开源 RSS 订阅阅读器的一些主要选择,每个在使用上都稍微有点不同。 + +### Miniflux + +[Miniflux][6] 是一个绝对简约的基于 Web 的 RSS 阅读器,但不要将其故意的轻设计与开发人员的懒惰混淆。它目的是构建一个简单而有效的设计。Miniflux 的哲学似乎是将程序弱化,其中一些我们可以在臃肿的 web 程序中看到,以便让读者可以专注于内容。 + +但轻便并不意味着功能没用。其响应式设计在任何设备上看起来都很好,并可以使用主题、API 接口、多语言、固定书签等等。 + +Miniflux的 [源代码][7]以 [GPLv3 Affero][8] 许可证在 GitHub 中发布。如果你不想设置托管,则可以支付每年 15 美元的托管计划。 + +### RSSOwl + +[RSSOwl][9]是一个跨平台桌面 Feed 阅读器。它用 Java 编写,在风格和感觉上它像很多流行的桌面邮件客户端。它具有强大的过滤和搜索功能、可定制的通知,以及用于排序 Feed 的标签。 如果你习惯使用 Thunderbird 或其他桌面阅读器进行电子邮件发送,那么在 RSSOwl 中你会感到宾至如归。 + +[RSSOwl][10]的源代码以[ Eclipse Public 许可][11]在 GitHub 中发布。 + +### Tickr + +[Ticker][12] 在这个系列中有点不同。它是一个 Linux 桌面客户端,但它不是传统的浏览-阅读形式。相反,它会将你的 Feed 标题如新闻报导那样在栏目中滚动显示。对于想要从各种来源获得最新消息的新闻界来说,这是一个不错的选择。点击标题将在你选择的浏览器中打开它。它不像这个列表中的其他程序那样是专门的阅读客户端,但是如果比起阅读每篇文章,你对阅读标题更感兴趣,这是一个很好的选择。 + +Ticker 的源代码和二进制文件以 GPL 许可证的形式在这个[网站][13]上可以找到。 + +### Tiny Tiny RSS + +如果不包含 [Tiny Tiny RSS][14],那么将很难列出现代的 RSS 阅读器列表。它是最受欢迎的自主托管的基于 Web 的阅读器,它功能丰富:OPML 导入和导出、键盘快捷键、共享功能、主题界面、插件支持、过滤功能等等。 + +Tiny Tiny RSS 还有官方的 [Android客户端][15],希望能够随时随地阅读。 + +[Tiny Tiny RSS] 的 [web][16] 和 [Android][17] 源代码以 [GPLv3 许可][18] 在 GitLab 上发布。 + +### Winds + +[Winds][19] 是一个建立在 React 之上的现代化的自我托管的 web 订阅阅读器。它利用称为 Stream 的机器学习个性化 API,帮助你根据当前的兴趣找到可能感兴趣的更多内容。这有一个在线显示版本,因此你可以在下载之前先[尝试][20]。这是一个只有几个月的新项目,也许评估它是否能取代我日常的 Feed 阅读器还太早,但这当然是一个我感兴趣关注的项目。 + +Winds 的[源代码][21] 以 [MIT][22] 许可证在 GitHub 上发布。 + +* * * + +这些绝对不是唯一的选择。RSS 是一个相对易于解析、文档格式良好的格式,因此许多许多因为不同的需求而建立的不同 Feed 阅读器。这有一个很长的自我托管开源的 Feed 阅读器[列表][23],你可能会考虑除了我们列出的之外使用它们。我们希望你能在下面的评论栏与我们分享你最喜欢的 RSS 阅读器。 + +-------------------------------------------------------------------------------- + +作者简介: + +Jason Baker - Jason 热衷于使用技术使世界更加开放,从软件开发到阳光政府行动。Linux 桌面爱好者、地图/地理空间爱好者、树莓派工匠、数据分析和可视化极客、偶尔的码农、云本土主义者。在 Twitter 上关注他。 + +-------------- + +via: https://opensource.com/article/17/3/rss-feed-readers + +作者:[ Jason Baker][a] +译者:[geekpi](https://github.com/geekpi) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/jason-baker +[1]:https://opensource.com/article/17/3/rss-feed-readers?rate=2sJrLq0K3QPQCznBId7K1Qrt3QAkwhQ435UyP77B5rs +[2]:https://www.flickr.com/photos/evokeartdesign/6002000807 +[3]:https://creativecommons.org/licenses/by/2.0/ +[4]:https://www.theguardian.com/music/2017/jan/03/record-sales-vinyl-hits-25-year-high-and-outstrips-streaming +[5]:https://opensource.com/life/13/6/open-source-rss +[6]:https://miniflux.net/ +[7]:https://github.com/miniflux/miniflux +[8]:https://github.com/miniflux/miniflux/blob/master/LICENSE +[9]:http://www.rssowl.org/ +[10]:https://github.com/rssowl/RSSOwl +[11]:https://github.com/rssowl/RSSOwl/blob/master/LICENSE +[12]:https://www.open-tickr.net/ +[13]:https://www.open-tickr.net/download.php +[14]:https://tt-rss.org/gitlab/fox/tt-rss/wikis/home +[15]:https://tt-rss.org/gitlab/fox/tt-rss-android +[16]:https://tt-rss.org/gitlab/fox/tt-rss/tree/master +[17]:https://tt-rss.org/gitlab/fox/tt-rss-android/tree/master +[18]:https://tt-rss.org/gitlab/fox/tt-rss-android/blob/master/COPYING +[19]:https://winds.getstream.io/ +[20]:https://winds.getstream.io/app/getting-started +[21]:https://github.com/GetStream/Winds +[22]:https://github.com/GetStream/Winds/blob/master/LICENSE.md +[23]:https://github.com/Kickball/awesome-selfhosted#feed-readers +[24]:https://opensource.com/user/19894/feed +[25]:https://opensource.com/article/17/3/rss-feed-readers#comments +[26]:https://opensource.com/users/jason-baker From 9236d6469a41ca12136edcff777041d242ac4782 Mon Sep 17 00:00:00 2001 From: jasminepeng Date: Mon, 10 Apr 2017 11:17:17 +0800 Subject: [PATCH 15/52] =?UTF-8?q?=E6=A0=A1=E5=AF=B9=E5=AE=8C=E6=AF=95=20@v?= =?UTF-8?q?im-kakali?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 校对完毕 谢谢 --- .../20170316 What is Linux VPS Hosting.md | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/translated/tech/20170316 What is Linux VPS Hosting.md b/translated/tech/20170316 What is Linux VPS Hosting.md index 4b5a97b526..f688317016 100644 --- a/translated/tech/20170316 What is Linux VPS Hosting.md +++ b/translated/tech/20170316 What is Linux VPS Hosting.md @@ -1,57 +1,60 @@ -什么是 Linux VPS Hosting? +什么是 Linux VPS 托管? ============================================================ - ![what is linux vps hosting](https://www.rosehosting.com/blog/wp-content/uploads/2017/03/what-is-linux-vps-hosting.jpg) -如果你有一个吞吐量很大的网站,或者至少,你想要增加你的网站吞吐量,那么你可以考虑使用 [Linux VPS hosting][6] 包 。你可以把它安装在网站所在的服务器上,如果你想要控制除此之外的很多事情,那么 Linux VPS hosting 包就是最好的选择之一。这里我会回答一些频繁被提及的关于 Linux VPS hosting 的问题。 +如果你有一个吞吐量很大的网站,或者至少,预期网站吞吐量很大,那么你可以考虑使用 [Linux VPS hosting][6] 包 。如果你想对网站托管的服务器上安装的东西有更多控制,那么 Linux VPS hosting 包就是最好的选择之一。这里我会回答一些频繁被提及的关于 Linux VPS hosting 的问题。 ### Linux VPS 意味着什么? -事实上, Linux VPS 就像一个运行在 Linux 系统上的虚拟专属服务器 。虚拟专属服务器是一个在物理服务器上的虚拟服务主机 。这种虚拟专属服务器运行在物理主机的内存里。物理主机可以轮流运行很多其他的虚拟专属服务器 。 + +基本上, **Linux VPS 就是一个运行在 Linux 系统上的虚拟专属服务器**。虚拟专属服务器是一个在物理服务器上的虚拟服务主机。运行在物理主机的内存里的服务器就称之为虚拟服务器。物理主机可以轮流运行很多其他的虚拟专属服务器。 ### 我必须和其他用户共享服务器吗? + 一般是这样的。但这并不意味着下载时间变长或者服务器性能降低。每个虚拟服务器可以运行它自己的操作系统,这些系统之间可以相互独立的进行管理。一个虚拟专属服务器有它自己的操作系统、数据、应用程序;它们都与物理主机和其他虚拟服务器中的操作系统、应用程序、数据相互分离。 尽管必须和其他虚拟专属服务器共享物理主机,但是你却可以不需花费大价钱得到一个昂贵专用服务器的诸多好处。 -### Linux VPS hosting 的优势是什么? -使用 Linux VPS hosting 服务会有很多的优势,包括容易使用、安全性增加以及在更低的总体成本上提高可用性。然而,对于大多数网站管理者、程序员、设计者和开发者来说,使用 Linux VPS hosting 服务的最大的优势是它的灵活性。每个虚拟专属务器都和它自己的操作环境相互隔离,这意味着你可以容易且安全的安装一个你喜欢的或者迫切需要的操作系统,每当你想要安装操作系统的时候,你可以很容易的卸载或者安装软件及应用程序。 +### Linux VPS 托管的优势是什么? +使用 Linux VPS 托管服务会有很多的优势,包括容易使用、安全性增加以及在更低的总体成本上提高可靠性。然而,对于大多数网站管理者、程序员、设计者和开发者来说,使用 Linux VPS hosting 服务的最大的优势是它的灵活性。每个虚拟专属服务器都和它自己的操作环境相互隔离,这意味着你可以容易且安全的安装一个你喜欢或者需要的操作系统 — 本例中是 Linux — 任何想要做的时候,你还可以很容易的卸载或者安装软件及应用程序。 你也可以更改你的 VPS 环境以适应你的性能需求,同样也可以提高你的网站用户或访客的体验。灵活性会是你超越对手的主要优势。 -记住,一些 Linux VPS 提供商可能不会给你 root 权限。这样你的服务器性能就会受到限制。要确定你得到的是 [拥有 root 权限的 Linux VPS][7] ,这样你就可以做任何你想做的修改。 +记住,一些 Linux VPS 提供商可能不会给你对你的 Linux VPS 的完全 root 访问权限。这样你的功能就会受到限制。要确定你得到的是 [拥有 root 权限的 Linux VPS][7] ,这样你就可以做任何你想做的修改。 -### 任何人都可以使用 Linux VPS hosting 吗? -当然,你甚至可以运行一个专门的个人兴趣博客,你可以从 Linux VPS hosting 包中受益。如果你为公司搭建开发一个网站,你也会获益匪浅。基本上,如果你想使你的网站更健壮并且增加它的网络吞吐量,那么 Linux VPS 就是为你而生。 +### 任何人都可以使用 Linux VPS 托管吗? +当然,即使你运行一个专门的个人兴趣博客,你也可以从 Linux VPS 托管包中受益。如果你为公司搭建、开发一个网站,你也会获益匪浅。基本上,如果你想使你的网站更健壮并且增加它的网络吞吐量,那么 Linux VPS 就是为你而生。 -个人和企业在进行定制开发的时候都需要很大的灵活行,所以他们肯定会选择 Linux VPS ; 特别是那些正在寻找不使用专用服务器就能得到高性能服务的人们,专用服务器会消耗大量的网站运营成本。 +在定制和开发中需要很大的灵活性的个人和企业,特别是那些正在寻找不使用专用服务器就能得到高性能和服务的人们,绝对应该选择 Linux VPS,因为专用服务器会消耗大量的网站运营成本。 ### 不会使用 Linux 也可以使用 Linux VPS 吗? -当然,如果 Linux VPS 由你管理,你的 VPS 提供商会为你管理整个服务器。更有可能,他们将会为你安装、配置一切你想要运行在 Linux VPS 上的服务。如果你使用我们的 VPS,我们会全天候的为你看管 7 天,也会安装、配置 、优化一切服务。这些免费的服务都被包括在所有的我们的 [Linux VPS hosting 管理器][8] 包里。 -如果你使用我们的主机服务,你会从 Linux VPS 中获益匪浅,并且不需要任何 Linux 工作经验。 +当然,如果 Linux VPS 由你管理,你的 VPS 提供商会为你管理整个服务器。更有可能,他们将会为你安装、配置一切你想要运行在 Linux VPS 上的服务。如果你使用我们的 VPS,我们会 24/7 全天候看护,也会安装、配置、优化一切服务。 -另一个方面,对于使用 Linux VPS 的新手来说,得到一个 [带有控制面板的 VPS][9]、 [DirectAdmin][10] 或者任何 [其他的主机控制面板][11] 都是很容易的。如果你使用控制面板,就可以通过一个 GUI 管理你的服务器,尤其对于新手,它是很容易使用的。[使用命令行管理 Linux VPS][12] 很有趣,而且你还可以在实践中学到很多。 +如果你使用我们的主机服务,你会从 Linux VPS 中获益匪浅,并且不需要任何 Linux 知识。 + +对于新手来说,另一简化 Linux VPS 使用的方式是得到一个带有 [cPanel][9]、[DirectAdmin][10] 或者任何 [其他托管控制面板][11]的 VPS。如果你使用控制面板,就可以通过一个 GUI 管理你的服务器,尤其对于新手,它是很容易使用的。虽然[使用命令行管理 Linux VPS][12] 很有趣,而且那样做可以学到很多。 ### Linux VPS 和专用服务器有什么不同? -如前所述,一个虚拟专属服务器仅仅是在物理主机上的一个虚拟分区。物理服务器与很多虚拟服务器相互分离,这些虚拟服务器可以降低多个虚拟分区用户的网站维护成本和开销。这就是 Linux VPS 相比一个 [专用服务器][13] 更加便宜的原因,专用服务器的字面意思就是指只有一个用户专用。想要知道关于更多不同点的细节,可以查看 [物理服务器(专用的)vs 虚拟服务器(VPS) 比较][14]。 -除了比专用服务器有更好的成本效益,Linux 虚拟专属服务器经常运行在主机上,所以它比专用服务器的性能更强大,同时它的容量也比专用服务器更大。 +如前所述,一个虚拟专属服务器仅仅是在物理主机上的一个虚拟分区。物理服务器被分为多个虚拟服务器,这些虚拟服务器用户可以分担降低成本和开销。这就是 Linux VPS 相比一个 [专用服务器][13] 更加便宜的原因,专用服务器的字面意思就是指只有一个用户专用。想要知道关于更多不同点的细节,可以查看 [物理服务器(专用)与 虚拟服务器(VPS) 比较][14]。 -### 我可以把网站从共享主机环境迁移到到 Linux VPS 上吗? -如果你当前使用 [共享主机服务][15],你可以很容易的迁移到 Linux VPS 上。一种做法就是 [让它自己完成迁移][16],但是迁移过程很复杂,不建议新手使用。最好的方法是找到一个提供 [免费网站迁移][17] 的主机,然后让它们帮你完成迁移。你还可以从一个带有控制面板的共享主机迁移到一个不带有控制面板的 Linux VPS 。 +除了比专用服务器有更好的成本效益,Linux 虚拟专属服务器经常运行在比专用服务器的性能更强大的主机上,因此其性能和容量常常比专用服务器更大。 + +### 我可以把网站从共享托管环境迁移到到 Linux VPS 上吗? + +如果你当前使用 [**共享托管服务**shared hosting][15],你可以很容易的迁移到 Linux VPS 上。一种做法就是 [**您自己做**][16],但是迁移过程有点复杂,不建议新手使用。最好的方法是找到一个提供 [免费网站迁移][17] 的主机,然后让他们帮你完成迁移。你还可以从一个带有控制面板的共享主机迁移到一个不带有控制面板的 Linux VPS 。 ### 更多问题? -随时在下面留下评论。 -如果你使用我们提供的 VPS,我们的 Linux 管理专家会帮助你完成需要在你的 Linux VPS 上的一切工作,并且会回答你的一切关于使用 Linux VPS 的问题。我们的管理员会一周全天候在线及时解决你的问题。 -PS. 如果你喜欢这个专栏,请使用下面的按钮把它分享给你的网友,或者你也可以在下面的评论区写下你的答复。谢谢。 +欢迎随时在下面留下评论。 +PS. 如果你喜欢这个专栏,请把它分享给你的彭友,或者你也可以在下面的评论区写下你的答复。谢谢。 -------------------------------------------------------------------------------- @@ -72,7 +75,6 @@ via: https://www.rosehosting.com/blog/what-is-linux-vps-hosting/ [5]:http://www.linkedin.com/shareArticle?mini=true&url=https://www.rosehosting.com/blog/what-is-linux-vps-hosting/&title=What%20is%20Linux%20VPS%20Hosting%3F&summary=If%20you%20have%20a%20site%20that%20gets%20a%20lot%20of%20traffic,%20or%20at%20least,%20is%20expected%20to%20generate%20a%20lot%20of%20traffic,%20then%20you%20might%20want%20to%20consider%20getting%20a%20Linux%20VPS%20hosting%20package.%20A%20Linux%20VPS%20hosting%20package%20is%20also%20one%20of%20your%20best%20options%20if%20you%20want%20more%20... [6]:https://www.rosehosting.com/linux-vps-hosting.html [7]:https://www.rosehosting.com/linux-vps-hosting.html -[8]:https://www.rosehosting.com/linux-vps-hosting.html [9]:https://www.rosehosting.com/cpanel-hosting.html [10]:https://www.rosehosting.com/directadmin-hosting.html [11]:https://www.rosehosting.com/control-panel-hosting.html From 4cd43fca354a52072fb945f408955f52f2a2514f Mon Sep 17 00:00:00 2001 From: jasminepeng Date: Mon, 10 Apr 2017 11:18:43 +0800 Subject: [PATCH 16/52] =?UTF-8?q?=E6=A0=A1=E5=AF=B9=E5=AE=8C=E6=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 再稍作修改 --- translated/tech/20170316 What is Linux VPS Hosting.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/translated/tech/20170316 What is Linux VPS Hosting.md b/translated/tech/20170316 What is Linux VPS Hosting.md index f688317016..8e7f2259c9 100644 --- a/translated/tech/20170316 What is Linux VPS Hosting.md +++ b/translated/tech/20170316 What is Linux VPS Hosting.md @@ -4,7 +4,7 @@ ![what is linux vps hosting](https://www.rosehosting.com/blog/wp-content/uploads/2017/03/what-is-linux-vps-hosting.jpg) -如果你有一个吞吐量很大的网站,或者至少,预期网站吞吐量很大,那么你可以考虑使用 [Linux VPS hosting][6] 包 。如果你想对网站托管的服务器上安装的东西有更多控制,那么 Linux VPS hosting 包就是最好的选择之一。这里我会回答一些频繁被提及的关于 Linux VPS hosting 的问题。 +如果你有一个吞吐量很大的网站,或者至少,预期网站吞吐量很大,那么你可以考虑使用 [Linux VPS 托管][6] 包 。如果你想对网站托管的服务器上安装的东西有更多控制,那么 Linux VPS 托管包就是最好的选择之一。这里我会回答一些频繁被提及的关于 Linux VPS 托管的问题。 ### Linux VPS 意味着什么? @@ -63,7 +63,7 @@ via: https://www.rosehosting.com/blog/what-is-linux-vps-hosting/ 作者:[https://www.rosehosting.com ][a] 译者:[vim-kakali](https://github.com/vim-kakali) -校对:[校对者ID](https://github.com/校对者ID) +校对:[jasminepeng](https://github.com/jasminepeng) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From c8d54ba07edf5e9bbd51524cb7b7f7921b3e0ecc Mon Sep 17 00:00:00 2001 From: jasminepeng Date: Mon, 10 Apr 2017 14:32:57 +0800 Subject: [PATCH 17/52] =?UTF-8?q?=E6=A0=A1=E5=AF=B9=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 校对中 --- translated/tech/20170330 5 open source RSS feed readers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translated/tech/20170330 5 open source RSS feed readers.md b/translated/tech/20170330 5 open source RSS feed readers.md index 023b82a780..efbce878fa 100644 --- a/translated/tech/20170330 5 open source RSS feed readers.md +++ b/translated/tech/20170330 5 open source RSS feed readers.md @@ -68,7 +68,7 @@ via: https://opensource.com/article/17/3/rss-feed-readers 作者:[ Jason Baker][a] 译者:[geekpi](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[jasminepeng](https://github.com/jasminepeng) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 3f9bbbe2846f6c28a7508f8227d5b7a40c9f580b Mon Sep 17 00:00:00 2001 From: jasminepeng Date: Mon, 10 Apr 2017 16:41:50 +0800 Subject: [PATCH 18/52] =?UTF-8?q?=E6=A0=A1=E5=AF=B9=E5=AE=8C=E6=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 校对完毕 谢谢 --- .../20170330 5 open source RSS feed readers.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/translated/tech/20170330 5 open source RSS feed readers.md b/translated/tech/20170330 5 open source RSS feed readers.md index efbce878fa..03d44ac625 100644 --- a/translated/tech/20170330 5 open source RSS feed readers.md +++ b/translated/tech/20170330 5 open source RSS feed readers.md @@ -12,25 +12,25 @@ 对于某些人而言,社交媒体和其他聚合工具满足了 RSS、Atom 以及其他格式阅读器的需求。但是老技术绝对不会因为新技术而死,特别是如果新技术不能完全覆盖旧技术的所有使用情况。技术的目标受众可能会有所改变,人们使用这个技术的工具也可能会改变。 -但是,RSS 并不比像 email、JavaScript、SQL 数据库、命令行或者十几年前告诉我的其他技术已经多了多少天。(黑胶专辑的销售额去年刚刚达到了[ 25 年的顶峰][4]奇怪么?)只要看看在线 Feed 阅读器网站 Feedly 的成功,就能了解 RSS 阅读器仍然有市场。 +但是,RSS 并不比像 email、JavaScript、SQL 数据库、命令行或者十几年前告诉我的其他时日无多的技术消失的更快。(黑胶专辑的销售额去年刚刚达到了[ 25 年的顶峰][4],这不是个奇迹么?)只要看看在线 Feed 阅读器网站 Feedly 的成功,就能了解 RSS 阅读器仍然有市场。 -事实是,RSS 和相关的 Feed 格式比任何尝试替换它更为广泛地使用。作为一名读者没有其他简单的方法可以以我选择的客户端格式化显示不同的出版物,我实际上看到的是所有发行的内容,而不会显示所有我已经阅读过的内容。作为发行商,这是一种简单的格式,我使用过的大多数发行软件都是开箱即用的,它可以让我被更多的人看到,并且可以简单地分发许多文档格式。 +事实是,RSS 和相关的 Feed 格式比任何广泛使用的尝试替换它的东西还要多才多艺。作为一名读者,没有比它更简单的方法了,我可以阅读大量以我选择的客户端格式化后的发布,确认看到发布的每一条内容,同时不会显示我已经阅读过的文章。作为发行商,这是一种简单的格式,我使用过的大多数发行软件都是开箱即用的,它可以让我被更多的人看到,并且可以简单地分发许多文档格式。 -所以 RSS 没有死。RSS 长存!我们最后一次是在 2013 年回顾了[开源 RSS 阅读器][5]选择,现在是更新的时候了。这里是 2017 年开源 RSS 订阅阅读器的一些主要选择,每个在使用上都稍微有点不同。 +所以 RSS 没有死。RSS 长存!我们最后一次是在 2013 年回顾了[开源 RSS 阅读器][5]选择,现在是更新的时候了。这里是我关于 2017 年开源 RSS 订阅阅读器的一些最佳选择,每个在使用上稍微不同。 ### Miniflux -[Miniflux][6] 是一个绝对简约的基于 Web 的 RSS 阅读器,但不要将其故意的轻设计与开发人员的懒惰混淆。它目的是构建一个简单而有效的设计。Miniflux 的哲学似乎是将程序弱化,其中一些我们可以在臃肿的 web 程序中看到,以便让读者可以专注于内容。 +[Miniflux][6] 是一个绝对简约的基于 Web 的 RSS 阅读器,但不要将其故意的轻设计与开发人员的懒惰混淆。它目的是构建一个简单而有效的设计。Miniflux 的思想似乎是将程序弱化,以便让读者可以专注于内容,在大量臃肿的 web 程序中我们会特别欣赏这一点。 但轻便并不意味着功能没用。其响应式设计在任何设备上看起来都很好,并可以使用主题、API 接口、多语言、固定书签等等。 -Miniflux的 [源代码][7]以 [GPLv3 Affero][8] 许可证在 GitHub 中发布。如果你不想设置托管,则可以支付每年 15 美元的托管计划。 +Miniflux 的 [源代码][7]以 [GPLv3 Affero][8] 许可证在 GitHub 中发布。如果你不想设置托管,则可以支付每年 15 美元的托管计划。 ### RSSOwl [RSSOwl][9]是一个跨平台桌面 Feed 阅读器。它用 Java 编写,在风格和感觉上它像很多流行的桌面邮件客户端。它具有强大的过滤和搜索功能、可定制的通知,以及用于排序 Feed 的标签。 如果你习惯使用 Thunderbird 或其他桌面阅读器进行电子邮件发送,那么在 RSSOwl 中你会感到宾至如归。 -[RSSOwl][10]的源代码以[ Eclipse Public 许可][11]在 GitHub 中发布。 +可以在 GitHub 中找到 [ Eclipse Public 许可][11]下的 [RSSOwl][10] 的源代码。 ### Tickr @@ -48,19 +48,19 @@ Tiny Tiny RSS 还有官方的 [Android客户端][15],希望能够随时随地 ### Winds -[Winds][19] 是一个建立在 React 之上的现代化的自我托管的 web 订阅阅读器。它利用称为 Stream 的机器学习个性化 API,帮助你根据当前的兴趣找到可能感兴趣的更多内容。这有一个在线显示版本,因此你可以在下载之前先[尝试][20]。这是一个只有几个月的新项目,也许评估它是否能取代我日常的 Feed 阅读器还太早,但这当然是一个我感兴趣关注的项目。 +[Winds][19] 是一个建立在 React 之上的看起来很现代的自我托管的 web 订阅阅读器。它利用称为 Stream 的机器学习个性化 API,帮助你根据当前的兴趣找到可能感兴趣的更多内容。这有一个在线显示版本,因此你可以在下载之前先[尝试][20]。这是一个只有几个月的新项目,也许评估它是否能取代我日常的 Feed 阅读器还太早,但这当然是一个我感兴趣关注的项目。 Winds 的[源代码][21] 以 [MIT][22] 许可证在 GitHub 上发布。 * * * -这些绝对不是唯一的选择。RSS 是一个相对易于解析、文档格式良好的格式,因此许多许多因为不同的需求而建立的不同 Feed 阅读器。这有一个很长的自我托管开源的 Feed 阅读器[列表][23],你可能会考虑除了我们列出的之外使用它们。我们希望你能在下面的评论栏与我们分享你最喜欢的 RSS 阅读器。 +这些当然不是仅有的选择。RSS 是一个相对易于解析、文档格式良好的格式,因此有许多许多因为不同的需求而建立的不同 Feed 阅读器。这有一个很长的自我托管开源的 Feed 阅读器[列表][23],除了我们列出的之外你还可能会考虑使用它们。我们希望你能在下面的评论栏与我们分享你最喜欢的 RSS 阅读器。 -------------------------------------------------------------------------------- 作者简介: -Jason Baker - Jason 热衷于使用技术使世界更加开放,从软件开发到阳光政府行动。Linux 桌面爱好者、地图/地理空间爱好者、树莓派工匠、数据分析和可视化极客、偶尔的码农、云本土主义者。在 Twitter 上关注他。 +Jason Baker - Jason 热衷于使用技术使世界更加开放,从软件开发到阳光政府行动。Linux 桌面爱好者、地图/地理空间爱好者、树莓派工匠、数据分析和可视化极客、偶尔的码农、云本土主义者。在 Twitter 上关注他 @jehb。 -------------- From 6772de282205291c4f32ad6a924048407259a243 Mon Sep 17 00:00:00 2001 From: jasminepeng Date: Mon, 10 Apr 2017 16:44:11 +0800 Subject: [PATCH 19/52] =?UTF-8?q?=E6=A0=A1=E5=AF=B9=E5=AE=8C=E6=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 校对完毕 --- translated/tech/20170330 5 open source RSS feed readers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translated/tech/20170330 5 open source RSS feed readers.md b/translated/tech/20170330 5 open source RSS feed readers.md index 03d44ac625..e6909330ec 100644 --- a/translated/tech/20170330 5 open source RSS feed readers.md +++ b/translated/tech/20170330 5 open source RSS feed readers.md @@ -44,7 +44,7 @@ Ticker 的源代码和二进制文件以 GPL 许可证的形式在这个[网站] Tiny Tiny RSS 还有官方的 [Android客户端][15],希望能够随时随地阅读。 -[Tiny Tiny RSS] 的 [web][16] 和 [Android][17] 源代码以 [GPLv3 许可][18] 在 GitLab 上发布。 +Tiny Tiny RSS 的 [web][16] 和 [Android][17] 源代码以 [GPLv3 许可][18] 在 GitLab 上发布。 ### Winds From c9cb11f60f8d608161a96dd5bb710fb6e8b7a301 Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 10 Apr 2017 17:20:06 +0800 Subject: [PATCH 20/52] PUB:20161216 The truth about traditional JavaScript benchmarks.md @geekpi @jasminepeng --- ...20170330 5 open source RSS feed readers.md | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) rename {translated/tech => published}/20170330 5 open source RSS feed readers.md (65%) diff --git a/translated/tech/20170330 5 open source RSS feed readers.md b/published/20170330 5 open source RSS feed readers.md similarity index 65% rename from translated/tech/20170330 5 open source RSS feed readers.md rename to published/20170330 5 open source RSS feed readers.md index e6909330ec..ad00a84ed8 100644 --- a/translated/tech/20170330 5 open source RSS feed readers.md +++ b/published/20170330 5 open source RSS feed readers.md @@ -10,51 +10,51 @@ 四年前当 Google Reader 宣布停止的时候,许多“技术专家”声称 RSS 订阅将会结束。 -对于某些人而言,社交媒体和其他聚合工具满足了 RSS、Atom 以及其他格式阅读器的需求。但是老技术绝对不会因为新技术而死,特别是如果新技术不能完全覆盖旧技术的所有使用情况。技术的目标受众可能会有所改变,人们使用这个技术的工具也可能会改变。 +对于某些人而言,社交媒体和其他聚合工具满足了 RSS、Atom 以及其它格式的阅读器的需求。但是老技术绝对不会因为新技术而死,特别是如果新技术不能完全覆盖旧技术的所有使用情况时。技术的目标受众可能会有所改变,人们使用这个技术的工具也可能会改变。 -但是,RSS 并不比像 email、JavaScript、SQL 数据库、命令行或者十几年前告诉我的其他时日无多的技术消失的更快。(黑胶专辑的销售额去年刚刚达到了[ 25 年的顶峰][4],这不是个奇迹么?)只要看看在线 Feed 阅读器网站 Feedly 的成功,就能了解 RSS 阅读器仍然有市场。 +但是,RSS 并不比像 email、JavaScript、SQL 数据库、命令行或者十几年前告诉我的其它时日无多的技术消失的更快。(黑胶专辑的销售额去年刚刚达到了其 [25 年的顶峰][4],这不是个奇迹么?)只要看看在线 Feed 阅读器网站 Feedly 的成功,就能了解 RSS 阅读器仍然有市场。 -事实是,RSS 和相关的 Feed 格式比任何广泛使用的尝试替换它的东西还要多才多艺。作为一名读者,没有比它更简单的方法了,我可以阅读大量以我选择的客户端格式化后的发布,确认看到发布的每一条内容,同时不会显示我已经阅读过的文章。作为发行商,这是一种简单的格式,我使用过的大多数发行软件都是开箱即用的,它可以让我被更多的人看到,并且可以简单地分发许多文档格式。 +事实是,RSS 和相关的 Feed 格式比任何广泛使用的尝试替换它的东西还要多才多艺。作为一名阅读消费者,对于我来说没有比它更简单的方法了,我可以阅读大量的出版信息,并且是用我选择的客户端格式化的,我可以确认看到发布的每一条内容,同时不会显示我已经阅读过的文章。而作为发布者,这是一种比我使用过的大多数发布软件都简单的格式,开箱即用,它可以让我的信息递交给更多的人,并且可以很容易地分发多种不同类型的文档格式。 所以 RSS 没有死。RSS 长存!我们最后一次是在 2013 年回顾了[开源 RSS 阅读器][5]选择,现在是更新的时候了。这里是我关于 2017 年开源 RSS 订阅阅读器的一些最佳选择,每个在使用上稍微不同。 ### Miniflux -[Miniflux][6] 是一个绝对简约的基于 Web 的 RSS 阅读器,但不要将其故意的轻设计与开发人员的懒惰混淆。它目的是构建一个简单而有效的设计。Miniflux 的思想似乎是将程序弱化,以便让读者可以专注于内容,在大量臃肿的 web 程序中我们会特别欣赏这一点。 +[Miniflux][6] 是一个极度简约的基于 Web 的 RSS 阅读器,但不要将其特意的轻设计与开发人员的懒惰混淆。它目的是构建一个简单而有效的设计。Miniflux 的思想似乎是将程序弱化,以便让读者可以专注于内容,在大量臃肿的 web 程序中我们会特别欣赏这一点。 -但轻便并不意味着功能没用。其响应式设计在任何设备上看起来都很好,并可以使用主题、API 接口、多语言、固定书签等等。 +但轻便并不意味着缺乏功能。其响应式设计在任何设备上看起来都很好,并可以使用主题、API 接口、多语言、固定书签等等。 -Miniflux 的 [源代码][7]以 [GPLv3 Affero][8] 许可证在 GitHub 中发布。如果你不想设置托管,则可以支付每年 15 美元的托管计划。 +Miniflux 的 [源代码][7]以 [GPLv3 Affero][8] 许可证在 GitHub 中发布。如果你不想自行托管,则可以支付每年 15 美元的托管计划。 ### RSSOwl -[RSSOwl][9]是一个跨平台桌面 Feed 阅读器。它用 Java 编写,在风格和感觉上它像很多流行的桌面邮件客户端。它具有强大的过滤和搜索功能、可定制的通知,以及用于排序 Feed 的标签。 如果你习惯使用 Thunderbird 或其他桌面阅读器进行电子邮件发送,那么在 RSSOwl 中你会感到宾至如归。 +[RSSOwl][9] 是一个跨平台的桌面 Feed 阅读器。它用 Java 编写,在风格和感觉上它像很多流行的桌面邮件客户端。它具有强大的过滤和搜索功能、可定制的通知,以及用于排序 Feed 的标签。 如果你习惯使用 Thunderbird 或其他桌面阅读器进行电子邮件发送,那么在 RSSOwl 中你会感到宾至如归。 -可以在 GitHub 中找到 [ Eclipse Public 许可][11]下的 [RSSOwl][10] 的源代码。 +可以在 GitHub 中找到 [Eclipse Public 许可证][11]下发布的 [RSSOwl][10] 的源代码。 ### Tickr -[Ticker][12] 在这个系列中有点不同。它是一个 Linux 桌面客户端,但它不是传统的浏览-阅读形式。相反,它会将你的 Feed 标题如新闻报导那样在栏目中滚动显示。对于想要从各种来源获得最新消息的新闻界来说,这是一个不错的选择。点击标题将在你选择的浏览器中打开它。它不像这个列表中的其他程序那样是专门的阅读客户端,但是如果比起阅读每篇文章,你对阅读标题更感兴趣,这是一个很好的选择。 +[Tickr][12] 在这个系列中有点不同。它是一个 Linux 桌面客户端,但它不是传统的浏览-阅读形式。相反,它会将你的 Feed 标题如滚动新闻那样在桌面横栏上滚动显示。对于想要从各种来源获得最新消息的新闻界来说,这是一个不错的选择。点击标题将在你选择的浏览器中打开它。它不像这个列表中的其他程序那样是专门的阅读客户端,但是如果比起阅读每篇文章,你对阅读标题更感兴趣,这是一个很好的选择。 -Ticker 的源代码和二进制文件以 GPL 许可证的形式在这个[网站][13]上可以找到。 +Tickr 的源代码和二进制文件以 GPL 许可证的形式在这个[网站][13]上可以找到。 ### Tiny Tiny RSS -如果不包含 [Tiny Tiny RSS][14],那么将很难列出现代的 RSS 阅读器列表。它是最受欢迎的自主托管的基于 Web 的阅读器,它功能丰富:OPML 导入和导出、键盘快捷键、共享功能、主题界面、插件支持、过滤功能等等。 +如果缺少了 [Tiny Tiny RSS][14],那么很难称之为这是一个现代化的 RSS 阅读器列表。它是最受欢迎的自主托管的基于 Web 的阅读器,它功能丰富:支持OPML 导入和导出、键盘快捷键、共享功能、主题界面、插件支持、过滤功能等等。 -Tiny Tiny RSS 还有官方的 [Android客户端][15],希望能够随时随地阅读。 +Tiny Tiny RSS 还有官方的 [Android客户端][15],让你可以随时随地阅读。 -Tiny Tiny RSS 的 [web][16] 和 [Android][17] 源代码以 [GPLv3 许可][18] 在 GitLab 上发布。 +Tiny Tiny RSS 的 [Web][16] 版本和 [Android][17] 源代码以 [GPLv3 许可][18] 在 GitLab 上发布。 ### Winds -[Winds][19] 是一个建立在 React 之上的看起来很现代的自我托管的 web 订阅阅读器。它利用称为 Stream 的机器学习个性化 API,帮助你根据当前的兴趣找到可能感兴趣的更多内容。这有一个在线显示版本,因此你可以在下载之前先[尝试][20]。这是一个只有几个月的新项目,也许评估它是否能取代我日常的 Feed 阅读器还太早,但这当然是一个我感兴趣关注的项目。 +[Winds][19] 是一个建立在 React 之上的看起来很现代化的自托管的 web 订阅阅读器。它利用称为 Stream 的机器学习个性化 API,帮助你根据当前的兴趣找到可能感兴趣的更多内容。这有一个在线显示版本,因此你可以在下载之前先[尝试][20]。这是一个只有几个月的新项目,也许评估它是否能取代我日常的 Feed 阅读器还太早,但这当然是一个我感兴趣关注的项目。 Winds 的[源代码][21] 以 [MIT][22] 许可证在 GitHub 上发布。 * * * -这些当然不是仅有的选择。RSS 是一个相对易于解析、文档格式良好的格式,因此有许多许多因为不同的需求而建立的不同 Feed 阅读器。这有一个很长的自我托管开源的 Feed 阅读器[列表][23],除了我们列出的之外你还可能会考虑使用它们。我们希望你能在下面的评论栏与我们分享你最喜欢的 RSS 阅读器。 +这些当然不是仅有的选择。RSS 是一个相对易于解析、文档格式良好的格式,因此有许许多多因为不同的需求而建立的各种 Feed 阅读器。这有一个很长的自托管的开源 Feed 阅读器[列表][23],除了我们列出的之外你还可能会考虑使用它们。我们希望你能在下面的评论栏与我们分享你最喜欢的 RSS 阅读器。 -------------------------------------------------------------------------------- @@ -66,7 +66,7 @@ Jason Baker - Jason 热衷于使用技术使世界更加开放,从软件开发 via: https://opensource.com/article/17/3/rss-feed-readers -作者:[ Jason Baker][a] +作者:[Jason Baker][a] 译者:[geekpi](https://github.com/geekpi) 校对:[jasminepeng](https://github.com/jasminepeng) From 2218b9a3d413ea8cdb72318d73de6539121f8151 Mon Sep 17 00:00:00 2001 From: ictlyh Date: Mon, 10 Apr 2017 17:51:01 +0800 Subject: [PATCH 21/52] Translated tech/20170201 Building your own personal cloud with Cozy.md --- ...lding your own personal cloud with Cozy.md | 98 ------------------- ...lding your own personal cloud with Cozy.md | 97 ++++++++++++++++++ 2 files changed, 97 insertions(+), 98 deletions(-) delete mode 100644 sources/tech/20170201 Building your own personal cloud with Cozy.md create mode 100644 translated/tech/20170201 Building your own personal cloud with Cozy.md diff --git a/sources/tech/20170201 Building your own personal cloud with Cozy.md b/sources/tech/20170201 Building your own personal cloud with Cozy.md deleted file mode 100644 index 120ae79647..0000000000 --- a/sources/tech/20170201 Building your own personal cloud with Cozy.md +++ /dev/null @@ -1,98 +0,0 @@ -ictlyh Translating -Building your own personal cloud with Cozy -============================================================ - - ![Building your own personal cloud with Cozy](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/life_tree_clouds.png?itok=dSV0oTDS "Building your own personal cloud with Cozy") ->Image by : [Pixabay][2]. Modified by Opensource.com. [CC BY-SA 4.0][3] - -Most everyone I know uses some sort of web-based application for their calendar, emails, file storage, and much more. But what if, like me, you've got concerns about privacy, or just want to simplify your digital life into a place you control? [Cozy][4] is a project that is moving in the right direction—toward a robust self-hosted cloud platform. Cozy's source code is available on [GitHub][5], and it is licensed under the AGPL 3.0 license. - -### Installation - -Installing Cozy is snap-easy, with [easy-to-follow instructions][6] for a variety of platforms. For my testing, I'm using Debian 8, 64-bit. The installation takes a few minutes, but then you just go to the server's IP, register an account, and a default set of applications is loaded up and ready to roll. - -One note on this—the installation assumes no other web server is running, and it will want to install [Nginx web server][7]. If your server already has websites running, configuration may be a bit more challenging. My install was on a brand new Virtual Private Server (VPS), so this was a snap. Run the installer, start Nginx, and you're ready to hit the cloud. - -Cozy has [an App Store][8] where you can download additional applications. Some look pretty interesting, like the [Ghost blogging platform][9] and [TiddlyWiki][10] open source wiki. The intent here, clearly, is to allow integration in the platform with lots of other goodies. I think it's just a matter of time before you'll see this start to take off, with many other popular open source applications offering integration abilities. Right now, [Node.js][11] applications are supported, but if other application layers were possible, you'd see that many other good things could happen. - -One capability that is possible is using the free Android application to access your information from Android devices. No iOS app exists, but there is a plan to solve that problem. - -Currently, Cozy comes with a nice set of core applications. - - ![Main Cozy Interface](https://opensource.com/sites/default/files/main_cozy_interface.jpg "Main Cozy Interface") - -Main Cozy interface - -### Files - -Like a lot of folks, I use [Dropbox][12] for file storage. In fact, I pay for Dropbox Pro because I use _so much_ storage. For me, then, moving my files to Cozy would be a money-saver—if it has the features I want. - -I wish I could say it does, truly I do. I was very impressed with the web-based file upload and file-management tool built into the Cozy web application. Drag-and-drop works like you'd expect, and the interface is clean and uncluttered. I had no trouble at all uploading some sample files and folders, navigating around, and moving, deleting, and renaming files. - -If what you want is a web-based cloud file storage, you're set. What's missing, for me, is the selective synchronization of files and folders, which Dropbox has. With Dropbox, if you drop a file in a folder, it's copied out to the cloud and made available to all your synced devices in a matter of minutes. To be fair, [Cozy is working on it][13], but it's in beta and only for Linux clients at the moment. Also, I have a [Chrome][14] extension called [Download to Dropbox][15] that I use to capture images and other content from time to time, and no such tool exists yet for Cozy. - - ![File Manager Interface](https://opensource.com/sites/default/files/cozy_2.jpg "File Manager Interface") - -File Manager interface - -### Importing data from Google - -If you currently use Google Calendar or Contacts, importing these is very easy with the app installed in Cozy. When you authorize access to Google, you're given an API key, which you paste in Cozy, and it performs the copy quickly and efficiently. In both cases, the contents were tagged as having been imported from Google. Given the clutter in my contacts, this is probably a good thing, as it gives you the opportunity to tidy up as you relabel them into more meaningful categories. Calendar events imported all on the "Google Calendar," but I noticed that _some_ of my events had the times incorrect, possibly an artifact of time zone settings on one end or the other. - -### Contacts   - -Contacts works like you'd expect, and the interface looks a _lot_ like Google Contacts. There are a few sticky areas, though. Synchronization with (for instance) your smart phone happens via [CardDAV][16], a standard protocol for sharing contacts data—and a technology that Android phones _do not speak natively_. To sync your contacts to an Android device, you're going to have to load an app on your phone for that. For me, that's a _huge_ strike against it, as I have enough odd apps like that already (work mail versus Gmail versus other mail, oh my!), and I do not want to install another that won't sync up with my smartphone's native contacts application. If you're using an iPhone, you can do CardDAV right out of the box. - -### Calendar   - -The good news for Calendar users is that an Android device _can_ speak [CalDAV][17], the interchange format for this type of data. As I noted with the import app, some of my calendar items came over with the wrong times. I've seen this before with other calendar system moves, so that really didn't bother me much. The interface lets you create and manage multiple calendars, just like with Google, but you can't subscribe to other calendars outside of this Cozy instance. One other quirk is of the app is starting of the week on Monday, which you can't change. Normally, I start my week on Sunday, so changing from Monday would be a useful feature for me. The Settings dialog didn't actually have any settings; it merely gave instructions on how to connect via CalDAV. Again, this application is close to what I need, but Cozy is not quite there. - -### Photos - -The Photos app is pretty impressive, borrowing a lot from the Files application. You can even add photos to an album that are in files in the other app, or upload directly with drag and drop. Unfortunately, I don't see any way to reorder or edit pictures once you've uploaded them. You can only delete them from the album. The app does have a tool for sharing via a token link, and you can specify one or more contact. The system will send those contacts an email inviting them to view the album. There are more feature-rich album applications than this, to be sure, but this is a good start for the Cozy platform. - - ![Photos Interface](https://opensource.com/sites/default/files/cozy_3_0.jpg "Photos Interface") - -Photos interface - -### Final thoughts - -Cozy has some really big goals. They're trying to build a platform where you can deploy _any_ cloud-based service you like. Is it ready for prime time? Not quite. Some of the shortcomings I've mentioned are problematic for power users, and there is no iOS application yet, which may hamper adoption for those users. However, keep an eye on this one—Cozy has the potential, as development continues, to become a one-stop replacement for a great many applications. - --------------------------------------------------------------------------------- - -译者简介: - -D Ruth Bavousett - D Ruth Bavousett has been a system administrator and software developer for a long, long time, getting her professional start on a VAX 11/780, way back when. She spent a lot of her career (so far) serving the technology needs of libraries, and has been a contributor since 2008 to the Koha open source library automation suite.Ruth is currently a Perl Developer at cPanel in Houston, and also serves as chief of staff for two cats. - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/17/2/cozy-personal-cloud - -作者:[D Ruth Bavousett][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://opensource.com/users/druthb -[1]:https://opensource.com/article/17/2/cozy-personal-cloud?rate=FEMc3av4LgYK-jeEscdiqPhSgHZkYNsNCINhOoVR9N8 -[2]:https://pixabay.com/en/tree-field-cornfield-nature-247122/ -[3]:https://creativecommons.org/licenses/by-sa/4.0/ -[4]:https://cozy.io/ -[5]:https://github.com/cozy/cozy -[6]:https://docs.cozy.io/en/host/install/ -[7]:https://www.nginx.com/ -[8]:https://cozy.io/en/apps/ -[9]:https://ghost.org/ -[10]:http://tiddlywiki.com/ -[11]:http://nodejs.org/ -[12]:https://www.dropbox.com/ -[13]:https://github.com/cozy-labs/cozy-desktop -[14]:https://www.google.com/chrome/ -[15]:https://github.com/pwnall/dropship-chrome -[16]:https://en.wikipedia.org/wiki/CardDAV -[17]:https://en.wikipedia.org/wiki/CalDAV -[18]:https://opensource.com/user/36051/feed -[19]:https://opensource.com/article/17/2/cozy-personal-cloud#comments -[20]:https://opensource.com/users/druthb diff --git a/translated/tech/20170201 Building your own personal cloud with Cozy.md b/translated/tech/20170201 Building your own personal cloud with Cozy.md new file mode 100644 index 0000000000..9be9d839fe --- /dev/null +++ b/translated/tech/20170201 Building your own personal cloud with Cozy.md @@ -0,0 +1,97 @@ +使用 Cozy 搭建个人云 +============================================================ + + ![使用 Cozy 搭建个人云](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/life_tree_clouds.png?itok=dSV0oTDS "Building your own personal cloud with Cozy") +>Image by : [Pixabay][2]. Modified by Opensource.com. [CC BY-SA 4.0][3] + +我认识的大部分人为了他们的日历、电子邮件、文件存储等,都会使用一些基于 Web 的应用。但是,如果像我这样,对隐私感到担忧、或者只是希望将你自己的数字生活简单化为一个你所控制的地方呢? [Cozy][4] 就是一个朝着健壮的自主云平台方向发展的项目。你可以从 [GitHub][5] 上获取 Cozy 的源代码,它采用 AGPL 3.0 协议。 + +### 安装 + +安装 Cozy 非常快捷简单,这里有多种平台的 [简单易懂安装指令][6]。在我的测试中,我使用 64 位的 Debian 8 系统。安装需要几分钟时间,然后你只需要到服务器的 IP 地址注册一个账号,就会加载并准备好默认的应用程序集。 + +要注意的一点 - 安装假设没有正在运行任何其它 Web 服务,而且它会尝试安装 [Nginx web 服务器][7]。如果你的服务器已经有网站正在运行,配置可能就比较麻烦。我是在一个全新的 VPS(Virtual Private Server,虚拟个人服务器)上安装,因此比较简单。运行安装程序、启动 Nginx,然后你就可以访问云了。 + +Cozy 还有一个 [应用商店][8],你可以从中下载额外的应用程序。有一些看起来非常有趣,例如 [Ghost 博客平台][9] 以及开源维基 [TiddlyWiki][10]。其中的目标,显然是允许把其它很多好的应用程序集成到这个平台。我认为你要看到很多其它流行的开源应用程序提供集成功能只是时间问题。此刻,已经支持 [Node.js][11],但是如何也支持其它应用层,你就可以看到很多其它很好的应用程序。 + +其中可能的一个功能是从安卓设备中使用免费的安卓应用程序访问你的信息。当前还没有 iOS 应用,但有计划要解决这个问题。 + +现在,Cozy 已经有很多核心的应用程序。 + + ![主要 Cozy 界面](https://opensource.com/sites/default/files/main_cozy_interface.jpg "Main Cozy Interface") + +主要 Cozy 界面 + +### 文件 + +和很多分支一样,我使用 [Dropbox][12] 进行文件存储。事实上,由于我有很多东西需要存储,我需要花钱买 DropBox Pro。对我来说,如果它有我想要的功能,那么把我的文件移动到 Cozy 能为我节省很多开销。 + +我希望我能说这是真的,我确实做到了。我被 Cozy 应用程序内建的基于 web 的文件上传和文件管理工具所惊讶。拖拽功能正如你期望的那样,界面也很干净整洁。我在上传事例文件和目录、随处跳转、移动、删除以及重命名文件时都没有遇到问题。 + +如果你想要的就是基于 web 的云文件存储,那么你做到了。对我来说,它缺失的是 DropBox 具有的选择性文件目录同步功能。在 DropBox 中,如果你拖拽一个文件到目录中,它就会被拷贝到云,几分钟后该文件在你所有同步设备中都可以看到。实际上,[Cozy 正在研发该功能][13],但此时它还处于 beta 版,而且只支持 Linux 客户端。另外,我有一个称为 [Download to Dropbox][15] 的 [Chrome][14] 扩展,我时不时用它抓取图片和其它内容,但当前 Cozy 中还没有类似的工具。 + + ![文件管理界面](https://opensource.com/sites/default/files/cozy_2.jpg "文件管理界面") + +文件管理界面 + +### 从 Google 导入数据 + +如果你正在使用 Google 日历和联系人,使用 Cozy 安装的应用程序很轻易的就可以导入它们。当你授权访问 Google 时,会给你一个 API 密钥,把它粘贴到 Cozy,它就会迅速高效地进行复制。两种情况下,内容都会被打上“从 Google 导入”的标签。对于我混乱的联系人,这可能是件好事情,因为它使得我有机会重新整理,把它们重新标记为更有意义的类别。“Google Calendar” 中所有的事件都导入了,但是我注意到其中一些事件的时间不对,可能是由于两端时区设置的影响。 + +### 联系人 + +联系人正如你期望的那样,界面也很像 Google 联系人。尽管如此,还是有一些不好的地方。和你(例如)智能手机的同步通过 [CardDAV][16] 完成,这是用于共享联系人数据的标准协议,但安卓手机并不原生支持该技术。为了把你的联系人同步到安卓设备,你需要在你的手机上安装一个应用。这对我来说是个很大的打击,因为我已经有很多类似这样的旧应用程序了(例如 work mail、Gmail以及其它 mail,我的天),我并不想安装一个不能和我智能手机原生联系人应用程序同步的软件。如果你正在使用 iPhone,你直接就能使用 CradDAV。 + +### 日历 + +对于日历用户来说好消息就是安卓设备支持这种类型数据的交换格式 [CalDAV][17]。正如我导入数据时提到的,我的一些日历时间的时间不对。在这之前我在和其它日历系统进行迁移时也遇到过这个问题,因此这对我并没有产生太大困扰。界面允许你创建和管理多个日历,就像 Google 那样,但是你不能订阅这个 Cozy 实例之外的其它日历。该应用程序另一个怪异的地方就是它的一周从周一开始,而且你不能更改。通常来说,我从周日开始我的一周,因此能更改从周一开始的功能对我来说非常有用。设置对话框并没有任何设置;它只是告诉你如何通过 CalDAV 连接的指令。再次说明,这个应用程序接近我想要的,但 Cozy 做的还不够好。 + +### 照片 + +照片应用让我印象深刻,它从文件应用程序借鉴了很多东西。你甚至可以把一个其它应用程序的照片文件添加到相册,或者直接通过拖拽上传。不幸的是,一旦上传后,我没有找到任何重拍和编辑照片的方法。你只能把它们从相册中删除。应用有一个通过令牌链接进行分享的工具,而且你可以指定一个或多个联系人。系统会给这些联系人发送邀请他们查看相册的电子邮件。当然还有很多比这个有更丰富功能的相册应用,但在 Cozy 平台中这算是一个好的起点。 + + ![Photos 界面](https://opensource.com/sites/default/files/cozy_3_0.jpg "Photos Interface") + +Photos 界面 + +### 总结 + +Cozy 目标远大。他们尝试搭建你能部署任意你想要的基于云的服务的平台。它已经到了黄金时段吗?我并不认为。对于一些重度用户来说我之前提到的一些问题很严重,而且还没有 iOS 应用,这可能阻碍用户使用它。不管怎样,继续关注吧 - 随着研发的继续,Cozy 有一家代替很多应用程序的潜能。 + +-------------------------------------------------------------------------------- + +译者简介: + +D Ruth Bavousett - D Ruth Bavousett 作为系统管理员和软件开发者已经很长时间了,长期以来她都专注于 a VAX 11/780。(到目前为止)她花了很多时间服务于图书馆的技术需求,她从 2008 年就开始成为 Koha 开源图书馆自动化套件的贡献者。 Ruth 现在是 Houston cPanel 公司的 Perl 开发人员,同时还是两个孩子的母亲。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/17/2/cozy-personal-cloud + +作者:[D Ruth Bavousett][a] +译者:[ictlyh](https://github.com/ictlyh) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/druthb +[1]:https://opensource.com/article/17/2/cozy-personal-cloud?rate=FEMc3av4LgYK-jeEscdiqPhSgHZkYNsNCINhOoVR9N8 +[2]:https://pixabay.com/en/tree-field-cornfield-nature-247122/ +[3]:https://creativecommons.org/licenses/by-sa/4.0/ +[4]:https://cozy.io/ +[5]:https://github.com/cozy/cozy +[6]:https://docs.cozy.io/en/host/install/ +[7]:https://www.nginx.com/ +[8]:https://cozy.io/en/apps/ +[9]:https://ghost.org/ +[10]:http://tiddlywiki.com/ +[11]:http://nodejs.org/ +[12]:https://www.dropbox.com/ +[13]:https://github.com/cozy-labs/cozy-desktop +[14]:https://www.google.com/chrome/ +[15]:https://github.com/pwnall/dropship-chrome +[16]:https://en.wikipedia.org/wiki/CardDAV +[17]:https://en.wikipedia.org/wiki/CalDAV +[18]:https://opensource.com/user/36051/feed +[19]:https://opensource.com/article/17/2/cozy-personal-cloud#comments +[20]:https://opensource.com/users/druthb From 5a511a88c6717b5e93ed1b4a1bf6d1d039455efd Mon Sep 17 00:00:00 2001 From: Ezio Date: Mon, 10 Apr 2017 19:36:47 +0800 Subject: [PATCH 22/52] =?UTF-8?q?20170410-1=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20170125 NMAP Common Scans – Part Two.md | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 sources/tech/20170125 NMAP Common Scans – Part Two.md diff --git a/sources/tech/20170125 NMAP Common Scans – Part Two.md b/sources/tech/20170125 NMAP Common Scans – Part Two.md new file mode 100644 index 0000000000..9b9d9704dd --- /dev/null +++ b/sources/tech/20170125 NMAP Common Scans – Part Two.md @@ -0,0 +1,128 @@ +NMAP Common Scans – Part Two +===================== + + + +In a previous article, ‘[NMAP Installation][1]’, a listing of ten different ZeNMAP Profiles were listed. Most of the Profiles used various parameters. Most of the parameters represented different scans which can be performed. This article will cover the last two remaining of the common four scan types. + +**The Common Four Scan Types** + +The four main scan types which are used most often are the following: + +1. PING Scan (-sP) +2. TCP SYN Scan (-sS) +3. TCP Connect() Scan (-sT) +4. UDP Scan (-sU) + +When using NMAP to perform scans these four scans are the four to keep in mind. The main thing to keep in mind about them is what they do and how they do it. This article covers the two TCP scans – TCP SYN Scan and TCP Connect Scan. + +([See Common scans - part one][2]) + +**TCP SYN Scan (-sS)** + +The TCP SYN Scan is the default NMAP scan. To run the TCP SYN Scan you are required to have Root privileges. + +The purpose of the TCP SYN Scan is to find open Ports on the scanned systems. As with NMAP scans you can scan systems on the other side of a Firewall. When scanning through a Firewall the scan time will be lengthened since packets will be slowed down. + +The way the TCP SYN Scan works is that it starts a three-way handshake. As described in another article, the three-way handshake takes place between two systems. The Source System sends a packet to the Target System which is a SYN (Sync) request. The Target System will respond with a SYN/ACK (Sync/Acknowledgement). The Source System will the respond with an Acknowledgement (ACK) so the communication link is established and data can be transferred between them. + +The TCP Syn Scan works by performing the steps as follows: + +1. Source System sends a SYN request to the Target but a Port number is added to the request in this case. +2. The Target System will respond with a SYN/ ACK (Sync/Acknowledgement) to the Source if the specified Port is open. +3. The Source System responds with a RST (Reset) to the Target to close the connection. +4. The Target System can respond with a RST/ACK (Reset/Acknowledgement) to the Source System. + +The connection was started to be established so this is considered a half-open connection. Because the connection state is being managed by NMAP you need Root privileges. + +If the Port being scanned is closed the following will occur: + +1. Source System sends a SYN request to the Target and a Port number is added to the request. +2. The Target responds with a RST (Reset) since the Port is closed. + +If the Target System is behind a Firewall then the ICMP transmission or responses will be blocked by the Firewall and the following happens: + +1. Source System sends a SYN request to the Target and the Port number is added to the request. +2. No response is received since it was Filtered by the Firewall. + +In this case the port is listed as Filtered and the Port may or may not be open. The Firewall may be set to stop all outgoing packets on the specified Port. The Firewall may block all incoming packets to a specified Port and so the Target System does not receive the request. + +**NOTE:** The lack of a response may also occur on a system with a Firewall program enabled on it. Even on a local network you may find Filtered Ports. + +I will perform a scan of a single system (10.0.0.2) and perform the TCP Syn Scan as shown in Figure 1\. The scan is done with the command ‘sudo nmap -sS ’. The ‘’ can be exchanged with a single IP Address, as in Figure 1, or by using a group of IP Addresses. + + ![Figure 01.jpg](https://www.linuxforum.com/attachments/figure-01-jpg.119/) + +**FIGURE 1** + +You can see that it states that 997 Filtered Ports are not shown. NMAP then finds two Ports open – 139 and 445. + +**NOTE:** Keep in mind that NMAP only scans the most well-known 1,000 Ports. We will cover other scans later which will allow us to scan all ports or only those specified. + +The scan was captured by WireShark as shown in Figure 2\. Here you can see the initial Address Resolution Protocol (ARP) requests being made for the Target System. Following the ARP requests are a long list of TCP requests to the Ports on the Target System. Line 4 is to the ‘http-alt’ Port (8080). The Source System Port number is 47,128\. Many SYN requests are sent until a response is made as shown in Figure 3. + + ![Figure 2.jpg](https://www.linuxforum.com/attachments/figure-2-jpg.120/) + +**FIGURE 2** + + ![Figure 3.jpg](https://www.linuxforum.com/attachments/figure-3-jpg.121/) + +**FIGURE 3** + +In Figure 3 on Lines 50 and 51 you can see the RST (Reset) packet sent to the Source System. Lines 53 and 55 shows a RST/ACK (Reset/Acknowledgement). Line 50 is for the ‘microsoft-ds’ Port (445) and Line 51 is for the ‘netbios-ssn’ Port (135) we can see that the Ports are opened. No other ACK (Acknowledgments) are made from the Target System except for these Ports. Each request can be sent over 1,000 times. + +The Target System was a Windows System and I turned off the Firewall software on the system and performed the scan again as shown in Figure 4\. Now instead of seeing 997 Filtered Ports there are 997 Closed Ports. Port 135 is also now open on the Target System which was being blocked by the Firewall. + + ![Figure 04.jpg](https://www.linuxforum.com/attachments/figure-04-jpg.122/) + +**FIGURE 4** + +**TCP Connect() Scan (-sT)** + +The TCP Connect() Scan (-sT) does not require Root privileges as the TCP Syn Scan does. A full Three-Way Handshake is performed in this Scan. Because Root privileges are not needed this scan can be helpful on a network where you cannot get Root privileges. + +The way the TCP Connect Scan works is that it performs a three-way handshake. As described above, the three-way handshake takes place between two systems. The Source System sends a packet to the Target System which is a SYN (Sync) request. The Target System will respond with a SYN/ACK (Sync/Acknowledgement). The Source System will then respond with an Acknowledgement (ACK) so the communication link is established and data can be transferred between them. + +The TCP Connect Scan works by performing the steps as follows: + +1. Source System sends a SYN request to the Target but a Port number is added to the request in this case. +2. The Target System will respond with a SYN/ ACK (Sync/Acknowledgement) to the Source if the specified Port is open. +3. The Source System responds with an ACK (Acknowledgement) to the Target to finish the session creation. +4. The Source System then sends the Target System a RST (Reset) packet to close the session. +5. The Target System can respond with a RST/ACK (Reset/Acknowledgement) to the Source System. + +When step 2 occurs the Source System knows that the Port Specified in Step 1 is an Open Port. + +If a Port is closed then the same thing happens as in a TCP Scan. In Step 2 the Target System will respond with a RST (Reset) packet. + +The scan is done with the command ‘nmap -sT ’. The ‘’ can be exchanged with a single IP Address, as in Figure 5, or by using a group of IP Addresses. + +The results of a TCP Connect Scan can be seen in Figure 5\. Here you can see that the two open Ports, 139 and 445, are found just like with the TCP SYN Scan. Port 80 is listed as being Closed. The remaining Ports are not shown and listed as Filtered. + + ![Figure 05.jpg](https://www.linuxforum.com/attachments/figure-05-jpg.123/) + +**FIGURE 5** + +Let’s try the scan again after shutting off the Firewall. The results are shown in Figure 6. + + ![Figure 06.jpg](https://www.linuxforum.com/attachments/figure-06-jpg.124/) + +**FIGURE 6** + +With the Firewall off we can see more Ports have been found. Just as with the TCP SYN Scan when having the Firewall off we find Ports 139, 445 and 135 are open. We also have found that Port 2869 is also open. There are also 996 closed Ports. Port 80 is now part of the 996 closed Ports – no longer Filtered by the Firewall. + +In some cases the TCP Connect Scan may finish in a shorter amount of time. The TCP Connect Scan also seems to find more open Ports than the TCP SYN Scan. + +-------------------------------------------------------------------------------- + +via: https://www.linuxforum.com/threads/nmap-common-scans-part-two.3879/ + +作者:[Jarret ][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linuxforum.com/members/jarret.268/ +[1]:https://www.linuxforum.com/threads/nmap-installation.3431/ +[2]:https://www.linuxforum.com/threads/nmap-common-scans-part-one.3637/ From 4ef1ada212b1ee47c7a3e93f694dbfecfa668479 Mon Sep 17 00:00:00 2001 From: Ezio Date: Mon, 10 Apr 2017 19:42:58 +0800 Subject: [PATCH 23/52] =?UTF-8?q?20170410-2=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... a New Disk to an Existing Linux Server.md | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 sources/tech/20170319 How to Add a New Disk to an Existing Linux Server.md diff --git a/sources/tech/20170319 How to Add a New Disk to an Existing Linux Server.md b/sources/tech/20170319 How to Add a New Disk to an Existing Linux Server.md new file mode 100644 index 0000000000..c4d32941bc --- /dev/null +++ b/sources/tech/20170319 How to Add a New Disk to an Existing Linux Server.md @@ -0,0 +1,166 @@ +How to Add a New Disk to an Existing Linux Server +============================================================ + + +As system administrators, we would have got requirements wherein we need to configure raw hard disks to the existing servers as part of upgrading server capacity or sometimes disk replacement in case of disk failure. + +In this article, I will take you through the steps by which we can add the new raw hard disk to an existing Linux server such as RHEL/CentOS or Debian/Ubuntu. + +**Suggested Read:** [How to Add a New Disk Larger Than 2TB to An Existing Linux][1] + +Important: Please note that the purpose of this article is to show only how to create a new partition and doesn’t include partition extension or any other switches. + +I am using [fdisk utility][2] to do this configuration. + +I have added a hard disk of 20GB capacity to be mounted as a `/data` partition. + +fdisk is a command line utility to view and manage hard disks and partitions on Linux systems. + +``` +# fdisk -l +``` + +This will list the current partitions and configurations. + +[ + ![Find Linux Partition Details](http://www.tecmint.com/wp-content/uploads/2017/03/Find-Linux-Partition-Details.png) +][3] + +Find Linux Partition Details + +After attaching the hard disk of 20GB capacity, the `fdisk -l` will give the below output. + +``` +# fdisk -l +``` +[ + ![Find New Partition Details](http://www.tecmint.com/wp-content/uploads/2017/03/Find-New-Partition-Details.png) +][4] + +Find New Partition Details + +New disk added is shown as `/dev/xvdc`. If we are adding physical disk it will show as `/dev/sda` based of the disk type. Here I used a virtual disk. + +To partition a particular hard disk, for example /dev/xvdc. + +``` +# fdisk /dev/xvdc +``` + +Commonly used fdisk commands. + +* `n` – Create partition +* `p` – print partition table +* `d` – delete a partition +* `q` – exit without saving the changes +* `w` – write the changes and exit. + +Here since we are creating a partition use `n` option. + +[ + ![Create New Partition in Linux](http://www.tecmint.com/wp-content/uploads/2017/03/Create-New-Partition-in-Linux.png) +][5] + +Create New Partition in Linux + +Create either primary/extended partitions. By default we can have upto 4 primary partitions. + +[ + ![Create Primary Partition](http://www.tecmint.com/wp-content/uploads/2017/03/Create-Primary-Partition.png) +][6] + +Create Primary Partition + +Give the partition number as desired. Recommended to go for the default value `1`. + +[ + ![Assign a Partition Number](http://www.tecmint.com/wp-content/uploads/2017/03/Assign-a-Partition-Number.png) +][7] + +Assign a Partition Number + +Give the value of the first sector. If it is a new disk, always select default value. If you are creating a second partition on the same disk, we need to add `1` to the last sector of the previous partition. + +[ + ![Assign Sector to Partition](http://www.tecmint.com/wp-content/uploads/2017/03/Assign-Sector-to-Partition.png) +][8] + +Assign Sector to Partition + +Give the value of the last sector or the partition size. Always recommended to give the size of the partition. Always prefix `+` to avoid value out of range error. + +[ + ![Assign Partition Size](http://www.tecmint.com/wp-content/uploads/2017/03/Assign-Partition-Size.png) +][9] + +Assign Partition Size + +Save the changes and exit. + +[ + ![Save Partition Changes](http://www.tecmint.com/wp-content/uploads/2017/03/Save-Partition-Changes.png) +][10] + +Save Partition Changes + +Now format the disk with mkfs command. + +``` +# mkfs.ext4 /dev/xvdc1 +``` +[ + ![Format New Partition](http://www.tecmint.com/wp-content/uploads/2017/03/Format-New-Partition.png) +][11] + +Format New Partition + +Once formatting has been completed, now mount the partition as shown below. + +``` +# mount /dev/xvdc1 /data +``` + +Make an entry in /etc/fstab file for permanent mount at boot time. + +``` +/dev/xvdc1 /data ext4 defaults 0 0 +``` + +##### Conclusion + +Now you know how to partition a raw disk using [fdisk command][12] and mount the same. + +We need to be extra cautious while working with the partitions especially when you are editing the configured disks. Please share your feedback and suggestions. + +-------------------------------------------------------------------------------- + +作者简介: + +I work on various platforms including IBM-AIX, Solaris, HP-UX, and storage technologies ONTAP and OneFS and have hands on experience on Oracle Database. + +----------------------- + +via: http://www.tecmint.com/add-new-disk-to-an-existing-linux/ + +作者:[Lakshmi Dhandapani][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.tecmint.com/author/lakshmi/ +[1]:http://www.tecmint.com/add-disk-larger-than-2tb-to-an-existing-linux/ +[2]:http://www.tecmint.com/fdisk-commands-to-manage-linux-disk-partitions/ +[3]:http://www.tecmint.com/wp-content/uploads/2017/03/Find-Linux-Partition-Details.png +[4]:http://www.tecmint.com/wp-content/uploads/2017/03/Find-New-Partition-Details.png +[5]:http://www.tecmint.com/wp-content/uploads/2017/03/Create-New-Partition-in-Linux.png +[6]:http://www.tecmint.com/wp-content/uploads/2017/03/Create-Primary-Partition.png +[7]:http://www.tecmint.com/wp-content/uploads/2017/03/Assign-a-Partition-Number.png +[8]:http://www.tecmint.com/wp-content/uploads/2017/03/Assign-Sector-to-Partition.png +[9]:http://www.tecmint.com/wp-content/uploads/2017/03/Assign-Partition-Size.png +[10]:http://www.tecmint.com/wp-content/uploads/2017/03/Save-Partition-Changes.png +[11]:http://www.tecmint.com/wp-content/uploads/2017/03/Format-New-Partition.png +[12]:http://www.tecmint.com/fdisk-commands-to-manage-linux-disk-partitions/ +[13]:http://www.tecmint.com/author/lakshmi/ +[14]:http://www.tecmint.com/10-useful-free-linux-ebooks-for-newbies-and-administrators/ +[15]:http://www.tecmint.com/free-linux-shell-scripting-books/ From 90a90b603e38017d64f50addf6a08ab5a0231f0a Mon Sep 17 00:00:00 2001 From: Ezio Date: Mon, 10 Apr 2017 19:43:29 +0800 Subject: [PATCH 24/52] =?UTF-8?q?20170410-3=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... Compare and Synchronize Files in Ubuntu.md | 212 ++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 sources/tech/20170409 FreeFileSync – Compare and Synchronize Files in Ubuntu.md diff --git a/sources/tech/20170409 FreeFileSync – Compare and Synchronize Files in Ubuntu.md b/sources/tech/20170409 FreeFileSync – Compare and Synchronize Files in Ubuntu.md new file mode 100644 index 0000000000..a118230ad7 --- /dev/null +++ b/sources/tech/20170409 FreeFileSync – Compare and Synchronize Files in Ubuntu.md @@ -0,0 +1,212 @@ +FreeFileSync – Compare and Synchronize Files in Ubuntu +============================================================ + + +FreeFileSync is a free, open source and cross platform folder comparison and synchronization software, which helps you [synchronize files and folders on Linux][2], Windows and Mac OS. + +It is portable and can also be installed locally on a system, it’s feature-rich and is intended to save time in setting up and executing backup operations while having attractive graphical interface as well. + +#### FreeFileSync Features + +Below are it’s key features: + +1. It can synchronize network shares and local disks. +2. It can synchronize MTP devices (Android, iPhone, tablet, digital camera). +3. It can also synchronize via [SFTP (SSH File Transfer Protocol)][1]. +4. It can identify moved and renamed files and folders. +5. Displays disk space usage with directory trees. +6. Supports copying locked files (Volume Shadow Copy Service). +7. Identifies conflicts and propagate deletions. +8. Supports comparison of files by content. +9. It can be configured to handle Symbolic Links. +10. Supports automation of sync as a batch job. +11. Enables processing of multiple folder pairs. +12. Supports in-depth and detailed error reporting. +13. Supports copying of NTFS extended attributes such as (compressed, encrypted, sparse). +14. Also supports copying of NTFS security permissions and NTFS Alternate Data Streams. +15. Support long file paths with more than 260 characters. +16. Supports Fail-safe file copy prevents data corruption. +17. Allows expanding of environment variables such as %UserProfile%. +18. Supports accessing of variable drive letters by volume name (USB sticks). +19. Supports managing of versions of deleted/updated files. +20. Prevent disc space issues via optimal sync sequence. +21. Supports full Unicode. +22. Offers a highly optimized run time performance. +23. Supports filters to include and exclude files plus lots more. + +### How To Install FreeFileSync in Ubuntu Linux + +We will add official FreeFileSync PPA, which is available for Ubuntu 14.04 and Ubuntu 15.10 only, then update the system repository list and install it like so: + +``` +-------------- On Ubuntu 14.04 and 15.10 -------------- +$ sudo apt-add-repository ppa:freefilesync/ffs +$ sudo apt-get update +$ sudo apt-get install freefilesync +``` + +On Ubuntu 16.04 and newer version, go to the [FreeFileSync download page][3] and get the appropriate package file for Ubuntu and Debian Linux. + +Next, move into the Download folder, extract the FreeFileSync_*.tar.gz into the /opt directory as follows: + +``` +$ cd Downloads/ +$ sudo tar xvf FreeFileSync_*.tar.gz -C /opt/ +$ cd /opt/ +$ ls +$ sudo unzip FreeFileSync/Resources.zip -d /opt/FreeFileSync/Resources/ +``` + +Now we will create an application launcher (.desktop file) using Gnome Panel. To view examples of `.desktop`files on your system, list the contents of the directory /usr/share/applications: + +``` +$ ls /usr/share/applications +``` + +In case you do not have Gnome Panel installed, type the command below to install it: + +``` +$ sudo apt-get install --no-install-recommends gnome-panel +``` + +Next, run the command below to create the application launcher: + +``` +$ sudo gnome-desktop-item-edit /usr/share/applications/ --create-new +``` + +And define the values below: + +``` +Type: Application +Name: FreeFileSync +Command: /opt/FreeFileSync/FreeFileSync +Comment: Folder Comparison and Synchronization +``` + +To add an icon for the launcher, simply clicking on the spring icon to select it: /opt/FreeFileSync/Resources/FreeFileSync.png. + +When you have set all the above, click OK create it. + +[ + ![Create Desktop Launcher](http://www.tecmint.com/wp-content/uploads/2017/03/Create-Desktop-Launcher.png) +][4] + +Create Desktop Launcher + +If you don’t want to create desktop launcher, you can start FreeFileSync from the directory itself. + +``` +$ ./FreeFileSync +``` + +### How to Use FreeFileSync in Ubuntu + +In Ubuntu, search for FreeFileSync in the Unity Dash, whereas in Linux Mint, search for it in the System Menu, and click on the FreeFileSync icon to open it. + +[ + ![FreeFileSync ](http://www.tecmint.com/wp-content/uploads/2017/03/FreeFileSync-launched.png) +][5] + +FreeFileSync + +#### Compare Two Folders Using FreeFileSync + +In the example below, we’ll use: + +``` +Source Folder: /home/aaronkilik/bin +Destination Folder: /media/aaronkilik/J_CPRA_X86F/scripts +``` + +To compare the file time and size of the two folders (default setting), simply click on the Compare button. + +[ + ![Compare Two Folders in Linux](http://www.tecmint.com/wp-content/uploads/2017/03/compare-two-folders.png) +][6] + +Compare Two Folders in Linux + +Press `F6` to change what to compare by default, in the two folders: file time and size, content or file size from the interface below. Note that the meaning of the each option you select is included as well. + +[ + ![File Comparison Settings](http://www.tecmint.com/wp-content/uploads/2017/03/comparison-settings.png) +][7] + +File Comparison Settings + +#### Synchronization Two Folders Using FreeFileSync + +You can start by comparing the two folders, and then click on Synchronize button, to start the synchronization process; click Start from the dialog box the appears thereafter: + +``` +Source Folder: /home/aaronkilik/Desktop/tecmint-files +Destination Folder: /media/aaronkilik/Data/Tecmint +``` +[ + ![Compare and Synchronize Two Folders](http://www.tecmint.com/wp-content/uploads/2017/03/compare-and-sychronize-two-folders.png) +][8] + +Compare and Synchronize Two Folders + +[ + ![Start File Synchronization](http://www.tecmint.com/wp-content/uploads/2017/03/start-sychronization.png) +][9] + +Start File Synchronization + +[ + ![File Synchronization Completed](http://www.tecmint.com/wp-content/uploads/2017/03/synchronization-complete.png) +][10] + +File Synchronization Completed + +To set the default synchronization option: two way, mirror, update or custom, from the following interface; press `F8`. The meaning of the each option is included there. + +[ + ![File Synchronization Settings](http://www.tecmint.com/wp-content/uploads/2017/03/synchronization-setttings.png) +][11] + +File Synchronization Settings + +For more information, visit FreeFileSync homepage at [http://www.freefilesync.org/][12] + +That’s all! In this article, we showed you how to install FreeFileSync in Ubuntu and it’s derivatives such as Linux Mint, Kubuntu and many more. Drop your comments via the feedback section below. + +-------------------------------------------------------------------------------- + +作者简介: + +I am Ravi Saive, creator of TecMint. A Computer Geek and Linux Guru who loves to share tricks and tips on Internet. Most Of My Servers runs on Open Source Platform called Linux. Follow Me: [Twitter][00], [Facebook][01] and [Google+][02] + +-------------------------------------------------------------------------------- + + +via: http://www.tecmint.com/freefilesync-compare-synchronize-files-in-ubuntu/ + +作者:[Ravi Saive ][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.tecmint.com/author/admin/ +[00]:https://twitter.com/ravisaive +[01]:https://www.facebook.com/ravi.saive +[02]:https://plus.google.com/u/0/+RaviSaive + +[1]:http://www.tecmint.com/sftp-command-examples/ +[2]:http://www.tecmint.com/rsync-local-remote-file-synchronization-commands/ +[3]:http://www.freefilesync.org/download.php +[4]:http://www.tecmint.com/wp-content/uploads/2017/03/Create-Desktop-Launcher.png +[5]:http://www.tecmint.com/wp-content/uploads/2017/03/FreeFileSync-launched.png +[6]:http://www.tecmint.com/wp-content/uploads/2017/03/compare-two-folders.png +[7]:http://www.tecmint.com/wp-content/uploads/2017/03/comparison-settings.png +[8]:http://www.tecmint.com/wp-content/uploads/2017/03/compare-and-sychronize-two-folders.png +[9]:http://www.tecmint.com/wp-content/uploads/2017/03/start-sychronization.png +[10]:http://www.tecmint.com/wp-content/uploads/2017/03/synchronization-complete.png +[11]:http://www.tecmint.com/wp-content/uploads/2017/03/synchronization-setttings.png +[12]:http://www.freefilesync.org/ +[13]:http://www.tecmint.com/author/admin/ +[14]:http://www.tecmint.com/10-useful-free-linux-ebooks-for-newbies-and-administrators/ +[15]:http://www.tecmint.com/free-linux-shell-scripting-books/ From 55b70a51c7cd1073b6f5da2390c9daf5fe78b085 Mon Sep 17 00:00:00 2001 From: Ezio Date: Mon, 10 Apr 2017 19:43:56 +0800 Subject: [PATCH 25/52] =?UTF-8?q?20170410-4=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Utilization by Running Processes in Linux.md | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 sources/tech/20170410 Cpustat – Monitors CPU Utilization by Running Processes in Linux.md diff --git a/sources/tech/20170410 Cpustat – Monitors CPU Utilization by Running Processes in Linux.md b/sources/tech/20170410 Cpustat – Monitors CPU Utilization by Running Processes in Linux.md new file mode 100644 index 0000000000..3594630195 --- /dev/null +++ b/sources/tech/20170410 Cpustat – Monitors CPU Utilization by Running Processes in Linux.md @@ -0,0 +1,167 @@ +Cpustat – Monitors CPU Utilization by Running Processes in Linux +============================================================ + +Cpustat is a powerful system performance measure program for Linux, written using [Go programming language][3]. It attempts to reveal CPU utilization and saturation in an effective way, using The Utilization Saturation and Errors (USE) Method (a methodology for analyzing the performance of any system). + +It extracts higher frequency samples of every process being executed on the system and then summarizes these samples at a lower frequency. For instance, it can measure every process every 200ms and summarize these samples every 5 seconds, including min/average/max values for certain metrics. + +**Suggested Read:** [20 Command Line Tools to Monitor Linux Performance][4] + +Cpustat outputs data in two possible ways: a pure text list of the summary interval and a colorful scrolling dashboard of each sample. + +### How to Install Cpustat in Linux + +You must have Go (GoLang) installed on your Linux system in order to use cpustat, click on the link below to follow the GoLang installation steps that is if you do not have it installed: + +1. [Install GoLang (Go Programming Language) in Linux][1] + +Once you have installed Go, type the go get command below to install it, this command will install the cpustat binary in your GOBIN variable: + +``` +# go get github.com/uber-common/cpustat +``` + +### How to Use Cpustat in Linux + +When the installation process completes, run cpustat as follows with root privileges using the sudo command that is if your controlling the system as a non-root user, otherwise you’ll get the error as shown: + +``` +$ $GOBIN/cpustat +This program uses the netlink taskstats interface, so it must be run as root. +``` + +Note: To run cpustat as well as all other Go programs you have installed on your system like any other commands, include GOBIN variable in your PATH environment variable. Open the link below to learn how to set the PATH variable in Linux. + +1. [Learn How to Set Your $PATH Variables Permanently in Linux][2] + +This is how cpustat works; the `/proc` directory is queried to get the current [list of process IDs][5] for every interval, and: + +* for each PID, read /proc/pid/stat, then compute difference from previous sample. +* in case it’s a new PID, read /proc/pid/cmdline. +* for each PID, send a netlink message to fetch the taskstats, compute difference from previous sample. +* fetch /proc/stat to get the overall system stats. + +Again, each sleep interval is adjusted to account for the amount of time consumed fetching all of these stats. Furthermore, each sample also records the time it took to scale each measurement by the actual elapsed time between samples. This attempts to account for delays in cpustat itself. + +When run without any arguments, cpustat will display the following by default: sampling interval: 200ms, summary interval: 2s (10 samples), [showing top 10 procs][6], user filter: all, pid filter: all as shown in the screenshot below: + +``` +$ sudo $GOBIN/cpustat +``` +[ + ![Cpustat - Monitor Linux CPU Usage](http://www.tecmint.com/wp-content/uploads/2017/03/Cpustat-Monitor-Linux-CPU-Usage.png) +][7] + +Cpustat – Monitor Linux CPU Usage + +From the output above, the following are the meanings of the system-wide summary metrics displayed before the fields: + +* usr – min/avg/max user mode run time as a percentage of a CPU. +* sys – min/avg/max system mode run time as a percentage of a CPU. +* nice – min/avg/max user mode low priority run time as a percentage of a CPU. +* idle – min/avg/max user mode run time as a percentage of a CPU. +* iowait – min/avg/max delay time waiting for disk IO. +* prun – min/avg/max count of processes in a runnable state (same as load average). +* pblock – min/avg/max count of processes blocked on disk IO. +* pstart – number of processes/threads started in this summary interval. + +Still from the output above, for a given process, the different columns mean: + +* name – common process name from /proc/pid/stat or /proc/pid/cmdline. +* pid – process id, also referred to as “tgid”. +* min – lowest sample of user+system time for the pid, measured from /proc/pid/stat. Scale is a percentage of a CPU. +* max – highest sample of user+system time for this pid, also measured from /proc/pid/stat. +* usr – average user time for the pid over the summary period, measured from /proc/pid/stat. +* sys – average system time for the pid over the summary period, measured from /proc/pid/stat. +* nice – indicates current “nice” value for the process, measured from /proc/pid/stat. Higher means “nicer”. +* runq – time the process and all of its threads spent runnable but waiting to run, measured from taskstats via netlink. Scale is a percentage of a CPU. +* iow – time the process and all of its threads spent blocked by disk IO, measured from taskstats via netlink. Scale is a percentage of a CPU, averaged over the summary interval. +* swap – time the process and all of its threads spent waiting to be swapped in, measured from taskstats via netlink. Scale is a percentage of a CPU, averaged over the summary interval. +* vcx and icx – total number of voluntary context switches by the process and all of its threads over the summary interval, measured from taskstats via netlink. +* rss – current RSS value fetched from /proc/pid/stat. It is the amount of memory this process is using. +* ctime – sum of user+sys CPU time consumed by waited for children that exited during this summary interval, measured from /proc/pid/stat. + +Note that long running child processes can often confuse this measurement, because the time is reported only when the child process exits. However, this is useful for measuring the impact of frequent cron jobs and health checks where the CPU time is often consumed by many child processes. + +* thrd – number of threads at the end of the summary interval, measured from /proc/pid/stat. +* sam – number of samples for this process included in the summary interval. Processes that have recently started or exited may have been visible for fewer samples than the summary interval. + +The following command displays the top 10 root user processes running on the system: + +``` +$ sudo $GOBIN/cpustat -u root +``` +[ + ![Find Root User Running Processes](http://www.tecmint.com/wp-content/uploads/2017/03/show-root-user-processes.png) +][8] + +Find Root User Running Processes + +To display output in a fancy terminal mode, use the `-t` flag as follows: + +``` +$ sudo $GOBIN/cpustat -u roo -t +``` +[ + ![Running Process Usage of Root User](http://www.tecmint.com/wp-content/uploads/2017/03/Root-User-Runnng-Processes.png) +][9] + +Running Process Usage of Root User + +To view the [top x number of processes][10] (the default is 10), you can use the `-n` flag, the following command shows the [top 20 Linux processes running][11] on the system: + +``` +$ sudo $GOBIN/cpustat -n 20 +``` + +You can also write CPU profile to a file using the `-cpuprofile` option as follows and then use the [cat command][12] to view the file: + +``` +$ sudo $GOBIN/cpustat -cpuprofile cpuprof.txt +$ cat cpuprof.txt +``` + +To display help info, use the `-h` flag as follows: + +``` +$ sudo $GOBIN/cpustat -h +``` + +Find additional info from the cpustat Github Repository: [https://github.com/uber-common/cpustat][13] + +That’s all! In this article, we showed you how to install and use cpustat, a useful system performance measure tool for Linux. Share your thoughts with us via the comment section below. + +-------------------------------------------------------------------------------- + +作者简介: + +Aaron Kili is a Linux and F.O.S.S enthusiast, an upcoming Linux SysAdmin, web developer, and currently a content creator for TecMint who loves working with computers and strongly believes in sharing knowledge. + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/cpustat-monitors-cpu-utilization-by-processes-in-linux/ + +作者:[Aaron Kili][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.tecmint.com/author/aaronkili/ + +[1]:http://www.tecmint.com/install-go-in-linux/ +[2]:http://www.tecmint.com/set-path-variable-linux-permanently/ +[3]:http://www.tecmint.com/install-go-in-linux/ +[4]:http://www.tecmint.com/command-line-tools-to-monitor-linux-performance/ +[5]:http://www.tecmint.com/find-process-name-pid-number-linux/ +[6]:http://www.tecmint.com/find-linux-processes-memory-ram-cpu-usage/ +[7]:http://www.tecmint.com/wp-content/uploads/2017/03/Cpustat-Monitor-Linux-CPU-Usage.png +[8]:http://www.tecmint.com/wp-content/uploads/2017/03/show-root-user-processes.png +[9]:http://www.tecmint.com/wp-content/uploads/2017/03/Root-User-Runnng-Processes.png +[10]:http://www.tecmint.com/find-processes-by-memory-usage-top-batch-mode/ +[11]:http://www.tecmint.com/install-htop-linux-process-monitoring-for-rhel-centos-fedora/ +[12]:http://www.tecmint.com/13-basic-cat-command-examples-in-linux/ +[13]:https://github.com/uber-common/cpustat +[14]:http://www.tecmint.com/author/aaronkili/ +[15]:http://www.tecmint.com/10-useful-free-linux-ebooks-for-newbies-and-administrators/ +[16]:http://www.tecmint.com/free-linux-shell-scripting-books/ From 455d4a133292a05120859efac4bc5c0abb7146fd Mon Sep 17 00:00:00 2001 From: Ezio Date: Mon, 10 Apr 2017 19:44:21 +0800 Subject: [PATCH 26/52] =?UTF-8?q?20170410-5=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... Filesystem Changes in Real-Time in Linux.md | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 sources/tech/20170407 Pyinotify – Monitor Filesystem Changes in Real-Time in Linux.md diff --git a/sources/tech/20170407 Pyinotify – Monitor Filesystem Changes in Real-Time in Linux.md b/sources/tech/20170407 Pyinotify – Monitor Filesystem Changes in Real-Time in Linux.md new file mode 100644 index 0000000000..3910f22329 --- /dev/null +++ b/sources/tech/20170407 Pyinotify – Monitor Filesystem Changes in Real-Time in Linux.md @@ -0,0 +1,109 @@ +Pyinotify – Monitor Filesystem Changes in Real-Time in Linux +============================================================ + +Pyinotify is a simple yet useful Python module for [monitoring filesystems changes][1] in real-time in Linux. + +As a System administrator, you can use it to monitor changes happening to a directory of interest such as web directory or application data storage directory and beyond. + +**Suggested Read:** [fswatch – Monitors Files and Directory Changes or Modifications in Linux][2] + +It depends on inotify (a Linux kernel feature incorporated in kernel 2.6.13), which is an event-driven notifier, its notifications are exported from kernel space to user space via three system calls. + +The purpose of pyinotiy is to bind the three system calls, and support an implementation on top of them providing a common and abstract means to manipulate those functionalities. + +In this article, we will show you how to install and use pyinotify in Linux to monitor filesystem changes or modifications in real-time. + +#### Dependencies + +In order to use pyinotify, your system must be running: + +1. Linux kernel 2.6.13 or higher +2. Python 2.4 or higher + +### How to Install Pyinotify in Linux + +First start by checking the kernel and Python versions installed on your system as follows: + +``` +# uname -r +# python -V +``` + +Once dependencies are met, we will use pip to install pynotify. In most Linux distributions, Pip is already installed if you’re using Python 2 >=2.7.9 or Python 3 >=3.4 binaries downloaded from python.org, otherwise, install it as follows: + +``` +# yum install python-pip [On CentOS based Distros] +# apt-get install python-pip [On Debian based Distros] +# dnf install python-pip [On Fedora 22+] +``` + +Now, install pyinotify like so: + +``` +# pip install pyinotify +``` + +It will install available version from the default repository, if you are looking to have a latest stable version of pyinotify, consider cloning it’s git repository as shown. + +``` +# git clone https://github.com/seb-m/pyinotify.git +# cd pyinotify/ +# ls +# python setup.py install +``` + +### How to Use pyinotify in Linux + +In the example below, I am monitoring any changes to the user tecmint’s home (/home/tecmint) directory as root user (logged in via ssh) as shown in the screenshot: + +``` +# python -m pyinotify -v /home/tecmint +``` +[ + ![Monitor Directory Changes](http://www.tecmint.com/wp-content/uploads/2017/03/Monitor-Directory-File-Changes.png) +][3] + +Monitor Directory Changes + +Next, we will keep a watch for any changes to the web directory (/var/www/html/tecmint.com): + +``` +# python -m pyinotify -v /var/www/html/tecmint.com +``` + +To exit the program, simply hit `[Ctrl+C]`. + +Note: When you run pyinotify without specifying any directory to monitor, the `/tmp` directory is considered by default. + +Find more about Pyinotify on Github: [https://github.com/seb-m/pyinotify][4] + +That’s all for now! In this article, we showed you how to install and use pyinotify, a useful Python module for monitoring filesystems changes in Linux. + +Have you come across any similar Python modules or related [Linux tools/utilities][5]? Let us know in the comments, perhaps you can as well ask any question in relation to this article. + +-------------------------------------------------------------------------------- + +作者简介: + +Aaron Kili is a Linux and F.O.S.S enthusiast, an upcoming Linux SysAdmin, web developer, and currently a content creator for TecMint who loves working with computers and strongly believes in sharing knowledge. + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/pyinotify-monitor-filesystem-directory-changes-in-linux/ + +作者:[Aaron Kili][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.tecmint.com/author/aaronkili/ + +[1]:http://www.tecmint.com/fswatch-monitors-files-and-directory-changes-modifications-in-linux/ +[2]:http://www.tecmint.com/fswatch-monitors-files-and-directory-changes-modifications-in-linux/ +[3]:http://www.tecmint.com/wp-content/uploads/2017/03/Monitor-Directory-File-Changes.png +[4]:https://github.com/seb-m/pyinotify +[5]:http://tecmint.com/tag/commandline-tools +[6]:http://www.tecmint.com/author/aaronkili/ +[7]:http://www.tecmint.com/10-useful-free-linux-ebooks-for-newbies-and-administrators/ +[8]:http://www.tecmint.com/free-linux-shell-scripting-books/ From 6d6def4be5b2c15243345a09a239b6ca2440fc96 Mon Sep 17 00:00:00 2001 From: Ezio Date: Mon, 10 Apr 2017 19:46:35 +0800 Subject: [PATCH 27/52] =?UTF-8?q?20170410-5=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...esktop Sharing In Ubuntu and Linux Mint.md | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 sources/tech/20170404 How To Enable Desktop Sharing In Ubuntu and Linux Mint.md diff --git a/sources/tech/20170404 How To Enable Desktop Sharing In Ubuntu and Linux Mint.md b/sources/tech/20170404 How To Enable Desktop Sharing In Ubuntu and Linux Mint.md new file mode 100644 index 0000000000..2ee5e7d94a --- /dev/null +++ b/sources/tech/20170404 How To Enable Desktop Sharing In Ubuntu and Linux Mint.md @@ -0,0 +1,128 @@ +How To Enable Desktop Sharing In Ubuntu and Linux Mint +============================================================ + + +Desktop sharing refers to technologies that enable remote access and remote collaboration on a computer desktop via a graphical terminal emulator. Desktop sharing allows two or more Internet-enabled computer users to work on the same files from different locations. + +In this article, we will show you how to enable desktop sharing in Ubuntu and Linux Mint, with a few vital security features. + +### Enabling Desktop Sharing in Ubuntu and Linux Mint + +1. In the Ubuntu Dash or Linux Mint Menu, search for “desktop sharing” as shown in the following screenshot, once you get it, launch it. + +[ + ![Search for Desktop Sharing in Ubuntu](http://www.tecmint.com/wp-content/uploads/2017/03/search-for-desktop-sharing.png) +][1] + +Search for Desktop Sharing in Ubuntu + +2. Once you launch Desktop sharing, there are three categories of desktop sharing settings: sharing, security and notification settings. + +Under sharing, check the option “Allow others users to view your desktop” to enable desktop sharing. Optionally, you can also permit other users to remotely control your desktops by checking the option “Allow others users to control your desktop”. + +[ + ![Desktop Sharing Preferences](http://www.tecmint.com/wp-content/uploads/2017/03/desktop-sharing-settings-inte.png) +][2] + +Desktop Sharing Preferences + +3. Next in security section, you can choose to manually confirm each remote connection by checking the option “You must confirm each access to this computer”. + +Again, another useful security feature is creating a certain shared password using the option “Require user to enter this password”, that remote users must know and enter each time they want to access your desktop. + +4. Concerning notifications, you can keep an eye on remote connections by choosing to show the notification area icon each time there is a remote connection to your desktops by selecting “Only when someone is connected”. + +[ + ![Configure Desktop Sharing Set](http://www.tecmint.com/wp-content/uploads/2017/03/Configure-Desktop-Sharing-Set.png) +][3] + +Configure Desktop Sharing Set + +When you have set all the desktop sharing options, click Close. Now you have successfully permitted desktop sharing on your Ubuntu or Linux Mint desktop. + +### Testing Desktop Sharing in Ubuntu Remotely + +You can test to ensure that it’s working using a remote connection application. In this example, I will show you how some of the options we set above work. + +5. I will connect to my Ubuntu PC using VNC (Virtual Network Computing) protocol via [remmina remote connection application][4]. + +[ + ![Remmina Desktop Sharing Tool](http://www.tecmint.com/wp-content/uploads/2017/03/Remmina-Desktop-Sharing-Tool.png) +][5] + +Remmina Desktop Sharing Tool + +6. After clicking on Ubuntu PC item, I get the interface below to configure my connection settings. + +[ + ![Remmina Desktop Sharing Preferences](http://www.tecmint.com/wp-content/uploads/2017/03/Remmina-Configure-Remote-Desk.png) +][6] + +Remmina Desktop Sharing Preferences + +7. After performing all the settings, I will click Connect. Then provide the SSH password for the username and click OK. + +[ + ![Enter SSH User Password](http://www.tecmint.com/wp-content/uploads/2017/03/shared-pass.png) +][7] + +Enter SSH User Password + +I have got this black screen after clicking OK because, on the remote machine, the connection has not been confirmed yet. + +[ + ![Black Screen Before Confirmation](http://www.tecmint.com/wp-content/uploads/2017/03/black-screen-before-confirmat.png) +][8] + +Black Screen Before Confirmation + +8. Now on the remote machine, I have to accept the remote access request by clicking on “Allow” as shown in the next screenshot. + +[ + ![Allow Remote Desktop Sharing](http://www.tecmint.com/wp-content/uploads/2017/03/accept-remote-access-request.png) +][9] + +Allow Remote Desktop Sharing + +9. After accepting the request, I have successfully connected, remotely to my Ubuntu desktop machine. + +[ + ![Remote Ubuntu Desktop](http://www.tecmint.com/wp-content/uploads/2017/03/successfully-connected-to-rem.png) +][10] + +Remote Ubuntu Desktop + +That’s it! In this article, we described how to enable desktop sharing in Ubuntu and Linux Mint. Use the comment section below to write back to us. + +-------------------------------------------------------------------------------- + + +作者简介: + +Aaron Kili is a Linux and F.O.S.S enthusiast, an upcoming Linux SysAdmin, web developer, and currently a content creator for TecMint who loves working with computers and strongly believes in sharing knowledge. + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/enable-desktop-sharing-in-ubuntu-linux-mint/ + +作者:[Aaron Kili][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.tecmint.com/author/aaronkili/ + +[1]:http://www.tecmint.com/wp-content/uploads/2017/03/search-for-desktop-sharing.png +[2]:http://www.tecmint.com/wp-content/uploads/2017/03/desktop-sharing-settings-inte.png +[3]:http://www.tecmint.com/wp-content/uploads/2017/03/Configure-Desktop-Sharing-Set.png +[4]:http://www.tecmint.com/remmina-remote-desktop-sharing-and-ssh-client +[5]:http://www.tecmint.com/wp-content/uploads/2017/03/Remmina-Desktop-Sharing-Tool.png +[6]:http://www.tecmint.com/wp-content/uploads/2017/03/Remmina-Configure-Remote-Desk.png +[7]:http://www.tecmint.com/wp-content/uploads/2017/03/shared-pass.png +[8]:http://www.tecmint.com/wp-content/uploads/2017/03/black-screen-before-confirmat.png +[9]:http://www.tecmint.com/wp-content/uploads/2017/03/accept-remote-access-request.png +[10]:http://www.tecmint.com/wp-content/uploads/2017/03/successfully-connected-to-rem.png +[11]:http://www.tecmint.com/author/aaronkili/ +[12]:http://www.tecmint.com/10-useful-free-linux-ebooks-for-newbies-and-administrators/ +[13]:http://www.tecmint.com/free-linux-shell-scripting-books/ From 9da59dd6b4da9492187ea6ac0aae7924d3ade4a3 Mon Sep 17 00:00:00 2001 From: firstadream Date: Mon, 10 Apr 2017 23:35:30 +0800 Subject: [PATCH 28/52] =?UTF-8?q?Delete=2020161223=20Will=20Android=20do?= =?UTF-8?q?=20for=20the=20IoT=20what=20it=20did=20for=C2=A0mobile.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...d do for the IoT what it did for mobile.md | 140 ------------------ 1 file changed, 140 deletions(-) delete mode 100644 sources/tech/20161223 Will Android do for the IoT what it did for mobile.md diff --git a/sources/tech/20161223 Will Android do for the IoT what it did for mobile.md b/sources/tech/20161223 Will Android do for the IoT what it did for mobile.md deleted file mode 100644 index 5d97f83b46..0000000000 --- a/sources/tech/20161223 Will Android do for the IoT what it did for mobile.md +++ /dev/null @@ -1,140 +0,0 @@ - -Translating by fristadream - -Will Android do for the IoT what it did for mobile? -============================================================ - - ![](https://cdn-images-1.medium.com/max/1000/1*GF6e6Vd-22PViWT8EDpLNA.jpeg) - -Android Things gives the IoT Wings - -### My first 24 hours with Android Things - -Just when I was in the middle of an Android based IoT commercial project running on a Raspberry Pi 3, something awesome happened. Google released the first preview of [Android Things][1], their SDK targeted specifically at (initially) 3 SBC’s (Single Board Computers) — the Pi 3, the Intel Edison and the NXP Pico. To say I was struggling is a bit of an understatement — without even an established port of Android to the Pi, we were at the mercy of the various quirks and omissions of the well-meaning but problematic homebrew distro brigade. One of these problems was a deal breaker too — no touchscreen support, not even for the official one sold by [Element14][2]. I had an idea Android was heading for the Pi already, and earlier a mention in a [commit to the AOSP project from Google][3] got everyone excited for a while. So when, on 12th Dec 2016, without much fanfare I might add, Google announced “Android Things” plus a downloadable SDK, I dived in with both hands, a map and a flashlight, and hung a “do not disturb” sign on my door… - -### Questions? - -I had many questions regarding Googles Android on the Pi, having done extensive work with Android previously and a few Pi projects, including being involved right now in the one mentioned. I’ll try to address these as I proceed, but the first and biggest was answered right away — there is full Android Studio support and the Pi becomes just another regular ADB-addressable device on your list. Yay! The power, convenience and sheer ease of use we get within Android Studio is available at last to real IoT hardware, so we get all the layout previews, debug system, source checkers, automated tests etc. I can’t stress this enough. Up until now, most of my work onboard the Pi had been in Python having SSH’d in using some editor running on the Pi (MC if you really want to know). This worked, and no doubt hardcore Pi/Python heads could point out far better ways of working, but it really felt like I’d timewarped back to the 80’s in terms of software development. My projects involved writing Android software on handsets which controlled the Pi, so this rubbed salt in the wound — I was using Android Studio for “real” Android work, and SSH for the rest. That’s all over now. - -All samples are for the 3 SBC’s, of which the the Pi 3 is just one. The Build.DEVICE constant lets you determine this at runtime, so you see lots of code like: - -``` - public static String getGPIOForButton() { - switch (Build.DEVICE) { - case DEVICE_EDISON_ARDUINO: - return "IO12"; - case DEVICE_EDISON: - return "GP44"; - case DEVICE_RPI3: - return "BCM21"; - case DEVICE_NXP: - return "GPIO4_IO20"; - default: - throw new IllegalStateException(“Unknown Build.DEVICE “ + Build.DEVICE); - } - } -``` - -Of keen interest is the GPIO handling. Since I’m only familiar with the Pi, I can only assume the other SBCs work the same way, but this is the set of pins which can be defined as inputs/outputs and is the main interface to the physical outside world. The Pi Linux based OS distros have full and easy support via read and write methods in Python, but for Android you’d have to use the NDK to write C++ drivers, and talk to these via JNI in Java. Not that difficult, but something else to maintain in your build chain. The Pi also designates 2 pins for I2C, the clock and the data, so extra work would be needed handling those. I2C is the really cool bus-addressable system which turns many separate pins of data into one by serialising it. So here’s the kicker — all that’s done directly in Android Things for you. You just _read()_and _write() _to/from whatever GPIO pin you need, and I2C is as easy as this: - -``` -public class HomeActivity extends Activity { - // I2C Device Name - private static final String I2C_DEVICE_NAME = ...; - // I2C Slave Address - private static final int I2C_ADDRESS = ...; - - private I2cDevice mDevice; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // Attempt to access the I2C device - try { - PeripheralManagerService manager = new PeripheralManagerService(); - mDevice = manager.openI2cDevice(I2C_DEVICE_NAME, I2C_ADDRESS) - } catch (IOException e) { - Log.w(TAG, "Unable to access I2C device", e); - } - } - - @Override - protected void onDestroy() { - super.onDestroy(); - - if (mDevice != null) { - try { - mDevice.close(); - mDevice = null; - } catch (IOException e) { - Log.w(TAG, "Unable to close I2C device", e); - } - } - } -} -``` - -### What version of Android is Android Things based on? - -This looks to be Android 7.0, which is fantastic because we get all the material design UI, the optimisations, the security hardening and so on from all the previous versions of Android. It also raises an interesting question — how are future platform updates rolled out, as opposed to your app which you have to manage separately? Remember, these devices may not be connected to the internet. We are no longer in the comfortable space of cellular/WiFi connections being assumed to at least be available, even if sometimes unreliable. - -The other worry was this being an offshoot version of Android in name only, where to accommodate the lowest common denominator, something so simple it could power an Arduino has been released — more of a marketing exercise than a rich OS. That’s quickly put to bed by looking at the [samples][4], actually — some even use SVG graphics as resources, a very recent Android innovation, rather than the traditional bitmap-based graphics, which of course it also handles with ease. - -Inevitably, regular Android will throw up issues when compared with Android Things. For example, there is the permissions conundrum. Mitigated somewhat by the fact Android Things is designed to power fixed hardware devices, so the user wouldn’t normally install apps after it’s been built, it’s nevertheless a problem asking them for permissions on a device which might not have a UI! The solution is to grant all the permissions an app might need at install time. Normally, these devices are one app only, and that app is the one which runs when it powers up. - - ![](https://cdn-images-1.medium.com/max/800/1*pi7HyLT-BVwHQ_Rw3TDSWQ.png) - -### What happened to Brillo? - -Brillo was the codename given to Googles previous IoT OS, which sounds a lot like what Android Things used to be called. In fact you see many references to Brillo still, especially in the source code folder names in the GitHub Android Things examples. However, it has ceased to be. All hail the new king! - -### UI Guidelines? - -Google issues extensive guidelines regarding Android smartphone and tablet apps, such as how far apart on screen buttons should be and so on. Sure, its best to follow these where practical, but we’re not in Kansas any more. There is nothing there by default — it’s up the the app author to manage _everything_. This includes the top status bar, the bottom navigation bar — absolutely everything. Years of Google telling Android app authors never to render an onscreen BACK button because the platform will supply one is thrown out, because for Android Things there [might not even be a UI at all!][5] - -### How much support of the Google services we’re used to from smartphones can we expect? - -Quite a bit actually, but not everything. The first preview has no bluetooth support. No NFC, either — both of which are heavily contributing to the IoT revolution. The SBC’s support them, so I can’t see them not being available for too long. Since there’s no notification bar, there can’t be any notifications. No Maps. There’s no default soft keyboard, you have to install one yourself. And since there is no Play Store, you have to get down and dirty with ADB to do this, and many other operations. - -When developing for Android Things I tried to make the same APK I was targeting for the Pi run on a regular handset. This threw up an error preventing it from being installed on anything other than an Android Things device: library “_com.google.android.things_” not present. Kinda makes sense, because only Android Things devices would need this, but it seemed limiting because not only would no smartphones or tablets have it present, but neither would any emulators. It looked like you could only run and test your Android Things apps on physical Android Things devices … until Google helpfully replied to my query on this in the [G+ Google’s IoT Developers Community][6] group with a workaround. Bullet dodged there, then. - -### How can we expect the Android Things ecosystem to evolve now? - -I’d expect to see a lot more porting of traditional Linux server based apps which didn’t really make sense to an Android restricted to smartphones and tablets. For example, a web server suddenly becomes very useful. Some exist already, but nothing like the heavyweights such as Apache or Nginx. IoT devices might not have a local UI, but administering them via a browser is certainly viable, so something to present a web panel this way is needed. Similarly comms apps from the big names — all it needs is a mike and speaker and in theory it’s good to go for any video calling app, like Duo, Skype, FB etc. How far this evolution goes is anyone’s guess. Will there be a Play Store? Will they show ads? Can we be sure they won’t spy on us, or let hackers control them? The IoT from a consumer point of view always was net-connected devices with touchscreens, and everyone’s already used to that way of working from their smartphones. - -I’d also expect to see rapid progress regarding hardware — in particular many more SBC’s at even lower costs. Look at the amazing $5 Raspberry Pi Zero, which unfortunately almost certainly can’t run Android Things due to its limited CPU and RAM. How long until one like this can? It’s pretty obvious, now the bar has been set, any self respecting SBC manufacturer will be aiming for Android Things compatibility, and probably the economies of scale will apply to the peripherals too such as a $2 3" touchscreen. Microwave ovens just won’t sell unless you can watch YouTube on them, and your dishwasher just put in a bid for more powder on eBay since it noticed you’re running low… - -However, I don’t think we can get too carried away here. Knowing a little about Android architecture helps when thinking of it as an all-encompassing IoT OS. It still uses Java, which has been hammered to death in the past with all its garbage-collection induced timing issues. That’s the least of it though. A genuine realtime OS relies on predictable, accurate and rock-solid timing or it can’t be described as “mission critical”. Think about medical applications, safety monitors, industrial controllers etc. With Android, your Activity/Service can, in theory, be killed at any time if the host OS thinks it needs to. Not so bad on a phone — the user restarts the app, kills other apps, or reboots the handset. A heart monitor is a different kettle all together though. If that foreground Activity/Service is watching a GPIO pin, and the signal isn’t dealt with exactly when it is supposed to, we have failed. Some pretty fundamental changes would have to be made to Android to support this, and so far there’s no indication it’s even planned. - -### Those 24 hours - -So, back to my project. I thought I’d take the work I’d done already and just port as much as I could over, waiting for the inevitable roadblock where I had to head over to the G+ group, cap in hand for help. Which, apart from the query about running on non-AT devices, never happened. And it ran great! This project uses some oddball stuff too, custom fonts, prescise timers — all of which appeared perfectly laid out in Android Studio. So its top marks from me, Google — at last I can start giving actual prototypes out rather than just videos and screenshots. - -### The big picture - -The IoT OS landscape today looks very fragmented. There is clearly no market leader and despite all the hype and buzz we hear, it’s still incredibly early days. Can Google do to the IoT with Android Things what it did to mobile, where it’s dominance is now very close to 90%? I believe so, and if that is to happen, this launch of Android Things is exactly how they would go about it. - -Remember all the open vs closed software wars, mainly between Apple who never licence theirs, and Google who can’t give it away for free to enough people? That policy now comes back once more, because the idea of Apple launching a free IoT OS is as far fetched as them giving away their next iPhone for nothing. - -The IoT OS game is wide open for someone to grab, and the opposition won’t even be putting their kit on this time… - -Head over to the [Developer Preview][7] site to get your copy of the Android Things SDK now. - --------------------------------------------------------------------------------- - -via: https://medium.com/@carl.whalley/will-android-do-for-iot-what-it-did-for-mobile-c9ac79d06c#.hxva5aqi2 - -作者:[Carl Whalley][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://medium.com/@carl.whalley -[1]:https://developer.android.com/things/index.html -[2]:https://www.element14.com/community/docs/DOC-78156/l/raspberry-pi-7-touchscreen-display -[3]:http://www.androidpolice.com/2016/05/24/google-is-preparing-to-add-the-raspberry-pi-3-to-aosp-it-will-apparently-become-an-officially-supported-device/ -[4]:https://github.com/androidthings/sample-simpleui/blob/master/app/src/main/res/drawable/pinout_board_vert.xml -[5]:https://developer.android.com/things/sdk/index.html -[6]:https://plus.google.com/+CarlWhalley/posts/4tF76pWEs1D -[7]:https://developer.android.com/things/preview/index.html From 7e87aad3f14fa7d7b3f63eff5b701a492967d6b3 Mon Sep 17 00:00:00 2001 From: firstadream Date: Mon, 10 Apr 2017 23:38:09 +0800 Subject: [PATCH 29/52] Add files via upload From 37d6088144b6d25a795b4948add5c2a32f66188d Mon Sep 17 00:00:00 2001 From: firstadream Date: Mon, 10 Apr 2017 23:44:54 +0800 Subject: [PATCH 30/52] =?UTF-8?q?Create=2020161223=20Will=20Android=20do?= =?UTF-8?q?=20for=20the=20IoT=20what=20it=20did=20for=C2=A0mobile.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...d do for the IoT what it did for mobile.md | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 translated/tech/20161223 Will Android do for the IoT what it did for mobile.md diff --git a/translated/tech/20161223 Will Android do for the IoT what it did for mobile.md b/translated/tech/20161223 Will Android do for the IoT what it did for mobile.md new file mode 100644 index 0000000000..87801ed572 --- /dev/null +++ b/translated/tech/20161223 Will Android do for the IoT what it did for mobile.md @@ -0,0 +1,129 @@ + +安卓IoT能否像在移动终端一样成功? +============================================================ + + ![](https://cdn-images-1.medium.com/max/1000/1*GF6e6Vd-22PViWT8EDpLNA.jpeg) +Android Things让IoT如虎添翼 + +###我在Android Things上的最初24小时 +正当我在开发一个基于Android的运行在树莓派3的物联网商业项目时,一些令人惊喜的事情发生了。谷歌发布了[Android Things] [1]的第一个预览版本,他们的SDK专门针对(最初)3个SBC(单板计算机) - 树莓派 3,英特尔Edison和恩智浦Pico。说我一直在挣扎似乎有些轻描淡写 - 没有成功的移植树莓派安卓可以参照,我们在理想丰满,但是实践漏洞百出的内测版本上叫苦不迭。其中一个问题,同时也是不可原谅的问题是,它不支持触摸屏,甚至连[Element14][2]官方销售的也不支持。曾经我认为安卓已经支持树莓派,更早时候[commi tto AOSP project from Google][3]提到过Pi曾让所有人兴奋不已。所以当2016年12月12日谷歌发布"Android Things"和其SDK的时候,我马上闭门谢客,全身心地去研究了…… + +### 问题? +安卓扩展的工作和Pi上做过的一些项目,包括之前提到的,当前正在开发中的Pi项目,使我对谷歌安卓产生了许多问题。未来我会尝试解决它们,但是最重要的问题可以马上解答 - 有完整的Android Studio支持,Pi成为列表上的另一个常规的ADB可寻址设备。好极了。Android Atudio强大的,便利的,纯粹的易用的功能包括布局预览,调试系统,源码检查器,自动化测试等可以真正的应用在IoT硬件上。这些好处怎么说都不过分。到目前为止,我在Pi上的大部分工作都是在python中使用SSH运行在Pi上的编辑器(MC,如果你真的想知道)。这是有效的,毫无疑问硬核Pi / Python头可以指出更好的工作方式,而不是当前这种像极了80年代码农的软件开发模式。我的项目涉及到在控制Pi的手机上编写Android软件,这有点像在伤口狂妄地撒盐 - 我使用Android Studio做“真正的”Android工作,用SSH做剩下的。但是有了"Android Things"之后,一切都结束了。 + +所有的示例代码都适用于3个SBC,Pi 只是其中之一。 Build.DEVICE常量在运行时确定,所以你会看到很多如下代码: + +``` + public static String getGPIOForButton() { + switch (Build.DEVICE) { + case DEVICE_EDISON_ARDUINO: + return "IO12"; + case DEVICE_EDISON: + return "GP44"; + case DEVICE_RPI3: + return "BCM21"; + case DEVICE_NXP: + return "GPIO4_IO20"; + default: + throw new IllegalStateException(“Unknown Build.DEVICE “ + Build.DEVICE); + } + } +``` + +我对GPIO处理有浓厚的兴趣。 由于我只熟悉Pi,我只能假定其他SBC工作方式相同,GPIO只是一组引脚,可以定义为输入/输出,是连接物理外部世界的主要接口。 基于Pi Linux的操作系统发行版通过Python中的读取和写入方法提供了完整和便捷的支持,但对于Android,您必须使用NDK编写C ++驱动程序,并通过JNI在Java中与这些驱动程序对接。 不是那么困难,但需要在你的构建链中维护额外的一些东西。 Pi还为I2C指定了2个引脚,时钟和数据,因此需要额外的工作来处理它们。 I2C是真正酷的总线寻址系统,它通过串行化将许多独立的数据引脚转换成一个。 所以这里的优势是 - Android Things已经帮你完成了所有这一切。 你只需要_read()_和_write()_to /from你需要的任何GPIO引脚,I2C同样容易: + +``` +public class HomeActivity extends Activity { + // I2C Device Name + private static final String I2C_DEVICE_NAME = ...; + // I2C Slave Address + private static final int I2C_ADDRESS = ...; + + private I2cDevice mDevice; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // Attempt to access the I2C device + try { + PeripheralManagerService manager = new PeripheralManagerService(); + mDevice = manager.openI2cDevice(I2C_DEVICE_NAME, I2C_ADDRESS) + } catch (IOException e) { + Log.w(TAG, "Unable to access I2C device", e); + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + + if (mDevice != null) { + try { + mDevice.close(); + mDevice = null; + } catch (IOException e) { + Log.w(TAG, "Unable to close I2C device", e); + } + } + } +} +``` +### Android Things基于Android的哪个版本? +看起来是Android 7.0,这样很好,因为我们可以继承Android以前的所有版本的文档,优化,安全加固等。它也提出了一个有趣的问题 - 与应用程序必须单独管理不同,未来的平台应如何更新升级?请记住,这些设备可能无法连接到互联网。我们可能不在蜂窝/ WiFi连接的舒适空间,虽然之前这些连接至少可用,即使有时不那么可靠。 + +另一个担心是,Android Things仅仅是一个名字不同的分支版本的Android,如何选择它们的共同特性,就像启动Arduino(已经发布的一个更像市场营销而不是操作系统的操作系统)这种简单特性。实际上,通过查看[samples] [4],一些功能可能永不再用 - 比如一个最近的Android创新,甚至使用SVG图形作为资源,而不是传统的基于位图的图形,当然Andorid Things也可以轻松处理。 + +不可避免地,与Android Things相比,普通的Android会抛出问题。例如,权限问题。因为Android Things为固定硬件设计,用户通常不会在这种设备上安装App,所以在一定程序上减轻了这个问题。另外,在没有图形界面的设备上请求权限通常不是问题,我们可以在安装时开放所有权限给App。 通常,这些设备只有一个应用程序,该应用程序从设备上电的那一刻就开始运行。 + + ![](https://cdn-images-1.medium.com/max/800/1*pi7HyLT-BVwHQ_Rw3TDSWQ.png) + +### Brillo怎么了? + +Brillo是谷歌以前的IoT操作系统的代号,听起来很像Android的前身。 实际上现在你仍然能看到很多Brillo引用,特别是在GitHub Android Things源码的例子中。 然而,它已经不复存在了。新王已经登基! + +### UI指南? +Google针对Android智能手机和平板电脑应用发布了大量指南,例如屏幕按钮间距等。 当然,你最好在可行的情况下遵循这些,但这已经不是本文应该考虑的范畴了。 缺省情况下什么也没有- 应用程序作者决定一切。 这包括顶部状态栏,底部导航栏 - 绝对一切。 多年来谷歌一直叮咛Android应用程序作者不要去渲染屏幕上的返回按钮,因为平台将提供一个抛出异常,因为对于Android Things,[可能甚至不是一个UI!] [5] + +### 多少智能手机上的服务可以期待? +有些,但不是所有。第一个预览版本没有蓝牙支持。没有NFC,两者都对物联网革命有重大贡献。 SBC支持他们,所以我们应该不会等待太久。由于没有通知栏,因此不支持任何通知。没有地图。缺省没有软键盘,你必须自己安装一个。由于没有Play商店,你只能屈尊通过 ADB做这个和许多其他操作。 + +当开发Android Things时我试图和Pi使用同一个APK。这引发了一个错误,阻止它安装在除Android Things设备之外的任何设备:库“_com.google.android.things_”不存在。 Kinda有意义,因为只有Android Things设备需要这个,但它似乎是有限的,因为不仅智能手机或平板电脑不会出现,任何模拟器也不会。似乎只能在物理Android Things设备上运行和测试您的Android Things应用程序...直到Google在[G + Google的IoT开发人员社区] [6]组中回答了我的问题,并提供了规避方案。但是,躲过初一,躲不过十五 。 + +### 让我如何期待Android Thing生态演进? + +我期望看到移植更多传统的基于Linux服务器的应用程序,这对Android只有智能手机和平板电脑没有意义。例如,Web服务器突然变得非常有用。一些已经存在,但没有像重量级的Apache,或Nginx。物联网设备可能没有本地UI,但通过浏览器管理它们当然是可行的,因此需要用这种方式呈现Web面板。类似的那些如雷贯耳的通讯应用程序 - 它需要的仅是一个麦克风和扬声器,在理论上对任何视频通话应用程序,如Duo,Skype,FB等都可行。这个演变能走多远目前只能猜测。会有Play商店吗?他们会展示广告吗?我们可以确定他们不会窥探我们,或让黑客控制他们?从消费者的角度来看,物联网应该是具有触摸屏的网络连接设备,因为每个人都已经习惯于通过智能手机工作。 + +我还期望看到硬件的迅速发展 - 特别是更多的SBC并且拥有更低的成本。看看惊人的5美元 树莓派0,不幸的是,由于其有限的CPU和RAM,几乎肯定不能运行Android Things。多久之后像这样的设备才能运行Android Things?这是很明显的,标杆已经设定,任何自重的SBC制造商将瞄准Android Things的兼容性,规模经济也将波及到外围设备,如23美元的触摸屏。没人购买不会播放YouTube的微波炉,你的洗碗机会在eBay上购买更多的粉末商品,因为它注意到你很少使用它…… + +然而,我不认为我们会失去掌控力。了解一点Android架构有助于将其视为一个包罗万象的物联网操作系统。它仍然使用Java,并几乎被其所有的垃圾回收机制导致的时序问题锤击致死。这仅仅是问题最少的部分。真正的实时操作系统依赖于可预测,准确和坚如磐石的时序,或者它不能被描述为“mission critical”。想想医疗应用程序,安全监视器,工业控制器等。使用Android,如果主机操作系统认为它需要,理论上可以在任何时候杀死您的活动/服务。在手机上不是那么糟糕 - 用户可以重新启动应用程序,杀死其他应用程序,或重新启动手机。心脏监视器完全是另一码事。如果前台Activity / Service正在监视一个GPIO引脚,并且信号没有被准确地处理,我们已经失败了。必须要做一些相当根本的改变让Android来支持这一点,到目前为止还没有迹象表明它已经在计划之中了。 + +###这24小时 +所以,回到我的项目。 我认为我会接管我已经完成和尽力能为的工作,等待不可避免的路障,并向G+社区寻求帮助。 除了一些在非Android Things上如何运行程序 的问题之外 ,没有其他问题。 它运行得很好! 这个项目也使用了一些奇怪的东西,自定义字体,高精定时器 - 所有这些都在Android Studio中完美地展现。对我而言,可以打满分 - 最后我可以开始给出实际原型,而不只是视频和截图。 + +### 蓝图 +今天的物联网操作系统环境看起来非常零碎。 显然没有市场领导者,尽管炒作之声沸反连天,物联网仍然在草创阶段。 谷歌Android物联网能否像它在移动端那样,现在Android在那里的主导地位非常接近90%? 我相信果真如此,Android Things的推出正是重要的一步。 + +记住所有的关于开放和封闭软件的战争,它们主要发生在从不授权的苹果和一直担心免费还不够充分的谷歌之间? 那个老梗又来了,因为让苹果推出一个免费的物联网操作系统的构想就像让他们免费赠送下一代iPhone一样遥不可及。 + +物联网操作系统游戏是开放的,大家机遇共享,不过这个时候,封闭派甚至不会公布它们的开发工具箱…… + +转到[Developer Preview] [7]网站,立即获取Android Things SDK的副本。 + +-------------------------------------------------------------------------------- + +via: https://medium.com/@carl.whalley/will-android-do-for-iot-what-it-did-for-mobile-c9ac79d06c#.hxva5aqi2 + +作者:[Carl Whalley][a] +译者:[firstadream](https://github.com/firstadream) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://medium.com/@carl.whalley +[1]:https://developer.android.com/things/index.html +[2]:https://www.element14.com/community/docs/DOC-78156/l/raspberry-pi-7-touchscreen-display +[3]:http://www.androidpolice.com/2016/05/24/google-is-preparing-to-add-the-raspberry-pi-3-to-aosp-it-will-apparently-become-an-officially-supported-device/ +[4]:https://github.com/androidthings/sample-simpleui/blob/master/app/src/main/res/drawable/pinout_board_vert.xml +[5]:https://developer.android.com/things/sdk/index.html +[6]:https://plus.google.com/+CarlWhalley/posts/4tF76pWEs1D +[7]:https://developer.android.com/things/preview/index.html From b2e24fde8f21bf85c205af788f4162f2f0dc0054 Mon Sep 17 00:00:00 2001 From: firstadream Date: Mon, 10 Apr 2017 23:58:27 +0800 Subject: [PATCH 31/52] Update 20110127 How debuggers work Part 2 - Breakpoints.md --- .../tech/20110127 How debuggers work Part 2 - Breakpoints.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20110127 How debuggers work Part 2 - Breakpoints.md b/sources/tech/20110127 How debuggers work Part 2 - Breakpoints.md index 59bad4ee0f..69fd87a90e 100644 --- a/sources/tech/20110127 How debuggers work Part 2 - Breakpoints.md +++ b/sources/tech/20110127 How debuggers work Part 2 - Breakpoints.md @@ -1,3 +1,5 @@ +Firstadream translating + [How debuggers work: Part 2 - Breakpoints][26] ============================================================ From bc1c41ad25310095e4eea7a6b8ccfc13fdad7c31 Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 11 Apr 2017 08:52:50 +0800 Subject: [PATCH 32/52] PRF&PUB:20161216 The truth about traditional JavaScript benchmarks.md @ictlyh --- ...h Monitoring and Debugging Tool for Linux.md | 50 +++++++++--------- ...a DHCP Server in CentOS RHEL and Fedora.md | 51 +++++++++---------- 2 files changed, 49 insertions(+), 52 deletions(-) rename {translated/tech => published}/20170203 bmon – A Powerful Network Bandwidth Monitoring and Debugging Tool for Linux.md (76%) diff --git a/translated/tech/20170203 bmon – A Powerful Network Bandwidth Monitoring and Debugging Tool for Linux.md b/published/20170203 bmon – A Powerful Network Bandwidth Monitoring and Debugging Tool for Linux.md similarity index 76% rename from translated/tech/20170203 bmon – A Powerful Network Bandwidth Monitoring and Debugging Tool for Linux.md rename to published/20170203 bmon – A Powerful Network Bandwidth Monitoring and Debugging Tool for Linux.md index 42b8017f9e..efb60ae7ee 100644 --- a/translated/tech/20170203 bmon – A Powerful Network Bandwidth Monitoring and Debugging Tool for Linux.md +++ b/published/20170203 bmon – A Powerful Network Bandwidth Monitoring and Debugging Tool for Linux.md @@ -1,11 +1,11 @@ -bmon - Linux 下一个强大的网络带宽监视和调试工具 +bmon:Linux 下一个强大的网络带宽监视和调试工具 ============================================================ -bmon 是类 Unix 系统中一个基于文本,简单但非常强大的 [网络监视和调试工具][1],它能抓取网络相关统计信息并把它们以用户友好的格式展现出来。它是一个可靠高效的带宽监视和网速预估器。 +bmon 是类 Unix 系统中一个基于文本,简单但非常强大的 [网络监视和调试工具][1],它能抓取网络相关统计信息并把它们以用户友好的格式展现出来。它是一个可靠高效的带宽监视和网速估测工具。 -它能使用各种输入模块读取输入,并以各种输出模式显示输出,包括交互式用户界面和用于脚本编写的可编程文本输出。 +它能使用各种输入模块读取输入,并以各种输出模式显示输出,包括交互式文本用户界面和用于脚本编写的可编程文本输出。 -**推荐阅读:** [监控 Linux 性能的20个命令行工具][2] +**推荐阅读:** [监控 Linux 性能的 20 个命令行工具][2] ### 在 Linux 上安装 bmon 带宽监视工具 @@ -19,9 +19,9 @@ $ sudo apt-get install bmon [On Debian/Ubuntu/Mint] 另外,你也可以从 [https://pkgs.org/download/bmon][3] 获取对应你 Linux 发行版的 `.rpm` 和 `.deb` 软件包。 -如果你想要最新版本(例如版本4.0)的 bmon,你需要通过下面的命令从源码构建。 +如果你想要最新版本(例如版本 4.0)的 bmon,你需要通过下面的命令从源码构建。 -#### 在 CentOS、RHEL 和 Fedora 中 +**在 CentOS、RHEL 和 Fedora 中** ``` $ git clone https://github.com/tgraf/bmon.git @@ -33,7 +33,7 @@ $ sudo make $ sudo make install ``` -#### 在 Debian、Ubuntu 和 Linux Mint 中 +**在 Debian、Ubuntu 和 Linux Mint 中** ``` $ git clone https://github.com/tgraf/bmon.git @@ -47,7 +47,7 @@ $ sudo make install ### 如何在 Linux 中使用 bmon 带宽监视工具 -通过以下命令运行它(给初学者:RX 表示每秒接收数据,TX 表示每秒发送数据): +通过以下命令运行它(初学者说明:RX 表示每秒接收数据,TX 表示每秒发送数据): ``` $ bmon @@ -63,19 +63,19 @@ $ bmon ![bmon - Detailed Bandwidth Statistics](http://www.tecmint.com/wp-content/uploads/2017/02/bmon-Detailed-Bandwidth-Statistics.gif) ][5] -按 `[Shift + ?]` 可以查看快速指南。再次按 `[Shift + ?]` 可以退出(指南)界面。 +按 `Shift + ?` 可以查看快速指南。再次按 `Shift + ?` 可以退出(指南)界面。 [ ![bmon - 快速指南](http://www.tecmint.com/wp-content/uploads/2017/02/bmon-Quick-Reference.png) ][6] -bmon – 快速指南 +*bmon – 快速指南* 通过 `Up` 和 `Down` 箭头键可以查看特定网卡的统计信息。但是,要监视一个特定的网卡,你也可以像下面这样作为命令行参数指定。 -**推荐阅读:** [监控 Linux 性能的13个工具][7] +**推荐阅读:** [监控 Linux 性能的 13 个工具][7] -标签 `-p` 指定了要显示的网卡,在下面的例子中,我们会监视网卡 `enp1s0`: +选项 `-p` 指定了要显示的网卡,在下面的例子中,我们会监视网卡 `enp1s0`: ``` $ bmon -p enp1s0 @@ -84,31 +84,30 @@ $ bmon -p enp1s0 ![bmon - 监控以太网带宽](http://www.tecmint.com/wp-content/uploads/2017/02/bmon-Monitor-Ethernet-Bandwidth.png) ][8] -bmon – 监控以太网带宽 +*bmon – 监控以太网带宽* -要查看每秒位数而不是字节数,可以像下面这样使用 `-b` 标签: +要查看每秒位数而不是每秒字节数,可以像下面这样使用 `-b` 选项: ``` $ bmon -bp enp1s0 ``` -我们也可以像下面这样指定每秒的间隔数: +我们也可以像下面这样按秒指定刷新间隔时间: ``` $ bmon -r 5 -p enp1s0 ``` ### 如何使用 bmon 的输入模块 -### How to Use bmon Input Modules bmon 有很多能提供网卡统计数据的输入模块,其中包括: 1. netlink - 使用 Netlink 协议从内核中收集网卡和流量控制统计信息。这是默认的输入模块。 -2. proc - 从 /proc/net/dev 文件读取网卡统计信息。它被认为是传统界面,且提供了向后兼容性。它是 Netlink 接口不可用时的备用模块。 +2. proc - 从 `/proc/net/dev` 文件读取网卡统计信息。它被认为是传统界面,且提供了向后兼容性。它是 Netlink 接口不可用时的备用模块。 3. dummy - 这是用于调试和测试的可编程输入模块。 4. null - 停用数据收集。 -要查看关于某个模块的其余信息,可以像下面这样使用 “help” 选项调用它: +要查看关于某个模块的其余信息,可以像下面这样使用 `help` 选项调用它: ``` $ bmon -i netlink:help @@ -125,12 +124,11 @@ $ bmon -i proc -p enp1s0 bmon 也使用输出模块显示或者导出上面输入模块收集的统计数据,输出模块包括: 1. curses - 这是一个交互式的文本用户界面,它提供实时的网上估计以及每个属性的图形化表示。这是默认的输出模块。 -2. ascii - 这是用于用户查看的简单可编程文本输出。它能显示网卡列表、详细计数以及图形到控制台。当 curses 不可用时这是默认的备选输出模块。 +2. ascii - 这是用于用户查看的简单可编程文本输出。它能显示网卡列表、详细计数以及图形到控制台。当 curses 库不可用时这是默认的备选输出模块。 3. format - 这是完全脚本化的输出模式,供其它程序使用 - 意味着我们可以在后面的脚本和程序中使用它的输出值进行分析。 4. null - 停用输出。 -像下面这样通过 “help” 标签获取更多的模块信息。 -To get more info concerning a module, run the it with the “help” flag set like so: +像下面这样通过 `help` 选项获取更多的模块信息。 ``` $ bmon -o curses:help @@ -144,7 +142,7 @@ $ bmon -p enp1s0 -o ascii ![bmon - Ascii 输出模式](http://www.tecmint.com/wp-content/uploads/2017/02/bmon-Ascii-Output-Mode.png) ][9] -bmon – Ascii 输出模式 +*bmon – Ascii 输出模式* 我们也可以用 format 输出模式,然后在脚本或者其它程序中使用获取的值: @@ -155,7 +153,7 @@ $ bmon -p enp1s0 -o format ![bmon - Format 输出模式](http://www.tecmint.com/wp-content/uploads/2017/02/bmon-format-output-mode.png) ][10] -bmon – Format 输出模式 +*bmon – Format 输出模式* 想要其它的使用信息、选项和事例,可以阅读 bmon 的 man 手册: @@ -163,7 +161,7 @@ bmon – Format 输出模式 $ man bmon ``` -访问 bmon 的Github 仓库:[https://github.com/tgraf/bmon][11]. +访问 bmon 的 Github 仓库:[https://github.com/tgraf/bmon][11]。 就是这些,在不同场景下尝试 bmon 的多个功能吧,别忘了在下面的评论部分和我们分享你的想法。 @@ -171,7 +169,7 @@ $ man bmon 译者简介: -Aaron Kili 是一个 Linux 和 F.O.S.S 爱好者、Linux 系统管理员、网络开发人员,现在也是 TecMint 的内容创作者,她喜欢和电脑一起工作,坚信共享知识。 +Aaron Kili 是一个 Linux 和 F.O.S.S 爱好者、Linux 系统管理员、网络开发人员,现在也是 TecMint 的内容创作者,他喜欢和电脑一起工作,坚信共享知识。 -------------------------------------------------------------------------------- @@ -179,7 +177,7 @@ via: http://www.tecmint.com/bmon-network-bandwidth-monitoring-debugging-linux/ 作者:[Aaron Kili][a] 译者:[ictlyh](https://github.com/ictlyh) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20170321 How to Install a DHCP Server in CentOS RHEL and Fedora.md b/translated/tech/20170321 How to Install a DHCP Server in CentOS RHEL and Fedora.md index 33fa8c3bc3..be044a15a9 100644 --- a/translated/tech/20170321 How to Install a DHCP Server in CentOS RHEL and Fedora.md +++ b/translated/tech/20170321 How to Install a DHCP Server in CentOS RHEL and Fedora.md @@ -7,27 +7,25 @@ DHCP(Dynamic Host Configuration Protocol)是一个网络协议,它使得 在这篇指南中,我们会介绍如何在 CentOS/RHEL 和 Fedora 发行版中安装和配置 DHCP 服务。 -#### 设置测试环境 +### 设置测试环境 -本次安装中我们使用如下的测试环境。 +本次安装中我们使用如下的测试环境: -``` -DHCP 服务器 - CentOS 7 -DHCP 客户端 - Fedora 25 和 Ubuntu 16.04 -``` +- DHCP 服务器 - CentOS 7 +- DHCP 客户端 - Fedora 25 和 Ubuntu 16.04 -#### DHCP 如何工作? +### DHCP 如何工作? 在进入下一步之前,让我们首先了解一下 DHCP 的工作流程: -* 当已连接到网络的客户端计算机(配置为使用 DHCP)启动时,它会发送一个 DHCPDISCOVER 消息到 DHCP 服务器。 -* 当 DHCP 服务器接收到 DHCPDISCOVER 请求消息时,它会回复一个 DHCPOFFER 消息。 -* 客户端收到 DHCPOFFER 消息后,它再发送给服务器一个 DHCPREQUEST 消息,表示客户端已准备好获取 DHCPOFFER 消息中提供的网络配置。 -* 最后,DHCP 服务器收到客户端的 DHCPREQUEST 消息,并回复 DHCPACK 消息,表示允许客户端使用分配给它的 IP 地址。 +* 当已连接到网络的客户端计算机(配置为使用 DHCP)启动时,它会发送一个 `DHCPDISCOVER` 消息到 DHCP 服务器。 +* 当 DHCP 服务器接收到 `DHCPDISCOVER` 请求消息时,它会回复一个 `DHCPOFFER` 消息。 +* 客户端收到 `DHCPOFFER` 消息后,它再发送给服务器一个 `DHCPREQUEST` 消息,表示客户端已准备好获取 `DHCPOFFER` 消息中提供的网络配置。 +* 最后,DHCP 服务器收到客户端的 `DHCPREQUEST` 消息,并回复 `DHCPACK` 消息,表示允许客户端使用分配给它的 IP 地址。 ### 第一步:在 CentOS 上安装 DHCP 服务 -1. 安装 DHCP 服务非常简单,只需要运行下面的命令即可。 +1、安装 DHCP 服务非常简单,只需要运行下面的命令即可。 ``` $ yum -y install dhcp @@ -35,7 +33,7 @@ $ yum -y install dhcp 重要:假如系统中有多个网卡,但你想只在其中一个网卡上启用 DHCP 服务,可以按照下面的步骤在该网卡上启用 DHCP 服务。 -2. 打开文件 /etc/sysconfig/dhcpd,将指定网卡的名称添加到 DHCPDARGS 列表,假如网卡名称为 `eth0`,则添加: +2、 打开文件 `/etc/sysconfig/dhcpd`,将指定网卡的名称添加到 `DHCPDARGS` 列表,假如网卡名称为 `eth0`,则添加: ``` DHCPDARGS=eth0 @@ -45,9 +43,9 @@ DHCPDARGS=eth0 ### 第二步:在 CentOS 上配置 DHCP 服务 -3. 对于初学者来说,配置 DHCP 服务的第一步是创建 `dhcpd.conf` 配置文件,DHCP 主要配置文件一般是 /etc/dhcp/dhcpd.conf(默认情况下该文件为空),该文件保存了发送给客户端的所有网络信息。 +3、 对于初学者来说,配置 DHCP 服务的第一步是创建 `dhcpd.conf` 配置文件,DHCP 主要配置文件一般是 `/etc/dhcp/dhcpd.conf`(默认情况下该文件为空),该文件保存了发送给客户端的所有网络信息。 -但是,有一个样例配置文件 /usr/share/doc/dhcp*/dhcpd.conf.sample,这是配置 DHCP 服务的良好开始。 +但是,有一个样例配置文件 `/usr/share/doc/dhcp*/dhcpd.conf.sample`,这是配置 DHCP 服务的良好开始。 DHCP 配置文件中定义了两种类型的语句: @@ -60,7 +58,7 @@ DHCP 配置文件中定义了两种类型的语句: $ cp /usr/share/doc/dhcp-4.2.5/dhcpd.conf.example /etc/dhcp/dhcpd.conf ``` -4. 然后,打开主配置文件并定义你的 DHCP 服务选项: +4、 然后,打开主配置文件并定义你的 DHCP 服务选项: ``` $ vi /etc/dhcp/dhcpd.conf @@ -76,7 +74,7 @@ max-lease-time 7200; authoritative; ``` -5. 然后,定义一个子网;在这个事例中,我们会为 192.168.56.0/24 局域网配置 DHCP(注意使用你实际场景中的值): +5、 然后,定义一个子网;在这个事例中,我们会为 `192.168.56.0/24` 局域网配置 DHCP(注意使用你实际场景中的值): ``` subnet 192.168.56.0 netmask 255.255.255.0 { @@ -91,7 +89,7 @@ range 192.168.56.120 192.168.56.200; ### 第三步:为 DHCP 客户端分配静态 IP -只需要在 /etc/dhcp/dhcpd.conf 文件中定义下面的部分,其中你必须显式指定它的 MAC 地址和打算分配的 IP,你就可以为网络中指定的客户端计算机分配一个静态 IP 地址: +只需要在 `/etc/dhcp/dhcpd.conf` 文件中定义下面的部分,其中你必须显式指定它的 MAC 地址和打算分配的 IP,你就可以为网络中指定的客户端计算机分配一个静态 IP 地址: ``` host ubuntu-node { @@ -112,7 +110,7 @@ fixed-address 192.168.56.110; $ ifconfig -a eth0 | grep HWaddr ``` -6. 现在,使用下面的命令启动 DHCP 服务,并使在下次系统启动时自动启动: +6、 现在,使用下面的命令启动 DHCP 服务,并使在下次系统启动时自动启动: ``` ---------- On CentOS/RHEL 7 ---------- @@ -120,9 +118,10 @@ $ systemctl start dhcpd $ systemctl enable dhcpd ---------- On CentOS/RHEL 6 ---------- $ service dhcpd start -$ chkconfig dhcpd on``` +$ chkconfig dhcpd on +``` -7. 另外,别忘了使用下面的命令允许 DHCP 服务通过防火墙(DHCPD 守护进程通过 UDP 监听67号端口): +7、 另外,别忘了使用下面的命令允许 DHCP 服务通过防火墙(DHCPD 守护进程通过 UDP 监听67号端口): ``` ---------- On CentOS/RHEL 7 ---------- @@ -135,7 +134,7 @@ $ service iptables save ### 第四步:配置 DHCP 客户端 -8. 现在,你可以为网络中的客户端配置自动从 DHCP 服务器中获取 IP 地址。登录到客户端机器并按照下面的方式修改以太网接口的配置文件(注意网卡的名称和编号): +8、 现在,你可以为网络中的客户端配置自动从 DHCP 服务器中获取 IP 地址。登录到客户端机器并按照下面的方式修改以太网接口的配置文件(注意网卡的名称和编号): ``` # vi /etc/sysconfig/network-scripts/ifcfg-eth0 @@ -152,15 +151,15 @@ ONBOOT=yes 保存文件并退出。 -9. 你也可以在桌面服务器中按照下面的截图(Ubuntu 16.04桌面版)通过 GUI 设置 Method 为 Automatic (DHCP)。 +9、 你也可以在桌面服务器中按照下面的截图(Ubuntu 16.04桌面版)通过 GUI 设置 `Method` 为 `Automatic (DHCP)`。 [ ![Set DHCP in Client Network](http://www.tecmint.com/wp-content/uploads/2017/03/Set-DHCP-in-Client-Network.png) ][3] -在客户端网络中设置 DHCP +*在客户端网络中设置 DHCP* -10. 按照下面的命令重启网络服务(你也可以通过重启系统): +10、 按照下面的命令重启网络服务(你也可以通过重启系统): ``` ---------- On CentOS/RHEL 7 ---------- @@ -190,7 +189,7 @@ via: http://www.tecmint.com/install-dhcp-server-in-centos-rhel-fedora/ 作者:[Aaron Kili][a] 译者:[ictlyh](https://github.com/ictlyh) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 2feee6d1300466a0a6adad93c016b4bb016b445c Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 11 Apr 2017 08:54:56 +0800 Subject: [PATCH 33/52] PRF:20161216 The truth about traditional JavaScript benchmarks.md part --- ...about traditional JavaScript benchmarks.md | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/translated/tech/20161216 The truth about traditional JavaScript benchmarks.md b/translated/tech/20161216 The truth about traditional JavaScript benchmarks.md index c9c52bab03..1a4b281fda 100644 --- a/translated/tech/20161216 The truth about traditional JavaScript benchmarks.md +++ b/translated/tech/20161216 The truth about traditional JavaScript benchmarks.md @@ -1,37 +1,37 @@ 探索传统 JavaScript 基准测试 ============================================================ -可以很公平地说,[JavaScript][22] 是当下软件工程最重要的技术。对于那些深入接触过编程语言、编译器和虚拟机的人来说,这仍然有点令人惊讶,因为在语言设计者看来,`JavaScript` 不是十分优雅;在编译器工程师看来,它没有多少可优化的地方;而且还没有一个伟大的标准库。取决于你和谁吐槽,`JavaScript` 的缺点你花上数周都枚举不完,不过你总会找到一些你从所未知的神奇的东西。尽管这看起来明显困难重重,不过 `JavaScript` 还是成为当今 web 的核心,并且还成为服务器端/云端的主导技术(通过 [Node.js][23]),甚至还开辟了进军物联网空间的道路。 +可以很公平地说,[JavaScript][22] 是当下软件工程最重要的技术。对于那些深入接触过编程语言、编译器和虚拟机的人来说,这仍然有点令人惊讶,因为在语言设计者看来,JavaScript 不是十分优雅;在编译器工程师看来,它没有多少可优化的地方;而且还没有一个伟大的标准库。这取决于你和谁吐槽,JavaScript 的缺点你花上数周都枚举不完,不过你总会找到一些你从所未知的神奇的东西。尽管这看起来明显困难重重,不过 JavaScript 还是成为当今 web 的核心,并且还成为服务器端/云端的主导技术(通过 [Node.js][23]),甚至还开辟了进军物联网空间的道路。 -问题来了,为什么 `JavaScript` 如此受欢迎/成功?我知道没有一个很好的答案。如今我们有许多使用 `JavaScript` 的好理由,或许最重要的是围绕其构建的庞大的生态系统,以及今天大量可用的资源。但所有这一切实际上是发展到一定程度的后果。为什么 `JavaScript` 变得流行起来了?嗯,你或许会说,这是 web 多年来的通用语了。但是在很长一段时间里,人们极其讨厌 `JavaScript`。回顾过去,似乎第一波 `JavaScript` 浪潮爆发在上个年代的后半段。不出所料,那个时候 `JavaScript` 引擎在不同的负载下实现了巨大的加速,这可能让很多人对 `JavaScript` 刮目相看。 +问题来了,为什么 JavaScript 如此受欢迎?或者说如此成功?我知道没有一个很好的答案。如今我们有许多使用 JavaScript 的好理由,或许最重要的是围绕其构建的庞大的生态系统,以及今天大量可用的资源。但所有这一切实际上是发展到一定程度的后果。为什么 JavaScript 变得流行起来了?嗯,你或许会说,这是 web 多年来的通用语了。但是在很长一段时间里,人们极其讨厌 JavaScript。回顾过去,似乎第一波 JavaScript 浪潮爆发在上个年代的后半段。不出所料,那个时候 JavaScript 引擎加速了各种不同的任务的执行,这可能让很多人对 JavaScript 刮目相看。 -回到过去那些日子,这些加速测试使用了现在所谓的传统 `JavaScript` 基准——从苹果的 [SunSpider 基准][24](JavaScript 微基准之母)到 Mozilla 的 [Kraken 基准][25] 和谷歌的 `V8` 基准。后来,`V8` 基准被 [Octane 基准][26] 取代,而苹果发布了新的 [JetStream 基准][27]。这些传统的 `JavaScript` 基准测试驱动了无数人的努力,使 `JavaScript` 的性能达到了本世纪初没人能预料到的水平。据报道加速达到了 1000 倍,一夜之间在网站使用 `