开发技巧笔记

(1)调试打印

#define prdebug(x, ...) fprintf(stderr, "[debug]"x, ##__VA_ARGS__)

其中 ’##‘ 是为了适应只有‘x’无‘VA_ARGS’的打印情况,否则当遇到类似 prdebug(“hello”) 情况时将编译不过。

(2)查看谁调用了这个函数

1、在被调用函数内放置打印函数,加参数

__builtin_return_address(0)//获得返回地址位置

2、arm-linux-addr2lineaddr2line 0xXXXXXXXX -e XYZ -f
若XYZ为so文件时需减去偏移,由 cat /proc/self pid/maps 可知,若出现 ?? 则说明调用函数不在符号表内,可通过在编译时加入‘-g’选项

(3)交叉编译时头文件默认搜索路径

当编译工具为 arm-linux-gcc时,命令echo 'main(){}' | arm-linux-gcc -E -v -,显示:

#include "..." search starts here:
#include <...> search starts here:
/home/tools/arm-tools-chains/4.3.3/include
......
......
End of search list

如果编译加入 -nostdinc,则不会到默认路径下去搜索,在用 -I 指定新路径即可

(4)设置nfs挂载

1、修改 /etc/exports
添加 /home/mnt 192.168.2.*(rw,sync,no_root_squash)
执行 exportfs -rv 使修改生效
2、启动 portmap 和 nfs 服务,并且 portmap 先于 nfs 启动
/etc/init.d/portmap start
/etc/init.d/nfs start
3、修改 /etc/hosts.allow,设置允许的IP
如 portmap:192.168.2.*
lockd:192.168.2.*
mountd:192.168.2.*
rquotad:192.168.2.*
statd:192.168.2.*
4、mount -t nfs 192.168.2.12:/home/mnt /mnt -o nolock

(5)C语言的 #ifdef 和 #if defined 的区别

#ifdef#if defined 的区别在于,后者可以组成复杂的预编译条件,比如

    #if defined (AAA) && defined (BBB)
        xxxxxxxxx
    #endif

    #if defined (AAA) || VERSION > 12
        xxxxxxxxx
    #endif

#ifdef 就不能用上面的用法,也就是说,当你要判断单个宏是否定义时#ifdef#if defined 效果是一样的,但是当你要判断复杂的条件时,只能用 #if defined

(6)nm命令

有时候可能需要查看一个库中到底有哪些函数,nm命令可以打印出库中的涉及到的所有符号。库既可以是静态的也可以是动态的。nm列出的符号有很多,常见的有三种:

l  一种是在库中被调用,但并没有在库中定义(表明需要其他库支持),用U表示;
l  一种是库中定义的函数,用T表示,这是最常见的;
l  一种是所谓的弱态”符号,它们虽然在库中被定义,但是可能被其他库中的同名符号覆盖,用W表示。

(7)创建个指定大小的文件

创建大小为 bs*count

[root@localhost utils]# dd if=/dev/zero of=4Kfile bs=20k count=2
[root@localhost utils]# ll 4Kfile
-rw-r--r--. 1 root root 40960 1125 14:12 4Kfile

从标准输入设备输入,当count=0时 配合seek参数 可以创建稀疏文件(文件可以很大,但不占用多少磁盘空间)

[root@localhost src]# dd of=100kbyte bs=1 seek=100k count=0
记录了0+0 的读入
记录了0+0 的写出
0字节(0 B)已复制,4.5022e-05 秒,0.0 kB/秒
[root@localhost src]# ls -ls 100kbyte
0 -rw-r--r--. 1 root root 102400 128 16:54 100kbyte
[root@localhost src]# od -x 100kbyte
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
0310000
[root@localhost src]#vim 100kbyte
0000000: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000020: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000040: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000050: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000060: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000070: 0000 0000 0000 0000 0000 0000 0000 0000  ................
:%!xxd       //vim 以十六进制显示内容                                                          

