天天看點

Linux日常使用整理------雜貨/linux-C-API

一、引言

好久沒發部落格啦,這段時間公司的項目有點忙(加上自己有點懶~)。這幾天剛剛忙完,是以想着來整理下這段時間的日常使用指令吧,會比較雜,但都是一些很好的指令,大家也可以多多補充哈!

二、git/repo的使用

之前整理過一篇關于git、repo的文章,這裡就簡單補充一點

repo

repo是一個基于git的android源碼管理工具,其實就是将很多git庫集中成了一個大庫,其中的子庫包括:kernel、uboot、system等

常用指令:

repo init -u ssh://{user}@192.168.120.246:29418/cmccc03/manifests --repo-url=ssh://{user}@192.168.120.246:29418/A31HomeLetMirror/android4.4backup/git-repo -m sys.xml

/*  更新項目的全部源碼,第一次則為pull*/
repo sync -c   
/* 将項目上的所有代碼切換到android-4.4分支 */
repo start --all android-4.4
           

之前必須設定git賬戶密碼,與gerrit上的一緻

git config --global user.name "xxxxxx"
git config --global user.email "[email protected]"
           

其他指令

repo status
repo branch
repo checkout
           

git

這段時間常用到的指令

git add     //添加新的檔案到庫中  如果為目錄,預設将其下的所有檔案加入庫
git commit   //送出修改
git commit  ----amend   //修改上一次commit的内容,并将兩次commit合并

git checkout xxx   //撤銷xxx的修改
git pull  //更新代碼
git push  //上傳代碼
git push origin master:refs/for/master  //送出修改到gerrit

git log   //檢視送出log
git reset  //回退到某一版本,版本号可在git log中看到
git diff  //比較和庫中檔案的不同
git status
git branch
git checkout xx  //轉換到某一分支

git branch -f C03_Master HEAD  //遇到頭指針分離的情況
git checkout C03_Master

           

三、linux中的塊裝置操作

dd指令

用指定大小的塊拷貝一個檔案,并在拷貝的同時進行指定的轉換。

dd if=input of=output bs=1048576(1024k) seek=%ld count=1
           

if=檔案名:輸入檔案名,預設為标準輸入。即指定源檔案。< if=input file >

of=檔案名:輸出檔案名,預設為标準輸出。即指定目的檔案。< of=output file >

ibs=bytes:一次讀入bytes個位元組,即指定一個塊大小為bytes個位元組。

obs=bytes:一次輸出bytes個位元組,即指定一個塊大小為bytes個位元組。

bs=bytes:同時設定讀入/輸出的塊大小為bytes個位元組。

注意:有些版本的dd指令,不支援1024k這種寫法,需要寫成1048576

skip=blocks:從輸入檔案開頭跳過blocks個塊後再進行複制。

seek=blocks:從輸出檔案開頭跳過blocks個塊再進行複制。

count=blocks:僅拷貝blocks個塊,塊大小等于ibs指定的位元組數。

conv=conversion:用指定的參數轉換檔案。

ascii:轉換ebcdic為ascii

ebcdic:轉換ascii為ebcdic

ibm:轉換ascii為alternate ebcdic

block:把每一行轉換為長度為cbs,不足部分用空格填充

unblock:使每一行的長度都為cbs,不足部分用空格填充

lcase:把大寫字元轉換為小寫字元

ucase:把小寫字元轉換為大寫字元

swab:交換輸入的每對位元組

noerror:出錯時不停止

notrunc:不截短輸出檔案

sync:将每個輸入塊填充到ibs個位元組,不足部分用空(NUL)字元補齊。

hexdump指令

檢視flash上的十六進制内容

-n length 隻格式化輸入檔案的前length的個位元組。

-C 輸出規範的十六進制和ASCII碼。

-b 單位元組八進制顯示。

-c 單位元組字元顯示。

-d 雙位元組十進制顯示。

-o 雙位元組八進制顯示。

-x 雙位元組十六進制顯示。

-s 從偏移量開始輸出。

-e 指定格式字元串,格式字元串包含在一對單引号中,格式字元串形如:‘a/b “format1” “format2”’。

hexdump   mmcblk0p13 -s 0x400 -n 512
           

列印 ‘mmcblk0p13’ 中從0x400 開始的512個位元組

du -h

檢視每個目錄/檔案 實際的大小

用ls -l 隻能看到單個目錄的大小,而不能看到裡面實際的大小

