#在每一行前加上行号 export PS4='+${BASH_SOURCE}:${LINENO}:${FUNCNAME[0]}: ' #进行调试 sh -x test.sh #调试结果 +test.sh:3:: for i in '{1..10}' +test.sh:5:: echo 1 1 +test.sh:3:: for i in '{1..10}' +test.sh:5:: echo 2 2 +test.sh:3:: for i in '{1..10}' +test.sh:5:: echo 3 3 +test.sh:3:: for i in '{1..10}' +test.sh:5:: echo 4 4 +test.sh:3:: for i in '{1..10}' +test.sh:5:: echo 5 5 +test.sh:3:: for i in '{1..10}' +test.sh:5:: echo 6 6 +test.sh:3:: for i in '{1..10}' +test.sh:5:: echo 7 7 +test.sh:3:: for i in '{1..10}' +test.sh:5:: echo 8 8 +test.sh:3:: for i in '{1..10}' +test.sh:5:: echo 9 9 +test.sh:3:: for i in '{1..10}' +test.sh:5:: echo 10 10
+
+
有时候,你只需要对脚本的一部分进行调试,那么可以使用如下命令:
+
1 2 3 4
set -x #在执行时显示参数和命令 set +x #禁止调试 set -v #当命令行读取时显示输入 set +v #禁止打印输入
for i in {1..5} do DEBUG echo -e "This is debug line!" echo $i done
+
我们将_DEBUG环境变量设定为一个开关,只有打开时才会输出调试日志. 使用如上脚本结果如下:
+
1 2 3 4 5 6 7 8 9 10 11
[aidu1602@ResU10 tools]$ _DEBUG=on sh debug.sh This is debug line! 1 This is debug line! 2 This is debug line! 3 This is debug line! 4 This is debug line! 5
本文将介绍在文本流中,读写整数的两个接口– int getw(FILE *fp)和int putw(int w, FILE *fp),并且与你分享改进后的更实用的接口– unsigned int get_uint(FILE *fp)和unsigned int put_uint(unsigned int i,FILE *fp).
SaaS(Software as a Service):软件即服务,SaaS公司提供完整并可直接使用的应用程序,用户通过网页浏览器即可接入使用。比较知名的SaaS有GoToMeeting,WebEx和Salesforce。
+
BaaS(Backend as a Service):后端即服务,为移动应用开发者提供后端云服务,包括云端数据存储、账户管理和消息推送等,简化了应用开发流程。这里推荐一篇对BaaS介绍的文章。
+
PaaS(Platform as a Service):平台即服务,也被叫做中间件。用户通过Internet可以使用PaaS公司在网上提供的各种开发和分发应用的解决方案,比如虚拟服务器和操作系统等,软件的开发和运行都可以在提供的平台上进行。不仅节约了硬件成本,更大大提高了协作开发的效率。比较知名的PaaS有Google App Engine,Microsoft Azure和AppFog。
+
IaaS(Infrastructure as a Service):基础设施即服务,用户通过租用IaaS公司的服务器,存储和网络硬件,利用Internet就可以完善地获取计算机基础设施服务,大大节约了硬件成本。比较知名的IaaS有Amazon,Microsoft和Aliyun等。
当通过UDP(User Datagram Protocal,用户数据报协议)或RTP(Real Time Protocal,实时传输协议)传输声音(或其他任何内容)时,数据包可能丢失,不同延时到达,甚至乱序,抖动缓冲器的作用是对数据包进行重排序并保存在足够长的buffer(但有一定限度)里,然后将数据包发送去解码
%p - insert pid into filename # 添加 pid %u - insert current uid into filename # 添加当前 uid %g - insert current gid into filename # 添加当前 gid %s - insert signal that caused the coredump into the filename # 添加导致产生 core 的信号 %t - insert UNIX time that the coredump occurred into filename # 添加 core 文件生成时的 unix 时间 %h - insert hostname where the coredump happened into filename # 添加主机名 %e - insert coredumping executable name into filename # 添加命令名
$ gcc -I. test2.c -L. -lt -o test $ ./test /tmp/ccdaJT7s.o: In function `main': test2.c:(.text+0xa): undefined reference to `bye' collect2: error: ld returned 1 exit status
/* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */
#include <string.h>
/* Parse S into tokens separated by characters in DELIM. If S is NULL, the last string strtok() was called with is used. For example: char s[] = "-abc-=-def"; x = strtok(s, "-"); // x = "abc" x = strtok(NULL, "-="); // x = "def" x = strtok(NULL, "="); // x = NULL // s = "abc\0=-def\0" */ char * strtok (char *s, const char *delim) { static char *olds; return __strtok_r (s, delim, &olds); }
/* Reentrant string tokenizer. Generic version. Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H # include <config.h> #endif
#include <string.h>
#ifndef _LIBC /* Get specification. */ # include "strtok_r.h" # define __strtok_r strtok_r #endif
/* Parse S into tokens separated by characters in DELIM. If S is NULL, the saved pointer in SAVE_PTR is used as the next starting point. For example: char s[] = "-abc-=-def"; char *sp; x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def" x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL x = strtok_r(NULL, "=", &sp); // x = NULL // s = "abc\0-def\0" */ char * __strtok_r (char *s, const char *delim, char **save_ptr) { char *end;
if (s == NULL) s = *save_ptr;
if (*s == '\0') { *save_ptr = s; return NULL; }
/* Scan leading delimiters. */ s += strspn (s, delim); if (*s == '\0') { *save_ptr = s; return NULL; }
/* Find the end of the token. */ end = s + strcspn (s, delim); if (*end == '\0') { *save_ptr = end; return s; }
/* Terminate the token and make *SAVE_PTR point past it. */ *end = '\0'; *save_ptr = end + 1; return s; } #ifdef weak_alias libc_hidden_def (__strtok_r) weak_alias (__strtok_r, strtok_r) #endif
Sections: Idx Name Size VMA LMA File off Algn 0 .data 0000fab0 0000000000000000 0000000000000000 00000040 2**0 CONTENTS, ALLOC, LOAD, DATA SYMBOL TABLE: 0000000000000000 l d .data 0000000000000000 .data 0000000000000000 g .data 0000000000000000 _binary_nhxc_wav_start 000000000000fab0 g .data 0000000000000000 _binary_nhxc_wav_end 000000000000fab0 g *ABS* 0000000000000000 _binary_nhxc_wav_size
Set the type of linker's hash table(s). style can be either "sysv" for classic ELF ".hash" section, "gnu" for new style GNU ".gnu.hash" section or "both" for both the classic ELF ".hash" and new style GNU ".gnu.hash" hash tables. The default is "sysv".
# 同步提交A $ git cherry-pick <commit id A> # 同步提交A和B $ git cherry-pick <commit id A> <commit id B> # 同步提交A到B的所有提交(不包括A),提交A必须早于提交B,否则命令将失败,但不会报错 $ git cherry-pick <commit id A>..<commit id B> # 同步提交A到B的所有提交(包括A),提交A必须早于提交B,否则命令将失败,但不会报错 $ git cherry-pick <commit id A>^..<commit id B>
+
+
标签管理
查看标签
1
$ git tag
+
+
创建标签
1 2
$ git tag -a <tagname> -m "tag message" # 创建标签在当前最新提交的commit上 $ git tag -a <tagname> -m "tag message" <commit id> # 创建标签在指定的commit上
可以使用 -Wl,--disable-new-dtags 选项来使链接器保持旧行为,即在 ubuntu 20.04(gcc version 9.3.0) 使用如下命令编译:
+
1
$ gcc -I. -o main main.c -Wl,--disable-new-dtags,--rpath,. -L. -lA -lB
+
重新运行并查看依赖:
+
1 2 3 4 5 6 7 8 9
$ ./main Hello, World
$ readelf -d main Dynamic section at offset 0x2da8 contains 29 entries: Tag Type Name/Value 0x0000000000000001 (NEEDED) Shared library: [libA.so] 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 0x000000000000000f (RPATH) Library rpath: [.]
+
可执行程序 main 可以正确运行,RUNPATH 也变成了 RPATH,链接器行为与 ubuntu 16.04(gcc version 5.4.0) 保持一致了。
+
+
同理,也有 -Wl,--enable-new-dtags 选项来使链接器保持新行为
+
+
如下为官方解释:
+
1 2 3
--enable-new-dtags --disable-new-dtags This linker can create the new dynamic tags in ELF. But the older ELF systems may not understand them. If you specify --enable-new-dtags, the new dynamic tags will be created as needed and older dynamic tags will be omitted. If you specify --disable-new-dtags, no new dynamic tags will be created. By default, the new dynamic tags are not created. Note that those options are only available for ELF systems.
structrusage { structtimevalru_utime;/* user CPU time used */ structtimevalru_stime;/* system CPU time used */ long ru_maxrss; /* maximum resident set size */ long ru_ixrss; /* integral shared memory size */ long ru_idrss; /* integral unshared data size */ long ru_isrss; /* integral unshared stack size */ long ru_minflt; /* page reclaims (soft page faults) */ long ru_majflt; /* page faults (hard page faults) */ long ru_nswap; /* swaps */ long ru_inblock; /* block input operations */ long ru_oublock; /* block output operations */ long ru_msgsnd; /* IPC messages sent */ long ru_msgrcv; /* IPC messages received */ long ru_nsignals; /* signals received */ long ru_nvcsw; /* voluntary context switches */ long ru_nivcsw; /* involuntary context switches */ };
$ gcc -O0 -o test_O0.o -c test.c $ g++ test_O0.o -o test_O0 test_O0.o: In function `main': test.c:(.text+0x5): undefined reference to `say' collect2: error: ld returned 1 exit status
+
+
分别查看文件test_O0.o和test_O3.o:
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14
$ readelf -s test_O0.o
Symbol table '.symtab' contains 10 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS test.c 2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 3: 0000000000000000 0 SECTION LOCAL DEFAULT 3 4: 0000000000000000 0 SECTION LOCAL DEFAULT 4 5: 0000000000000000 0 SECTION LOCAL DEFAULT 6 6: 0000000000000000 0 SECTION LOCAL DEFAULT 7 7: 0000000000000000 0 SECTION LOCAL DEFAULT 5 8: 0000000000000000 16 FUNC GLOBAL DEFAULT 1 main 9: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND say
+
+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
$ readelf -s test_O3.o
Symbol table '.symtab' contains 13 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS test.c 2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 3: 0000000000000000 0 SECTION LOCAL DEFAULT 2 4: 0000000000000000 0 SECTION LOCAL DEFAULT 3 5: 0000000000000000 0 SECTION LOCAL DEFAULT 4 6: 0000000000000000 0 SECTION LOCAL DEFAULT 5 7: 0000000000000000 0 SECTION LOCAL DEFAULT 6 8: 0000000000000000 0 SECTION LOCAL DEFAULT 9 9: 0000000000000000 0 SECTION LOCAL DEFAULT 10 10: 0000000000000000 0 SECTION LOCAL DEFAULT 8 11: 0000000000000000 21 FUNC GLOBAL DEFAULT 6 main 12: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND puts
%p - insert pid into filename # 添加 pid %u - insert current uid into filename # 添加当前 uid %g - insert current gid into filename # 添加当前 gid %s - insert signal that caused the coredump into the filename # 添加导致产生 core 的信号 %t - insert UNIX time that the coredump occurred into filename # 添加 core 文件生成时的 unix 时间 %h - insert hostname where the coredump happened into filename # 添加主机名 %e - insert coredumping executable name into filename # 添加命令名