Linux01

1.Linux下的重定向机制

重定向符号
**>**输出重定向到一个文件或设备,覆盖原来的文件。
**>!**输出重定向到一个文件或设备,强制覆盖原来的文件。
**>>**输出重定向到一个文件或设备,追加原来的文件。
**<**输入重定向到一个程序。

标准错误重定向:
2>
2>>
2>&1

如:
ls -al > list.txt 将ls的结果输出到list.txt中,若该文件已存在则予以取代。
ls -al >> list.txt 将ls的结果累加到list.txt中,该文件旧数据保留。
ls -al 1 > list.txt 2 > list.err 将数据正确的输出到list.txt,错误的输出到list.err。
ls -al 1>list.txt 2>&1 将数据不论正确还是错误均输入到list.txt中。
ls -al 1>list.txt 2>/dev/null 正确的输出到list.txt,错误的予以丢弃。

管道:
|可以用于连接命令,用简单命令的组合来完成很多复杂的任务。下一个命令的输入是上一个命令的输出。

2.chmod

ls -l查看Linux下文件的详细信息:
10个占位符,分成四个部分。
1.文件类型,如-代表普通文件,d代表文件夹,还有c,p,b等。
2.剩下的9个占位符,每三个为一组,分别对应了当前用户,当前用户所在同组用户组,所有其它用户的权限。
3.r,w,x分别对应可读,可写,可执行,可以使用chmod来修改文件权限。

3.Linux脚本运行解释机制

#! /usr/bin/python
代表着解释器的绝对路径。
对于拥有井号,感叹号这样的脚本文件,当它直接运行时,Linux会根据解释器的路径,启动该解释器,并将这个脚本文件作为参数,传递给那个解释器。

4.Linux下文件操作及文件属性

1.int creat(const char *filename,mode_t mode),filename:要创建的文件名(包括路径,默认当前路径),mode:创建模式(S_IRUSR可读,1,S_IWUSR可写,2,S_IXUSR可执行,4,S_IRWXR可读、写、执行,7)
(也可以用数字代替,如0777,0表示没有任何权限)
返回值:文件描述符,值为一个整数,发生错误时返回-1
2.int open(const char *pathname,int flags),打开一个文件,flags是打开文件的模式,如只读,只写等等,返回值是文件描述符。
3.int close(int fd)关闭文件。
4.int read(int fd,const void *buf,size_t length),fd读取的文件的文件描述符,buf是读取之后要存放的缓冲区,length是读取的长度。
5.int write(int fd,const void *buf,size_t length),fd要写入的文件的文件描述符,buf是要写的内容的存放区,length是要写入的长度。
6.int lseek(int fd,offset_t offset,int whence),offset是偏移的位移量,whence是代表开始偏移的位置,SEEK_SET相对文件开头,SEEK_CUR相对读写指针当前位置,SEEK_END相对文件末尾。

int stat(const char *file_name, struct stat *buf);第二个参数是一个结构体,结构体中包含了Linux所管理的文件属性。
如:
ID
inode
文件的权限属性
硬链接数目
所属用户ID和组ID以及文件相关时间。
st_mode(是一个重要的参数,包括文件类型和其他信息)

opendir和readdir
DIR * opendir(const char *name)
struct dirent * readdir(DIR * dirp)

opendir用于打开目录,返回一个指针DIR*的指针,代表目录中元素的集合。
然后将这个返回的指针传给readdir,readdir找到元素,并且封装成struct dirent,并将地址返回。

struct dirent{
ino_t d_ino;//inode编号。
char d_name[256];//文件名。
}

fcntl
用于读取或者设置一个已经打开的fd的属性。
在这里插入图片描述

dup
int newfd = dup(fd);newfd和fd指向同一个文件,共享同一个数据结构,共享所有锁定。
dup2可以同时指定想要的newfd的值,比如可以将标准输出重定向到文件。dup2()与dup()的区别在于可以用newfd来指定新描述符数值,若newfd指向的文件已经被打开,会先将其关闭。若newfd等于oldfd,就不关闭newfd,newfd和oldfd共同指向一份文件。

int main(void)
{
    int fd;
    int new_fd;

    fd = open("./test.file", O_RDWR | O_CREAT | O_TRUNC, 0666);
    printf("fd = %d\n", fd);

    dup2(fd, 1);
    printf("hello world!!\n");

    return 0;
}

