cp: 拷贝文件

格式1:cp file1 file2

第一种格式中:

  • file2不存在,则创建file2;
  • file2存在且是文件,则覆盖file2;
  • file2存在且是目录,则按格式二处理

示例

file2不存在

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@localhost 文件管理和目录管理]# ls
p1.c
[root@localhost 文件管理和目录管理]# cat p1.c
#include <stdio.h>

void main(){
printf("%s\n","HelloWolrd!");
}
[root@localhost 文件管理和目录管理]# cp p1.c p2.c
[root@localhost 文件管理和目录管理]# ls
p1.c p2.c
[root@localhost 文件管理和目录管理]# cat p2.c
#include <stdio.h>

void main(){
printf("%s\n","HelloWolrd!");
}
[root@localhost 文件管理和目录管理]#

file2存在

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@localhost 文件管理和目录管理]# ls
p1.c p2.c
[root@localhost 文件管理和目录管理]# echo line 1 in p2.c >p2.c
[root@localhost 文件管理和目录管理]# cat p2.c
line 1 in p2.c
[root@localhost 文件管理和目录管理]# cat p1.c
#include <stdio.h>

void main(){
printf("%s\n","HelloWolrd!");
}
[root@localhost 文件管理和目录管理]# cp p1.c p2.c
cp:是否覆盖"p2.c"? y
[root@localhost 文件管理和目录管理]# cat p2.c
#include <stdio.h>

void main(){
printf("%s\n","HelloWolrd!");
}
[root@localhost 文件管理和目录管理]#

格式2:cp file1 file2 … filen dir

其中file1,…,filen为文件名,dir为已有目录名

第二种格式中:dir必须已经存在并且是一个目录

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cp a.c a.bak
cp a.c b.c backup.d

[root@localhost 文件管理和目录管理]# ls
p1.c p2.c
[root@localhost 文件管理和目录管理]# cp p*.c backup.d
cp: 目标"backup.d" 不是目录
[root@localhost 文件管理和目录管理]# mkdir backup.d
[root@localhost 文件管理和目录管理]# cp p*.c backup.d
[root@localhost 文件管理和目录管理]# ls *
p1.c p2.c

backup.d:
p1.c p2.c
[root@localhost 文件管理和目录管理]#

带文件通配符星号*的情况

例:
cp *.c backup.d

  • 与Windows命令COPY *.C BAK.D执行结果相同,过程不同
  • UNIX中实际执行cp a1.c a2.c b1.c b2.c backup.d

从备份目录拷贝回当前目录

当前目录和备份目录结构

1
2
3
4
5
6
[root@localhost 文件管理和目录管理]# ls *
p1.c p2.c

backup.d:
p1.c p2.c
[root@localhost 文件管理和目录管理]#

备份目录下的文件的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@localhost 文件管理和目录管理]# cat backup.d/p1.c
#include <stdio.h>

void main(){
printf("%s\n","HelloWolrd!");
}
[root@localhost 文件管理和目录管理]# cat backup.d/p2.c
#include <stdio.h>

void main(){
printf("%s\n","HelloWolrd!");
}
[root@localhost 文件管理和目录管理]#

当前目录下的文件内容

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@localhost 文件管理和目录管理]# cat p1.c 
#include <stdio.h>

void main(){
printf("%s\n","HelloWolrd!");
}
[root@localhost 文件管理和目录管理]# cat p2.c
#include <stdio.h>

void main(){
printf("%s\n","HelloWolrd!");
}
[root@localhost 文件管理和目录管理]#

修改当前目录下的p2.c文件的内容

1
2
3
4
[root@localhost 文件管理和目录管理]# echo this is line 1 in p2.c >p2.c 
[root@localhost 文件管理和目录管理]# cat p2.c
this is line 1 in p2.c
[root@localhost 文件管理和目录管理]#

使用备份目录下的文件覆盖当前目录下的同名文件

错误做法
1
cp backup.d/p*.c

使用通配符*的时候需要注意,命令执行的是经过shell替换之后的命令,也就是实际执行的是

1
cp backup.d/p1.c backup.d/p2.c

结果:backup.d目录下文件p1.c将覆盖掉p2.c
运行过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@localhost 文件管理和目录管理]# ls *
p1.c p2.c

backup.d:
p1.c p2.c
[root@localhost 文件管理和目录管理]# cat p2.c
this is line 1 in p2.c
[root@localhost 文件管理和目录管理]# cat backup.d/p2.c
#include <stdio.h>

void main(){
printf("%s\n","HelloWolrd!");
}
[root@localhost 文件管理和目录管理]# cp backup.d/p*.c
cp:是否覆盖"backup.d/p2.c"? n
[root@localhost 文件管理和目录管理]#
正确做法

将这两个文件拷贝回当前目录下的正确用法:

1
cp backup.d/p*.c  .

运行过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@localhost 文件管理和目录管理]# ls *
p1.c p2.c

backup.d:
p1.c p2.c
[root@localhost 文件管理和目录管理]# cat p2.c
this is line 1 in p2.c
[root@localhost 文件管理和目录管理]# cat backup.d/p2.c
#include <stdio.h>

void main(){
printf("%s\n","HelloWolrd!");
}
[root@localhost 文件管理和目录管理]# cp backup.d/p*.c .
cp:是否覆盖"./p1.c"? y
cp:是否覆盖"./p2.c"? y
[root@localhost 文件管理和目录管理]# cat p2.c
#include <stdio.h>

void main(){
printf("%s\n","HelloWolrd!");
}
[root@localhost 文件管理和目录管理]#

mv: 移动文件

