入门
编译
1、gcc -o hello hello.c 命令可以把 hello.c编译为 hello,其中-o指定编译后目标。如果不指定,就编译为a.out。
2、Linux很多可执行程序在 /usr/bin可以找到,头文件通常放置于 /usr/include
3、-I (这是大写的ai)后接要使用的头文件目录,比如 -I/usr/include/opencv。有些目录可以被编译器自动搜索到,比如标准库。
4、标准的库总是以lib开头,随后指明是什么库。 .a 表示静态库, .so表示共享库。
gcc -o fred fred.c /usr/lib/libm.a
可以在编译时链接后面这个库,也可以使用简写方式
gcc -o fred fred.c -lm
-lm表示要链接到一个名字为libm.a 或者libm.so中,编译器会优先搜索共享库,找不到才用静态库。
可以使用-L指明要添加的库路径,比如
gcc -o fred fred.c -L/usr/lib -lm
注意没有-L和后面路径没有空格。
5、编译一个静态库
//fred.c
#include<stdio.h>
void fred(int arg){
printf("fred: we passed %d\n", arg);
}
//bill.c
#include<stdio.h>
void bill(char *arg){
printf("bill: we passed %s\n", arg);
}
这两个文件都没有main函数,所以直接编译不能生成完整程序。我们可以通过指定一个 -c 来阻止生成它,但是可以产生目标文件,也就是 .o文件。
gcc -c bill.c fred.c
ls *.o
输出 bill.o fred.o
接下来创建一个头文件,包含这两个函数的声明:
//lib.h
void bill(char *);
void fred(int);
再使用一个程序去调用他们,但我们不连接源程序。
//program.h
#include <stdio.h>
#include "lib.h"
int main(){
bill("Hello world");
fred(3);
return 0;
}
现在来编译一个试试。
gcc -c program.c #这个可以生成program.o
gcc -o program program.o bill.o fred.o
但是两个函数放到两个.o文件太麻烦了,我们想把它放一块。使用ar程序可以完成它。ar可以创建一个归档文件将目标文件添加进去,具体可以看帮助。
ar crv libfoo.a bill.o fred.o
接下来就用这个libfoo.a来试试。
gcc -o program2 program.o libfoo.a
#或者是:
#gcc -o program2 program.o -L. -lfoo
总结一下静态库与共享库。静态库在每个程序运行时都会产生一个库的副本。所以如果一个静态库被很多程序使用,那就会产生很多副本,浪费很多内存和磁盘IO。而共享库可以被程序共享,只有一份需要使用的会被加载到内存,被需要使用的程序共享。
ldd命令可以查看一个程序使用了那些共享库。
ldd program2
6、帮助
通过man和info可以获取命令的帮助。有点命令可以通过输入–help等方式。
第一节完
shell
为什么使用shell
shell就是一种脚本语言,其实就是很多别人已经写好的程序,可以供你调用。这些小程序可以完成各种各样的功能,你可以通过命令的组合完成强大而复杂的功能。但是这些小程序只是帮助你快速完成任务,对于一些计算密集型任务,肯定就不行了。
例如ls、more、less、grep等等,都是常用的小命令。各种命令可以通过管道进行连接。
管道和重定向
重定向输出
重定向可以将命令的输出定向到其他地方,比如文件。
ls -l > lsoutput.txt
上面这个命令会把 输出 的结果定向到一个txt文件,需要注意的是这个会生成一个名为 lsoutput.txt的文件,如果它原来就存在,那么就会被覆盖。
还可以使用 >> 进行追加。
ps >> lsoutput.txt
重定向还可以更多的控制输出,比如0表示一个程序的标准输入,1表示标准输出,2表示标准错误输出。
我们正在运行的程序如果输出特别多,而我们又需要保留这些输出,那就可以把它输出至一个文件。如下例子:
#!/usr/bin/env sh
CURRENT_TIME="`date +20%y%m%d_%H%M%S`"
caffe-master/build/tools/caffe train --solver=solver.prototxt >${CURRENT_TIME} 2>&1
重定向输入
可以把文件等重定向输入给程序:
more < kill.txt
不过这样做没什么用,因为more自己可以接受参数的。
管道
管道可以让数据在不同进程之间流动,这样就可以把命令串起来用,最后输出一个想要的结果,效率更高!
ps | sort > pssort.txt
先用ps列出进程,然后利用管道输给sort,sort接收管道数据后进行排序,,然后将结果重定向到文件。
允许连接的进程数目是没有限制。
ls -xo comn | sort | grep -v sh | more