将标准输出重定向到了文件描述符,所以在运行文件后,本来是标准输出,应该输出到屏幕上的hello world,但是却被输入到了文件里面,打开文件可以看见hello world内容。

调用dup(oldfd)等效于fcntl(oldfd,F_DUPFD,0);
调用dup2(oldfd, newfd)等效于,close(oldfd);fcntl(oldfd, F_DUPFD, newfd);

5.Linux下的软硬链接

ln命令可以创建链接文件。

ln yc yclink
创建了一个yclink的硬链接,且与yc中的内容是一样并且同步的。但是删除其中一个,另外一个不会被删除。
为什么呢,因为硬链接背后的技术就是基于引用计数,具有相同的inode,每增加一个硬链接,inode链接数加一,当inode链接数为0时,才会删除文件。

硬链接不方便之处:
1.不能对目录文件建立硬链接。
2.不能跨文件系统区创建硬链接。

所以发明软链接:
ln -s yc ycsoftlink
软链接拥有新的inode,相当于一个快捷方式。

6.Linux下动静态库

ar r libmymath.a myadd.o myminus.o
根据myadd.o myminus.o创建一个名为libmymath.a的静态库,然后可以直接用libmymath.a来替代myadd.o myminus.o与其他的模块进行链接。
Linux下以gcc -l 的方式来指定链接库,如gcc -lmymath.a main.o -o main.exe,链接器就会在系统路径下寻找名为mymath.a 并尝试链接。

在编译情况下,makefile写法:

all: main.exe

main.exe: main.o libmymath.a
	gcc ‐g main.o libmymath.a ‐o main.exe

libmymath.a: myadd.o myminus.o
	ar r libmymath.a myadd.o myminus.o

myminus.o:
	gcc ‐g ‐c myminus.c ‐o myminus.o

main.o:
	gcc ‐g ‐c main.c ‐o main.o

myadd.o:
	gcc ‐g ‐c myadd.c ‐o myadd.o

clean:
	rm ‐rf *.o *.exe

静态库的缺点:
1.因为代码静态链接,如果不同的程序中使用了同一个静态库,则代码冗余,浪费空间。
2.当某一个obj或者.a文件被修改后,需要重新链接才能得到新的exe,才有新功能。

于是发明了动态库,.so文件。
gcc ‐g ‐c ‐fpic myadd.c ‐o myadd2.o
gcc ‐g ‐c ‐fpic myminus.c ‐o myminus2.o
gcc ‐g ‐shared myadd2.o myminus2.o ‐o libmymath.so

-fpic的意义是:生成位置无关代码
-shared 生成.so文件。

动态库的使用:静态使用:
gcc ‐g main.o ‐o main_so.exe libmymath.so

如果直接运行main_so.exe报找不到libmymath.so错误,有两个解决方法:
1.将libmymath.so拷贝到系统库目录下:sudo cp libmymath.so /usr/lib
2.通过设置LD_LIBRARY_PATH来增加so的搜索路径:LD_LIBRARY_PATH=./ ./main_so.exe。

动态使用:
使用Linux下提供好的API接口:

void *dlopen(const char *filename, int flag); //将so加载到内存中,
返回值表示内存中so的首地址
void *dlsym(void *handle, const char *symbol); //根据上一步的so首
地址,以及函数名字,找函数指针

插件模式:
区分主模块与插件,并提前约定好接口。主模块按照约定遍历各个插件模块(.so文件),并按照约定调用其中的接口。

7.fork和execve

1.fork(),调用fork()产生子进程。
2.wait(),用于父进程等待子进程。
3.execve(),用于子进程脱胎换骨为新进程。
4.exit(),退出进程。

fork被调用一次,有两个返回值。
如果返回值大于0,则是父进程返回,返回的是子进程的pid。
如果返回值等于0,则是子进程返回。
如果返回值小于0,fork出现错误。

wait()用于父进程等待子进程结束,如果子进程没有结束,则wait会阻塞,如果不wait,父进程早于子进程退出,则子进程会变成孤儿进程,init进程会接管,作为它的父进程。

