Linux开发学习笔记(一)
安装虚拟机并联网
1、安装虚拟机vmware:
安装完vmware并打开——》点击创建新的虚拟机——》自定义——》下一步——》选择稍后安装操作系统——》选择Linux Ubuntu 64位——》给虚拟机取名字、选择安装路径——》配置处理器数量1和内核数量2——》虚拟机内存选择1G——》使用桥接网络——》一直选默认——》完成。
2、在虚拟机下安装Ubuntu:
下载好Ubuntu镜像文件——》在虚拟机设置里面选择镜像文件的路径——》选择english——》install Ubuntu——》设置账号密码——》安装并重启。
3、虚拟机联网
点击菜单栏的虚拟机——》设置——》网络适配器选择NAT。
如果出现连不上网的情况:
打开Windows的服务窗口
将这三项设置成自动并启动。
4、Ubuntu14.04如何设置固定IP和DNS
参考:https://blog.****.net/biqioso/article/details/81104617
更新软件
sudo apt-get update 更新源
sudo apt-get upgrade 更新软件
sudo apt-get clean 清理缓存
安装使用vim
1、安装vim
sudo apt-get install vim
2、添加 vim 配置文件
配置自己的vim,输入:
vi ~/.vimrc
将以下内容添加到.vimrc中,就可以实现基本的vim配置:
(还可安装各种插件将vim配置成一个强大的IDE工具)
"显示行号
set nu
"启动时隐去援助提示
set shortmess=atI
"语法高亮
syntax on
"使用vim的键盘模式
"set nocompatible
"不需要备份
set nobackup
"没有保存或文件只读时弹出确认
set confirm
"鼠标可用
set mouse=a
"tab缩进
set tabstop=4
set shiftwidth=4
set expandtab
set smarttab
"文件自动检测外部更改
set autoread
"c文件自动缩进
set cindent
"自动对齐
set autoindent
"智能缩进
set smartindent
"高亮查找匹配
set hlsearch
"背景色
set background=dark
"显示匹配
set showmatch
"显示标尺,就是在右下角显示光标位置
set ruler
"去除vi的一致性
set nocompatible
"允许折叠
set foldenable
"""""""""""""""""设置折叠"""""""""""""""""""""
"
"根据语法折叠
set fdm=syntax
"手动折叠
"set fdm=manual
"设置键盘映射,通过空格设置折叠
nnoremap <space> @=((foldclosed(line('.')<0)?'zc':'zo'))<CR>
""""""""""""""""""""""""""""""""""""""""""""""
"不要闪烁
set novisualbell
"启动显示状态行
set laststatus=2
"浅色显示当前行
autocmd InsertLeave * se nocul
"用浅色高亮当前行
autocmd InsertEnter * se cul
"显示输入的命令
set showcmd
"被分割窗口之间显示空白
set fillchars=vert:/
set fillchars=stl:/
set fillchars=stlnc:/
3、基础使用
(最全的vim快捷键 https://blog.****.net/biqioso/article/details/81140600)
使用vi来打开/创建一个文件,vi 文件名
vi的两种模式
1、命令模式:当vi打开时默认为命令模式,要转入输入模式,需要按a或者i键。在命令模式下,此时键盘上输入的所有东西都被vi当作命令来对待。(所以不要乱输)
2、输入模式:输入模式用来向文件输入内容。可以从命令模式中按a或者i进入输入模式。输入完成后如果要保存,要先退回到命令模式(因为保存也是一种命令)。在输入模式下按ESC键或 Ctrl+[
回到命令模式。
注:输入模式下,屏幕左下角会提示 -- INSERT --。否则就是命令模式。
在命令模式下如何保存
:wq 保存并且退出
:w 只保存不退出
:q 不保存只退出
:q! 不保存强制退出
:wq! 保存并强制退出(!可理解成强制)
查找
在命令模式下,输入(/xxx),就可以查找到xxx
快速切换行
在命令模式下,输入(:num),就可以快速切换到num行
复制
复制一行则:yy
复制三行则:3yy,即从当前光标+下两行。
复制当前光标所在的位置到行尾:y$
复制当前光标所在的位置到行首:y^
剪切
剪切一行:dd
前切三行:3dd,即从当前行+下两行被剪切了。
剪切当前行光标所在的位置到行尾:d$
剪切当前行光标所在的位置到行首:d^
粘贴
用v选中文本之后可以按y进行复制,如果按d就表示剪切,之后按p进行粘贴。
gp:和p的功能基本一样,但是粘贴完,它会把光标移动至粘贴内容之后;gP同理。
撤销与恢复
'u' : 撤销上一个编辑操作
'ctrl + r' : 恢复,即回退前一个命令
'U' : 行撤销,撤销所有在前一个编辑行上的操作
. :重复最后一条修改正文的命令
外部文件与vim之间的粘帖和复制
ubuntu默认vim是不支持从外部文件与vim之间的粘帖复制,vim有自己的剪切版,分别是”0-”9,”-,”8,”+,”:,”/,”%,”i,这些都是vim的寄存器,可以用命令:reg查看。ubuntu需要安装vim-gnome。
输入命令sudo apt-get install vim-gnome进行安装。
“+y表示从vim复制到系统剪切版
“+p表示从外部文件(系统剪切版)粘帖到vim
“+d表示剪切
屏幕翻页
Ctrl+u: 向上翻半屏
Ctrl+f: 向上翻一屏
Ctrl+d: 向下翻半屏
Ctrl+b: 向下翻一屏
移动光标指令
移动光标普遍使用的是方向键,考虑兼容问题,vi定义太多的方向指令,下面只是一小小部分(常用的几个):
space: 光标右移一个字符
Backspace: 光标左移一个字符
Enter: 光标下移一行
nG: 光标移至第n行首
n+: 光标下移n行
n-: 光标上移n行
H: 将光标移到屏幕上的起始行(或最上行);
M: 将光标移到屏幕中间;
L : 将光标移到屏幕最后一行。
插入删除指令
常用插入、删除指令如下:
i:在当前光标前插入,光标后文本向后移
a:从当前光标后插入,光标后文本后移
I:在光标所在行首插入(第一个非空白字符前)
A:从光标所在行末插入
o: 在光标所在行下面新增一行(并进入输入模式)
O: 在光标所在行上方新增一行(并进入输入模式)
x: 删除光标所在字符,等同于[Delete]功能键
X: 删除光标前字符,相当与[Backspace]
dd: 删除光标所在的行,并去除空隙
cc:删除当前行并进入编辑模式
r: 修改光标所在字符
R: 替换当前字符及其后的字符,直到按 [ESC]
s: 从当前光标位置处开始,以输入的文本替代指定数目的字符
S: 删除指定数目的行,并以所输入文本代替之
do: 删至行首
d$: 删至行尾
安装samba
sudo apt-get install samba
vi /etc/samba/smb.conf
在文档的最后加上:
添加samba用户并设置密码:
Windows访问Ubuntu的/home/share
查看UbuntuIP地址:
快捷键Win+R 打开运行对话框,输入Ubuntu的IP地址:
输入账号密码之后就可以使用samba实现共享服务,还可以映射网络驱动器,方便打开。
注意:如果每次打开虚拟机,IP地址变来变去的话,可以将其设置为静态IP。
(参考: https://blog.****.net/biqioso/article/details/81104617)
Git配合OSC的使用
在码云上创建项目,然后复制HTTPS
右键
将刚才复制的HTTPS粘贴到URL那个地方,点击ok之后
之后桌面就会有个文件夹
添加文件到仓库中(把文件拉到文件夹中),然后选择要添加的文件点右键点击Add
然后点击commit——》输入描述信息——》点击commit——》push——》输入账号密码(可以设置不用每次都输入密码)——》这时码云上面就有刚上传的文件了。
注意:假如现在有几个人同时在维护这个项目,然后我准备将本地的文件改动之后上传到服务器,上传之前需要先pull,将最新的项目更新到本地,再编辑再commit再push,这样才不会报错,如果没有pull的话,就会跟服务器产生冲突。
点击showlog可以比较版本差异:
Shift+鼠标左键,可以选中两个版本,再鼠标右键,选中Compare revisions,就可以比较两个版本,点击那个文件可以具体看到差异。
Ubuntu上安装使用Git
安装完成后对git进行配置:
第一行是账号,第二行是邮箱地址。
因为本地Git仓库和远程仓库(如GitHub)之间的传输是通过SSH加密的,所以需要SSH Key。
接下来是生成公钥(SSH Key):输入指令之后按回车即可,无需设置密码。
如果一切顺利的话,可以在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。
创建完公钥之后,需要上传。
之后会打开一个文档
将里面的内容全部复制。
打开码云——》设置
将刚才复制的粘贴到红色框内。
为什么 码云或者GitHub 需要SSH Key呢?因为它们需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,码云或者GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。(可添加多个公钥)
然后测试连接是否通畅
到这里,git就安装配置成功了。
Linux下使用Git
1、使用git
先了解一件事:Git支持多种协议,包括ssh、https,但通过ssh支持的原生git协议速度最快。
- 关联本地库和远程库
先创建一个文件夹(以wenjian为例)然后使用git init指令初始化一个空的git仓库。
接着添加一个远程仓库,输入git remote add origin <项目地址>
项目地址的格式:https://git.oschina.net/用户名/项目名.git(其实就是复制项目的网址,然后在后面加上 .git),还可以用ssh协议的那种。
(Git 里面的 origin 代表远程库 https://mp.****.net/postedit/81140711)
这样,就把本地仓库和远程库关联起来了。
关联后,使用命令git push -u origin master第一次推送master分支的所有内容;
此后就可以使用命令git push origin master推送最新修改;
上面命令中使用-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
- 远程库克隆
要克隆一个仓库,首先得先有远程库的地址,然后输入:git clone <项目地址>
项目地址的格式:https://git.oschina.net/用户名/项目名.git(其实就是复制项目的网址,然后在后面加上 .git),还可以用ssh协议的那种。
克隆某一个特定的远程分支:git clone –b <分支名> <项目地址>
- 进行一次提交
平时注意提交之前要先pull一下(避免冲突)。输入git pull origin master
然后把要提交的文件(以1234为例)弄到这个文件夹里,或者直接在这个文件夹中编辑新的文件。
然后输入git add .(注意有个点)添加文件,输入git commit –m “注释”提交到仓库。
git add -A 提交所有变化
git add -u 提交被修改(modified)和被删除(deleted)文件,不包括新文件(new)
git add . 提交新文件(new)和被修改(modified)文件,不包括被删除(deleted)文件
输入git push origin master就可以完成推送了。
接着去码云上面就可以看到刚push上去的文件了。
参考网站:
http://www.cnblogs.com/wangmingshun/category/819852.html
2、Git常用命令
git status 显示当前仓库的最新状态。提交之后,工作区就是“干净的”,即没有新的修改;三部分:(已经在stage区, 等待添加到HEAD中的文件) (有修改, 但是没有被添加到stage区的文件) (没有tracked过的文件, 即从没有add过的文件)可通过.gitignore的配置去忽略某些不想显示出来的没有tracked过的文件
在每次执行 git commit之前先使用git status检查文件状态是一个很好的习惯, 这样能防止你不小心提交了您不想提交的东西。
git status -s 或 git status –short 状态简览。新添加的未跟踪文件前面有 ?? 标记,新添加到暂你可能注意到了 M 有两个可以出现的位置,出现在右边的 M 表示该文件被修改了但是还没放入暂存区,出现在靠左边的 M 表示该文件被修改了并放入了暂存区。
git diff 查看工作区中的修改。
git diff <commit id1> <commit id2> 比较两次 commit 之间的差异。
git diff <branch1> <branch2> 在两个 branch 之间比较。
git diff 文件 查看指定文件具体修改了哪些内容。
git log 查看当前分支的提交历史
git branch xxx 创建本地分支xxx(只创建,不进行分支切换)
git branch 查看本地分支
git checkout xxx 切换分支到xxx
git branch –d xxx 删除本地分支xxx
git branch -d -r xxx 删除远程分支
git branch –a 查看所有本地分支和远程分支(前面带*的表示当前工作目录所在分支)
git remote –v 查看远程的仓库(origin)
git branch –r 查看远程分支
git merge dev 合并指定分支dev到当前分支。
git branch -m | -M oldbranch newbranch 重命名分支,如果newbranch名字分支已经存在,则需要使用-M强制重命名,否则,使用-m进行重命名。
git pull <远程主机名origin> <远程分支名master>:<本地分支名>
git remote show origin 查看remote地址,远程分支,本地分支与之相对应关系
git push origin master –f 强制推送代码(协同开发时,很可能会覆盖别人的代码)
git stash 将当前改动暂存起来:
git stash pop 恢复最后一次暂存的改动
git stash list 查看有多少暂存
打标签:
git checkout master 切换到需要打标签的分支上
git tag v1.0 打一个新标签
git tag 查看所有标签
默认标签是打在最新提交的commit上的。
git log --pretty=oneline --abbrev-commit 找到历史提交的commit id
git tag v0.9 f52c633 就可以对commit id是f52c633的这次提交打标签
git show v0.9 查看标签信息
git tag -a v0.1 -m "version 0.1 released" 1094adb 创建带有说明的标签,用-a指定标签名,-m指定说明文字
git tag -d v0.1 删除标签,因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。
git push origin v0.1 推送某个标签到远程
git push origin –tags 一次性推送全部尚未推送到远程的本地标签
如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:
git tag -d v0.9
然后,从远程删除。删除命令是
git push origin :refs/tags/v0.9
注意:标签总是和某个commit挂钩。如果这个commit既出现在master分支,又出现在dev分支,那么在这两个分支上都可以看到这个标签。
git reset –hard 撤销当前的修改(注意:这条命令会完全重置你的修改,如果你想保留某些文件,请使用checkout +文件路径 命令来逐一撤销修改)
git reset --hard origin/master (回退到和远程版本一样origin代表你远程仓库的名字,master代表分支名)
git commit –amend 修改最近一次提交的提交信息
git filter-branch --tree-filter 'rm -f passwords.txt' HEAD 从每一个提交移除一个文件(passwords.txt),为了让 filter-branch 在所有分支上运行,可以给命令传递 --all 选项。
git cherry-pick <commit id> 从众多提交中保留只需要的提交
git config –global core.editor “vim” 这样就可以把vim编辑器作为git commit时的编辑器,就可以在里面添加大段的注释。
git config –global credential.helper store 可以记住用户和密码,不用每次pull、push都输入密码
各种问题都可以查看这个网站:http://git.mydoc.io/?t=154701
3、git log规范
禁止中文,必须全英文log,log的作用,为了追溯以前的代码
格式如下
[修改的主要大目录] 同步人姓名
1. 修改内容,简介明了,让大家看的懂
例子:
[package:input] sync code from zhangbh ===>package为修改的大目录,不是工程总目录,input为所修改的最小目录
1.Add buzzer function.
2.Change the multi touch report to single point report.
使用vscode、notepad++、截图工具
额…没什么好说的,下载之后动手操作一波就可以了。
使用beyond compare
使用Source Insight
新建工程
输入工程名,选择保存路径(一般创建一个文件夹用来存放source insight有关文件,这里以si_project为例)
然后会弹出这个窗口
选择要加入的文件夹,点击Add Tree将所有文件递归加到工程中,然后点击Close就搞定了。
常用操作:
1、Project->Synchronizing Files 同步
2、对一个变量或函数 右键lookup references…可以进行查找,然后可以通过红色标记打开对应代码文件,再点一次就返回查找结果页面。也有可以对查找结果进行上下跳转的按钮。
3、对函数右键jump to caller,会跳转到调用的地方。
4、Ctrl + 鼠标单击 进入定义.
5、Alt + F12可以切换,让字符宽度变得一致,或者是大小不同地显示。
6、Ctrl + G (或者F5) 跳转到某一行。
7、Ctrl + O 搜索文件,找到回车打开,找不到ESC退出
8、Alt + G (或者F7) 打开Symbol Window.
9、Alt +, 后退;Alt+.前进.
10、Ctrl + F 查找关键字。
11、Ctrl + Shift + F 全工程查找关键字
Xshell通过SSH登录虚拟机的Ubuntu系统
先了解一下SSH:SSH(全称 Secure Shell)是一种加密的网络协议。使用该协议的数据将被加密,如果在传输中间数据泄漏,也可以确保没有人能读取出有用信息。要使用 SSH,目标机器应该安装 SSH 服务端应用程序,因为 SSH 是基于客户-服务模式的。 当你想安全的远程连接到主机,可中间的网络(比如因特网)并不安全,通常这种情况下就会使用 SSH。
首先打开Xshell——》新建会话
然后去Ubuntu输入指令 ifconfig 查看Ubuntu系统的IP地址
确定之后输入Ubuntu的用户账号密码就可以连上了
这样就是连上之后的情形。
密码也可以设置长期有效,不用每次连接都输入密码。
如果上面的步骤还没有连上的话,很可能是Ubuntu主机没有打开SSH服务。
(ssh程序分为有客户端程序openssh-client和服务端程序openssh-server。如果需要ssh登陆到别的电脑,需要安装openssh-client,该程序Ubuntu是默认安装的。而如果需要从远程连接到本机,则需要安装openssh-server,该程序需要自己安装。在Ubuntu下安装openssh-server非常简单。)
所以首先输入sudo apt-get install openssh-server安装一下openssh-server。
输入ps -e | grep ssh查看ssh服务有没有运行,有运行的话可以看到
有sshd进程说明openssh-server已经启动。
没有启动的话可以输入 /etc/init.d/ssh start启动。
再输入 netstat –ntlp可以看到下面红框
这说明sshd已经能够正常工作了(默认端口是22)。再打开xshell连接就搞定了。
Linux命令
1、常用命令
(1)ls(list,列表)
作用:使用列表把当前文件夹下所有文件显示出来
ls -a 显示所有文件,包括隐藏文件
ls -l 以详细信息显示
ls -a -l 显示所有文件的详细信息
ls -l-a
ls -la
ls -al 以上都可以用,强调一种思维
(2)man
作用:查询man手册,获得帮助信息
man 1 ls 1表示查询的是linux命令
man 2 xxx 2表示查询的是linux API
man 3 xxx 3表示查询的是C库函数
注意:在man手册中查询时,退出按Q键(Q就是quit的缩写)
(3)cd(change directory,更改目录)
作用:用来切换目录
涉及到相对路径和绝对路径
cd .. ..代表上一层目录
cd . .代表当前目录
../../../../代表上上上上层目录
注意:每个新的空的文件夹里面都有两个隐藏的文件,分别是(.)、(..),这两个文件里面分别是两个路径。也就是说cd.的时候,看似在进入当前目录,其实就是进入了那个叫做.的文件。同理,cd..的时候,看似进入了上一层目录,其实就是进入了那个叫做..的文件。
在看文件详情的时候,前面d表示文件夹,前面-表示普通文件,前面l表示符号连接文件。
(4)pwd(print work directory,打印工作目录)
作用:打印出当前的绝对路径
(5)mkdir(make directory,创建文件夹)
作用:创建空文件夹
mkdir -p 级联创建文件夹
如: mkdir -p 111/222
(6)touch
作用:创建空文件
格式:touch pathname
(7)mv (move,移动)
作用:在目录间移动文件(只改path不改name),重命名文件(不改path改name)
也可以同时改
格式:mv 源文件pathname 目标文件pathname
(8)cp(copy,复制)
作用:复制文件或文件夹(复制时路径可以改,名字也可以改,也可以都改)
格式: cp 源文件pathname 目标文件pathname
cp -r 用来复制文件夹
cp -f 强制复制
cp -rf 强制复制文件夹
实际操作时,一般都是cp-f复制文件(因为有时执行之后并没有真正复制过去,所以需要强制。不过需要注意是否会覆盖到同名文件,所以平时要有备份的习惯。)
(9) rm(remove,去除,删除)
作用:用来删除文件或文件夹
rm 文件pathname
rm -f 文件pathname
re -r 文件夹pathname
re -rf 文件夹pathname
(rm和rm -f的区别是返回值不同,不管文件存不存在,用rm -f执行都会成功,因为是强制的。而用rm就可能会报错。)
(10)rmdir(remove directory,删除文件夹)(没什么卵用)
作用:删除空文件夹(相当于rm -r)
rmdir和rm -r的区别:rmdir只能删除空文件夹,而rm -r可以删除空文件夹和非空文件夹。
(11)cat
作用:直接在命令行下显示文件内容,也可以用来向文件输入
(用vi也可以看文件内容,视实际情况选择用哪种方式)
(12)ln(link,连接文件)
基础:windows中快捷文件,实际上快捷方式和它指向的文件是独立的两个文件,两个都占硬盘空间,只不过用户访问快捷方式时,其效果等同于访问指向的文件。
linux中有两种连接文件:
一种叫软连接(符号连接),效果等同于windows中快捷文件
一种叫硬连接
注意:不能在VMware共享文件夹里面建立连接。
1、创建软链接文件:ln -s 源文件名 符号连接文件名
举例:ln -s a.c b.c b.c就是a.c的一个符号连接文件
软连接创建出来的文件是连接文件(l)
2、硬连接:ln 源文件名 连接文件名
硬连接实际上和源文件在硬盘中是同一个东西,效果类似于硬盘上的一个文件,在文件系统上,在我们看来有好多个文件一样,每次删除一个文件时,只要他还有其他的硬连接存在,这个文件就不会被真正删除。只有等所有的连接文件都被删除掉了,这个文件才会被真正从硬盘上删除。
注意:硬连接后,修改源文件或任意一个连接文件的内容,所有文件都跟着改变。
硬连接创建出来的文件是普通文件(-)
(13)apt-get(ubantu才有)
作用:在ubantu中用来在线安装、卸载软件的程序
sudo apt-get install vim
sudo apt-get remove vim
注意:安装和卸载都是在线的,也就是说ubantu必须能上网才能使用apt-get
apt-get安装软件的原理和必要性:
在linux中安装软件是是一件困难的事,经常发生不兼容。所以ubantu将适合某个发行版的所有软件做了一个列表,然后用户通过apt-get install的方式安装软件,就会实时连接到ubantu服务器,服务器就会根据你的uabntu版本,给你下载适合的软件来安装。这样确保了软件的兼容性。
(14)find
功能:在linux文件系统中,用来查找一个文件放在哪里了。一般是用在 知道要找的文件的文件名,但是忘了放在哪个目录下。
参数-name : 按照文件名查找文件。
举例:1. 在/dir目录及其子目录下面查找名字为filename的文件
find /dir -name filename
2. 在当前目录及其子目录(用“.”表示)中查找任何扩展名为“c”的文件
find . -name "*.c"
3. 在当前目录及其子目录(用“.”表示)中,只想查看文件,把符合条件的文件夹名去除。
find . –type f –name filename
除了-name,还有其他的选项,这里不详讲。
(15)grep
功能:在一个具体存在的文件中查找。
举例: grep main test.c
用来搜索 test.c里是否包含字串 main
grep -nr u8
用来查找含有 u8 的目录或文件集合
-n表示查找结果中显示行号,-r表示要递归查找,搜索子目录。
如果想在特定的文件中查找:
比如在USER文件夹中查找所有含有u8的地方
grep -nr u8 USER
其他选项:
grep -r pattern files :搜索子目录
grep -n pattern files : 显示匹配行及行号
grep -i pattern files :不区分大小写地搜索。默认情况区分大小写,
grep -l pattern files :只列出匹配的文件名,
grep -L pattern files :列出不匹配的文件名,
grep -w pattern files :只匹配整个单词,而不是字符串的一部分(如匹配‘magic’,而不是‘magical’),
grep -C number pattern files :匹配的上下文分别显示[number]行,
grep pattern1 | pattern2 files :显示匹配 pattern1 或 pattern2 的行,
grep pattern1 files | grep pattern2 :显示既匹配 pattern1 又匹配 pattern2 的行。
(16)文件打包压缩与解压缩
tar -czvf dir.tar.gz dir/ 将dir目录打包成dir.tar.gz (算法gz)
tar -cjvf dir.tar.bz2 dir/ 将dir目录打包成dir.tar.bz2(算法bz2)
tar -zxvf dir.tar.gz 解压缩dir.tar.gz
tar -jxvf dir.tar.bz2 解压缩dir.tar.bz2
(17)du
功能:显示每个文件和目录的磁盘使用空间。
选项:
-a或-all 显示目录中个别文件的大小。
-b或-bytes 显示目录或文件大小时,以byte为单位。
-c或--total 除了显示个别目录或文件的大小外,同时也显示所有目录或文件的总和。
-k或--kilobytes 以KB(1024bytes)为单位输出。
-m或--megabytes 以MB为单位输出。
-s或--summarize 仅显示总计,只列出最后加总的值。
-h或--human-readable 以K,M,G为单位,提高信息的可读性。
-x或--one-file-xystem 以一开始处理时的文件系统为准,若遇上其它不同的文件系统目录则略过。
-L<符号链接>或--dereference<符号链接> 显示选项中所指定符号链接的源文件大小。
-S或--separate-dirs 显示个别目录的大小时,并不含其子目录的大小。
-X<文件>或--exclude-from=<文件> 在<文件>指定目录或文件。
--exclude=<目录或文件> 略过指定的目录或文件。
-D或--dereference-args 显示指定符号链接的源文件大小。
-H或--si 与-h参数相同,但是K,M,G是以1000为换算单位。
-l或--count-links 重复计算硬件链接的文件。
2、基础知识
1、ls -l显示的详细信息中:
drwxr-xr-x 2 huangzj huangzj 4096 3月 16 22:59 Desktop
drwxr-xr-x 2 huangzj huangzj 4096 3月 16 22:45 Documents
drwxr-xr-x 2 huangzj huangzj 4096 3月 16 22:45 Downloads
-rw-r--r-- 1 huangzj huangzj 8980 3月 16 22:38 examples.desktop
一共10个字符,第一个字符表示文件类型,后面9个字符表示文件权限。
文件类型:
- 表示普通文件。普通文件指文本文件和二进制文件,如a.c 1.txt a.out都是普通文件
d 表示文件夹,d是directory的缩写
l 表示符号连接文件,后面会用->打印出它指向的文件
s 表示socket文件
p 表示管道文件 pipe
文件权限:
前三个表示此文件的 属主 对文件的权限
中间三个表示此文件属主所在的组对文件的权限
最后三个表示其他用户对文件的权限
rwx:r代表可读,w代表可写,x代表可执行。
所以r-x:可读,不可写,可执行
2、linux命令行中一些符号的含义:
. 代表当前目录
.. 代表上一个目录,当前目录的父目录
- 代表前一个目录,我刚才从哪个目录过来
~ 代表当前用户的宿主目录
/ 代表根目录
$ 普通用户的命令行提示符
# root用户的命令行提示符
* 万能匹配符 (*可以代替一个或多个字符)
3、使用sudo暂时获取root权限
就是说偶尔需要切换一次root用户状态去做一件事,就可以在不切换到root用户的状态下,去做一些只有root用户才能做的事,目的就是为了省去切换来切换去的麻烦,但是还是要输入密码的。
在root用户模式和普通用户模式下封装命令
打开配置文件:
root模式下
普通用户下
不同模式下虽然命令一样,但是打开的文件是不一样的,作用范围也是不一样的。
接着就可以在配置文件中封装命令了
比如输入: alias gitll=’git pull’
alias gitsh=’git push’
保存之后退出,然后执行文件让它及时生效
这样命令就封装完成了,需要输入git pull的时候输入gitll就可以了。
gcc的编译流程
1、整体流程
gcc的执行过程是四个相互关联的步骤∶预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编(Assembly)和连接(Linking)。命令gcc首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析。接着调用cc1进行编译,这个阶段根据输入文件生成以.i为后缀的目标文件。汇编过程是针对汇编语言的步骤,调用as进行工作,一般来讲,.S为后缀的汇编语言源代码文件和汇编、.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。当所有的目标文件都生成之后,gcc就调用ld来完成最后的关键性工作,这个阶段就是连接。在连接阶段,所有的目标文件被安排在可执行程序中的恰当的位置,同时,该程序所调用到的库函数也从各自所在的库中连到合适的地方。
详解这四个过程:
1、预处理
预处理器的预处理过程主要为 文件包含、宏替换、去注释
输入命令:gcc -E hello.c -o hello.i
生成hello.i文件,也就是预处理后的文件。
2、编译
编译器把预处理之后的源文件hello.i编译成汇编语言,并进行语法检查,有错误就会停止编译并打印出错误信息。
输入命令:gcc -S hello.i -o hello.s
生成hello.s汇编文件
3、汇编
汇编器把hello.s文件汇编成目标机器指令,也就是hello.o文件。
输入命令:gcc -c hello.s -o hello.o
生成hello.o目标文件
(目标文件有几种类型,这里不详讲)
4、链接
将有关的目标文件彼此连接,生成可执行文件
输入命令:gcc hello.o -o hello
生成可执行文件hello,如果不用-o去指定生成可执行文件为hello的话,gcc会给出预设的可执行文件a.out
(链接也有动态链接、静态链接等)
2、常用编译命令选项
假设源程序文件名为test.c。
1. 无选项编译链接
用法:#gcc test.c
作用:将test.c预处理、汇编、编译并链接形成可执行文件。这里未指定输出文件,默认输出为a.out。
2. 选项 -o
用法:#gcc test.c -o test
作用:将test.c预处理、汇编、编译并链接形成可执行文件test。-o选项用来指定输出文件的文件名。
3. 选项 -E
用法:#gcc -E test.c -o test.i
作用:将test.c预处理输出test.i文件。
-E 仅执行编译预处理,不生成文件,如果需要保存,则得需要重定向
4. 选项 -S
用法:#gcc -S test.i
作用:将预处理输出文件test.i汇编成test.s文件。
5. 选项 -c
用法:#gcc -c test.s
作用:将汇编输出文件test.s编译输出test.o文件。
6. 无选项链接
用法:#gcc test.o -o test
作用:将编译输出文件test.o链接成最终可执行文件test。
7. 选项-O
用法:#gcc -O1 test.c -o test
作用:使用编译优化级别1编译程序。级别为1~3,级别越大优化效果越好,但编译时间越长。
3、 多源文件的编译方法
如果有多个源文件,基本上有两种编译方法:
[假设有两个源文件为test.c和testfun.c]
1. 多个文件一起编译
用法:#gcc testfun.c test.c -o test
作用:将testfun.c和test.c分别编译后链接成test可执行文件。
2. 分别编译各个源文件,之后对编译后输出的目标文件链接。
用法:
#gcc -c testfun.c //将testfun.c编译成testfun.o
#gcc -c test.c //将test.c编译成test.o
#gcc -o testfun.o test.o -o test //将testfun.o和test.o链接成test
以上两种方法相比较,第一中方法编译时需要所有文件重新编译,而第二种方法可以只重新编译修改的文件,未修改的文件不用重新编译
4、gcc所遵循的部分约定规则
.c为后缀的文件,C语言源代码文件;
.a为后缀的文件,是由目标文件构成的档案库文件;
.C,.cc或.cxx 为后缀的文件,是C++源代码文件;
.h为后缀的文件,是程序所包含的头文件;
.i 为后缀的文件,是已经预处理过的C源代码文件;
.ii为后缀的文件,是已经预处理过的C++源代码文件;
.m为后缀的文件,是Objective-C源代码文件;
.o为后缀的文件,是编译后的目标文件;
.s为后缀的文件,是汇编语言源代码文件;
.S为后缀的文件,是经过预编译的汇编语言源代码文件。
5、gcc选项
1. 总体选项 (Overall Option)
-c(生成目标但不连接)
-S(汇编)
-E(预处理)
-o file(生成指定的文件)
-pipe -v(显示过程)
-x language (设定文件所使用的语言,使后缀名无效`c’, 可用参数`objective-c’, `c-header’, `c++’, `cpp-output’, `assembler’, and `assembler-with-cpp’)
2. 语言选项 (LANGUAGE OPTIONS)
-ansi 只支持 ANSI 标准的 C 语法.这一选项将禁止 GNU C 的某些特色
3. 预处理器选项 (Preprocessor Option)
-Aassertion
-C
-dD
-dM
-dN
-Dmacro[=defn]
-E
-H
-idirafter dir
-include file
-imacros file
-iprefix file
-iwithprefix dir
-M
-MD
-MM
-MMD
-nostdinc
-P
-Umacro 相当于C语言中的#undef macro
-undef
-DMACRO 以字符串“1”定义 MACRO 宏
-DMACRO=DEFN 以字符串“DEFN”定义 MACRO 宏
4. 汇编器选项 (ASSEMBLER OPTION)
-Wa,option
5. 连接器选项 (LINKER OPTION)
-llibrary
-nostartfiles
-nostdlib
-static
-shared
-symbolic
-Xlinker option
-Wl,option
-u symbol
6. 目录选项 (DIRECTORY OPTION)
-Bprefix
-Idir
-I-
-Ldir
7. 警告选项 (WARNING OPTION)
-w 不生成所有警告信息
-Wall 生成所有警告信息
8.调试选项 (DEBUGGING OPTION)
-a
-g
-p
-pg
9. 优化选项 (OPTIMIZATION OPTION)
-O0不进行优化处理,-O或-O1优化生成代码 -O2进一步优化 -O3比-O2更进一步优化,包括inline函数
10. 目标机选项 (TARGET OPTION)
-b machine
-V version
11. 机器相关选项 (MACHINE DEPENDENT OPTION)
-m486 针对 486 进行代码优化
12. 代码生成选项 (CODE GENERATION OPTION)
-fpic
-fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。如果不加-fPIC,则加载.so文件的代码段时,代码段引用的数据对象需要重定位, 重定位会修改代码段的内容,这就造成每个使用这个.so文件代码段的进程在内核里都会生成这个.so文件代码段的copy.每个copy都不一样,取决于这个.so文件代码段和数据段内存映射的位置.
使用makefile进行代码的模块化编程
(以下内容基于:http://www.cnblogs.com/wang_yb/p/3990952.html)
基本格式
target ... : prerequisites ...
command
...
...
说明
Target 目标文件, 可以是 Object File, 也可以是可执行文件
Prerequisites 生成 target 所需要的文件或者目标
Command make需要执行的命令(任意的shel命令),Makefile中的命令必须以[tab]开头,command太长,可以用 "\" 作为换行符。
例子
hello:main.c xx.c xxx.c
gcc –o hello main.c xx.c xxx.c
这是最基本的一个用法,第一行冒号之前的hello,叫做目标,是这条语句要处理的对象,也就是所要编译的程序hello。冒号后面的main.c xx.c xxx.c,这些叫做依赖关系表,也就是生成hello所需要的文件。这些文件只要有一个发生变化,或者说这些文件的文件日期比hello文件的文件日期新,就需要执行第二行的命令部分,也就是编译命令。使用方法就是将这两句写到一个名为Makefile或者makefile的文件(也可以自己命名,但这两个基本是通用可以的),然后在终端输入make,就可以按照我们的设定去编译程序了。注意第二行的gcc前面必须是一个tab缩进,否则make会报错。
1、通配符
* 表示任意一个或多个字符
? 表示任意一个字符
[...] 比如[abcd] 表示a,b,c,d中任意一个字符, [^abcd]表示除a,b,c,d以外的字符, [0-9]表示 0~9中任意一个数字
~ 表示用户的home目录
2、路径搜索
VPATH 使用方法:
vpath <directories> 当前目录中找不到文件时, 就从<directories>中搜索
vpath <pattern> <directories>符合<pattern>格式的文件, 就从<directories>中搜索
vpath <pattern> 清除符合<pattern>格式的文件搜索路径
vpath 清除所有已经设置好的文件路径
3、变量定义 ( = or := )
OBJS = programA.o programB.o
OBJS-ADD = $(OBJS) programC.o
# 或者
OBJS := programA.o programB.o
OBJS-ADD := $(OBJS) programC.o
其中 = 和 := 的区别在于, := 只能使用前面定义好的变量, = 可以使用后面定义的变量
用法:变量替换、变量追加值、变量覆盖、目标变量等,不在这里说明,参考网站就行。
4、Makefile命名前缀
Makefile 中书写shell命令时可以加2种前缀 @ 和 -, 或者不用前缀.
3种格式的shell命令区别如下:
不用前缀 :: 输出执行的命令以及命令执行的结果, 出错的话停止执行
前缀 @ :: 只输出命令执行的结果, 出错的话停止执行
前缀 - :: 命令执行有错的话, 忽略错误, 继续执行
5、伪目标
伪目标并不是一个"目标(target)", 不像真正的目标那样会生成一个目标文件.
典型的伪目标是 Makefile 中用来清理编译过程中中间文件的 clean 伪目标, 一般格式如下:
.PHONY: clean <-- 这句没有也行, 但是最好加上
clean:
-rm -f *.o
6、引用其他的 Makefile
语法: include <filename> (filename 可以包含通配符和路径)
(示例看网站)
7、查看C文件的依赖关系
写 Makefile 的时候, 需要确定每个目标的依赖关系.
GNU提供一个机制可以查看C代码文件依赖那些文件, 这样我们在写 Makefile 目标的时候就不用打开C源码来看其依赖那些文件了.
下面命令显示内核源码中 virt/kvm/kvm_main.c 中的依赖关系
$ cd virt/kvm/
$ gcc -MM kvm_main.c
kvm_main.o: kvm_main.c iodev.h coalesced_mmio.h async_pf.h <-- 这句就可以加到 Makefile 中作为编译 kvm_main.o 的依赖关系
8、make 退出码
Makefile的退出码有以下3种:
0 :: 表示成功执行
1 :: 表示make命令出现了错误
2 :: 使用了 "-q" 选项, 并且make使得一些目标不需要更新
9、指定 Makefile, 指定特定目标
默认执行 make 命令时, GNU make在当前目录下依次搜索下面3个文件 "GNUmakefile", "makefile", "Makefile",
找到对应文件之后, 就开始执行此文件中的第一个目标(target). 如果找不到这3个文件就报错.
非默认情况下, 可以在 make 命令中指定特定的 Makefile 和特定的 目标
$make -f MyMake <-- 指定特定的Makefile
$ make -f MyMake target2 <-- 指定特定的目标(target)
10、make 参数介绍
make 的参数有很多, 可以通过 make -h 去查看,以下是比较有用的。
参数 |
含义 |
--debug[=<options>] |
输出make的调试信息, options 可以是 a, b, v |
-j --jobs |
同时运行的命令的个数, 也就是多线程执行 Makefile |
-r --no-builtin-rules |
禁止使用任何隐含规则 |
-R --no-builtin-variabes |
禁止使用任何作用于变量上的隐含规则 |
-B --always-make |
假设所有目标都有更新, 即强制重编译 |
11、Makefile 隐含规则
这里只列一个和编译C相关的.
编译C时,<n>.o 的目标会自动推导为 <n>.c
# Makefile 中
main : main.o
gcc -o main main.o
#会自动变为:
main : main.o
gcc -o main main.o
main.o: main.c <-- main.o 这个目标是隐含生成的
gcc -c main.c
12、隐含规则中的 命令变量 和 命令参数变量
12.1命令变量, 书写Makefile可以直接写 shell时用这些变量.
下面只列出一些C相关的
变量名 |
含义 |
RM |
rm -f |
AR |
ar |
CC |
cc |
CXX |
g++ |
示例:
# Makefile 内容
all:
@echo $(RM)
@echo $(AR)
@echo $(CC)
@echo $(CXX)
# bash 中执行make, 显示各个变量的值
$ make
rm -f
ar
cc
g++
12.2命令参数变量
变量名 |
含义 |
ARFLAGS |
AR命令的参数 |
CFLAGS |
C语言编译器的参数 |
CXXFLAGS |
C++语言编译器的参数 |
13、自动变量
Makefile 中很多时候通过自动变量来简化书写, 各个自动变量的含义如下:
自动变量 |
含义 |
目标集合 |
|
$% |
当目标是函数库文件时, 表示其中的目标文件名 |
$< |
第一个依赖目标. 如果依赖目标是多个, 逐个表示依赖目标 |
$? |
比目标新的依赖目标的集合 |
$^ |
所有依赖目标的集合, 会去除重复的依赖目标 |
$+ |
所有依赖目标的集合, 不会去除重复的依赖目标 |
$* |
这个是GNU make特有的, 其它的make不一定支持 |
14、函数
foreach函数
用法:$(foreach<var>,<list>,<text>)
功能:
把参数中的单词逐一取出放到参数<var>所指定的变量中,然后再执行<text>
所包含的表达式。每一次<text>会返回一个字符串,循环过程中,<text>的所返回的每个字符串会以空格分隔,最后当整个循环结束时, <text>所返回的每个字符串所组成的整个字符串(以空格分隔)将会是 foreach函数的返回值。
所以, <var>最好是一个变量名, <list>可以是一个表达式,而<text>中一般会使用<var>这个参数来依次枚举<list>中的单词。举个例子:
names := a b c d
files := $(foreach n,$(names),$(n).o)
上面的例子中, $(name)中的单词会被挨个取出, 并存到变量“n”中, “$(n).o”每次根据“$(n)”计算出一个值,这些值以空格分隔,最后作为 foreach 函数的返回,所以, $(files)的值是“a.o b.o c.o d.o”。
注意, foreach 中的<var>参数是一个临时的局部变量, foreach 函数执行完后, 参数<var>的变量将不在作用,其作用域只在 foreach 函数当中。
addprefix函数
该函数叫做 加前缀函数。
用法:$(addprefix <prefix>,<names...>)
功能:把前缀<prefix>加到<names>中的每个单词后面。
返回:返回加过前缀的文件名序列。
示例:
$(addprefix src/,foo bar)
返回值是“ src/foo src/bar”。
常用于加路径,加-I选项(指定第一个寻找头文件的目录)。
wildcard函数 : 扩展通配符
notdir函数 : 去除路径
patsubst函数 :替换通配符
高级用法还没学,未完待续…
学会制作动态库、静态库
(以上制作静态库、动态库内容参考http://blog.****.net/llzk_/article/details/55519242,但是该网站内容有几处错误,已在下面修正)
库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。
Linux下库分为两种,静态库和动态库。
这两种库相同点是两种库都是由.o文件生成的
1、静态库
静态库文件名的命名方式是“libxxx.a”,库名前加”lib”,后缀用”.a”,“xxx”为静态库名。
链接时间: 静态库的代码是在编译过程中被载入程序中。
链接方式:静态库的链接是将整个函数库的所有数据都整合进了目标代码。这样做优点是在编译后的执行程序不在需要外部的函数库支持,因为所使用的函数都已经被编进去了。缺点是,如果所使用的静态库发生更新改变,你的程序必须重新编译。
2、动态库
动态库的命名方式与静态库类似,前缀相同,为“lib”,后缀变为“.so”。所以为“libxxx.so”
链接时间:动态库在编译的时候并没有被编译进目标代码,而是当你的程序执行到相关函数时才调用该函数库里的相应函数。这样做缺点是因为函数库并没有整合进程序,所以程序的运行环境必须提供相应的库。优点是动态库的改变并不影响你的程序,所以动态函数库升级比较方便。
静态库和动态库还有很明显的不同点:当同一个程序分别使用静态库,动态库两种方式生成两个可执行文件时,静态链接所生成的文件所占用的内存要远远大于动态链接所生成的文件。(因为静态链接是在编译时将所有的函数都编译进了程序。而动态链接是在运行是才调用库里相应函数)
3、静态库的实现
准备三个文件 time.c time.h test.c
因为静态库还是动态库都是由.o文件生成的,所以将time.c编译成time.o
输入命令:gcc -c time.c
接下来是由.o文件生成静态库文件:
设静态库名称为mytime,所以静态库的文件名就为libmytime.a
输入命令:ar cr libmytime.a time.o
接下来是静态库的使用:
输入命令进行静态链接,生成可执行程序:
gcc -o test test.c -static -lmytime -L. (注意-L后面有个小点)
-static :表示程序的静态链接
-lmytime:链接静态库mytime
-L. :链接时需指明静态库所存在的路径,‘.’表示当前路径
接下来执行test
输入命令:./test
将当前目录下的静态库文件libmytime.a删除,再次运行test。
我们会发现程序依然运行成功。这是因为静态库链接是在程序编译时就将所有代码整合到了程序中,编译后的可执行程序不再需要外部的函数库支持。
4、动态库的实现
同样以上面三个文件来测试
先将time.c编译成time.o
输入命令:gcc -c time.c
然后由.o文件生成动态库
输入命令:gcc -shared -fPIC -o libmytime.so time.c
动态库的使用:
输入命令进行动态编译,生成可执行文件
gcc -o test test.c -lmytime –L.
接下来执行test
输入命令:./test
发现会报错,错误信息说没有找到动态库libmytime.so,因为进行动态库链接时,程序并不会在当前目录中寻找动态库,而是在/usr/lib目录下寻找,所以将动态库libmytime.so移动到/usr/lib下就可以了但是需要在root权限下,也有在没权限的情况下的解决方式,这里不详解。
输入命令:mv libmytime.so /usr/lib
然后执行程序,输入 ./test
程序运行成功。
比较一下两个可执行程序文件大小,可以发现静态链接生成的可执行文件要比动态链接生成的大得多。