ibs=bytes:一次读入 bytes 个字节(即一个块大小为 bytes 个字节)
obs=bytes:一次写 bytes 个字节(即一个块大小为 bytes 个字节)
bs=bytes:同时设置读写块的大小为 bytes ,可代替 ibs 和 obs
cbs=bytes:一次转换 bytes 个字节,即转换缓冲区大小
skip=blocks:从输入文件开头跳过 blocks 个块后再开始复制
seek=blocks:从输出文件开头跳过 blocks 个块后再开始复制。(通常只有当输出文件是磁盘或磁带时才有效)
count=blocks:仅拷贝 blocks 个块,块大小等于 ibs 指定的字节数

(8)带颜色的进度条

#include <stdio.h>
void bar();
int main()
{
        printf("\033[1m\033[0;31mPING\033[0m");
        bar();
        printf("\033[1m\033[0;31mNETSTAT\033[0m");
        bar();
        return(0);
}
void bar()
{
        int i,j;
        printf("\n");
        for(i=0;i<=10;i++){
                printf("[");
                for(j=0;j<i;j++)
                        printf("\033[0;32m>\033[0m");
                for(; j<10;j++)
                        printf(" ");
                printf("]");
                printf("\033[0;33m%3d%%\033[0m", i*10);
                if(i == 10){
                        printf(" \033[0;32m[COMPLETED]\033[0m");
                }
                printf("\r");
                fflush(stdout);
                sleep(1);
        }
        printf("\n");
}

效果如下:
这里写图片描述

(9)代码注释 TODO、FIXME 和 XXX 的用处

TODO: + 说明:
如果代码中有该标识,说明在标识处有功能代码待编写,待实现的功能在说明中会简略说明。

FIXME: + 说明:
如果代码中有该标识,说明标识处代码需要修正,甚至代码是错误的,不能工作,需要修复,如何修正会在说明中简略说明。

XXX: + 说明:
如果代码中有该标识,说明标识处代码虽然实现了功能,但是实现的方法有待商榷,希望将来能改进,要改进的地方会在说明中简略说明。

(10)屏幕协作

yum install screen

具体操作方法如下:
a、ssh登录机器后,执行如下命令(参数-S是为当前会话设置一个名称):

screen -S xxxxxx

b、然后告诉客户,执行screen -x xxxxxx,就这么简单,接下无论你做什么操作客户都能看得一清二楚,同样客户做什么你也能看得清清楚楚。

c、暂时离开,保留screen会话中的任务或程序
当需要临时离开时(会话中的程序不会关闭,仍在运行)可以用快捷键Ctrl+a d(即按住Ctrl,依次再按a,d)

d、恢复screen会话
当回来时可以再执行执行:screen -r abc 即可恢复到离开前创建的abc会话的工作界面。

e、关闭screen的会话
执行:exit ,会提示:[screen is terminating],表示已经成功退出screen会话。

常用快捷键
Ctrl+a c :在当前screen会话中创建窗口
Ctrl+a w :窗口列表
Ctrl+a n :下一个窗口
Ctrl+a p :上一个窗口
Ctrl+a 0-9 :在第0个窗口和第9个窗口之间切换

(11)ls显示年

[root@localhost ~]# ls -l --time-style=long
总用量 8
-rw-------. 1 root root 1189 2016-04-21 02:54 anaconda-ks.cfg
-rw-r--r--. 1 root root 1429 2016-04-20 18:59 initial-setup-ks.cfg
drwxr-xr-x. 2 root root    6 2016-04-20 18:59 公共
drwxr-xr-x. 2 root root    6 2016-04-20 18:59 模板
drwxr-xr-x. 2 root root    6 2016-04-20 18:59 视频
drwxr-xr-x. 2 root root    6 2016-04-20 18:59 图片
drwxr-xr-x. 2 root root    6 2016-04-20 18:59 文档
drwxr-xr-x. 2 root root    6 2016-04-20 18:59 下载
drwxr-xr-x. 2 root root    6 2016-04-20 18:59 音乐
drwxr-xr-x. 2 root root    6 2016-04-20 18:59 桌面

(12)忽然ping不通虚拟机了

这里写图片描述

不要选自动。。。

(13)vim中查找替换

:s/vivian/sky/ 替换当前行第一个 vivian 为 sky
:s/vivian/sky/g 替换当前行所有 vivian 为 sky

:n,$s/vivian/sky/ 替换第 n 行开始到最后一行中每一行的第一个 vivian 为 sky
:n,$s/vivian/sky/g 替换第 n 行开始到最后一行中每一行所有 vivian 为 sky
n 为数字,若 n 为 .,表示从当前行开始到最后一行