格式

1
2
3
mv file1 file2
mv file1 file2 ... filen dir
mv dir1 dir2

功能

重命名文件或目录

使用mv命令可以将文件和目录改名

重命名文件

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost 文件管理和目录管理]# ls *
p1.c p2.c

backup.d:
p1.c p2.c
[root@localhost 文件管理和目录管理]# mv p1.c HelloWorld.c
[root@localhost 文件管理和目录管理]# ls *
HelloWorld.c p2.c

backup.d:
p1.c p2.c
[root@localhost 文件管理和目录管理]#

重命名目录

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost 文件管理和目录管理]# ls *
HelloWorld.c p2.c

backup.d:
p1.c p2.c
[root@localhost 文件管理和目录管理]# mv backup.d/ 备份
[root@localhost 文件管理和目录管理]# ls *
HelloWorld.c p2.c

备份:
p1.c p2.c
[root@localhost 文件管理和目录管理]#

将一个目录下的文件和子目录移动到另一个目录下

一个目录的结构

1
2
3
4
5
6
7
8
[root@localhost Linux_Test]# ls
a.txt b.txt cat cmp c.txt date d.txt less ls more ps sed sort tr uniq vi wc 文件管理和目录管理 文件名和文件通配符 正则表达式
[root@localhost Linux_Test]# ls 文件管理和目录管理/*
文件管理和目录管理/HelloWorld2.c 文件管理和目录管理/HelloWorld.c

文件管理和目录管理/备份:
p1.c p2.c
[root@localhost Linux_Test]#

创建一个新目录

1
2
3
4
5
[root@localhost Linux_Test]# mkdir 文件管理和目录管理2
[root@localhost Linux_Test]# ls
a.txt cat c.txt d.txt ls ps sort uniq wc 文件管理和目录管理2 正则表达式
b.txt cmp date less more sed tr vi 文件管理和目录管理 文件名和文件通配符
[root@localhost Linux_Test]#

移动一个目录下的所有文件以及子目录 到 另一个目录

1
2
3
4
5
6
7
8
[root@localhost Linux_Test]# mv 文件管理和目录管理/* 文件管理和目录管理2
[root@localhost Linux_Test]# ls 文件管理和目录管理/
[root@localhost Linux_Test]# ls 文件管理和目录管理2/*
文件管理和目录管理2/HelloWorld2.c 文件管理和目录管理2/HelloWorld.c

文件管理和目录管理2/备份:
p1.c p2.c
[root@localhost Linux_Test]#

移动一个目录到另一个目录之中

当前目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@localhost Linux_Test]# ls
a.txt cat c.txt d.txt ls ps sort uniq wc 文件管理和目录管理2 正则表达式
b.txt cmp date less more sed tr vi 文件管理和目录管理 文件名和文件通配符
[root@localhost Linux_Test]# tree -N 文件管理和目录管理
文件管理和目录管理

0 directories, 0 files
[root@localhost Linux_Test]# tree -N 文件管理和目录管理2/
文件管理和目录管理2/
├── HelloWorld2.c
├── HelloWorld.c
└── 备份
├── p1.c
└── p2.c

1 directory, 4 files
[root@localhost Linux_Test]#

移动一个目录到另一个目录之中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost Linux_Test]# mv 文件管理和目录管理2/ 文件管理和目录管理/
[root@localhost Linux_Test]# ls
a.txt b.txt cat cmp c.txt date d.txt less ls more ps sed sort tr uniq vi wc 文件管理和目录管理 文件名和文件通配符 正则表达式
[root@localhost Linux_Test]# tree -N 文件管理和目录管理/
文件管理和目录管理/
└── 文件管理和目录管理2
├── HelloWorld2.c
├── HelloWorld.c
└── 备份
├── p1.c
└── p2.c

2 directories, 4 files
[root@localhost Linux_Test]#

mv dir1 dir2 两种执行情况(同文件系统,不同文件系统)

rm: 删除文件

命令格式

1
rm file1 file2 ... filen

1
2
rm core a.out
rm *.o *.tmp

错误写法:

1
rm * .bak

会删除当前目录下的所有的文件,最后尝试删除.bak文件,如果有.bak这个文件的话,已经包含在通配符*里面了,也就是被删掉了,此时再想删除.bak,系统会报错,说.bak文件不存在。

选项

选项 功能
-r 递归地(Recursive)删除实参表中的目录,也就是删除一整棵目录树
-i 每删除一个文件前需要操作员确认(Inform)
-f 强迫删除(Force)。只读文件也被删除并且无提示

其它问题

在运行的可执行程序文件不能被删除

显式区分命令选项和处理对象

问题

设当前目录下只有a,b,c三个文件
执行

1
rm -i

只提供选项,未指定任何文件,命令格式错
执行

1
ls>-i

生成文件-i(符合文件的命名规则)
执行

1
rm -i

不能删除文件-i
执行:

1
rm *

shell会替换成:

1
rm -i a b c

这里的-i会解释成选项,而不是文件,rm会按选项-i的方式处理,而不会删除文件-i。
执行:

1
cat *

shell会替换成:

1
cat -i a b c

执行:

1
ls *

shell会替换成:

1
ls -i a b c

解决方法

许多Linux命令(如cp,ls,mv,rm,cat,grep,set等)用--显式地标志命令行选项的结束,识别以-开头的处理对象。如:
执行:

1
rm -- -i

即可删除文件-i
例如,我们想在文件ht.c中查找-1这个字符串,你可能输入如下命令:

1
grep -1 ht.c