eog -f

此指令用于檢視圖檔

linux中檢視塊裝置的目錄

一般在 '/dev/block’下查找,目前裝置的所有塊,如果還做了分區表,就可以和分區名對應

Linux日常使用整理------雜貨/linux-C-API

如下是做了分區表的

Linux日常使用整理------雜貨/linux-C-API

四、dbus

是一種進階的程序間通訊方式,東西比較多,後面慢慢完善了,不過覺得廷常用的。

五、cat 合并檔案

cat是concatenate的縮寫,意為串聯,之前經常看到别人在用cat指令,沒有細究

cat指令兩個常用的用法是:

1、cat file.txt能夠将txt中的内容顯示出來

2、合并檔案

'>'是建立檔案,并合并兩個内容。

'>>'是把file1和file2附加到file3中

六、shell腳本

1、在shell腳本中,需要執行一些shell指令時 可以這樣寫

$(pwd)
`command`
           

兩者作用相同,即擷取command指令的結果

2、我們可以在bash中使用以下指令擷取所執行腳本的絕對路徑:

#!/bin/bash
DIR=$( cd "$(dirname "${BASH_SOURCE[0]}")" && pwd);
echo $DIR
           

BASH_SOURCE[0] - 等價于 BASH_SOURCE ,取得目前執行的 shell 檔案所在的路徑及檔案名

dirname - 去除檔案名中的非目錄部分,僅顯示與目錄有關的部分

$() - 相當于

command

, 即擷取command指令的結果

&& - 邏輯運算符号,隻有當&&左邊運作成功時才會運作&&右邊的指令

或者如下

BUILD_SCRIPT_DIR=`dirname $PWD/${0}`
           

$0 就是你寫的shell腳本本身的名字,$1 是你給你寫的shell腳本傳的第一個參數,$2 是你給你寫的shell腳本傳的第二個參數

PWD 是目前工作目錄的絕對路徑名,該變量的取值随cd指令的使用而變化,為環境變量,值為目前目錄。

</font color=ff0000>我們在寫腳本時,最好都使用以上方式來擷取腳本的絕對路徑,這樣移植到其他系統時,也可以繼續使用,不用修改路徑

3、getopts函數

getopts函數是用來處理指令行中傳遞進來的參數。

getopts 有兩個參數,第一個參數是一個字元串,包括字元和“:”符号,每一個字元都是一個有效的選項,如果字元後面帶有“:”,表示這個字元有自己的參數。getopts從指令中擷取這些參數,并且删去了“-”,并将其指派在第二個參數中,如果帶有自己參數,這個參數指派在“OPTARG”中。

這裡變量 O P T A R G 存 儲 相 應 選 項 的 參 數 , 而 OPTARG存儲相應選項的參數,而 OPTARG存儲相應選項的參數,而OPTIND總是存儲原始$*中下一個要處理的元素位置。

while getopts “🅰️bc” opt #第一個冒号表示忽略錯誤;字元後面的冒号表示該選項必須有自己的參數

while getopts "u:D:p:m:K:R:E:T:vh" opt; do
  case $opt in
    u)
      MYSQL_USER=$OPTARG
      ;;
    D)
      MYSQL_DATABASE=$OPTARG
      ;;
    p)
      MYSQL_PASSWORD=$OPTARG
      ;;
    m)
      MYSQL_HOST=$OPTARG
      ;;
    K)
      MASTER=$OPTARG
      ;;
    R)
      KEYSTONE_REGION=$OPTARG
      ;;
    E)
      export SERVICE_ENDPOINT=$OPTARG
      ;;
    T)
      export SERVICE_TOKEN=$OPTARG
      ;;
    v)
      set -x
      ;;
    h)
      cat <<EOF
Usage: $0 [-m mysql_hostname] [-u mysql_username] [-D mysql_database] [-p mysql_password]
       [-K keystone_master ] [ -R keystone_region ] [ -E keystone_endpoint_url ] 
       [ -T keystone_token ]
          
Add -v for verbose mode, -h to display this message.
EOF
      exit 0
      ;;
    \?)
      echo "Unknown option -$OPTARG" >&2
      exit 1
      ;;
    :)
      echo "Option -$OPTARG requires an argument" >&2
      exit 1
      ;;
  esac
done  
           

七、塊裝置