execve:
int execve(const char *filename, char *const argv[ ], char *const envp[ ]);
函数执行成功时没有返回值,执行失败时的返回值为-1。
参数filename字符串所代表的文件路径,第二个参数是利用数组指针来传递给执行文件,并且需要以空指针(NULL)结束,最后一个参数则为传递给执行文件的新环境变量数组。

#include<unistd.h>   
main()   
{   
  char *argv[ ]={"ls", "-al", "/etc/passwd", NULL};   
  char *envp[ ]={"PATH=/bin", NULL}   
  execve("/bin/ls", argv, envp);   
}  

exec系列的系统调用是把当前程序替换成要执行的程序,而fork用来产生一个和当前进程一样的进程(虽然通常执行不同的代码流)。通常运行另一个程序,而同时保留原程序运行的方法是,fork+exec。

8.Linux管道

1.管道是单向,先进先出的,把一个进程的输出和另一个进程的输入连在一起。
2.在管道的尾部写入数据,另一个进程在管道的头部读出数据。
3.数据被一个进程读出后,将被从管道中删除,其他进程不能读这些数据。
4.提供简单的流控制机制,进程读空管道时,将阻塞,管道已满时,写入数据,将阻塞。
5.无名管道和有名管道,前者用于父进程和子进程之间的通信,后者则可以用于同一系统中任意两个进程之间的通信。

对于当前进程不需要的pipefd,应该及时关闭:
1.逻辑上,管道的通信是单向的。即一方写入数据,另一方读取数据。
2.管道具有阻塞的属性,当一个管道中没有内容,而某个进程去read它时,会阻塞,只有当管道的所有写入方的pipefd全部close后,读取管道,才会返回。

无名管道:
int pipe(int filedis[2]);
建立时,会创建两个文件描述符。
filedis[0],用于读管道。
filedis[1],用于写管道。

通常先创建一个管道,再通过fork()函数创建一个子进程,该子进程会继承父进程所创建的管道。
必须在系统调用fork()之前调用pipe(),否则子进程将不会继承文件描述符。

管道容量使用ulimit -a命令查看,由内核设置。

有名管道:
int mkfifo(const * pathname,mode_tmode),pathname是fifo的路径加文件名,mode是建立的方式和所赋予的权限。

原理:在内核空间中,分配一块专门的内存,用于进程间的通信,数据写入管道时,将数据从应用层拷贝到内核层。读取数据时,从内核层被拷贝到应用层。

9.Linux下的coredump文件

当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中,这种行为就叫做Core Dump(中文有的翻译成“核心转储”)。我们可以认为 core dump 是“内存快照”,但实际上,除了内存信息之外,还有些关键的程序运行状态也会同时 dump 下来,例如寄存器信息(包括程序指针、栈指针等)、内存管理信息、其他处理器和操作系统状态和信息。core dump 对于编程人员诊断和调试程序是非常有帮助的,因为对于有些程序错误是很难重现的,例如指针异常,而 core dump 文件可以再现程序出错时的情景。

coredump默认是关闭的
用ulimit -c检查是否打开生成coredump文件,如果输出显示为0,则没有打开。
使用ulimit -c unlimited命令使当前用户下的程序生成coredump文件。

gdb调试core文件。
coredump文件生成的路径就在程序路径下,且名称一般就为core。
用gdb program core ,program为程序名。

10.exit与atexit

#include <stdlib.h>
void exit( int status );
void _Exit( int status );
#include <unistd.h>
void _exit( int status );

_exit和_Exit立即进入内核,而exit要先做一些清理工作(调用执行个终止处理程序,关闭所有标准I/O流),再进入内核。三个函数所带的整形参数称为终止状态或退出状态,如果(a)调用这些函数不带参数,(b)main函数中的return 语句无返回值,(c)main函数没有声明返回类型为整形,则进程的终止状态是未定义的。main函数返回一个整形值与用该值调用exit是等价的。
exit()函数用于在程序运行的过程中随时结束程序,exit的参数state是返回给操作系统,返回0表示程序正常结束,非0表示程序非正常结束。

int atexit (void (*)(void)))登记函数。

1.在程序正常退出前,被注册的函数都会被调用。
2.回调函数被调用的顺序,与注册的顺序保持逆序。

11.Linux信号机制