:%s/vivian/sky/ (等同于 :g/vivian/s//sky/) 替换每一行的第一个 vivian 为 sky
:%s/vivian/sky/g(等同于 :g/vivian/s//sky/g) 替换每一行中所有 vivian 为 sky

可以使用 # 作为分隔符,此时中间出现的 / 不会作为分隔符  
:s#vivian/#sky/# 替换当前行第一个 vivian/ 为 sky/

:s/vivian/sky/g 替换当前行所有 vivian 为 sky
在命令后面加上一个字母c就可以实现替换确认作用,即:s/vivian/sky/gc
顾名思意,c是confirm的缩写

从上述替换命令可以看到:不加 g,表示只对搜索字符串的首次出现进行替换;g 放在命令末尾,表示对搜索字符串的每次出现进行替换;g 放在命令开头,表示对正文中所有包含搜索字符串的行进行替换操作
(转)

(14)删除文本中的^M

  问题描述:对于换行,window下用回车换行(0A0D)来表示,linux下是回车(0A)来表示。这样,将window上的文件拷到unix上用时,总会有个^M.请写个用在unix下的过滤windows文件的换行符(0D)的shell或c程序。
 
  。 使用命令:cat filename1 | tr -d “^V^M” > newfile
 
  。 使用命令:sed -e “s/^V^M//” filename > outputfilename.需要注意的是在1、2两种方法中,^V和^M指的是Ctrl+V和Ctrl+M.你必须要手工进行输入,而不是粘贴。
 
  。 在vi中处理:首先使用vi打开文件,然后按ESC键,接着输入命令:%s/^V^M//.
 
  。 :%s/^M$//g
 
  如果上述方法无用,则正确的解决办法是: [Page]
 
  。 tr -d \"\\r\" < src >dest
 
  。 tr -d \"\\015\" dest
 
  。 strings A>B
  (转)

(15)LIBRARY_PATH和LD_LIBRARY_PATH环境变量的区别

LIBRARY_PATH环境变量用于在程序编译期间查找动态链接库时指定查找共享库的路径
LD_LIBRARY_PATH环境变量用于在程序加载运行期间查找动态链接库时指定除了系统默认路径之外的其他路径

(16)printf 中文 ,终端显示乱码

文件编码转换 iconv -f GBK -t UTF-8 srcfile -o destfile

[root@localhost ssl_test]#
[root@localhost ssl_test]# file ssl_server.cpp ssl_client.cpp
ssl_server.cpp: C source, ISO-8859 text
ssl_client.cpp: C source, UTF-8 Unicode text
[root@localhost ssl_test]#
[root@localhost ssl_test]# cat run_server.sh run_client.sh
#!/bin/sh
./ssl_server 7838 1 127.0.0.1 cacert.pem privkey.pem
#!/bin/sh
./ssl_client 127.0.0.1 7838
[root@localhost ssl_test]#
[root@localhost ssl_test]# ./run_server.sh
socket created
binded
begin listen
server: got connection from 127.0.0.1, port 37478, socket 4
▒▒Ϣ'server->client'▒▒▒ͳɹ▒▒▒▒▒▒▒▒▒▒▒14▒▒▒ֽڣ▒
▒▒▒▒▒▒Ϣ▒ɹ▒:'from client->server'▒▒▒▒19▒▒▒ֽڵ▒▒▒▒

^C
[root@localhost ssl_test]#
[root@localhost ssl_test]# iconv -f ISO-8859 -t UTF-8 ssl_server.cpp -o ssl_server.cpp
iconv: 不支持以“ISO-8859”为源头的转换
试用“iconv --help”或“iconv --usage”以获取更多信息。
[root@localhost ssl_test]# iconv -f GBK -t UTF-8 ssl_server.cpp -o ssl_server.cpp
[root@localhost ssl_test]#
[root@localhost ssl_test]# file ssl_server.cpp
ssl_server.cpp: C source, UTF-8 Unicode text
[root@localhost ssl_test]#
[root@localhost ssl_test]# cat mk_server.sh
#!/bin/sh
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/ssl/lib
g++ -g -o ssl_server ssl_server.cpp -I/usr/local/ssl/include -L/usr/local/ssl/lib -lssl -lcrypto -ldl

[root@localhost ssl_test]#
[root@localhost ssl_test]# ./mk_server.sh
[root@localhost ssl_test]# ./run_server.sh
socket created
binded
begin listen
server: got connection from 127.0.0.1, port 37480, socket 4
消息'server->client'发送成功,共发送了14个字节!
接收消息成功:'from client->server',共19个字节的数据
^C
[root@localhost ssl_test]#
[root@localhost ssl_test]#
[root@localhost ssl_test]# ./run_client.sh
socket created
address created
server connected
Connected with AES256-SHA encryption
数字证书信息:
证书: /C=ls/ST=Some-State/O=Internet Widgits Pty Ltd
颁发者: /C=ls/ST=Some-State/O=Internet Widgits Pty Ltd
接收消息成功:'server->client',共14个字节的数据
消息'from client->server'发送成功,共发送了19个字节!
[root@localhost ssl_test]#

(17)yum安装linux-devel

yum install kernel-devel-xxx

 yum install kernel-devel-3.10.0

(18)syslog简单使用

(centos 6.5中为 rsyslog, /etc/rsyslog.conf)
首先先确认我们的开发板上是否安装了syslog服务,在开发板的文件系统下输入syslogd help命令查看。当确定安装了后我们根据help显示的默认配置文件来查看该配置文件是否存在,如果不存在我们需要创建一个配置文件如:touch /etc/syslog.conf,同时使用syslogd -f /etc/syslog.conf来进行绑定。
LOG_LOCAL0~LOG_LOCAL7——为本地使用保留

syslog的使用:

1.在/etc/syslog.conf下加入一行localN.* pathname
例 local5.* /root/Desktop/test.log

2.重新启动syslog /etc/init.d/syslog restart

3.使用syslog
实例

#include<stdio.h>
#include<stdlib.h>
#include <syslog.h>
#define SYSNAME "wohawoha"
void Info(void)
{
     openlog("info",LOG_PID,LOG_LOCAL5);/*注意这里的数字5与第一条里面提到的local5.*里的5必须相同,并且这个数字的范围为0--7*/
     syslog(LOG_INFO, "hello %s","woring");
}

void Woring(void)
{
     openlog("woring",LOG_PID,LOG_LOCAL5);
     syslog(LOG_WARNING, "hello %s","test");
}

int main()
{
     Info();
     Woring();
     closelog();
     return 0;
}

4.进入目录查看内容
例如:进入/root/Desktop/test.log这个文件查看里面的内容

Dec 13 12:31:21 localhost info[11750]: hello woring
Dec 13 12:31:21 localhost woring[11750]: hello test

(19)将输出重定向到/dev/null

ping -c 4 baidu.com > /dev/null 2>&1

(20)按内存/CPU资源使用量对进程排序

ps aux | sort -rnk 4
ps aux | sort -nk 3

(21)在一个目录里批量查找替换

在一个目录里批量查找替换的命令如下:

sed -i "s/OldString/NewString/g" `grep OldString -rl Dir`

例如,把/product目录里所有的ip地址10.168.195.52替换成172.27.77.72,可以这样:

sed -i "s/10.168.195.52/172.27.77.72/g" `grep 10.168.195.52 -rl /product`

(22)把字符转换为十六进制

把字符(0123456789abcdefABCDEF)转换为十六进制(0x12)—两个字符对应一个十六进制

memset(hexbuf, 0, TPCM_HASH_SIZE);

shift = 4;
j = 0;
while(j<(2*TPCM_HASH_SIZE)){
unsigned char c = instr[j];

if (c >= '0' && c <= '9') {
    hexbuf[j>>1] |= ((c - '0') << shift);
} else if (c >= 'a' && c <= 'f') {
    hexbuf[j>>1] |= ((c - 'a' + 10) << shift);
} else if (c >= 'A' && c <= 'F') {
    hexbuf[j>>1] |= ((c - 'A' + 10) << shift);
} else {
    printf("Input contains non-hex character!\n");
}
    shift ^= 4; /*between 4 & 0 ,alternate*/
    j++;
}       
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值