我們去看linux中的’/dev/block’是 會發現有很多以下目錄(該環境是在linux虛拟機下)

lrwxrwxrwx 1 root root 6 4月   8 21:18 11:0 -> ../sr0
lrwxrwxrwx 1 root root 8 4月   8 21:18 7:0 -> ../loop0
lrwxrwxrwx 1 root root 8 4月   8 21:18 7:1 -> ../loop1
lrwxrwxrwx 1 root root 9 4月   8 21:18 7:10 -> ../loop10
lrwxrwxrwx 1 root root 9 4月   8 21:18 7:11 -> ../loop11
lrwxrwxrwx 1 root root 9 4月   8 21:18 7:12 -> ../loop12
lrwxrwxrwx 1 root root 9 4月   8 21:18 7:13 -> ../loop13
lrwxrwxrwx 1 root root 9 4月   8 21:18 7:14 -> ../loop14
lrwxrwxrwx 1 root root 8 4月   8 21:18 7:2 -> ../loop2
lrwxrwxrwx 1 root root 8 4月   8 21:18 7:3 -> ../loop3
lrwxrwxrwx 1 root root 8 4月   8 21:18 7:4 -> ../loop4
lrwxrwxrwx 1 root root 8 4月   8 21:18 7:5 -> ../loop5
lrwxrwxrwx 1 root root 8 4月   8 21:18 7:6 -> ../loop6
lrwxrwxrwx 1 root root 8 4月   8 21:18 7:7 -> ../loop7
lrwxrwxrwx 1 root root 8 4月   8 21:18 7:8 -> ../loop8
lrwxrwxrwx 1 root root 8 4月   8 21:18 7:9 -> ../loop9
lrwxrwxrwx 1 root root 6 4月   8 21:18 8:0 -> ../sda
lrwxrwxrwx 1 root root 7 4月   8 21:18 8:1 -> ../sda1
lrwxrwxrwx 1 root root 7 4月   8 21:18 8:2 -> ../sda2
lrwxrwxrwx 1 root root 7 4月   8 21:18 8:5 -> ../sda5
           

其中

/dev/sr0:光驅的裝置名

/dev/sr0 光驅的裝置名

/dev/cdrom 代表光驅

cdrom是sr0的軟連結.

Linux日常使用整理------雜貨/linux-C-API

loop裝置:是一種僞裝置(pseudo-device),或者也可以說是仿真裝置。它能使我們像塊裝置一樣通路一個檔案。在使用之前,一個 loop 裝置必須要和一個檔案進行連接配接。這種結合方式給使用者提供了一個替代塊特殊檔案的接口。是以,如果這個檔案包含有一個完整的檔案系統,那麼這個檔案就可以像一個磁盤裝置一樣被 mount 起來

sda:d是SCSI硬碟和SATA硬碟,a是第一塊盤,0是第一個主分區

SISC:支援硬體熱拔插,性能好、穩定性高、适合長時間高負荷運作、接口擴充性強,可以支援10塊以上的硬碟,常用作伺服器 價格昂貴

SATA:民用為主,每個接口隻能聯結一塊硬碟

IDE:我們平常用的多數都為IDE,耗費CPU大,逐漸被SATA代替

loop裝置

對應使用的losetup指令

losetup [ -e encryption ] [ -o offset ] loop_device file

losetup [ -d ] loop_device

此指令用來設定循環裝置。循環裝置可把檔案虛拟成塊裝置,籍此來模拟整個檔案系統,讓使用者得以将其視為硬碟驅動器,光驅或軟驅等裝置,并挂入當作目錄來使用。指令格式中的選項與參數名:

-e 表示加密的方式

-o 設定資料偏移量

-d 解除安裝裝置

loop_device 循環裝置名,在 linux 下如 /dev/loop0 , /dev/loop1 等。

file 要與循環裝置相關聯的檔案名,這個往往是一個磁盤鏡象檔案,如 *.img

示例:

//建立空的磁盤鏡像檔案,這裡建立一個1.44M的軟碟
$ dd if=/dev/zero of=floppy.img bs=512 count=2880

//使用 losetup将磁盤鏡像檔案虛拟成快裝置
$ losetup /dev/loop1 floppy.img

//挂載塊裝置
 $ mount /dev/loop0 /tmp

//解除安裝loop裝置
$ umount /tmp
$ losetup -d /dev/loop1
           

八、常用接口

popen

簡單說一下linux程式設計中常用的popen函數

