linux编程基本
库的使用
头文件:.h 里面的函数及变量的声明 比如#include <stdio.h> ,Linux下默认头文件的搜索路径
系统定义的头文件:
/usr/include
/usr/local/include
/usr/target/include (平台不同路径不同)
库文件:/lib64
c库函数
root@centos1 c]# ls /lib64/libc.so.6
/lib64/libc.so.6
查看一个程序使用了哪些库
ldd 可执行程序路径
//wait.c代码 #include <sys/wait.h> #include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> void child(int delay){ sleep(delay); exit(0); } void parent(int *status){ wait(status); } main(){ pid_t pid; int status; printf("Before:%d\n",getpid()); pid=fork(); if(pid == 0){ child(10); } if(pid >0 ){ printf("pid =%d\n",getpid()); parent(&status); printf("status =%d\n",status); } }
[root@centos1 c]# ldd ./wait
linux-vdso.so.1 => (0x00007ffebd1d2000)
libc.so.6 => /lib64/libc.so.6 (0x000000333a200000)
/lib64/ld-linux-x86-64.so.2 (0x0000003339e00000)
编译时默认链接c库,如果使用其它库编译时需要用-l
比如使用数学库
gcc -o m.c -lm -lc
系统限制
本身平台的类型:32位,64位
数据类型的限制:
位置根据机器
/usr/include/limits.h
/usr/lib/gcc/x86_64-redhat-linux/4.4.4/include/float.h
系统本身的限制
命令行:ulimit来修改和获取
编程时使用:
getrlimit来获取
setrlimit来设置
man getrlimit #include <sys/time.h> #include <sys/resource.h> int getrlimit(int resource, struct rlimit *rlim); int setrlimit(int resource, const struct rlimit *rlim); struct rlimit { rlim_t rlim_cur; /* Soft limit */ rlim_t rlim_max; /* Hard limit (ceiling for rlim_cur) */ }; resource 的一些值 RLIMIT_CORE:core文件的最大字节数. core文件是系统某个文件出现异常退出时,系统为其保存的上下文信息,在gdb调试时常需要用 RLIMIT_CPU:cpu时间最大值(秒) RLIMIT_DATA:一个进程数据段的最大字节数 RLIMIT_FSIZE:可创建文件的大小最大值 RLIMIT_NOFILE:每个进程可以打开的文件的个数 RLIMIT_STACK:进程栈空间的最大值,使系统不会自动的动态修改这个限制 RLIMIT_VMEM:虚拟地址空间的最大值 RLIMIT_AS:系统进程可用内存空间最大值
命令行参数
选项:-l -a -i
参数: -l /etc
main函数的参数形式
#include <stdio.h> int main(int argc,char* argv[]){ int i=0; for(;i<argc;i++){ printf("argv[%d]=%s\n",i,argv[i]); } return 0; } /* [root@centos1 c]# ./arg -a -bl c argv[0]=./arg argv[1]=-a argv[2]=-bl argv[3]=c */
命令行选项很多,提取时无需知道命令行参数的顺序
getopt
getopt_long
长选项(一个字符串)和短选项(一个字符)
man 3 getopt 库函数里查找
#include <unistd.h> int getopt(int argc, char * const argv[],const char *optstring); extern char *optarg; extern int optind, opterr, optopt;
选项:一个选项一般完成不同功能的操作
参数:在执行相应选项功能操作时传入的信息
-a:选项
参数:-h host -u root -p 123456
为了识别命令行输入信息,getopt函数第三个参数的约定
1.如果就是一个字符,表示某个选项
2.如果一个字符后有1个冒号,表示选项后面一定要跟一个参数,参数可以紧跟选项或者与选项相隔一个空格
3.如果一个字符后有2个冒号,表示选项后可以有一个参数或没有参数,在选项后的参数一定不能跟字符以空格间隔
ab:c::d::
a是一个选项
b后有冒号,其后内容一定是个参数
c,d后双冒号,其后内容可以后也可以没有,有的话一定紧挨
./getopt -a -b host -chello -d word
a是选项,host是b的参数
hello是c的参数
word和-d没任何关系
getopt每成功执行一次,将返回当前的一个选项
并且
extern char *optarg;//将向下一个要扫描的参数
extern int optind, //索引为下一个要处理的指针小标
opterr, //oprerr=0 不将错误输出的标准错误输出设备
optopt;//用于处处可能的错误或者不可知的信息
getopt.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc,char **argv) { int result; opterr=0; while( (result = getopt(argc,argv,"ab:c::")) !=-1 ) { switch(result) { case 'a': printf("option=a,optopt=%c,optarg=%s\n",optopt,optarg); break; case 'b': printf("option=b,optopt=%c,optarg=%s\n",optopt,optarg); break; case 'c': printf("option=c,optopt=%c,optarg=%s\n",optopt,optarg); break; case '?': printf("option=?,optopt=%c,optarg=%s\n",optopt,optarg); break; default: printf("option=default,optopt=%c,optarg=%s\n",optopt,optarg); } printf("argv[%d]=%s\n",optind,argv[optind]); } printf("result=%d,optind=%d\n",result,optind); for(result=optind;result<argc;result++) { printf("-------argv[%d]=%s\n",result,argv[result] ); } for(result=1;result<argc;result++){ printf("\nat the end ---argv[%d]=%s\n",result,argv[result] ); } return 0; }
[root@centos1 c]# ./getopt -b b1 -a1 -cc1 d option=b,optopt=,optarg=b1 argv[3]=-a1 option=a,optopt=,optarg=(null) argv[3]=-a1 option=?,optopt=1,optarg=(null) argv[4]=-cc1 option=c,optopt=1,optarg=c1 argv[5]=d result=-1,optind=5 -------argv[5]=d at the end ---argv[1]=-b at the end ---argv[2]=b1 at the end ---argv[3]=-a1 at the end ---argv[4]=-cc1 at the end ---argv[5]=d
长选项:这个选项由一个字符串组成,在选项很多的时候容易记忆
#include <unistd.h> int getopt(int argc, char * const argv[], const char *optstring); extern char *optarg; extern int optind, opterr, optopt; #include <getopt.h> int getopt_long( int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);
optstring:一般为一个字符串常量,代表所有的短选项,就是一般以"-"开头的选项,
如果选项后带参数,则必须在相应的字符后面加":",如"ab:cde:"
longindex参数如果没有设置为NULL,那么它就指向一个变量,这个变量会被赋值为寻找到的长选项在longopts中的索引值,这可以用于错误诊断
几种返回值
0 getopt_long()设置一个标志,它的值与option结构中的val字段的值一样
1 每碰到一个命令行参数,optarg都会记录它
'?' 无效选项
':' 缺少选项参数
'x' 选项字符'x'
-1 选项解析结束
struct option { const char *name; //长选项名 int has_arg; //是否有参数 0、1、2,分别表示没有参数、有参数、参数可选 int *flag; int val; //返回值,短选项值 };
flag如果为NULL,函数返回val的值,
否则将val的值写入flag指向的变量中,
一般情况下,如果flag为NULL,则val的值为该长选项对应的短选项
短选项 长选项
-h --help
-o filename --output filename
-v --version
第三个参数 :短选项方式的格式
ho:v
第四个参数struct
struct option my_option={ {"help",0,NULL,'h'}, {"output",1,NULL,'o'}, {"version",0,NULL,'v'} }
长选项使用
getopt_long.c
#include <stdio.h> #include <unistd.h> #include <getopt.h> #include <stdlib.h> int main(int argc,char *argv[]) { int opt; struct option longopts[] = { {"initialize",0,NULL,'i'}, {"file",1,NULL,'f'}, {"list",0,NULL,'l'}, {"restart",0,NULL,'r'}, {"help",0,NULL,'h'}, {"output",1,NULL,'o'}, {"version",0,NULL,'v'} }; while((opt = getopt_long(argc, argv, "if:lrho:v", longopts, NULL)) != -1){ switch(opt){ case ':': printf("option needs a value\n"); break; case '?': printf("unknown option: %c\n",optopt); break; default: printf("opt=%c,optind=%d,optarg=%s\n",opt,optind,optarg); } } }
执行结果
[root@centos1 c]# ./getopt_long -v -i --file a.php -l --eee -o opt=v,optind=2,optarg=(null) opt=i,optind=3,optarg=(null) opt=f,optind=5,optarg=a.php opt=l,optind=6,optarg=(null) ./getopt_long: unrecognized option '--eee' unknown option: ./getopt_long: option requires an argument -- 'o' unknown option: o