開發技巧筆記

(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++;
}       
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章