#include <stdio.h>
FILE * popen(const char *command , const char *type );
int pclose(FILE *stream);
           

popen()函數通過建立一個管道,調用fork()産生一個子程序,執行一個shell以運作指令來開啟一個程序。這個管道必須由pclose()函數關閉,而不是fclose()函數。

type參數隻能是讀或者寫中的一種,得到的傳回值(标準I/O流)也具有和type相應的隻讀或隻寫類型。如果type是"r"則檔案指針連接配接到command的标準輸出;如果type是"w"則檔案指針連接配接到command的标準輸入

command參數是一個指向以NULL結束的shell指令字元串的指針。這行指令将被傳到bin/sh并使用-c标志,shell将執行這個指令。

作用: popen函數允許一個程式将另外一個程式作為新程序來啟動,并可以傳遞資料或者通過它接受資料。

其内部實作為調用 fork 産生一個子程序,執行一個 shell, 以運作指令來開啟一個程序,這個程序必須由 pclose() 函數關閉。

示例

int exe_pipe(const char *cmd, char *result, int len)
{
   FILE *ptr = popen(cmd, "r");
   if (ptr) {
       if (result)
           while (fgets(result + strlen(result), len, ptr) != NULL);
       pclose(ptr);
   } else {
       printf("popen is filed\n");
       return -1;
   }
   return 0;
}
           

unlink

unlink(filename,contest);

删除一個檔案

filename:檔案名,必需

context:檔案句柄的環境,可選

fork

建立一個新程序,向父程序傳回PID号,向子程序傳回0

pid = fork();
	if (pid < 0) {
		return -1;
	} else if (pid == 0) {
		child(argc, argv);
		_exit(0);
	} else {
	parents(argc, argv);
	_exit(0);
		}
           

execvp

exec系統調用會從目前程序中把目前程式的機器指令清除,然後在空的程序中載入調用時指定的程式代碼,最後運作這個新的程式。不會再回到目前程序

(1) 第一個參數是要運作的檔案,會在環境變量PATH中查找file,并執行.

(2) 第二個參數,是一個參數清單,如同在shell中調用程式一樣,參數清單為0,1,2,3……是以wensen.sh 作為第0個參數,需要重複一遍.

(3) argv清單最後一個必須是 NULL.

(4) 失敗會傳回-1, 成功無傳回值,但是,失敗會在目前程序運作,執行成功後,直接結束目前程序,可以在子程序中運作.

#include <unistd.h>
#include <stdio.h>
#include <errno.h>
int main()
{
    char * argv[] = {"test.sh", 0};  // 數組最後一位需要為0
    execvp("/xxx/xxx/xxx/test/test.sh", argv);
    return 0;
}
           

stat

擷取檔案資訊

傳回值:成功傳回0,失敗傳回-1;

​ 參數:檔案路徑(名),struct stat 類型的結構體

struct stat
{
    dev_t     st_dev;     /* ID of device containing file */檔案使用的裝置号
    ino_t     st_ino;     /* inode number */    索引節點号 
    mode_t    st_mode;    /* protection */  檔案對應的模式,檔案,目錄等
    nlink_t   st_nlink;   /* number of hard links */    檔案的硬連接配接數  
    uid_t     st_uid;     /* user ID of owner */    所有者使用者識别号
    gid_t     st_gid;     /* group ID of owner */   組識别号  
    dev_t     st_rdev;    /* device ID (if special file) */ 裝置檔案的裝置号
    off_t     st_size;    /* total size, in bytes */ 以位元組為機關的檔案容量   
    blksize_t st_blksize; /* blocksize for file system I/O */ 包含該檔案的磁盤塊的大小   
    blkcnt_t  st_blocks;  /* number of 512B blocks allocated */ 該檔案所占的磁盤塊  
    time_t    st_atime;   /* time of last access */ 最後一次通路該檔案的時間   
    time_t    st_mtime;   /* time of last modification */ /最後一次修改該檔案的時間   
    time_t    st_ctime;   /* time of last status change */ 最後一次改變該檔案狀态的時間   
};

           

stat結構體中的st_mode 則定義了下列數種情況:

S_IFMT   0170000    檔案類型的位遮罩
    S_IFSOCK 0140000    套接字
    S_IFLNK 0120000     符号連接配接
    S_IFREG 0100000     一般檔案
    S_IFBLK 0060000     區塊裝置
    S_IFDIR 0040000     目錄
    S_IFCHR 0020000     字元裝置
    S_IFIFO 0010000     先進先出