这种情况下,grep可能认为-1,是个选项。
此时你可以使用--区分选项和参数:

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost 文件管理和目录管理]# cat ht.c 
56
35
-1
-4
-5
8
[root@localhost 文件管理和目录管理]# grep -1 ht.c
^C
[root@localhost 文件管理和目录管理]# grep -- -1 ht.c
-1
[root@localhost 文件管理和目录管理]#

图片

如果你想在文件中查找--help这个字符串,你输入如下命令:

1
grep --help *.c

grep会吧–help解释为选项。而达不到效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@localhost 文件管理和目录管理]# cat ht.c 
56
-1
-4
8
--help
--hello
--world
[root@localhost 文件管理和目录管理]# grep --help *.c
用法: grep [选项]... PATTERN [FILE]...
在每个 FILE 或是标准输入中查找 PATTERN。
默认的 PATTERN 是一个基本正则表达式(缩写为 BRE)。
......
如果有任意行被匹配,那退出状态为 0,否则为 1;
如果有错误产生,且未指定 -q 参数,那退出状态为 2。

请将错误报告给: bug-grep@gnu.org
GNU Grep 主页: <http://www.gnu.org/software/grep/>
GNU 软件的通用帮助: <http://www.gnu.org/gethelp/>
[root@localhost 文件管理和目录管理]#

此时输入

1
grep -- --help *.c

可以达到效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@localhost 文件管理和目录管理]# ls
ht.c 文件管理和目录管理2
[root@localhost 文件管理和目录管理]# cat ht.c
56
-1
-4
8
--help
--hello
--world
[root@localhost 文件管理和目录管理]# grep -- --help *.c
--help
[root@localhost 文件管理和目录管理]#

ls:文件名列表

基本功能

在同一命令行中可以指定0~n个实参

  • 不给出实参时,列出当前目录下所有文件和目录
  • 实参为文件时,列出文件项
  • 实参为目录时,列出目录下的所有文件项

ls命令有几十个选项

  • 控制列表格式,有选择的为每个项目列出某些属性

选项-F (Flag)

  • 若列出的是目录,就在名字后面缀以斜线/
  • 若列出的是可执行文件,就在名字后面缀以星号*
  • 若列出的是符号连接文件,就在名字后面缀以符号@
  • 若列出的是普通文件,则名字面后无任何标记

现在的终端可以根据颜色还区分文件与目录,在一些很简单的没有颜色的嵌入式终端中ls -F比较有用。

ls选项-l: 长格式列表

例:ls -l arg
-rwxr-x–x l liang stud 519 Jul 5 15:02 arg

第1列:文件属性

第1字符为文件类型

第1个字符 文件类型
- 普通文件
b 块设备文件(Block)
d 目录文件(Dir)
c 字符设备文件(Char)
l 符号连接文件(Link)
p 命名管道文件(Pipe)

文件的访问权限

(r读权限,w写权限,x可执行权限)

ls -l第1列 描述
2-4字符: 文件所有者对文件的访问权限
5-7字符: 同组用户对文件的访问权限
8-10字符: 其它用户对文件的访问权限

第2列:文件link数

涉及到此文件的目录项数

第3列,第4列:

文件主的名字和组名

第5列

类型 描述
普通磁盘文件: 列出文件大小(字节数)
目录: 列出目录表大小,不是目录下文件长度和
符号连接文件: 列出符号连接文件自身的长度
字符设备和块设备文件: 列出主设备号和次设备号
管道文件: 列出管道内的数据长度

第6列:

文件最后一次被修改的日期和时间

第7列:文件名

对于符号连接文件,附带列出符号连接文件的内容

选项-h

(human-readable),许多其他命令中也有类似选项
以便于人阅读的方式打印数值 (例如:1K 234M 2G)

选项-d

(directory)当ls的参数是目录时,不象默认的情况那样列出目录下的文件,而是列出目录自身的信息

1
2
3
4
5
[root@localhost Linux_Test]# ls -d
.
[root@localhost Linux_Test]# ls -ld
drwxr-xr-x. 18 root root 4096 5月 31 21:06 .
[root@localhost Linux_Test]#

ls与ls *的区别

1
2
3
4
5
6
7
8
[root@localhost vi]# ls
encode helloworld.c helloworld.out out.txt test.txt
[root@localhost vi]# ls *
helloworld.c helloworld.out out.txt test.txt

encode:
helloworld.c mini.txt
[root@localhost vi]#

ls -l /etc与ls -ld /etc的区别

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost vi]# ls -l /etc
总用量 1332
-rw-r--r--. 1 root root 12 11月 17 2020 adjtime
-rw-r--r--. 1 root root 1529 4月 1 2020 aliases
drwxr-xr-x. 2 root root 4096 4月 20 17:53 alternatives
......
drwxr-xr-x. 6 root root 4096 3月 16 03:03 yum
-rw-r--r--. 1 root root 970 10月 2 2020 yum.conf
drwxr-xr-x. 2 root root 4096 4月 23 15:07 yum.repos.d
[root@localhost vi]# ls -ld /etc
drwxr-xr-x. 73 root root 4096 5月 31 21:04 /etc
[root@localhost vi]#

选项-a

(all)
列出文件名首字符为圆点的文件(默认情况下这些文件不列出,经常会用来保存用户的偏好设置信息或保存某些软件的状态信息)。

选项-A

(功能与-a相同,除了不列出. 和..)
例如:

ls
ls -a
ls –ad