kill,向指定的pid进程发送信号,默认的信号是SIGKILL。

int kill(int pid,int sig);

1.如果pid大于0,则将信号发送给特定的进程。
2.如果pid是-1,结束掉所有有权限结束的进程。
3.如果是除-1以外的负数,结束-pid同进程组的所有进程。
4.如果是0,则不发信号,只检查是否可以发送成功,检查对应的pid是否存在。

12.Linux下多线程编程

进程与线程:
1.进程的创建和销毁需要的资源较多。
2.进程之间相互独立,进程间通信的手段,相对复杂。
3.一个进程可以拥有多个线程。
4.一个线程只能属于一个进程。
5.同属于一个进程的线程,共享进程的各项资源(内存空间,文件描述符)。
6.与函数调用有关的栈帧空间,不共享,会随着线程的切换而切换。

与线程有关的函数构成了一个完整的系列,绝大多数函数的名字都是以pthread_d打头的,要使用这些函数库,要通过引入头文件pthread.h,链接这些线程函数库时要使用编译器命令的-lpthread选项。

线程有关函数:
创建线程:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);

thread:返回线程ID//这里用的是pthread_self获得tid号
attr:设置线程的属性,attr为NULL表示使用默认属性
start_routine:函数地址,线程启动后要执行的函数
arg:传给线程启动函数的参数
成功返回0,失败返回错误码

线程等待函数:

int pthread_join(pthread_t thread, void **value_ptr);

thread:线程ID
value_ptr:指向一个指针,后者指向线程的返回值
成功返回0,失败返回错误码

获取自己线程ID的函数:

pthread_t pthread_self(void);

pthread_t的类型是unsigned long int,所以在打印的时候要是用%lu方式,否则显示结果出问题。

线程终止函数:

void pthread_exit(void * status);

线程的退出:
1.进程退出或者main主线程退出。
2.线程函数达到返回。
3.线程自己调用了pthread_exit函数。
4.被其他线程使用pthread_cancel取消执行。

会话和进程组:
一个进程组中有很多进程
一个会话中有很多进程组
创建新的会话,setsid。

13.daemon程序(守护进程)

一般作为Linux下的服务端程序
1.没有输入,输出。
2.长期运行。
3.不会因为终端结束而结束。

技术上的实现:
1.setsid
2.利用重定向,将标准输入,标准输出重定向到/dev/null。

建立daemon程序:
1.程序运行后调用fork,并让父进程退出。
子进程获得一个新的进程ID,但继承了父进程的进程组ID。

2.调用setsid创建一个新的session,是自己成为新session和新进程组的leader,并使进程没有控制终端(tty)

3.改变当前工作目录至根目录,以免影响可加载文件系统,或者也可以加载到某些特定目录。

4.设置文件创建mask为0,避免创建文件时权限的影响。

5.关闭不需要的文件描述符如,close(0),close(1),close(2)。

14.线程同步

锁:
互斥锁:
pthread_mutex_t mtx;
初始化:pthread_mutex_init(&mtx,NULL);使用NULL会将互斥锁的属性设置为默认属性。
除了使用pthread_mutex_init初始化之外,还可以使用pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
阻塞调用:
pthread_mutex_lock(&mtx);
解锁:pthread_mutex_unlock(&mtx);

读写锁:
读写锁是"写模式加锁"时, 解锁前,所有对该锁加锁的线程都会被阻塞。
读写锁是"读模式加锁"时, 如果线程以读模式对其加锁会成功;如果线程以写模式加锁会阻塞。
读写锁是"读模式加锁"时, 既有试图以写模式加锁的线程,也有试图以读模式加锁的线程。那么读写锁会阻塞随后的读模式锁请求。优先满足写模式锁。读锁、写锁并行阻塞,写锁优先级高
读写锁也叫共享-独占锁。当读写锁以读模式锁住时,它是以共享模式锁住的;当它以写模式锁住时,它是以独占模式锁住的。写独占、读共享。

读写锁非常适合于对数据结构读的次数远大于写的情况。

1.pthread_rwlock_t类型 用于定义一个读写锁变量。
2.初始化一把读写锁

int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);

参2:attr表读写锁属性,通常使用默认属性,传NULL即可。

