本文原创地址:博客园骏马金龙https://www.cnblogs.com/f-ck-need-u/p/6995195.html
linux文件类基础命令
1.关于路径和通配符
linux中分绝对路径和相对路径,绝对路径一定是从/开始写的,相对路径不从根开始写,还可能使用路径符号。
路径展开符号:
1 | . :一个点表示当前目录 |
切换路径用cd命令;
显示当前所在目录用pwd命令。若当前所在目录为链接目录,使用pwd显示的将是链接自身,使用-P选项将定位到链接的原始目录。
1 | [root@ansible6_node1 ~]# ll ; cd tmp; pwd; pwd -P |
获取文件名使用basename命令,获取文件所在目录使用dirname命令。注意,这两个命令其实不太完善,它不会检查文件或目录是否存在,只要写出来了就会去获取。
1 | [root@xuexi tmp]# basename /etc/shadow |
bash shell通配符:
可以使用”*”、”?”、”[]”等的通配符来扩展路径或文件名。例如, ls *.log 将列出当前路径下所有以”.log”字符结尾的文件名(但不包括”.”开头的隐藏文件)。
默认情况下,bash提供的通配符规则比较弱,例如”*”无法匹配文件名开头的”.”,无法匹配路径分隔符号(即斜线”/“),但可以通过set或shopt命令开启额外的通配功能,实现更完善的通配符规则。
例如,默认情况下,想要匹配目录/path下所有隐藏文件和非隐藏文件,如下:
1 | ls .* * |
开启dotglob功能,”*”就可以匹配以”.”开头的文件:
1 | shopt -s dotglob |
有时想要递归到目录内部,又想要匹配文件名,例如想要递归找出多层目录/path下所有的”.css”文件,这时可以开启globstar功能,使用”两星连珠”(**)就可以匹配匹配路径斜线。
1 | shopt -s globstar # 开启星号匹配模式 |
必须要说明的是,对于非bash内置命令,有些可能也提供了自己的通配符匹配方式,它们的通配模式和shell提供的可能并不一样。例如find的”-name”选项就可以采用自己的通配符,它的星号”*”可以匹配以点开头的隐藏文件,如1
2
3
4
5
6
7
8
9#### 2. 查看目录内容(ls和tree)
ls命令列出目录中的内容,和dir命令完全等价。tree命令按树状结构递归列出目录和子目录中的内容,而ls使用-R选项时才会递归列出。
注意:ls的结果中是以制表符分隔多个文件的。
2.1 ls命令
ls的各个选项说明如下:
-l:(long)长格式显示,即显示属性等信息(包括mtime)。注意:显示的目录大小是节点所占大小。像win一样计算目录大小时包括文件大小要用du -sh
-c:列出ctime
-u:列出atime
-d:(direcorty)查看目录本身属性信息,不查看目录里面的东西。不加-d会查看里面文件的信息
-a:会显示所有文件,包括两个相对路径的文件”.”和”..”以及以点开头的隐藏文件
-A:会列出绝大多数文件,即忽略两个相对路径的文件”.”和”..”
-h:(human)人类可读的格式,将字节换成k,将K换成M,将M换成G
-i:(inode)权限属性的前面加上一堆数字
-p:对目录加上/标识符以作区分
-F:对不同类型的文件加上不同标识符以作区分,对目录加的文件也是/
-t:按修改时间排序内容。不加任何改变顺序的选项时,ls默认按照字母顺序排序
-r:反转排序
-R:递归显示
-S:按文件大小排序,默认降序排序
–color:显示颜色
-m:使用逗号分隔各文件,当然,只适用于未使用长格式(ls -l)的情况
-1:(数值一),以换行符分隔文件,当然,和-m或-l(小写字母)是冲突的
-I pattern:忽略被pattern匹配到的文件
1 | 注意,ls以-h显示文件大小时,一般显示的都是不带B的单位,如K/M/G,它们的转换比例是1024,如果显示的都是带了B的,如KB/MB/GB,则它们的转换比例为1000而非1024,一般很少显示带B的大小。 |
[root@xuexi ~]# ll /tmp
drwxr-xr-x 2 root root 4096 Mar 26 16:44 test1
#分析
当为d则是目录,当为-则是文件,当为l则表示为链接文件这是文件的类型
rwx,r-x,r-x分别表示所有者权限,所属组权限,其他人权限
2表示硬链接数
root所有者,root所属组
4096文件大小(字节)-h可以转换显示方式
Mar 26 16:44:最近一次修改的日期
test1:表示文件(目录名)
1 | #### 2.2tree命令 |
-L:用于指定递归显示的深度,指定的深度必须是大于0的整数。
-P:用于显示通配符匹配模式的目录和文件,但是不管是否匹配,目录一定显示。
-I:用于显示除被通配符匹配外的所有目录和文件。
1 | 【 显示选项:】 |
-a:用于显示隐藏文件,默认不显示。
-d:指定只显示目录。
-f:指定显示全路径。
-i:不缩进显示。和-f一起使用很有用。
-p:用于显示权限位信息。
-h:用于显示大小。
-u:显示username或UID(当没有username时只能显示UID了)。
-g:显示groupname或GID。
-D:显示文件的最后一次Mtime。
–inodes:显示inode号。
–device:显示文件或目录所属的设备号。
-C:显示颜色。
1 | 【 输出选项:】 |
-o filename:指定将tree的结果输出到filename文件中。
1 | #### 3. 文件的时间戳(atime/ctime/mtime) |
mkdir [-mp] 目录名
-m:表示创建目录时直接设置权限
-p:表示递归创建多层目录,即上层目录不存在时也会直接将其创建出来(parent)
[root@xuexi ~]# mkdir /tmp/test1 # 在tmp目录中创建一个test1目录
[root@xuexi ~]# mkdir -m 711 /tmp/test2 # 直接创建test2时就赋予权限711
[root@xuexi ~]# mkdir -p /tmp/test3/test4/test5 # 创建test5,此时会将不存在的test3和test4目录也创建好
1 | ##### 4.2 创建文件touch |
touch file_name
[root@xuexi ~]# touch /tmp/test1/test1.txt
[root@xuexi ~]# touch {1..10} # 创建文件名为1-10的文件
1 | 多个{}还可以交换扩展。类似(a+b)(c+d)=ac+ad+bc+bd。 |
touch -a修改atime,-m修改mtime,没有修改ctime的选项。因为使用touch改变atime或mtime,同时也都会改变ctime,虽说atime并不总是会影响ctime(如cat文件时)。
-t选项表示使用”[[CC]YY]MMDDhhmm[.ss]”格式的时间替代当前时间。
shell> touch -a -t 201212211212 file # 将file文件的atime修改为2012年12月21号12点12分
-d选项表示使用指定的字符串描述时间格式来替代当前时间,如”3 days ago”,”next Sunday”等很多种格式。
所以,touch命令选项说明如下:
-c:强制不创建文件
-a:修改文件access time(atime)
-m:修改文件modification time(mtime)
-t:使用”[[CC]YY]MMDDhhmm[.ss]”格式的时间替代当前时间
-d:使用字符串描述的时间格式替代当前时间
1 | #### 4.3 删除文件/目录 |
rm [-rfi] file_name
-r:表示递归删除,删除目录时需要加此参数
-i:询问是否删除(yes/no)
-f:强制删除,不进行询问
[root@xuexi ~]# rm -rf /tmp/test2
1 | 删除空目录时还可以使用rmdir。 |
[root@xuexi tmp]# file /etc/aliases.db
/etc/aliases.db: Berkeley DB (Hash, version 9, native byte-order) # 数据文件
[root@xuexi tmp]# file ~/.bashrc
/root/.bashrc: ASCII text # ASCII文件
[root@xuexi tmp]# file /bin/ls
/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
1 |
|
[root@server1 ~]# file -s /dev/sda1
/dev/sda1: Linux rev 1.0 ext4 filesystem data (needs journal recovery) (extents) (huge files)
[root@server1 ~]# file -s /dev/sda
/dev/sda: x86 boot sector; GRand Unified Bootloader, stage1 version 0x3, boot drive 0x80, 1st sector stage2 0x7f86, GRUB version 0.94; partition 1: ID=0x83,
active, starthead 32, startsector 2048, 512000 sectors; partition 2: ID=0x83, starthead 254, startsector 514048, 37332992 sectors; partition 3: ID=0x82,
starthead 254, startsector 37847040, 4096000 sectors, code offset 0x48
1 | #### 6. 文件/目录复制和移动 |
cp [-apdriulfs] src dest # 复制单文件或单目录
cp [-apdriuslf] src1 src2 src3……dest_dir # 复制多文件、目录到一个目录下
1 | 选项说明: |
-p: 文件的属性(权限、属组、时间戳)也复制过去。如果不指定p选项,谁执行复制动作,文件所有者和组就是谁。
-r或-R:递归复制,常用于复制非空目录。
-d:复制的源文件如果是链接文件,则复制链接文件而不是指向的文件本身。即保持链接属性,复制快捷方式本身。如果不指定-d,则复制的是链接所指向的文件。
-a:a=pdr三个选项。归档拷贝,常用于备份。
-i:复制时如果目标文件已经存在,询问是否替换。
-u:(update)若目标文件和源文件同名,但属性不一样(如修改时间,大小等),则覆盖目标文件。
-f:强制复制,如果目标存在,不会进行-i选项的询问和-u选项的考虑,直接覆盖。
-l:在目标位置建立硬链接,而不是复制文件本身。
-s:在目标位置建立软链接,而不是复制文件本身(软链接或符号链接相当于windows的快捷方式)。
1 | 一般使用cp -a即可,对于目录加上-r选项即可。 |
cp -a /etc/skel/. /tmp
1 | 如果有重复文件,则即使加上-f选项,也一样会交互式询问。解决方法可以是使用"yes"这个工具,它会不断的生成y字母直到进程被杀掉,当然也可以自行指定要生成的字符串。 |
yes | cp -a /etc/skel/. /tmp
1 | 6.2 scp命令和执行过程分析 |
scp [-12BCpqrv] [-l limit] [-o ssh_option] [-P port] [[user@]host1:]file1 … [[user@]host2:]file2
选项说明:
-1:使用ssh v1版本,这是默认使用协议版本
-2:使用ssh v2版本
-C:拷贝时先压缩,节省带宽
-l limit:限制拷贝速度,Kbit/s.
-o ssh_option:指定ssh连接时的特殊选项,一般用不上。偶尔在连接过程中等待提示输入密码较慢时,可以设置GSSAPIAuthentication为no
-P port:指定目标主机上ssh端口,大写的字母P,默认是22端口
-p:拷贝时保持源文件的mtime,atime,owner,group,privileges
-r:递归拷贝,用于拷贝目录。注意,scp拷贝遇到链接文件时,会拷贝链接的源文件内容填充到目标文件中(scp的本质就是填充而非拷贝)
-v:输出详细信息,可以用来调试或查看scp的详细过程,分析scp的机制
1 | 示例: |
1.把本地文件/home/a.tar.tz拷贝到远程服务器192.168.0.2上的/home/tmp,连接时使用远程的root用户:
scp /home/a.tar.tz root@192.168.0.2:/home/tmp/
2.目标主机不写路径时,表示拷贝到对方的家目录下:
scp /home/a.tar.tz root@192.168.0.2
3.把远程文件/home/a.tar.gz拷贝到本机:
scp root@192.168.0.2:/home/a.tar.tz # 不接本地目录表示拷贝到当前目录
scp root@192.168.0.2:/home/a.tar.tz /tmp # 拷贝到本地/tmp目录下
4.拷贝远程机器的/home/目录到本地/tmp目录下。
scp -r root@192.168.0.2:/home/ /tmp
5.从远程主机192.168.100.60拷贝文件到另一台远程主机192.168.100.62上。
scp root@192.168.100.60:/tmp/copy.txt root@192.168.100.62:/tmp
1 | 在远程复制到远程的过程中,例如在本地执行scp命令将A主机(192.168.100.60)上的/tmp/copy.txt复制到B主机(192.168.100.62)上的/tmp目录下,如果使用-v选项查看调试信息的话,会发现它的步骤类似是这样的。 |
以下是从结果中提取的过程
首先输出本地要执行的命令
Executing: /usr/bin/ssh -v -x -oClearAllForwardings yes -t -l root 192.168.100.60 scp -v /tmp/copy.txt root@192.168.100.62:/tmp
从本地连接到A主机
debug1: Connecting to 192.168.100.60 [192.168.100.60] port 22.
debug1: Connection established.
要求验证本地和A主机之间的连接
debug1: Next authentication method: password
root@192.168.100.60‘s password:
将scp命令行修改后发送到A主机上
debug1: Sending command: scp -v /tmp/copy.txt root@192.168.100.62:/tmp
在A主机上执行scp命令
Executing: program /usr/bin/ssh host 192.168.100.62, user root, command scp -v -t /tmp
验证A主机和B主机之间的连接
debug1: Next authentication method: password
root@192.168.100.62‘s password:
从A主机上拷贝源文件到最终的B主机上
debug1: Sending command: scp -v -t /tmp
Sending file modes: C0770 24 copy.txt
Sink: C0770 24 copy.txt
copy.txt 100% 24 0.0KB/s
关闭本地主机和A主机的连接
Connection to 192.168.100.60 closed.
1 | 也就是说,远程主机A到远程主机B的复制,实际上是将scp命令行从本地传递到主机A上,由A自己去执行scp命令。也就是说,本地主机不会和主机B有任何交互行为,本地主机就像是一个代理执行者一样,只是帮助传送scp命令行以及帮助显示信息。 |
mv [-iuf] src dest # 移动单个文件或目录
mv [-iuf] src1 src2 src3 dest_dir # 移动多个文件或目录
选项说明:
–backup[=CONTROL]:如果目标文件已存在,则对该文件做一个备份,默认备份文件是在文件名后加上波浪线,如/b.txt~
-b:类似于–backup,但不接受参数, 默认备份文件是在文件名后加上波浪线,如/b.txt~
-f:如果目标文件已存在,则强制覆盖文件
-i:如果目标文件已存在,则提示是否要覆盖,这是alias mv的默认选项
-n:如果目标文件已存在,则不覆盖已存在的文件
如果同时指定了-f/-i/-n,则后指定的生效
-u:(update)如果源文件和目标文件不同,则移动,否则不移动
1 | mv默认已经是递归移动,不需要-r参数。 |
[root@toystory tmp]# tree -L 3 a -fC
a
└── a/a
├── a/a/a
2 directories, 1 file
[root@toystory tmp]# mv a/* .
mv: overwrite ./a'? y
mv: cannot move
a/a’ to `./a’: Directory not empty
[root@toystory tmp]# mv -f /tmp/a/* /tmp
mv: cannot move /tmp/a/a' to
/tmp/a’: Directory not empty
1 | 复制代码 |
-n:显示所有行的行号
-b:显示非空行的行号
-E:在每行行尾加上$符号
-T:将TAB符号输出为”^I”
-s:压缩连续空行为单个空行
1 | cat还有一个重要功能,允许将分行键入的内容输入到一个文件中去。 |
[root@xuexi tmp]# cat <<eof
abc.com
eof
abc.com
1 | 再测试<eof,发现没有输入的机会,并且此时只能使用eof作为符号,EOF或其他任何都不可以。因为<eof是读取标准输入,会将eof当成输入文件处理。所以一定要使用<<eof,这表示here document,而两个eof正是document的起始和结束标志。 |
[root@xuexi tmp]# cat <eof
[root@xuexi tmp]# cat <eox
-bash: eox: No such file or directory
[root@xuexi tmp]# cat <EOF
-bash: EOF: No such file or directory
1 | 再进一步测试<<eof的功能,将键入的内容重定向到文件而非标准输入中。这时有两种书写方案: |
[root@xuexi ~]# cat >>/tmp/test.txt<<EOF # 输入到这里按回车键继续输入下一行
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # 按回车输入下一行
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy # 按回车输入下一行
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz # 按回车输入下一行
EOF # 顶格写EOF结束输入
1 | 第二种方案:<<eof>filename或<<eof>>filename |
[root@xuexi tmp]# cat <
abc.com
eof
1 | 两种方案结果是一样的,且总是使用<<eof,只不过所写的位置不同而已,不管写在哪个位置,它都表示将键入的内容追加到标准输入。然后再使用>filename或>>filename控制重定向的方式,将标准输入中的内容重定向到filename文件中。 |
shell> echo -e ‘1\n2\n3\n4\n5’ | tac
5
4
3
2
1
1 | 7.3 head |
-n:显示前num行;如果num是负数,则显示除了最后|num|(绝对值)行的其余所有行,即显示前”总行数 - |num|”
-v:会显示出文件名
-n num是显示文件的前num行,num可以是+/-或不加正负号的整数,如果是正整数或不写+号,则显示前num行。如果是负整数,则从后向前数num行,并打印除了这些行的前面所有的行,即打印除了最后num行的所有行,也即总行数减num的前正数行。不写-n时默认是前10行。正整数时”-n num”可以直接简写”-num”。
1 | 不管怎么样,它取的都是前几行,哪怕是负整数也是前几行。 |
[root@xuexi ~]# echo -e ‘1\n2\n3\n4\n5’ | head # 取出默认前10行,但总共才有5行。
1
2
3
4
5
[root@xuexi ~]# echo -e ‘1\n2\n3\n4\n5’ | head -2 # 取出前2行
1
2
1 | 或者 |
[root@xuexi ~]# echo -e ‘1\n2\n3\n4\n5’ | head -n 2 # 取出前2行
1
2
[root@xuexi ~]# echo -e ‘1\n2\n3\n4\n5’ | head -n -1 # 取出前5-1=4行
1
2
3
4
1 | 7.4 tail |
tail [OPTION]… [FILE]…
选项说明:
-n:输出最后num行,如果使用-n +num则表示输出从第num行开始的所有行
-f:监控文件变化
–pid=PID:和-f一起使用,在给定PID的进程死亡后,终止文件监控
-v:显示文件名
“-n -num”或”-num”或”-n num”(num为正整数)表示输出最后的num行。使用”-n +num”(num为正整数)则表示输出从第num行开始的所有行。
[root@xuexi ~]# echo -e ‘1\n2\n3\n4\n5’ | tail -3 # 等价于 tail -n 3和tail -n -3
3
4
5
[root@xuexi tmp]# seq 6 | tail -n +3 # 打印除了前3-1=2行的所有行
3
4
5
6
1 |
|
[root@xuexi ~]# nl /etc/issue # 默认空行不显示行号
1 CentOS release 6.6 (Final)
2 Kernel \r on an \m
[root@xuexi ~]# nl -b a /etc/issue
1 CentOS release 6.6 (Final)
2 Kernel \r on an \m
3
1 | 7.6 more和less |
shell> which mv
alias mv=’mv -i’
/bin/mv
1 | 8.2 whereis |
shell> whereis cd
cd: /usr/bin/cd /usr/share/man/man1/cd.1.gz /usr/share/man/man1p/cd.1p.gz /usr/share/man/mann/cd.n.gz
1 | 8.3 whatis |
shell> whatis passwd
sslpasswd (1ssl) - compute password hashes
passwd (1) - update user’s authentication tokens
passwd (5) - password file
1 | 根据上面的结果,执行: |
man 1 passwd # 获取passwd命令的man文档
man 5 passwd # 获取password文件的man文档,文件类的man文档说明的是该文件中各配置项意义
man sslpasswd # 获取sslpasswd命令的man文档,实际上是openssl passwd的man文档