1
2
3
4
5
6
7
[root@localhost vi]# ls 
encode helloworld.c helloworld.out out.txt test.txt
[root@localhost vi]# ls -a
. .. encode helloworld.c .helloworld.c.swp helloworld.out out.txt test.txt
[root@localhost vi]# ls -A
encode helloworld.c .helloworld.c.swp helloworld.out out.txt test.txt
[root@localhost vi]#

选项-s

(size)列出文件占用的磁盘空间

1
2
3
4
5
6
7
[root@localhost vi]# ls -s
总用量 32
4 encode 4 helloworld.c 16 helloworld.out 4 out.txt 4 test.txt
[root@localhost vi]# ls -sh
总用量 32K
4.0K encode 4.0K helloworld.c 16K helloworld.out 4.0K out.txt 4.0K test.txt
[root@localhost vi]#

选项-i

(i-node)列出文件的i节点号

1
2
3
[root@localhost vi]# ls -i
532546 encode 524412 helloworld.c 524416 helloworld.out 524430 out.txt 524431 test.txt
[root@localhost vi]#

shell与kernel

shell

  • shell是一个用户态进程,如/bin/bash
  • 对用户提供命令行界面
  • 启动其他应用程序(ap)使用操作系统核心提供的功能:包括系统命令和用户编写的程序

kernel:操作系统核心

  • 管理系统资源(包括内存,磁盘等)运行在核心态
  • 通过软中断方式对用户态进程提供系统调用接口

程序获取命令行参数的方式

从main函数的两个参数,可获得命令行参数的内容
演示程序arg.c

arg.c
1
2
3
4
5
6
7
#include <stdio.h>
void main(int argc, char *argv[])
{
int i;
for (i = 0; i < argc; i++)
printf("%d:[%s]\n", i, argv[i]);
}

编译,链接:

1
gcc arg.c -o arg

运行

1
./arg abc ABCDEF

运行结果:

1
2
3
4
5
[root@localhost 文件名和文件通配符]# ./arg abc ABCDEF
0:[./arg]
1:[abc]
2:[ABCDEF]
[root@localhost 文件名和文件通配符]#

shell文件名通配符处理

文件名通配符的处理由shell完成,分以下三步

  • 在shell提示符下,从键盘输入命令,被shell接受
  • shell对所键入内容作若干加工处理,其中含有对文件通配符的展开工作(文件名生成),生成结果命令
  • 执行前面生成的结果命令

文件名通配符举例(1)

设当前目录下只有try.czap.carc.c三文件

  • 键入内容cat *.c
    • 实际执行cat arc.c try.c zap.c (按字典序)
    • 对命令cat来说,指定了3个文件

设当前目录下有a1.ca2.c

  • grep a*.c try.cgrep 'a*.c' try.c的区别
    • 前者实际执行grep a1.c a2.c try.c
      • a2.ctry.c中查找正则表达式a1.c
    • 后者在try.c文件中查找正则表达式a*.c

文件名通配符举例(2)

键入命令时的简化输入
手工键入vi m*e
实际执行vi makefile
手工键入cd *sna*
实际执行cd configure-IBM-sna-network.d

验证文件通配符处理方式

执行

1
./arg *
1
./arg  /usr/include/*
1
./arg  */*  /usr/*

Linux下的运行结果

./arg *运行结果:

1
2
3
4
5
[root@localhost 文件名和文件通配符]# ./arg *
0:[./arg]
1:[arg]
2:[arg.c]
[root@localhost 文件名和文件通配符]#

./arg /usr/include/*运行结果:

1
2
3
4
5
6
7
8
9
10
[root@localhost 文件名和文件通配符]# ./arg  /usr/include/*
0:[./arg]
1:[/usr/include/aio.h]
2:[/usr/include/aliases.h]
......
14:[/usr/include/c++]
15:[/usr/include/com_err.h]
16:[/usr/include/complex.h]
17:[/usr/include/cpio.h]
......

./arg */* /usr/*运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@localhost 文件名和文件通配符]# ./arg */* /usr/*
0:[./arg]
1:[*/*]
2:[/usr/bin]
3:[/usr/etc]
4:[/usr/games]
5:[/usr/include]
6:[/usr/lib]
7:[/usr/lib64]
8:[/usr/libexec]
9:[/usr/local]
10:[/usr/sbin]
11:[/usr/share]
12:[/usr/src]
13:[/usr/tmp]
[root@localhost 文件名和文件通配符]#

Windows下运行结果

arg.exe *运行结果:

1
2
3
4
5
G:\Desktop\test\Linux\Debug>arg.exe *
0:[arg.exe]
1:[*]

G:\Desktop\test\Linux\Debug>