3.销毁一把读写锁 int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
4.pthread_rwlock_rdlock函数

以读方式请求读写锁。(常简称为:请求读锁)

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
5.pthread_rwlock_wrlock函数

以写方式请求读写锁。(常简称为:请求写锁)

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
6.pthread_rwlock_unlock函数

解锁

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

条件变量
初始化:pthread_cond cond = PTHREAD_COND_INITIALIZER;
或:pthread_cond cond;pthread_cond_init(&cond,NULL);

销毁:pthread_cond_destroy(&cond);

条件变量的使用需要和互斥锁相互配合。
pthread_mutex_lock(&mtx);
pthread_cond_wait(&pcond,&mtx);
pthread_mutex_unlock(&mtx);

在其他地方:
pthread_cond_signal(&pcond);

一个Condition Variable总是和一个Mutex搭配使用的。一个线程可以调用
pthread_cond_wait在一个Condition Variable上阻塞等待,这个函数做以下三步操作:

  1. 释放Mutex
  2. 阻塞等待
  3. 当被唤醒时,重新获得Mutex并返回

好莱坞原则:不要打电话给我们,我们会通知你。就和公司面试一样,面试完你就可以回去等通知了,有结果我自然会联系你,哈哈。

pthread_cond_wait之后的代码暂时不执行,当接受到来自pthread_cond_signal的信号时继续执行,如果有多个线程都处于
pthread_cond_wait状态,pthread_cond_signal只会唤醒其中的一个线程,唤醒顺序规则:线程优先级高的先被唤醒,优先级相同的,等待时间长的先被唤醒。

信号量

sem_t *sem_open(const char *name, int oflag);如:
sem_t* psem = sem_open("/nr1101sem", O_CREAT, 0777, 1);

sem_open打开或者创建信号量
sem_wait 锁住信号量
sem_post 释放信号量

信号量大于0时,可以访问,否则将阻塞。
pv语句是对信号量的操作,当调用一次p操作(即sem_wait函数),信号量减一,当调用一次v操作(即sem_post函数),信号量加一。

用信号量处理同步时,定义两个信号量,一个为1,一个为0,当1的信号量运行结束后,减为0,对另一个信号量作加操作,加为1,另一个信号量即可运行,然后同样运行完减为0,然后对上一个信号量作加操作,加为1,然后运行上一个信号量函数,如此保持同步。

15.Linux下的进程间通信

1.管道和有名管道。
2.消息队列
1.msgget:创建和访问一个消息队列 。

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflag);

参数:
key:某个消息队列的名字,用ftok()产生
msgflag:有两个选项IPC_CREAT和IPC_EXCL,单独使用IPC_CREAT,如果消息队列不存在则创建之,如果存在则打开返回;单独使用IPC_EXCL是没有意义的;两个同时使用,如果消息队列不存在则创建之,如果存在则出错返回。
返回值:成功返回一个非负整数,即消息队列的标识码,失败返回-1。

#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);

调用成功返回一个key值,用于创建消息队列,如果失败,返回-1。

2.msgctl:消息队列的控制函数 。

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgctl(int msqid, int cmd, struct msqid_ds *buf);

参数:
msqid:由msgget函数返回的消息队列标识码
cmd:有三个可选的值

IPC_STAT 把msqid_ds结构中的数据设置为消息队列的当前关联值
IPC_SET 在进程有足够权限的前提下,把消息队列的当前关联值设置为msqid_ds数据结构中给出的值
IPC_RMID 删除消息队列

返回值: 成功返回0,失败返回-1

3.msgsnd:把一条消息添加到消息队列中

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

参数:
msgid:由msgget函数返回的消息队列标识码
msgp:指针指向准备发送的消息
msgze:msgp指向的消息的长度(不包括消息类型的long int长整型)
msgflg:默认为0
返回值:成功返回0,失败返回-1

4.msgrcv

功能:是从一个消息队列接受消息
原型:
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
参数:与msgsnd相同
返回值:成功返回实际放到接收缓冲区里去的字符个数,失败返回-1

3.共享内存
实现进程间通信最简单也是最直接的方法就是共享内存——为参与通信的多个进程在内存中开辟一个共享区。由于进程可以直接对共享内存进行读写操作,因此这种通信方式效率特别高,但其弱点是,它没有互斥机制,需要信号量之类的手段来配合。