​
    S_ISUID 04000     檔案的(set user-id on execution)位
    S_ISGID 02000     檔案的(set group-id on execution)位
    S_ISVTX 01000     檔案的sticky位
​
    S_IRUSR(S_IREAD) 00400     檔案所有者具可讀取權限
    S_IWUSR(S_IWRITE)00200     檔案所有者具可寫入權限
    S_IXUSR(S_IEXEC) 00100     檔案所有者具可執行權限
​
    S_IRGRP 00040             使用者組具可讀取權限
    S_IWGRP 00020             使用者組具可寫入權限
    S_IXGRP 00010             使用者組具可執行權限
​
    S_IROTH 00004             其他使用者具可讀取權限
    S_IWOTH 00002             其他使用者具可寫入權限
    S_IXOTH 00001             其他使用者具可執行權限
​
    上述的檔案類型在POSIX中定義了檢查這些類型的宏定義:
    S_ISLNK (st_mode)    判斷是否為符号連接配接
    S_ISREG (st_mode)    是否為一般檔案
    S_ISDIR (st_mode)    是否為目錄
    S_ISCHR (st_mode)    是否為字元裝置檔案
    S_ISBLK (s3e)        是否為先進先出
    S_ISSOCK (st_mode)   是否為socket
    若一目錄具有sticky位(S_ISVTX),則表示在此目錄下的檔案隻能被該檔案所有者、此目錄所有者或root來删除或改名,在linux中,最典型的就是這個/tmp目錄啦。
           

acess

#include<unistd.h>
int access(const char* pathname, int mode);
           

pathname 是檔案的路徑名+檔案名

mode:指定access的作用,取值如下

F_OK 值為0,判斷檔案是否存在
X_OK 值為1,判斷對檔案是可執行權限
W_OK 值為2,判斷對檔案是否有寫權限
R_OK 值為4,判斷對檔案是否有讀權限 
注:後三種可以使用或“|”的方式,一起使用,如W_OK|R_OK
           

傳回值:成功0,失敗-1

readdir和readdir_r

因為内部使用了靜态資料,是以readdir被認為不是線程安全的函數

但隻要不是多個線程使用相同的dirstream,就盡可能的使用readdir,它其實更簡單

API手冊

關于Linux C API,大家可以參考以下連結:Linux C API 參考手冊

下面做一些簡單的總結

1、字元測試

is+xxx:islower 測試字元是否為小寫字母

2、字元轉換

atoi、atol等

3、記憶體控制

calloc(會初始為0)、malloc(不會初始化)、mmap、free等

4、日期時間

ctime、time、gmtime等

5、記憶體及字元串操作

bcmp、bcopy、bzero、memcpy、index等記憶體操作

strcat、strchr、strcmp等字元串操作函數

6、常用數學函數

abs、pow、sqrt等

7、使用者組

endgrent、getpid等

8、資料結構及算法

rand、srand、qsort(快速排序)、lsearch(線性搜尋)等

9、檔案操作

#include<unistd.h>

close、creat、lseek、open、read、write、sync等

(f開頭的為操作檔案指針的标準庫,不帶f開頭的直接操作檔案描述符,為系統庫)

10、檔案内容操作

fgetc、fgets(指定輸入/輸出流)、fseek、gets(從标準輸入流中擷取)

11、程序操作

exit、execl、execv、vfork、getpid、waitpid、

12、格式化輸入輸出

fprintf、fscanf、printf、sprintf、sccanf、vfprintf等

13、檔案權限控制

access、chdir、chmod、closedir、fchdir、fstat、link、opendir、readdir、remove、stat等

14、信号處理

alarm、pause、signal、sleep、perror、mkfifo、pipe、popen等

15、接口處理

accept、bind、connect、inet_addr、listen、recv、recvfrom、send、sendmsg、sendto、socket等

16、環境變量

getenv、putenv、setenv

17、終端控制

getopt、select、ttyname等

九、proc目錄

裡面包括目前系統中運作的所有程序的資訊。

主要内容可以看如下部落格,整理的比較好

Linux下的proc/程序号目錄

十、磁盤相關指令

df -h 檢視磁盤總共大小

du -sh /xxx 檢視/xxx目錄的實際大小

繼續閱讀