arg.exe /usr/include/*运行结果:

1
2
3
4
5
G:\Desktop\test\Linux\Debug>arg.exe /usr/include/*
0:[arg.exe]
1:[/usr/include/*]

G:\Desktop\test\Linux\Debug>

arg.exe */* /usr/*运行结果:

1
2
3
4
5
6
G:\Desktop\test\Linux\Debug>arg.exe */* /usr/*
0:[arg.exe]
1:[*/*]
2:[/usr/*]

G:\Desktop\test\Linux\Debug>

执行结果与同样arg.c在Windows下运行的比较

  • UNIX由shell完成对文件通配符的展开
  • Windows由命令自身来解释文件通配符

星号 *

  • 匹配任意长度的文件名字符串(包括空字符串)
  • 点字符(.),当它作为文件名或路径名分量的第一个字符时,必须显式匹配
  • 斜线(/)也必须显式匹配
  • 例:*file匹配filemakefile,不匹配.profile文件;try*c 匹配try1.ctry.ctry.basic

问号 ?

匹配任一单字符

方括号 [ ]

匹配括号内任一字符,也可以用减号指定一个范围

例: [A-Z]**.[ch][Mm]akefile

波浪线 ~

(Bash特有的)
~ 当前用户的主目录(home)
~kuan 用户kuan的主目录(home)
~root 用户root的主目录(home)

点文件.与点点文件..

当前目录与上级目录
.文件解释为当前目录,不是通配符处理程序完成的,来源于目录的存储结构

注意

  • 文件名通配符规则与正则表达式的规则不同,应用场合不同
  • 不同种类shell通配符规则会略有些差别
  • Windows中*.*匹配所有文件,Linux中*.*要求文件名中必须含有圆点否则不匹配,如:*.*makefile不匹配
  • 可以使用类似*/*.[ch]通配符, */*/*.conf
  • 文件通配符适用所有命令

文件和目录的命名规则

名字长度

  • 一般允许1-255字符
  • 有些UNIX不支持长文件名,但至少长度为1-14

取名的合法字符

  • 除斜线外的所有字符都是命名的合法字符
  • 不可打印字符也可以做文件名(除了字节0)
  • 斜线(/)留做路径名分割符

大小写字母有区别

  • Makefile与makefile是两个不同的文件
  • 尽量不要依靠字母的大小写区分不同文件名,文件名带来的说明性差,不便于Windows/Linux之间的迁移

系统配置信息

/etc目录

  • 供系统维护管理用的命令和配置文件
    • 文件格式为文本文件
    • 功能类似Windows的注册表信息

/etc目录包括如下内容

  • `passwd,hosts文件
  • *.conf文件
  • ssh,xinet.d,apt,network….等目录
  • 系统启动阶段系统初始化和启动各服务的脚本rc*.d
  • profile/bash.bashrc系统级bash等shell的偏好设置
  • 自定义的需要自启动的服务脚本rc.local

临时目录

/tmp

临时文件,每个用户都可以在这里临时创建文件,但只能删除自己的文件,不可以删除其他用户创建的文件

/var

系统运行时要改变的数据
系统日志syslog等

可运行程序和设备文件

(类似Windows的Program Files目录和Windows\system32)

/bin

系统常用命令,如ls,ln,cp,cat等

/usr/bin

存放一些常用命令,如ssh,ftp,make,gcc,git等

/sbin,/usr/sbin

系统管理员专用命令

/dev

设备文件,如终端设备,磁带机,打印机等

头文件和库文件

/usr/include (usr=Unix System Resource)

C语言头文件存放目录

/lib,/usr/lib

  • 存放各种库文件,指C语言的链接库文件,以及terminfo终端库等等
  • 静态链接库文件有.a后缀(archive,存档)
  • 动态链接库文件后缀是.so (shared objects:共享的目标代码,多个.o文件的集成)
  • Linux广泛使用动态链接库,静态链接库逐渐过时

使用动态链接库的好处

动态链接

动态链接与静态链接

命令ldd

1
2
3
4
5
[root@localhost vi]# ldd ./helloworld.out 
linux-vdso.so.1 => (0x0000007f85b2f000)
libc.so.6 => /lib64/libc.so.6 (0x0000007f859a2000)
/lib/ld-linux-aarch64.so.1 (0x000000557443e000)
[root@localhost vi]#
1
2
gcc hello.c –o hello          #hello大小(7.2KB)
gcc –static hello.c –o hello #hello大小(712KB)

应用程序可编程控制的动态链接库的加载、卸载和调用

屏幕显示乱码问题

现象

1
cat /bin/bash

1
head -n 1 /bin/bash

导致屏幕乱码,键盘输入也只能看到画表用的框框符

原因

/bin/bash文件不是文本文件,这些二进制内容逐字节送到终端,凑巧一个序列被终端理解为一个转义序列,执行动作:修改了终端字符集

字符集

ASCII字符集(7比特128种符号)
选择其他字符集,相同码值代表了那个字符集之中的某个符号

解决方法

断开连接,重新登录
注意不要把非文本信息在终端输出

文本文件格式问题

现象

Linux下的文本文件在Windows用notepad打开,所有内容粘在一行内

原因

Linux和Windows的文本文件的存储格式不同

解决方法

在Linux完成格式转换后再用Windows处理(首选此方案)
用Windows中可容忍Linux文本文件格式的其他编辑器

文本文件格式

Windows和Linux文本文件行的行尾不同

  • Linux:行尾处仅存换行字符
  • Windows:行尾处存回车和换行两个字符

例:文件mini.txt,第一行为ab,第二行为xyz
Windows中,文件的大小为9字节

61 62 0d 0a 78 79 7a 0d 0a

在Linux中,文件的大小为7字节

61 62 0a 78 79 7a 0a

示例

Windows文本文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
lan@DESKTOP-8ISAT6B MINGW64 /g/Desktop/test/Linux
$ ls
helloworld.c mini_windows.txt

lan@DESKTOP-8ISAT6B MINGW64 /g/Desktop/test/Linux
$ file mini_windows.txt
mini_windows.txt: ASCII text, with CRLF line terminators

lan@DESKTOP-8ISAT6B MINGW64 /g/Desktop/test/Linux
$ cat mini_windows.txt
ab
xyz
lan@DESKTOP-8ISAT6B MINGW64 /g/Desktop/test/Linux
$ od -t x1 mini_windows.txt
0000000 61 62 0d 0a 78 79 7a
0000007

lan@DESKTOP-8ISAT6B MINGW64 /g/Desktop/test/Linux
$

linux文本文件

1
2
3
4
5
6
7
8
9
[root@localhost encode]# file mini.txt 
mini.txt: ASCII text
[root@localhost encode]# cat mini.txt
ab
xyz
[root@localhost encode]# od -t x1 mini.txt
0000000 61 62 0a 78 79 7a 0a
0000007
[root@localhost encode]#

相关命令

(两种格式间转换)
dos2unix/unix2dos, todos/fromdos
(查看文件的数据类型,供参考)

dos2unix和fromdos命令

https://www.linuxidc.com/Linux/2014-01/95144.htm
两个命令的用法相同,不同的是两个命令使用的环境不一样.
dos2unix在CentOS系列的系统中使用,fromdos则在Ubuntu系列的系统中使用。
用法:

1
2
dos2unix filename
fromdos filename

意思是:转换文件格式,将windos系统的文件转换成linux系统可以使用的文件格式,否则文件在linux系统中可能会出现错误,如:文件中显示^m 这样的错误字符。
导致这样的错误出现的原因是,windos环境中的换行符是\r\n,而linux系统中的换行符直接\n就行了。

file

如果没有file命令则需要先安装file命令:

1
2
3
4
5
6
7
8
9
10
[root@localhost vi]# file helloworld.c 
-bash: file: 未找到命令
[root@localhost vi]# yum list file
已加载插件:fastestmirror
Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast
Determining fastest mirrors
* epel: mirrors.ustc.edu.cn
可安装的软件包
file.aarch64 5.11-37.el7 base
[root@localhost vi]# yum install file

示例

1
2
3
[root@localhost vi]# file helloworld.c 
helloworld.c: C source, ASCII text
[root@localhost vi]#
1
2
3
lan@DESKTOP-8ISAT6B MINGW64 /e/Blog/blog/source/_posts/编程/Linux/通用/vi编辑器及乱码问题 (master)
$ file 'Linux 显示乱码问题.md'
Linux 显示乱码问题.md: UTF-8 Unicode text

Windows文本文件和Linux文本文件相互转换

Windows系统中用记事本创建的helloworld.c文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
lan@DESKTOP-8ISAT6B MINGW64 /g/Desktop/test/Linux
$ cat helloworld.c
#include <stdio.h>

int main()
{
printf("%s\n","Hello");
printf("%s\n","World");
printf("%s\n","Welcome to Linux");
}
lan@DESKTOP-8ISAT6B MINGW64 /g/Desktop/test/Linux
$ file helloworld.c
helloworld.c: C source, ASCII text, with CRLF line terminators

可以看到helloworld.c文件使用的是CRLF,也就是回车换行符\r\n

Linux中打开Windows文本文件

将该文件上传到CentOS中,再次执行file命令:

1
2
3
[root@localhost encode]# file helloworld.c 
helloworld.c: C source, ASCII text, with CRLF line terminators
[root@localhost encode]#

使用vi打开该文件:
图片

Linux中吧Windows文本文件转换成Linux文本文件

1
2
3
4
5
[root@localhost encode]# dos2unix helloworld.c 
dos2unix: converting file helloworld.c to Unix format ...
[root@localhost encode]# file helloworld.c
helloworld.c: C source, ASCII text
[root@localhost encode]#

然后在使用vi打开该文件:
图片

中文编码问题

问题

从Windows迁来的文件,只有在显示中文字符时是乱码。Linux本生的中文信息正常显示。

原因

中文GBK与UTF8不兼容

英文字符集

7比特ASCII码,字节高位为0的,后面7位是英文ASCII码

中文字符编码GBK

Windows默认中文编码方案,两个字节表示一个汉字,字节的高位为1,以区别于ASCII码

中文字符编码UTF8

许多Linux默认中文编码方案,三个字节表示一个汉字,字节的高位为1,以区别于ASCII码

检查系统设置

与语言有关的环境变量LANG应为en_US.UTF-8

1
env | grep LANG

若有问题,设置方法为:

1
export LANG=en_US.UTF-8

命令iconv:中文字符编码的转换

from GBK to UTF8

1
iconv –f gbk –t utf8

from UTF8 to GBK

1
iconv –f utf8 –t gbk

示例

1
2
3
4
$ echo "汉字" | od -t x1
0000000 e6 b1 89 e5 ad 97 0a
$ echo "汉字" | iconv -f utf-8 -t gbk | od -t x1
0000000 ba ba d7 d6 0a

终端配置:配色和中文编码

问题

终端不是默认的黑底白字,ls,grep,vi等输出信息无配色
中文显示的是乱码

调整终端仿真软件的配置

根据所用的终端仿真软件的不同,调整终端类型和字符编码,具体方法与所用软件有关

死机问题

所谓“死机”问题

现象

vi编辑结束后执行存盘操作,结果导致屏幕卡死,输入任何信息都不再有显示(死机,终端死机)

原因

vi编辑结束后按下Ctrl-S,因为Windows编辑器一般设置Ctrl-S热键的动作为Save,但Linux却进入流量控制状态

解决方法

按下Ctrl-Q键后流量控制解除

意外中止问题

现象

vi编辑结束后存盘,程序意外中止,编辑成果丢失,文件内容未发生变化

原因

vi存盘命令Shift-ZZ,误操作为Ctrl-ZZ,而Ctrl-Z按键导致当前运行进程被挂起(suspend),暂停运行(但进程尚在,处于Stopped状态)

解决方法

调用bash的作业管理机制,恢复运行被Stopped的进程
列表当前被Stopped的进程有哪些

1
jobs

将1号作业恢复到前台(foreground)运行

1
fg %1

或者:

1
%1

退格键(Backspace)无法使用的问题

现象

bash命令输入时,Backspace键可用,但是,运行自己写的程序时Backspace键无法正常使用

原因

当前终端的“行律”设置不正确

解决方法

Backspace按键对应的ASCII码是控制字符Ctrl-H
执行stty erase ^H设定行律模块把Ctrl-H为删除符,以后Ctrl-H和Backspace都可以做删除。如果需要,把命令放到$HOME/.bash_profile中(类似的,stty erase ^A可以设置用Ctrl-A做删除操作)
stty -a可以了解终端行律的状态

Linux 查找、编辑及存盘

删除命令

删除字符

删除当前字符的命令 x

图片

命令5x 删除从当前光标开始的5个字符

图片

删除行

删除当前行的命令 dd

图片

删除从当前行开始的3行命令 3dd

图片

字符替换

替换光标处字符 r

将当前光标处字符替换为a:ra命令

图片

连续替换多个字符

将当前光标处开始的三个字符依次替换为abc,则需要按命令rarbrc

亲测这种方式不可行,只会替换当前字符,如果想连续替换着需要按下shift键和r键,切换到REPLACE模式下才行。

取消和重复

取消上一次的编辑操作(undo) u

如:误删了一段正文,用u命令可撤销删除
如:把文件中的所有abc字符串替换成xyz字符串, 用u命令可撤销替换
图片

重复上一次的编辑操作 圆点.

按圆点键,可以重复上一次的编辑操作
例如:按3dd命令删除了三行,然后按圆点键就再删除三行,接着连续按圆点键,则继续删除三行,每按一次删三行。
图片

文件操作命令

存盘退出

图片

ZZ

1
2
3
4
5
6
7
8
[root@localhost vi]# cat helloworld.c 
xx#include <stdio.h>

int main()
{
printf("%s\n","HelloWorld!");
}
[root@localhost vi]#

:wq回车

存盘不退出

1
:w<CR>

这里的<CR>表示Enter键

不存盘退出

1
:q!<CR>

当前行下插入文件内容

读入文件xyz.c插入到当前行之下

1
:r xyz.c<CR>

示例

test.txt文件:

test.txt
1
2
3
4
5
[root@localhost vi]# cat test.txt 
test.txt line 1
test.txt line 2
test.txt line 3
[root@localhost vi]#

光标在第1行时,输入:r test.txt<CR>后:
图片

把当前文件的部分行写入文件

写文件,把第50行至文件尾的内容写到文件file1中

1
:50,$w file1<CR>

图片

强制覆,把第50行到行尾的内容强制覆盖到文件file1中:

1
:50,$w! file1<CR>

图片

剪贴板

删除,并拷贝到剪贴板

删除第10-50行:

1
:10,50d<CR>

图片

删除文件首至当前行的部分:

1
:1,.d<CR>

图片

删除当前行到文件尾

1
:.,$d<CR>

图片

不删除,拷贝到剪贴板(yank)

1
:10,50y<CR>

图片
图片

粘贴剪贴板信息(paste)

1
p

图片

块操作:复制与删除

复制

复制第5-10行到第56行之下:

1
:5,10co56<CR>

图片

移动

移动第8-34行的内容到第78行的内容之下:

1
:8,34m78<CR>

图片
图片

行合并、刷屏和状态显示

两行合并(Join):J(shiff+j)

需要注意的是这个J是大写的,也就是按shift+j进行输入,单独按j键是不会起效果的:
图片

两行合并末行命令 :j

也可以使用在末行命令:

1
:j

当前行下面的行合并到当前行
图片

刷新屏幕显示(load) Ctrl-l

图片

状态显示Ctrl-g

在屏幕最下面一行列出正在编辑的文件的名字,总行数,当前行号,文件是否被修改过等信息
图片
图片

模式查找

用“正则表达式”来描述一个字符串模式

查找命令格式

1
/pattern

例:

1
/[0-9][0-9]*

vi好像只支持基本的正则表达式,扩展的正则表达式例如.+并不支持。
图片

其实不是而是.+需要写成.\+
图片

继续查找命令

n 向下查找下一个next
N 向上查找下一个
循环式搜索(向下搜索时遇到文件尾则回到文件头继续搜索)

图片
图片
图片

模式替换

替换命令(substitution)
格式

1
:n1,n2s/pattern/string/g

1
:1,50s/abc/xyz/
1
:1,50s/abc/xyz/g

第50-75行右移4列:

1
:50,80s/^/ /

第50-75行左移4列:

1
:50,80s/^ //

消除尾部多余的空格

1
:1,$s/  *$//

小心陷阱:不能把a[i]替换为b[j]

1
:1,$s/a[i]/b[j]/g

小心陷阱:不能把a*b替换为x+y

1
:1,$/a*b/x+y/g

模式替换中的转义符

尤其是编辑C语言源程序时需要
a[i]*b[j]替换为x[k]*y[n]的命令

1
:1,$s/a\[i]\*b\[j]/x[k]*y[n]/g

buf.len/1000替为buffer.size/1024的命令

1
:1,$s/buf\.len\/1000/buffer.size\/1024/g

模式串和替换字符串中的斜线前加转义符\以区别于替换命令格式中所必须的斜线.

使用其他符号作为s替换末行命令的分隔符

1
:1,$s:buf\.len/1000:buffer.size/1024:g

s后面以冒号取代斜线,分界符就换为冒号,避免对斜线的转义

1
:1,$s^http://www\.myvdo\.com/a/b/c/index\.html^https://www.xyvdo.com/index.html^g

分组:模式描述中增加(和)

在正则表达式中圆括号,仍然代表它自身
在正则表达式中出现的(和)不影响匹配操作

1
2
[a-zA-Z_][a-zA-Z0-9_]*->number
\([a-zA-Z_][a-zA-Z0-9_]*\)->number

反向引用:\0 \1 \2

将“变量名->number”替换为“变量名->num

1
:1,$s/\([a-zA-Z_][a-zA-Z0-9_]*\)->number/\1->num/g

将日期格式“月-日-年”改为“年.月.日”,
比如:将04-26-1997替换为1997.04.26使用命令:

1
:1,$s/\([0-9][0-9]\)-\([0-9][0-9]\)-\([0-9][0-9]*\)/\3.\1.\2/g

本文已过时

gitee已经开启防盗链。

如果你把图片放到gitee上,却把博客搭建在github pages上。那么你github pages上的博客是无法访问gitee仓库中的图片的。

如果你还是想使用gitee作为图床,那么你可以把博客搭建到gitee pages上。

同理,如果你想把博客搭建在github pages上,那么你就把图片放到github仓库中。又由于github的图片地址有时候会被墙,你可以使用加速器。(例如 网易UU加速器)

以下为原文:

前言

最近Github搭建的图床老是无法正常访问。所以我打算把放在github上的图床迁移到gitee上。

PicGo上安装gitee插件

点击PicGo左侧的插件设置,然后在搜索框中输入gitee,安装gitee x.x.x这个插件:

图片

在gitee上创建仓库

点击gitee网站右上方的加号,选择创建仓库,或者从github导入。

图片

我原先在github上有图库了,这里选择从github导入。

获取gitee的token

点击gitee网站右上角的头像旁边的下拉菜单,选择设置,然后点击网站左侧的安全设置下方的私人令牌

然后单击右上方的生成令牌按钮:

然后只勾选projects即可,其他的不要选:

然后复制生成的token:

Gitee图床插件设置

gitee图床插件输入框 描述
owner 填写你的gitee的用户名,不知道用户名可以从浏览器的地址中得到。
repo 填写仓库名,可从仓库的地址中复制的到
path 填写本次上传的图片相对于仓库根目录的路径,如果没有设置则图片保存在仓库的根路径中。还需要注意的是这个路径开头和结尾都不要带有地址符/
token 填写刚才复制的私人令牌

path开头和结尾不要带有地址符‘/’,也就是要写成Blog/Hexo,而不是/Blog/Hexo/或者Blog/Hexo/
如果你path填写成Blog/Hexo/则得到的图片地址可能是

https://gitee.com/XiaoLan223/images/raw/master/Blog/Hexo//7.png

这种形式。

上传图片验证

到这里需要设置的都设置完了,可以上传图片查看效果。

vi用户的偏好设置

通过用户HOME目录下的文件.exrc设置vi偏好

记作$HOME/.exrc(每用户一份,用户独立设置)

1
2
set number       每行左边显示行号
set tabstop=4 制表符位置为4格对齐
1
2
3
4
5
[root@localhost vi]# vi ~/.exrc
[root@localhost vi]# cat ~/.exrc
set number
set tabstop=4
[root@localhost vi]#

图片

在vi运行时检查偏好设置

在vim中输入

1
2
:set number
:set tabstop=4

执行:set number:set tabstop=4后:
图片

vi的两种工作状态

图片

命令状态:键盘输入解释为命令

  • vi一启动就进入命令方式,键盘输入解释为命令
  • 一般按键无回显
  • 以冒号可以引入行编辑的命令和查找命令
  • 在命令状态下按下i键或a键等,可以从命令状态转到文本状态

文本状态

  • 键盘输入解释为输入的文本
  • 可以输入多行,每输入完一行后按回车转入下一行
  • 正文输入时有回显
  • 输入完毕按键盘左上角的Esc键,返回到命令状态

正文插入

命令i

在当前字符前插入正文段,直至按Esc键(insert)

命令a

在当前字符后插入正文段,直至按Esc键(append)

光标单字符移动

单字符移动

(四个字母键盘上相邻的按键)

  • h 光标左移一列
  • j 光标下移一行
  • k 光标上移一行
  • l 光标右移一列

一般可以直接使用键盘上的方向键代替这四个字母

执行多次单字符移动命令

命令前加一整数,表示这个命令连续执行多少遍

  • 5h 光标左移5列
  • 6j 光标下移6行
  • 23k 光标上移23行
  • 10l 光标右移10列

注意:在vi命令状态下的按键命令没有回显
图片

翻页命令

  • Ctrl+b 向后翻页(Backward)
  • Ctrl+f 向前翻页(Forward)

图片

一般可以用PgDn键代替Ctrl+f,用PgUp键代替Ctrl+b

连续翻页

也可以使用下面的命令

  • 6Ctrl-f 向前翻6页
  • 15Ctrl-b 向后翻15页

光标行内快速移动

行尾行首

  • 将光标移至当前行首^,(按shift+6按键即可输入^
  • 将光标移至当前行尾$,(按shift+4按钮即可输入$

图片

移动一个单词

  • 移到右一个单词w
  • 移到左一个单词b
  • 也可以使用6w,5b命令

图片
图片

光标移动到指定行

移到指定的行

  • :476 将光标定位于第476行
  • :1 将光标定位于第1行(文件首)
  • :$ 将光标定位于文件尾

图片

在描述行号时可以使用

圆点(.)代表当前行号,
$代表最后一行的行号。

图片

括号配对%

把光标移到一个花括号(或圆括号,或方括号)上,按%键,则光标自动定位到与它配对的那一个括号
图片

参考资料

http://c.biancheng.net/vi/