文件目录
- /bin:
bin是Binary的缩写, 这个目录存放着最经常使用的命令。 - /boot:
这里存放的是启动Linux时使用的一些核心文件,包括一些连接文件以及镜像文件。 - /dev :
dev是Device(设备)的缩写, 该目录下存放的是Linux的外部设备,在Linux中访问设备的方式和访问文件的方式是相同的。 - /etc:
这个目录用来存放所有的系统管理所需要的配置文件和子目录。 - /home:
用户的主目录,在Linux中,每个用户都有一个自己的目录,一般该目录名是以用户的账号命名的。 - /lib:
这个目录里存放着系统最基本的动态连接共享库,其作用类似于Windows里的DLL文件。几乎所有的应用程序都需要用到这些共享库。 - /lost+found:
这个目录一般情况下是空的,当系统非法关机后,这里就存放了一些文件。 - /media:
linux系统会自动识别一些设备,例如U盘、光驱等等,当识别后,linux会把识别的设备挂载到这个目录下。 - /mnt:
系统提供该目录是为了让用户临时挂载别的文件系统的,我们可以将光驱挂载在/mnt/上,然后进入该目录就可以查看光驱里的内容了。 - /opt:
这是给主机额外安装软件所摆放的目录。比如你安装一个ORACLE数据库则就可以放到这个目录下。默认是空的。 - /proc:
这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这个目录来获取系统信息。
Linux文件类型
- 普通文件(-)
- 目录(d)
- 软链接(字符链接L)
- 套接字文件(S)
- 字符设备(S)
- 块设备(B)
- 管道文件(命名管道P)
通过ls -l
的第一个字符可以判断。
常见命令
- ls的参数有哪些以及作用
- -l
列举目录内容的细节,包括权限,所有者,组群,大小,创建日期,文件是否是链接等。 - -a
显示全部文件,包括隐藏文件。
- -l
- vim回到第一行
gg
- 快速到命令的最左边和最右边
Ctrl+a
Ctrl+e
- 查看头10行和末10行
head -n 10 文件路径
tail -n 10 文件路径
- 查找线程
ps -ef | grep "名字"
- rpm包怎么安装?怎么卸载?
rpm -ivh
rpm -e
- 如何查看文件的第3行到第9行?
sed -n '3,9p' 文件名
- netstat相关
- -a (all)
显示所有选项,默认不显示LISTEN相关。 - -t (tcp)
仅显示tcp相关选项。 - -u (udp)
仅显示udp相关选项。 - -n
拒绝显示别名,能显示数字的全部转化成数字。 - -l
仅列出有在 Listen (监听) 的服务状态。
- -a (all)
找出程序运行的端口:netstat -anp | grep "ssh"
;
找出运行在指定端口上的进程号:netstat -anp | grep ":3306"
;
- 如何往文件写东西?
追加命令:echo "hello" >> hello.txt
覆盖命令:echo "hello" > hello.txt
- awk打印内容
awk '{print}' hello.txt
软链接和硬链接的作用与区别
作用
- 软链接:
ln -s 源文件 目标文件
可以理解成快捷方式。它和windows下的快捷方式的作用是一样的。 - 硬链接:ln 源文件 目标文件
等于cp -p加同步更新。
区别
软链接 | 硬链接 | |
---|---|---|
incode | 拥有不同的incode,说明是两个不同的文件 | 拥有相同的incode,是同一个文件 |
跨越文件系统建立 | 支持 | 不支持 |
存在形式 | 以路径的形式存在 | 以副本的形式存在,但不占用实际空间 |
是否能对不存在的文件链接 | 可以 | 不可以 |
是否能对目录进行链接 | 可以 | 不可以 |
特殊进程
idle(PID=0)
由系统自动创建,运行在内核态 ,它是唯一一个没有通过fork或者kernel_thread产生的进程。
kthreadd(PID=2,PPID=0)
由idle通过kernel_thread创建,并始终运行在内核空间,负责所有内核线程的调度和管理。
init(PID=1,PPID=0)
由idle通过kernel_thread创建,在内核空间完成初始化后,加载init程序,并最终用户空间创建。init进程由0进程创建,完成系统的初始化,是系统中所有其它用户进程的祖先进程。
加载过程为:0号进程->1号内核进程->1号用户进程(init进程)->getty进程->shell进程。
另外,init进程还会负责收集孤儿进程。
free命令中buffer与cache的区别
- total:物理内存实际总量;
- used:这块千万注意,这里可不是实际已经使用了的内存哦,这里是总计分配给缓存(包含buffers 与cache )使用的数量,但其中可能部分缓存并未实际使用;
- free:未被分配的内存,实际可使用的内存;
- shared:共享内存;
- buffers:系统分配的,但未被使用的buffer剩余量。注意这不是总量,而是未分配的量;
- cached:系统分配的,但未被使用的cache 剩余量。buffer 与cache 的区别见后面;
- available:应用程序认为可用内存数量,
available = free + buffer + cache
。(注:只是大概的计算方法)
Cache和Buffer
- Cache
高速缓存,主要用于查询,CPU的速度远高于内存速度,可以减少CPU的等待时间,提高效率。
在free命令中是作为page cache的内存, 文件系统的cache。 - Buffer
缓冲区,主要用于写请求,当两个设备存储速度不同或者优先级不同,它可以使进程之间的相互等待变少,使速度快的操作不发生间断。
在free命令中是作为buffer cache的内存,是块设备的读写缓冲区。
Page Cache和Buffer Cache
- page cache
文件系统层级的缓存,从磁盘里读取的内容是存储到这里,这样程序读取磁盘内容就会非常快,比如使用grep和find等命令查找内容和文件时,第一次会慢很多,再次执行就快好多倍,几乎是瞬间。但如上所说,如果对文件的更新不关心,就没必要清cache,否则如果要实施同步,必须要把内存空间中的cache clean下。 - buffer cache
磁盘等块设备的缓冲,内存的这一部分是要写入到磁盘里的。这种情况需要注意,位于内存buffer中的数据不是即时写入磁盘,而是系统空闲或者buffer达到一定大小统一写到磁盘中,所以断电易失,为了防止数据丢失所以我们最好正常关机或者多执行几次sync命令,让位于buffer上的数据立刻写到磁盘里。
信号
linux下有很多信号,按可靠性分为可靠信号和非可靠信号,按时间分为实时信号和非实时信号,linux进程也有三种方式来处理收到的信号:
- 忽略信号,即对信号不做任何处理,其中,有两个信号不能忽略:SIGKILL及SIGSTOP;
- 捕捉信号。定义信号处理函数,当信号发生时,执行相应的处理函数;
- 执行缺省操作,Linux对每种信号都规定了默认操作。
常见的五个信号
- SIGINT 终止进程,通常我们的Ctrl+C就发送的这个消息。
- SIGQUIT 和SIGINT类似, 但由QUIT字符(通常是Ctrl- \ )来控制. 进程收到该消息退出时会产生core文件。
- SIGKILL 消息编号为9,我们经常用kill -9来杀死进程发送的就是这个消息,程序收到这个消息立即终止,这个消息不能被捕获,封锁或这忽略,所以是杀死进程的终极武器。
- SIGTERM 是不带参数时kill默认发送的信号,默认是杀死进程。
SIGINT与SIGTERM区别
前者与字符ctrl+c关联,后者没有任何控制字符关联。
前者只能结束前台进程,后者则不是。
SIGTERM与SIGKILL的区别
前者可以被阻塞、处理和忽略,但是后者不可以。
KILL命令的默认不带参数发送的信号就是SIGTERM,让程序有好的退出。
SIGTERM比较友好,进程能捕捉这个信号,根据您的需要来关闭程序。在某些情况下,假如进程正在进行作业而且不能中断,那么进程可以忽略这个SIGTERM信号。
因为SIGTERM可以被阻塞,所以有的进程不能被结束时,需要用kill发送SIGKILL。即:kill-9 进程号。
Linux创建进程的过程
在Linux中主要提供了fork、vfork、clone三个进程创建方法。
在linux源码中这三个调用的执行过程是执行fork(),vfork(),clone()时,通过一个系统调用表映射到sys_fork(),sys_vfork(),sys_clone(),再在这三个函数中去调用do_fork()去做具体的创建进程工作。
fork
vfork
vfork系统调用不同于fork,用vfork创建的子进程与父进程共享地址空间,也就是说子进程完全运行在父进程的地址空间上,如果这时子进程修改了某个变量,这将影响到父进程。
但此处有一点要注意的是用vfork()创建的子进程必须显示调用exit()来结束,否则子进程将不能结束,而fork()则不存在这个情况。Vfork也是在父进程中返回子进程的进程号,在子进程中返回0。
用 vfork创建子进程后,父进程会被阻塞直到子进程调用exec(exec,将一个新的可执行文件载入到地址空间并执行之。)或exit。vfork的好处是在子进程被创建后往往仅仅是为了调用exec执行另一个程序,因为它就不会对父进程的地址空间有任何引用,所以对地址空间的复制是多余的 ,因此通过vfork共享内存可以减少不必要的开销。由于fork有了写时复制,vfork就不怎么用了。
clone
系统调用fork()和vfork()是无参数的,而clone()则带有参数。fork()是全部复制,vfork()是共享内存,而clone() 是则可以将父进程资源有选择地复制给子进程,而没有复制的数据结构则通过指针的复制让子进程共享,具体要复制哪些资源给子进程,由参数列表中的 clone_flags来决定。另外,clone()返回的是子进程的pid。
三者区别
- fork出来的子进程是父进程的一个拷贝,即,子进程从父进程得到了数据段和堆栈段的拷贝,这些需要分配新的内存,而对于只读的代码段,通常使用共享内存的方式访问;而vfork则是子进程与父进程共享内存空间, 子进程对虚拟地址空间任何数据的修改同样为父进程所见;clone则由用户通过参clone_flags的设置来决定哪些资源共享,哪些资源拷贝。
- fork不对父子进程的执行次序进行任何限制,fork返回后,子进程和父进程都从调用fork函数的下一条语句开始行,但父子进程运行顺序是不定的,它取决于内核的调度算法;而在vfork调用中,子进程先运行,父进程挂起,直到子进程调用了exec或exit之后,父子进程的执行次序才不再有限制;clone中由标志CLONE_VFORK来决定子进程在执行时父进程是阻塞还是运行,若没有设置该标志,则父子进程同时运行,设置了该标志,则父进程挂起,直到子进程结束为止。
Linux执行二进制文件的过程
在安装软件的时候,通常使用./xxx运行二进制文件即可,其实背后是依赖了自带的c语言的编译-汇编-链接过程