共享内存原理:内存映射
void * mmap(void *start, size_t len, int prot, int flags, int fd, off_t offset);
Linux将物理内存,映射到进程的虚拟内存中,操作内存就是操作文件,因此效率很高。

参数:
start是加载的内存地址
len是想要加载的内存大小
prot是内存属性
flags,属性,MAP_SHARED或者MAP_PRIVATE,MAP_SHARED实现进程间通信,MAP_PRIVATE,使用写时拷贝技术,映射文件到内存。
fd,被加载的文件描述符。
offset,文件开始映射的偏移。

当不同的进程,利用mmap映射同一个fd,那么操作系统层面,就会将不同进程的虚拟内存,映射到同一个段物理内存,实现进程间通信。

1.创建共享内存
第一个参数为 key 值,一般由 ftok() 函数产生

  • 第二个参数为欲创建的共享内存段大小(单位为字节)
  • 第三个参数用来标识共享内存段的创建标识

int shmget(key_t key, size_t size, int shmflg);

2.共享内存控制
第一个参数为要操作的共享内存标识符

  • 第二个参数为要执行的操作
  • 第三个参数为 shmid_ds 结构的临时共享内存变量信息

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

3.映射共享内存对象
第一个参数为要操作的共享内存标识符

  • 第二个参数用来指定共享内存的映射地址,非0则为此参数,为0的话由系统分配
  • 第三个参数用来指定共享内存段的访问权限和映射条件

void *shmat(int shmid, const void *shmaddr, int shmflg);

4.分离共享内存对象
参数为分配的共享内存首地址

int shmdt(const void *shmaddr);

4.信号量
和之前Linux保持线程同步的用法相似,只不过是在不同的进程间使用。

16.Linux常用命令

关机(root)
      >Poweroff 直接断电
      >init 0 先关闭所有服务,再断电
      >shutdown -h now 先向所有登录的用户发消息,然后关闭服务,最后断电。
      >shutdown -h 数字 //单位是分钟
      >[root@localhost ~]# shutdown –c //取消正在运行的关机或重启
      >halt 停止系统运行, 相当于shutdown –h now
重启(root)
      >reboot
      >shutdown -r now 或 10 立刻重启,10分钟后重启
      >init 6

查看当前工作目录 Pwd
查看目录内容 ls
切换目录 cd
查看内存、swap使用情况
      free –m //默认是以KB为单位
      cat /proc/meminfo
查看CPU
      top 查看系统状态,按数字1,展开cpu
      cat /proc/cpuinfo
查看IP
      ifconfig
查看主机名
      hostname
查看磁盘的使用情况、查看磁盘的挂载情况
df -h //-h:以人类可读的方式显示
创建目录
  mkdir [-选项] [参数]
    -p 级联创建,在父目录不存在的情况下,先创建父目录,再创建子目录。
      例:mkdir -p dou1/dou11/dou111/
拷贝(备份)目录、重命名目录
  语法:cp -r 源1 源2… 目的
  拷贝:如果目标目录已存在,那么就会将拷贝的目录作为其子目录
    cp -r /home/test /tmp
  重命名:目标不存在,就相当于拷贝并重命名目录
    cp –r /home/test /tmp/tom
  拷贝时可以有多个源文件或源目录,但是目标就只能是目录
    cp -r /home/test /home/test1 /root
文件的查看 cat more less head tail tac
  cat 适用场合:一般查看短小的文件
  -n :显示每行的行号
  more 可以实现空格键分页查看,默认不能往回翻
  less 可以实现分页查看,能上下翻,支持“/关键字 ”搜索
  head 查看文件的开头部分,默认前10行, -5 显示前5行
  tail 显示文件的尾部,默认后10行,tail -5 显示后5行
  -f 动态查看内容 !$上一次命令参数
  tac 倒序输出文件的每一行
创建文件
  vim 不存在的文件名
  touch 创建空白文件
    如果目标文件不存在,那么就创建新的空文件
    如果目标文件存在,那么就更新文件的时间戳

netstat 查看连接端口
ping 查看网络连接
route 添加和设置路由
kill 发送信号
ps 显示进程
uptime 显示已运行时间

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值