Linux文件中看到的数据有两种存储方式:
因为Linxu一切接文件, 所以在系统中看到的文件和数据可能是内存数据和文件, 也可能是硬盘数据和文件
外存-硬盘文件-存储器-辅助存储
内存-主存储器

Centos7以后, 两个存放内容相同的目录, 会被做成软链接形式:
/bin->/usr/bin
/sbin->/usr/sbin
/lib->/usr/lib
/lib64->/usr/lib64
每个Shell和系统进程都有一个当前的工作目录: Current Working Directory
显示当前所在目录命令: pwd
[22:17:41 root@demo-c8 ~]#pwd
/root
绝对路径: 从根/开始描述
相对路径: 从当前工作目录开始描述
cd ~USERNAME
cd
# 只能回到上一个目录, 上一次目录记录在OLDPWD变量, 当前目录记录在PWD变量
cd -
[20:32:16 root@Anabile-1 /]#cd root
[20:32:25 root@Anabile-1 ~]#echo $PWD
/root
[20:32:29 root@Anabile-1 ~]#echo $OLDPWD
/
[20:32:32 root@Anabile-1 ~]#cd -
/
[20:32:56 root@Anabile-1 /]#cd -
/root
[20:32:57 root@Anabile-1 ~]#cd -
/
[22:37:07 root@demo-c8 ~]#cd /etc/profile.d
[22:37:14 root@demo-c8 /etc/profile.d]#cd ..
[22:37:15 root@demo-c8 /etc]#cd ..
[22:37:16 root@demo-c8 /]#cd ..
[22:37:17 root@demo-c8 /]#cd ..
[22:37:20 root@demo-c8 /]# # 最外层就是/目录
cd .
当前目录用.表示, 上层目录用..表示
basename: 只取文件名
dirname: 只取文件所在的目录, 从/开始取
basename+dirname即为一个文件的完整路径
[20:26:39 root@Anabile-1 ~]#basename /root/anaconda-ks.cfg
anaconda-ks.cfg
[20:29:38 root@Anabile-1 ~]#dirname /root/anaconda-ks.cfg
/root
常见选项:
-R: 目录递归, 默认只显示当前目录内的内容, 递归后, 会进入到每个目录, 进行数据显示
-1: 让文件名分行显示, ls -1
-S: 按照文件大小, 从大到小排序, -r -S, 从小到大排序
-t: 按照mtime排序, 默认从新到旧
-u: 配合-t选项, 按照atime时间, 从新到旧排序
-U: 按照目录存放顺序排序
-X: 按照文件后缀排序
-r: 按照默认顺序的反向顺序排序
anaconda-ks.cfg.bak Desktop Downloads Music Public test.txt Videos
asicc.txt.txt Documents initial-setup-ks.cfg Pictures Templates 't.txt'$'\033'':Q!'
[22:44:01 root@demo-c8 ~]#ls -l
total 28
-rw-------. 1 root root 1385 Aug 15 17:06 anaconda-ks.cfg.bak
-rw-r--r--. 1 root root 7 Aug 17 12:02 asicc.txt.txt
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Desktop
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Documents
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Downloads
-rw-r--r--. 1 root root 1495 Aug 15 17:17 initial-setup-ks.cfg
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Music
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Pictures
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Public
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Templates
-rw-r--r--. 1 root root 6 Aug 17 11:55 test.txt
-rw-r--r--. 1 root root 8233 Aug 17 11:54 't.txt'$'\033'':Q!'
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Videos
modify time(mtime): 内容更改
access time(atime):读文件
change time(ctime):属性,元数据变化
ls -l --time=atime FILE
ls -l --time=mtime FILE
ls -l --time=ctime FILE
[20:36:54 root@Anabile-1 ~]#ls -l --time=atime anaconda-ks.cfg # atime
-rw-------. 1 root root 1412 Aug 13 20:36 anaconda-ks.cfg
[20:36:58 root@Anabile-1 ~]#ls -l anaconda-ks.cfg # 默认显示mtime
-rw-------. 1 root root 1412 Aug 12 14:06 anaconda-ks.cfg
[20:37:46 root@Anabile-1 ~]#l. # l.是别名
. .ansible .bash_history .bash_profile .cshrc .tcshrc .vimrc
.. .ansible-console_history .bash_logout .bashrc .ssh .viminfo .vimrc.0
[20:38:25 root@Anabile-1 ~]#alias l.
alias l.='ls -d .* --color=auto'
[22:44:16 root@demo-c8 ~]#ls -a
. asicc.txt.txt .bash_profile .config Desktop .esd_auth .lesshst Pictures .tcshrc 't.txt'$'\033'':Q!' .Xauthority
.. .bash_history .bashrc .cshrc Documents .ICEauthority .local .pki Templates Videos
anaconda-ks.cfg.bak .bash_logout .cache .dbus Downloads initial-setup-ks.cfg Music Public test.txt .viminfo
-d: 显示目录本身信息, 配合通配符时, -d只会显示目录这一层, 不会继续显示子目录的内容
-l: 显示目录内部的文件内容信息
-ld: 显示目录本身详细信息
[22:51:01 root@demo-c8 ~]#ls .config # .config是一个隐藏目录
dconf evolution gconf gnome-initial-setup-done gnome-session goa-1.0 gtk-3.0 ibus pulse user-dirs.dirs user-dirs.locale yelp
[22:51:05 root@demo-c8 ~]#ls -d .config
.config
[22:51:13 root@demo-c8 ~]#ls -l .config
total 16
drwxr-xr-x. 2 root root 18 Aug 15 17:25 dconf
drwx------. 3 root root 21 Aug 15 17:19 evolution
drwx------. 2 root root 6 Aug 15 17:19 gconf
-rw-r--r--. 1 root root 3 Aug 15 17:21 gnome-initial-setup-done
drwx------. 3 root root 27 Aug 15 17:19 gnome-session
drwxr-xr-x. 2 root root 6 Aug 15 17:19 goa-1.0
drwx------. 2 root root 23 Aug 15 17:19 gtk-3.0
drwx------. 3 root root 17 Aug 15 17:16 ibus
drwx------. 2 root root 4096 Aug 15 17:19 pulse
-rw-------. 1 root root 633 Aug 15 17:19 user-dirs.dirs
-rw-r--r--. 1 root root 5 Aug 15 17:19 user-dirs.locale
drwxr-xr-x. 2 root root 22 Aug 15 17:21 yelp
[22:51:23 root@demo-c8 ~]#ls -ld .config
drwx------. 11 root root 215 Aug 15 17:21 .config
[22:51:28 root@demo-c8 ~]#ls -Sla
total 84
-rw-r--r--. 1 root root 8233 Aug 17 11:54 't.txt'$'\033'':Q!'
-rw-------. 1 root root 8090 Aug 17 21:43 .viminfo
-rw-------. 1 root root 7275 Aug 17 21:43 .bash_history
dr-xr-x---. 15 root root 4096 Aug 17 21:43 .
-rw-r--r--. 1 root root 1495 Aug 15 17:17 initial-setup-ks.cfg
-rw-------. 1 root root 1385 Aug 15 17:06 anaconda-ks.cfg.bak
-rw-------. 1 root root 310 Aug 15 17:19 .ICEauthority
dr-xr-xr-x. 18 root root 236 Aug 17 10:15 ..
drwx------. 10 root root 230 Aug 15 17:21 .cache
-rw-r--r--. 1 root root 224 Aug 16 21:14 .bashrc
-rw-r--r--. 1 root root 216 Aug 17 19:05 .bash_profile
drwx------. 11 root root 215 Aug 15 17:21 .config
-rw-r--r--. 1 root root 129 May 11 2019 .tcshrc
-rw-r--r--. 1 root root 100 May 11 2019 .cshrc
-rw-------. 1 root root 58 Aug 16 21:52 .Xauthority
-rw-------. 1 root root 37 Aug 17 20:00 .lesshst
drwx------. 3 root root 25 Aug 15 17:16 .dbus
drwx------. 3 root root 19 Aug 15 17:19 .local
drwxr-----. 3 root root 19 Aug 15 17:19 .pki
-rw-r--r--. 1 root root 18 May 11 2019 .bash_logout
-rw-------. 1 root root 16 Aug 15 17:19 .esd_auth
-rw-r--r--. 1 root root 7 Aug 17 12:02 asicc.txt.txt
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Desktop
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Documents
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Downloads
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Music
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Pictures
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Public
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Templates
-rw-r--r--. 1 root root 6 Aug 17 11:55 test.txt
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Videos
[22:57:13 root@demo-c8 ~]#ls -Slar # -r: 从小到大, 反向
total 84
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Videos
-rw-r--r--. 1 root root 6 Aug 17 11:55 test.txt
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Templates
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Public
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Pictures
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Music
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Downloads
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Documents
drwxr-xr-x. 2 root root 6 Aug 15 17:19 Desktop
-rw-r--r--. 1 root root 7 Aug 17 12:02 asicc.txt.txt
-rw-------. 1 root root 16 Aug 15 17:19 .esd_auth
-rw-r--r--. 1 root root 18 May 11 2019 .bash_logout
drwxr-----. 3 root root 19 Aug 15 17:19 .pki
drwx------. 3 root root 19 Aug 15 17:19 .local
drwx------. 3 root root 25 Aug 15 17:16 .dbus
-rw-------. 1 root root 37 Aug 17 20:00 .lesshst
-rw-------. 1 root root 58 Aug 16 21:52 .Xauthority
-rw-r--r--. 1 root root 100 May 11 2019 .cshrc
-rw-r--r--. 1 root root 129 May 11 2019 .tcshrc
drwx------. 11 root root 215 Aug 15 17:21 .config
-rw-r--r--. 1 root root 216 Aug 17 19:05 .bash_profile
-rw-r--r--. 1 root root 224 Aug 16 21:14 .bashrc
drwx------. 10 root root 230 Aug 15 17:21 .cache
dr-xr-xr-x. 18 root root 236 Aug 17 10:15 ..
-rw-------. 1 root root 310 Aug 15 17:19 .ICEauthority
-rw-------. 1 root root 1385 Aug 15 17:06 anaconda-ks.cfg.bak
-rw-r--r--. 1 root root 1495 Aug 15 17:17 initial-setup-ks.cfg
dr-xr-x---. 15 root root 4096 Aug 17 21:43 .
-rw-------. 1 root root 7275 Aug 17 21:43 .bash_history
-rw-------. 1 root root 8090 Aug 17 21:43 .viminfo
-rw-r--r--. 1 root root 8233 Aug 17 11:54 't.txt'$'\033'':Q!'
ls -R: 递归显示, 会进入到每个子目录内显示出所有文件, 而ls默认只显示当前目录内的内容

ls查看不同后缀文件时的颜色由/etc/DIR_COLORS和@LS_COLORS变量定义
案例: jpg类型默认显示为紫色, 我们修改为绿色

[23:22:35 root@demo-c8 ~]#vim /etc/DIR_COLORS
# image formats
.jpg 01;32
退出当前终端, 重新登录

Linux文件包含元数据Metadata和实际数据Data
access time: 访问时间, atime, 读取文件内容
modify time: 修改时间, mtime, 改变文件内容(数据)
change time: 改变时间, ctime, 元数据发生改变
[20:37:02 root@Anabile-1 ~]#stat anaconda-ks.cfg
File: anaconda-ks.cfg
Size: 1412 Blocks: 8 IO Block: 4096 regular file
Device: 802h/2050d Inode: 202265935 Links: 1
Access: (0600/-rw-------) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-08-13 20:36:54.310987472 +1000
Modify: 2020-08-12 14:06:15.405009322 +1000
Change: 2020-08-12 14:06:15.405009322 +1000
Birth: -
文件可以包含多种类型的数据, 可以使用file命令检查文件的类型, 然后确定适当的打开命令或使用对应的应用程序
file通过检测文件前几位, 也就是元数据来判断文件类型
Linux文件对后缀没有要求, 即便是二进制可执行程序改成了.txt后缀, 也可以照样执行, 但是执行时需要写上文件后缀,否则会提示找不到文件, 因为不加后缀执行,系统会认为执行的还是原来的程序文件
比如 把/usr/bin/ls 改成/usr/bin/ls.txt
那么执行命令时就要用ls.txt而不是ls
[23:25:16 root@demo-c8 ~]#ls
anaconda-ks.cfg.bak Desktop Downloads Music Public test.jpg 't.txt'$'\033'':Q!'
asicc.txt.txt Documents initial-setup-ks.cfg Pictures Templates test.txt Videos
[23:43:14 root@demo-c8 ~]#mv /usr/bin/ls /usr/bin/ls.txt
[23:43:26 root@demo-c8 ~]#ls
-bash: /usr/bin/ls: No such file or directory
[23:43:31 root@demo-c8 ~]#ls.txt
anaconda-ks.cfg.bak Desktop Downloads Music Public test.jpg 't.txt'$'\033'':Q!'
asicc.txt.txt Documents initial-setup-ks.cfg Pictures Templates test.txt Videos
[23:43:40 root@demo-c8 ~]#mv /usr/bin/ls.txt /usr/bin/ls
[23:43:58 root@demo-c8 ~]#ls
anaconda-ks.cfg.bak Desktop Downloads Music Public test.jpg 't.txt'$'\033'':Q!'
asicc.txt.txt Documents initial-setup-ks.cfg Pictures Templates test.txt Videos
ELF: Linux二进制可执行程序
软链接: symbolic link to FILE
Windows的换行是回车+换行实现的, 换行是光标移动到当前位置下一行的同一位置, 回车是回到当前行首. 所以Windows是先执行0d再执行0a.
Linux 只有换行,没有回车,也就是Linux换行把两件事都干了. 所以, Linux只有0a
换行 \n 0a
回车 \r 0d
Windows文件在Linux里用file命令查看会显示为CRLF line terminators, 表示带有回车的行结束符, 因为Windows文件比Linux文件多一个\r回车符
hexdump -C: 将文件内容以16进制展示
避免文本乱码, 需要确保文本保存和打开使用相同的编码机制. 用UTF-8保存的文本, 就要用UTF-8编码去打开, 否则会乱码
Windows文本格式转换成Linux格式
dos2unix
unix2dos
dos2unix和unix2dos只是转换文本格式(修改0a和0d), 而不会修改文本的编码
在Linux上完成对Windows文本文件的转码, 从其他编码转到UTF-8
案例:


将a.txt从Windows传到Linux中, 验证打开为乱码, 因为Linux默认用UTF-8编码保存和打开文件

[23:57:03 root@demo-c8 ~]#file a.txt # ISO-8859表示的就是GBK编码
a.txt: ISO-8859 text, with CRLF line terminators
iconv命令, 将GBK编码文件转换为UTF-8编码
iconv也可以把UTF-8转成其他编码格式
文件通配符可以用来匹配符合条件的多个文件名和目录名, 方便批量管理文件和目录.
通配符采用特定的符号, 表示特定的含义, 此特定符号称为元meta字符
通配符除了*匹配0个或任意个字符外, 其余的通配符都是逐位匹配, 无法通过某一个通配符, 匹配一串字符
常见通配符如下:
这里的字符指的是任何人类字符, 汉字,英文,数字,标点
* 匹配零个或多个任意字符, 但是不匹配'.'开头的文件, 也就是隐藏文件和目录
? 匹配任意单个字符
[0-9] 匹配0-9内的任意一个数字
[a-z] 匹配aAbBcCdDeE...z内的任意一个字母
[A-Z] 匹配AbBcCdDeE...zZ内的任意一个字母
[wang] 匹配列表内的任意一个字符, w, a, n, g都符合要求
[^wang] 匹配列表内的所有字符以外的任意单个字符, 也就是匹配不是w, a, n, g的任意一个字符
通配符[]匹配连续范围字母时的顺序为aAbBcC...zZ; 花括号{}作为扩展命令时, 其顺序为ASCII顺序
书写通配符时, 只需要按照要求的模式, 把每一个字符位上的模式写出来即可, 从文件第一个字符位, 写到最后一个字符位
另外还有在Linux系统中预定义的字符类: man 7 glob, 这些字符类在使用时需要写在[]里
[:digit:] 相当于0-9, 表示任意单个数字, 范围是0-9
[:lower:] 任意一个小写字母, 和[a-z]不等价
[:upper:] 任意一个大写字母, 和[A-Z]不等价
[:alpha:] 任意一个大写或小写字母
[:blank:] 任意一个水平空白字符
[:space:] 任意一个水平或垂直空白字符
[:punct:] 任意一个标点符号
[:print:] 任意一个可打印字符
[:cntrl:] 任意一个控制(非打印)字符
[:graph:] 图形字符
[:xdigit:] 任意一个16进制字符
?匹配的是一个字符, 可以是英文, 也可以是中文. ?匹配的是字符个数, 不是字节个数.UTF-8编码: 在磁盘上,一个英文单词占一个字节,byte, 一个汉字占3-4个字节,byte
[]中括号通配符, 用于匹配文件名或目录名-分开两个字符[字符1-字符2], 表示的是匹配从字符1到字符2的任意单个字符, 如果要匹配离散字符, 也就是指定的字符, 用[136aW!]这种ls 显示文件就是按照顺序aAbB..zZ显示, 如果首字母相同, 再比较第二个,,,/结尾的, 而文件的结尾没有/, 所以使用通配符管理文件和目录时, 可以按照结尾是否有/来区分文件和目录案例: 比较有无*的功能区别, *不显示隐藏文件和目录
ls -a * : 不显示隐藏文件和目录
ls -a: 显示隐藏文件和目录

touch可以用来创建空文件或刷新已有文件的时间戳
-a 仅改变atime和ctime
-m 仅改变mtime和ctime
-t [[CC]YY]MMDDhhmm[.ss] 指定atime和mtime的时间戳
-c 如果文件不存在, 则不予创建
[20:54:49 root@demo-c8 ~]#mkdir /data/test
[20:54:53 root@demo-c8 ~]#cd /data/test
[20:54:56 root@demo-c8 /data/test]#touch `date +%F_%T`.log
[20:55:06 root@demo-c8 /data/test]#ls
2022-08-18_20:55:06.log
>


利用cp命令可以实现文件或目录的复制, 复制文件或目录时, 源文件会保留, 生成新的文件或目录
工作中, 无论是复制还是移动文件, 最好先把源文件和目标文件都备份一下, 避免误操作
root账号下的cp命令是cp -i的别名, 如果目标存在, 会提示是否覆盖, 而普通账号下的cp不是别名, 复制不会提示是否覆盖
格式:
CP [OPTION]... [-T] SOURCE DEST
CP [OPTION]... SOURCE... DIRECTORY
CP [OPTION]... -t DIRECTORY SOURCE...
复制的不同情况:

1. 源是单个文件:
目标文件不存在: 在目标目录创建目标文件, 将源文件中的内容, 覆盖到新创建的目标文件
cp -a /etc/fstab /tmp/fstab.bak # 将fstab复制到/tmp下, 文件名为fstab.bak
目标存在, 且为文件: 将源文件中的内容, 覆盖到已存在的目标文件. root账号会提示是否覆盖, 普通账号建议用cp -i, 避免数据丢失
cp -a /etc/bashrc /tmp/fstab.bak # 因为fstab.bak已经存在, 所以在cp时会提示是否覆盖
目标存在, 且为目录: 在目标目录下, 创建与源文件同名的文件, 将源文件的内容, 填充至新创建的文件
cp -a /etc/fstab /tmp # 将fstab复制到/tmp下, 文件名为fstab
2. 源是多个文件:
目标不存在: 提示错误
目标存在且为文件: 提示错误, 源是多个文件, 那么目标必须是一个已存在的目录
目标存在且为目录: 在目标目录下, 创建与源文件同名的多个文件, 并且将源文件内容对应写到新创建的目标文件
3. 源是目录, 则必须使用-r/-R递归复制
目标目录不存在: 在目标目录的父目录创建目标目录, 把源目录中的内容, 复制到新创建的目标目录下
cp -a /etc /etc_backup # 在/根目录创建名为etc_backup的目录, 把/etc目录内的内容, 复制到/etc_backup目录下
目标存在且为文件: 提示错误
目标存在且为目录: 在已存在的目录下, 创建与源目录同名的目录, 并且将源目录中的内容, 复制到目标目录下
cp -a /etc /etc_backup # 如果/etc_backup已经存在, 则在/etc_backup目录下, 创建新的目录etc, 把/etc内的内容复制过去
-u: 仅复制源比目标更新newer的文件, 或目标不存在的文件, 两个目录保存了名字相同的文件, 可以用-u去更新, 避免由于要覆盖的文件量太大, 命令执行时间慢
-b: 会把已经存在的目标文件, 在复制前做备份, 因为目标文件存在, cp命令会用源文件覆盖目标文件. 默认只备份一次, 加--backup=numbered选项会保留多个目标文件版本


[21:01:43 root@demo-c8 /data/test]#ll /dev/zero
crw-rw-rw-. 1 root root 1, 5 Aug 18 13:50 /dev/zero
[21:04:18 root@demo-c8 /data/test]#ll /dev/sda*
# 8 major类型, 0-5minor类型
brw-rw----. 1 root disk 8, 0 Aug 18 13:50 /dev/sda
brw-rw----. 1 root disk 8, 1 Aug 18 13:50 /dev/sda1
brw-rw----. 1 root disk 8, 2 Aug 18 13:50 /dev/sda2
brw-rw----. 1 root disk 8, 3 Aug 18 13:50 /dev/sda3
brw-rw----. 1 root disk 8, 4 Aug 18 13:50 /dev/sda4
brw-rw----. 1 root disk 8, 5 Aug 18 13:50 /dev/sda5
cp过程中, 文件的元数据默认不会全部保留, 可能会丢失一部分普通文本文件, 三个时间戳可能会变成复制命令执行时的时间, 新产生的文件的所有者也可能发生变化
字符文件, cp /dev/zero /tmp/zero.bak 新的bak文件会变成普通文件
cp对于普通文件影响较小, 不会影响文件类型, 对于特殊文件如字符文件, 复制后, 文件类型会发生变化
[12:12:13 root@centos8-2 /data/prac]#cp /etc/issue .
[12:18:07 root@centos8-2 /data/prac]#ll /etc/issue ./issue
-rw-r--r--. 1 root root 23 Jun 3 11:02 /etc/issue
-rw-r--r-- 1 root root 23 Aug 18 12:18 ./issue # mtime发生变化
复制出来的文件, 三个时间戳都是执行复制命令时的时间
[12:18:28 root@centos8-2 /data/prac]#stat !*
stat /etc/issue ./issue
File: /etc/issue
Size: 23 Blocks: 8 IO Block: 4096 regular file
Device: 802h/2050d Inode: 134329398 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-08-17 20:09:23.017015589 +1000
Modify: 2020-06-03 11:02:49.000000000 +1000
Change: 2020-08-12 13:59:15.012002240 +1000
Birth: -
File: ./issue
Size: 23 Blocks: 8 IO Block: 4096 regular file
Device: 805h/2053d Inode: 67108993 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-08-18 12:18:04.055021409 +1000 # 复制出来的文件, 三个时间戳都发生了变化, 时间戳都是执行复制命令时的时间
Modify: 2020-08-18 12:18:04.055021409 +1000
Change: 2020-08-18 12:18:04.055021409 +1000
Birth: -
[12:19:37 root@centos8-2 /data/prac]#cp /dev/zero ./zero.bak
^C
[12:22:23 root@centos8-2 /data/prac]#ll !*
ll /dev/zero ./zero.bak
crw-rw-rw- 1 root root 1, 5 Aug 18 10:38 /dev/zero # 1-设备大类别 5-第五个设备
-rw-r--r-- 1 root root 91480064 Aug 18 12:22 ./zero.bak # 字符文件c变成了普通文件, 文件大小和三个时间戳也都变成了复制命令执行的时间
[12:26:32 root@centos8-2 ~]#cp ~david/test.123 ./hh.txt
[12:26:56 root@centos8-2 ~]#ll !*
ll ~david/test.123 ./hh.txt
-rw-r--r-- 1 root root 6 Aug 18 12:26 ./hh.txt # 复制出来的文件的属主和属组变成了root, 源文件是david
-rw-rw-r-- 1 david david 6 Aug 18 12:26 /home/david/test.123
-p 选项: 复制时, 保留源文件部分属性, 包括权限rwx, owner, group, 和atime和mtime. ctime是文件元数据修改的时间, 和源文件是不一样的
-p same as --preserve=mode,ownership,timestamps
--preserve[=ATTR_LIST] preserve the specified attributes (default:
mode,ownership,timestamps), if possible
additional attributes: context, links, xattr,
all
[12:29:16 root@centos8-2 ~]#cp -p ~david/test.123 ./lala.txt
[12:29:39 root@centos8-2 ~]#ll !*
ll -p ~david/test.123 ./lala.txt
-rw-rw-r-- 1 david david 6 Aug 18 12:26 /home/david/test.123
-rw-rw-r-- 1 david david 6 Aug 18 12:26 ./lala.txt
但是-p也有可能丢失文件类型信息, 比如, 复制软链接时会丢失软链接属性, 而实际复制的是软链接指向的文件, 结果就是源文件是软链接, 复制出来的文件变成了普通文件
# /etc/grub2.cfg是/boot/grub2/grub.cfg的软链接, 如果不加任何选项进行复制, 那么复制后的目标文件会变成普通文件
[12:36:39 root@centos8-2 /data/prac]#cp /etc/grub2.cfg ./grub2.bak
[12:36:49 root@centos8-2 /data/prac]#ll !*
ll /etc/grub2.cfg ./grub2.bak
lrwxrwxrwx. 1 root root 22 Apr 15 00:53 /etc/grub2.cfg -> ../boot/grub2/grub.cfg
-rw-r--r-- 1 root root 5140 Aug 18 12:36 ./grub2.bak
-d 选项: 复制快捷方式本身, 不会复制软链接指向的实际文件, 这样可以保留软链接的属性

-r/-R 选项: 递归复制整个目录内容, 不加-r/-R是无法复制整个目录的
[21:04:22 root@demo-c8 /data/test]#cp /boot .
cp: -r not specified; omitting directory '/boot'
[21:10:39 root@demo-c8 /data/test]#cp -r /boot .
-a 选项: 用于归档, 相当于-dR, --preserv=all, 保留所有属性,常用于备份功能
[13:15:08 root@centos8-2 /data/prac]#cp -a /etc/grub2.cfg ./grub2.cfg.bak
[13:16:25 root@centos8-2 /data/prac]#ll !*
ll -a /etc/grub2.cfg ./grub2.cfg.bak
lrwxrwxrwx. 1 root root 22 Apr 15 00:53 /etc/grub2.cfg -> ../boot/grub2/grub.cfg
lrwxrwxrwx. 1 root root 22 Apr 15 00:53 ./grub2.cfg.bak -> ../boot/grub2/grub.cfg
# 典型备份命令, 利用花括号扩展, 这样备份文件名字会在源文件后加.bak
cp -a test.sh{,.bak}
cp命令多次执行时效果不一样
[13:17:11 root@centos8-2 /data/prac]#ls
[13:25:19 root@centos8-2 /data/prac]#cp /boot /data/prac/bootbak #复制目录时, 需要-r或者-R递归复制目录里的文件
cp: -r not specified; omitting directory '/boot'
[13:25:36 root@centos8-2 /data/prac]#cp -r /boot /data/prac/bootbak #第一次复制时, 由于目标目录不存在, 则cp会把源目录,复制到指定目录下,并且更名为指定的新目录
[13:25:40 root@centos8-2 /data/prac]#ls
bootbak
[13:25:44 root@centos8-2 /data/prac]#cp -r /boot /data/prac/bootbak #第二次复制,由于目标目录已经存在, 则cp命令会把源目录复制到该已经存的目录下作为子目录, 这时bootbak目录里包含第一次从boot里复制来的文件,和第二次复制来的整个boot目录,
[13:25:48 root@centos8-2 /data/prac]#ls
bootbak
[13:25:50 root@centos8-2 /data/prac]#ls bootbak/
boot
config-4.18.0-193.el8.x86_64
efi
grub2
initramfs-0-rescue-f072eccf217a4374b5b44dc4461b3c54.img
initramfs-4.18.0-193.el8.x86_64.img
initramfs-4.18.0-193.el8.x86_64kdump.img
loader
lost+found
System.map-4.18.0-193.el8.x86_64
vmlinuz-0-rescue-f072eccf217a4374b5b44dc4461b3c54
vmlinuz-4.18.0-193.el8.x86_64
[13:26:00 root@centos8-2 /data/prac]#cp -r /boot /data/prac/bootbak #第三次再复制, 由于bootbak目录存在, 则cp把boot复制到bootbak目录下,但是由于boot目录在第二次已经复制时已经复制到boobak目录了,那么就会提示是否替换内容
#如果不想提示覆盖, 可以用\cp, cp的-f并不是强制覆盖
cp: overwrite '/data/prac/bootbak/boot/vmlinuz-4.18.0-193.el8.x86_64'?
cp: overwrite '/data/prac/bootbak/boot/System.map-4.18.0-193.el8.x86_64'?
cp: overwrite '/data/prac/bootbak/boot/config-4.18.0-193.el8.x86_64'?
修改配置文件之前要备份
/etc/motd: 用户登录后提示信息设置, 全局用户有效
cp -av /etc/motd{,.bak}
mv命令可以实现文件或目录的移动和改名
同一个分区, 移动数据, 速度很快, 因为数据位置没有变化
不同分区, 移动数据, 速度相对慢, 因为数据位置发生了变化
mv支持:
格式:
mv [OPTION]... [-T] SOURCE DEST
mv [OPTION]... SOURCE... DIRECTORY
nv [OPTION]... -t DIRECTORY SOURCE...
常用选项:
-i 交互式, 提示目标存在是否覆盖, root用户使用mv会提示是否覆盖
-f 强制移动
-b 当目标文件/目录已存在, 在覆盖前先备份
mv只能一次处理一个文件的改名操作, 而rename可以批量修改文件名
格式:
rename [options] <expression> <replacement> <file>...
rename的expression就是目标文件的文件名中需要修改的部分, replacement为替换后的内容. <file>支持通配符
rename适用于当多个文件的文件名有相同的部分时, 需要把这个相同的部分统一做修改
范例1: 为所有的conf文件, 加上后缀.bak
rename "conf" "conf.bak" file*
范例2: 去掉所有文件的.bak后缀
rename ".bak" "" *.bak
[root@demo-c8 ~]# cd /tmp
[root@demo-c8 tmp]# rm -rf *
[root@demo-c8 tmp]# touch f{1..10}.txt
[root@demo-c8 tmp]# ll
total 0
-rw-r--r--. 1 root root 0 Aug 18 23:33 f10.txt
-rw-r--r--. 1 root root 0 Aug 18 23:33 f1.txt
-rw-r--r--. 1 root root 0 Aug 18 23:33 f2.txt
-rw-r--r--. 1 root root 0 Aug 18 23:33 f3.txt
-rw-r--r--. 1 root root 0 Aug 18 23:33 f4.txt
-rw-r--r--. 1 root root 0 Aug 18 23:33 f5.txt
-rw-r--r--. 1 root root 0 Aug 18 23:33 f6.txt
-rw-r--r--. 1 root root 0 Aug 18 23:33 f7.txt
-rw-r--r--. 1 root root 0 Aug 18 23:33 f8.txt
-rw-r--r--. 1 root root 0 Aug 18 23:33 f9.txt
[root@demo-c8 tmp]# rename "txt" "txt.bak" f[1-9].txt
[root@demo-c8 tmp]# ll
total 0
-rw-r--r--. 1 root root 0 Aug 18 23:33 f10.txt
-rw-r--r--. 1 root root 0 Aug 18 23:33 f1.txt.bak
-rw-r--r--. 1 root root 0 Aug 18 23:33 f2.txt.bak
-rw-r--r--. 1 root root 0 Aug 18 23:33 f3.txt.bak
-rw-r--r--. 1 root root 0 Aug 18 23:33 f4.txt.bak
-rw-r--r--. 1 root root 0 Aug 18 23:33 f5.txt.bak
-rw-r--r--. 1 root root 0 Aug 18 23:33 f6.txt.bak
-rw-r--r--. 1 root root 0 Aug 18 23:33 f7.txt.bak
-rw-r--r--. 1 root root 0 Aug 18 23:33 f8.txt.bak
-rw-r--r--. 1 root root 0 Aug 18 23:33 f9.txt.bak
rm命令可以删除Linux系统上的文件, 此命令非常危险
格式:
rm [OPTION]... FILE
常用选项:
-i 交互式
-f 强制删除
-r 递归
--no-preserve-root 删除/目录
root上的rm是别名, 会提示是否删除, rm -f会强制删除文件, rm -rf会强制删除目录
Linux中, 即使文件正在编辑,也是可以删除的
移动, 复制, 删除大文件时, 要找系统空闲的时间进行, 避免对系统造成过大压力
范例1: 删根
rm -rf / # 从CentOS6开始, 已经禁止执行此命令
[root@demo-c8 tmp]# rm -rf /
rm: it is dangerous to operate recursively on '/'
rm: use --no-preserve-root to override this failsafe
rm -rf /* 仍然可以执行, 工作中要命令禁止此命令
比如: 如果要删除test目录内的内容, 保留test目录, 需要执行rm -rf test/*
[root@demo-c8 data]# ls
test
[root@demo-c8 data]# rm -rf test/*
但是, 一旦在test和/*中间, 无意间加了空格, 那么就是执行rm -rf test和rm -rf /*, 就会把根删了
范例2: 将rm设置为mv的别名
# root用户, rm为rm -i的别名, 删除会提示是否删除
# 把rm设置为mv的别名后, 执行rm是无法删除任何文件和目录的, 因为mv命令需要两个参数, 此时, 执行rm的用户就会知道rm是不让使用的, 需要执行mv命令
[root@demo-c8 data]# alias rm
alias rm='rm -i'
[root@demo-c8 data]# alias rm=mv
[root@demo-c8 data]# alias rm
alias rm='mv'
[root@demo-c8 data]# rm test
mv: missing destination file operand after 'test'
Try 'mv --help' for more information.
[root@demo-c8 data]# rm -rf test
mv: invalid option -- 'r'
Try 'mv --help' for more information.
# 或者把rm改成echo, 执行rm提示不要删除文件也行
[root@demo-c8 data]# alias rm="echo DO NOT RM ANY FILES"
[root@demo-c8 data]# rm test
DO NOT RM ANY FILES test
# 创建/data/-f文件
[root@demo-c8 data]# touch ./-f
[root@demo-c8 data]# ll
total 0
-rw-r--r--. 1 root root 0 Aug 18 23:52 -f
[root@demo-c8 data]# ls
-f
# 删除/data/-f文件
方法1. 使用相对或者绝对路径
方法2. 使用rm -- -f
[root@demo-c8 data]# rm -- -f
[root@demo-c8 data]# ll
total 0
Linux的rm删除文件, 只是删除文件名, 磁盘文件还是存在的, 如果想把磁盘文件也删了, rm不能彻底删除干净, 可以使用一些工具进行恢复
格式:
shred [OPTION]... FILE...
选项:
-z 最后一次覆盖文件时添加0, 以隐藏覆盖操作
-v 显示操作进度
-u 覆盖后截断并删除文件
-n 数字 指定覆盖文件内容的次数, 默认是3次
范例: shred删除文件
[root@demo-c8 data]# cp -a /etc/passwd ./passwd.txt
[root@demo-c8 data]# ll
total 4
-rw-r--r--. 1 root root 2658 Aug 15 17:05 passwd.txt
[root@demo-c8 data]# shred -zvun 5 passwd.txt
shred: passwd.txt: pass 1/6 (random)...
shred: passwd.txt: pass 2/6 (ffffff)...
shred: passwd.txt: pass 3/6 (random)...
shred: passwd.txt: pass 4/6 (000000)...
shred: passwd.txt: pass 5/6 (random)...
shred: passwd.txt: pass 6/6 (000000)...
shred: passwd.txt: removing
shred: passwd.txt: renamed to 0000000000
shred: 0000000000: renamed to 000000000
shred: 000000000: renamed to 00000000
shred: 00000000: renamed to 0000000
shred: 0000000: renamed to 000000
shred: 000000: renamed to 00000
shred: 00000: renamed to 0000
shred: 0000: renamed to 000
shred: 000: renamed to 00
shred: 00: renamed to 0
shred: passwd.txt: removed
常见选项:
默认显示目录内所有层级的目录和文件
-d 只列出所有层级的目录结构, 不显示文件
-L # 指定显示的层级数目
-P pattern 只显示由指定通配符匹配到的路径
[root@demo-c8 ~]# tree -d -L 2 /tmp
/tmp
├── systemd-private-a07e43724f874410b0748e3d9d005f9d-bluetooth.service-phNwvu
│?? └── tmp
├── systemd-private-a07e43724f874410b0748e3d9d005f9d-colord.service-8Pl0aZ
│?? └── tmp
├── systemd-private-a07e43724f874410b0748e3d9d005f9d-ModemManager.service-mSF6wP
│?? └── tmp
├── systemd-private-a07e43724f874410b0748e3d9d005f9d-rtkit-daemon.service-RhHyFa
│?? └── tmp
└── vmware-root_953-3979774151
常见选项:
-p 自动递归创建所需的各层级目录
-v 显示详细信息
-m MODE 创建目录时直接指定权限
常见选项:
-p 递归删除父级空目录, rmdir -p 逆向删除空目录, 父目录如果是空的, 也会被删除
-v 显示详细信息
rmdir只能删除空目录, 如果目录内有内容,则无法删除, 因此rmdir可以用来批量删除空目录
如果想要删除非空目录, 需要用rm -rf, 递归删除目录树
[root@demo-c8 ~]# rm -rf /data
rm: cannot remove '/data': Device or resource busy
[root@demo-c8 ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 100G 0 disk
├─sda1 8:1 0 1G 0 part /boot
├─sda2 8:2 0 40G 0 part /
├─sda3 8:3 0 2G 0 part [SWAP]
├─sda4 8:4 0 1K 0 part
└─sda5 8:5 0 40G 0 part /data # sda5挂载到了/data下, 所以/data是无法被删除的, 只能删除/data里的内容
sr0 11:0 1 7.7G 0 rom
# 仅对rm命令有效, 如果执行rm -rf是会报错的, 因为mv命令没有-rf选项, 所以rm -rf也是无法执行的
alias rm='DIR=/data/backup_`date +%F_%T`; mkdir -p $DIR; mv -t $DIR'
如何创建目录/testdir/dir1/x, /testdir/dir1/y, /testdir/dir1/x/a,/testdir/dir1/x/b,/testdir/dir1/y/a,/testdir/dir1/y/b
mkdir -p /testdir/dir1/{x,y}/{a,b}
[root@demo-c8 ~]# mkdir -p /testdir/dir1/{x,y}/{a,b}
[root@demo-c8 ~]# tree /testdir/dir1
/testdir/dir1
├── x
│ ├── a
│ └── b
└── y
├── a
└── b
如何创建目录/testdir/dir2/x. /testdir/dir2/y, /testdir/dir2/x/a, /testdir/dir2/x/b
mkdir -p /testdir/dir2/x/{a,b}
mkdir -p /testdir/dir2/y
[root@demo-c8 ~]# mkdir -p /testdir/dir2/{x/{a,b},y}
[root@demo-c8 ~]# tree -d /testdir/dir2
/testdir/dir2
├── x
│ ├── a
│ └── b
└── y
如何创建目录/testdir/dir3, /testdir/dir4, /testdir/dir5, /testdir/dir5/dir6, /testdir/dir5/dir7
mkdir -p /testdir/dir{3,4,5/dir{6,7}}
[root@demo-c8 ~]# mkdir -p /testdir/dir{3,4,5/dir{6,7}}
[root@demo-c8 ~]# tree -d /testdir/
/testdir/
├── dir1
│ ├── x
│ │ ├── a
│ │ └── b
│ └── y
│ ├── a
│ └── b
├── dir2
│ ├── x
│ │ ├── a
│ │ └── b
│ └── y
├── dir3
├── dir4
└── dir5
├── dir6
└── dir7
每个文件的属性信息, 比如: 文件的大小, 时间, 类型等, 成为文件的元数据(meta data). 这些元数据是存放在node(index node)表中. node表中有很多条记录组成, 每一条记录对应的存放了一个文件的元数据信息. 而文件名称并不属于一个文件的元数据, 文件名称属于目录的数据部分
每一个node表记录对应的保存了以下信息, 也就是文件的元数据信息:
inode number 节点号
文件类型
权限
UID
GID
链接数(指向这个文件名的名称个数, 硬链接个数)
该文件的大小和不同的时间戳
指向磁盘上文件的数据块指针
有关文件的其他数据
inode 文件节点编号, 整个系统唯一, 用来与其他文件区分开来, 操作系统会自动分配,底层管理文件会使用inode
# -i 选项会显示inode编号
[root@demo-c8 ~]# ls -i
103221107 anaconda-ks.cfg 666292 Downloads 666294 Music 68360890 Public 68360891 Videos
101475423 Documents 101475459 initial-setup-ks.cfg 35080439 Pictures 35080438 Templates
一个硬盘, 可以大致分为两个空间, 一个存放元数据, 另一部分空间存放时间数据.
元数据: 文件属性, 索引, 通过指针指向文件在磁盘真正存放文件的位置
实际数据: 通过指针, 指向文件在磁盘上真正存放的位置
# 1385为文件实际数据大小
[root@demo-c8 ~]# ll -i anaconda-ks.cfg
103221107 -rw-------. 1 root root 1385 Aug 15 17:06 anaconda-ks.cfg
block块: 文件在磁盘存放的最小单元, 一般4kb, 即使一个文件大小不到4kb, 也要占4kb
指针: 通过指针, 指向文件在磁盘上真正存放的位置
直接指针: 直接指向数据在磁盘的存放位置. 直接指针有12个, 每个指针指向一个4k块, 那么最多有12个指针, 指向12个4k文件, 也就是最多有48k的数据可以通过直接指针找到
间接指针: 如果文件大于48k, 比如1M, 那么要使用间接指针
间接指针指向一个索引块, 该索引块并不是数据块, 其大小为4kb, 该索引快被切割成多个相同大小的小块, 每块占4byte, 所以总共有1024个小块. (这个索引块一共4k, 每块占4b, 1kb=1024b, 所以一共有1024个小块)
每个小块就是一个指针, 指向4k大小的空间, 一共1024个指针, 指向总大小为4k*1024=4096kb大小的数据, 也就是指向4M数据, 所以通过间接指针, 最多可以找到4M大小的数据
双重间接指针: 最多指向4G大小, 双重指针包含两个索引块
三重间接指向: 最多指向4T大小, 三重指针包含三个索引快
总结:
单个文件数据小于4k, 用直接指针
单个文件数据大于4k小于4M,用间接指针
单个文件数据大于4M, 双重,三重间接指针
数据文件越大, 找到该文件花费时间越多
目录是个特殊文件, 一般文件存放的东西就是其数据本身, 而目录文件的数据内容保存了此目录中, 文件的列表(文件名), 和文件inode number的对应关系
文件引用的是inode编号
人是通过文件名来引用一个文件
一个目录的实际数据是目录下的文件名和文件名对应inode号之间的映射
文件名是是目录里的内容, 属于目录的数据部分
[root@demo-c8 ~]# ls -i
103221107 anaconda-ks.cfg 666292 Downloads 666294 Music 68360890 Public 68360891 Videos
101475423 Documents 101475459 initial-setup-ks.cfg 35080439 Pictures 35080438 Templates
inode节点表并不保存文件名信息, 也就是说文件元数据不包含文件名, 而是包含, mode权限, owner信息,大小,时间戳,各种时间戳
目录则存放的是里面的文件列表(文件名)和inode节点编号对应信息

一般inode表会占用文件系统磁盘空间的1%. 节点编号不是无限的, 每个分区会有固定的节点编号数量, 用光了就无法创建新的文件和目录了. 分区空间越大, 节点编号越多
df -i 查看磁盘inode使用情况
[root@demo-c8 ~]# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
devtmpfs 989313 443 988870 1% /dev
tmpfs 996355 1 996354 1% /dev/shm
tmpfs 996355 907 995448 1% /run
tmpfs 996355 17 996338 1% /sys/fs/cgroup
/dev/sda2 20971520 119379 20852141 1% /
/dev/sda5 20971520 20 20971500 1% /data
/dev/sda1 65536 309 65227 1% /boot
tmpfs 996355 20 996335 1% /run/user/42
tmpfs 996355 11 996344 1% /run/user/0
当inode不足时, 可以把小文件删了, 释放inode. 如果在一个分区里, 建的都是小文件, 那么就会出现空间大小有剩余, 但是inode不足, 导致无法创建新的文件或目录
访问一个文件的过程: 先在目录里看文件的节点编号, 然后查看节点表, 节点表有节点编号和指针对应关系, 通过节点编号, 找到指针,也就找到了文件在磁盘中的存储位置
No space left on device一般是两种原因, 1. inode用光, 2. 磁盘大小用光
通过`df -i`确定inode是否用光, 还是磁盘空间用光了
df命令还是显示磁盘空间快满了有可能是被删除的文件,正在被访问, 例如应用程序文件, 这时需要找到该文件, 把对应的应用程序关闭, 然后再删除该文件
构建实验环境:
# 先确定磁盘分区使用情况
[root@demo-c8 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 3.8G 0 3.8G 0% /dev
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 3.9G 9.7M 3.8G 1% /run
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/sda2 40G 4.3G 36G 11% /
/dev/sda5 40G 318M 40G 1% /data
/dev/sda1 976M 189M 721M 21% /boot # boot分区还剩721M空间
tmpfs 779M 1.2M 778M 1% /run/user/42
tmpfs 779M 4.0K 779M 1% /run/user/0
# 利用/dev/zero文件, 在/boot分区创建一个测试大文件
[root@demo-c8 ~]# cp /dev/zero /boot/zero.bak
cp: error writing '/boot/zero.bak': No space left on device
[root@demo-c8 ~]# ll -h /boot
-rw-r--r--. 1 root root 772M Aug 19 15:06 zero.bak
[root@demo-c8 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 3.8G 0 3.8G 0% /dev
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 3.9G 9.7M 3.8G 1% /run
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/sda2 40G 4.3G 36G 11% /
/dev/sda5 40G 318M 40G 1% /data
/dev/sda1 976M 960M 0 100% /boot # boot分区被撑满
tmpfs 779M 1.2M 778M 1% /run/user/42
tmpfs 779M 4.0K 779M 1% /run/user/0
# 在另一个窗口, 通过vim打开/boot/zero.bak文件, 模拟文件再被应用程序占用
[root@demo-c8 ~]# vim /boot/zero.bak
# 回到之前的窗口, 通过rm -rf把zero.bak删除
[root@demo-c8 ~]# rm -rf /boot/zero.bak
# 可以看到, 即使zero.bak被删除了, boot分区空间还是没有释放
[root@demo-c8 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 3.8G 0 3.8G 0% /dev
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 3.9G 9.7M 3.8G 1% /run
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/sda2 40G 4.3G 36G 11% /
/dev/sda5 40G 318M 40G 1% /data
/dev/sda1 976M 960M 0 100% /boot
tmpfs 779M 1.2M 778M 1% /run/user/42
tmpfs 779M 4.0K 779M 1% /run/user/0
[root@demo-c8 ~]# ll /boot
total 184388
-rw-r--r--. 1 root root 187648 May 8 2020 config-4.18.0-193.el8.x86_64
drwxr-xr-x. 3 root root 4096 Aug 15 16:53 efi
drwx------. 4 root root 4096 Aug 15 17:05 grub2
-rw-------. 1 root root 98497217 Aug 15 17:03 initramfs-0-rescue-eaab49a3b5f746ae847c443ec9bc62c4.img
-rw-------. 1 root root 50808400 Aug 15 17:06 initramfs-4.18.0-193.el8.x86_64.img
-rw-------. 1 root root 17536677 Aug 15 17:16 initramfs-4.18.0-193.el8.x86_64kdump.img
drwxr-xr-x. 3 root root 4096 Aug 15 17:00 loader
drwx------. 2 root root 16384 Aug 15 16:52 lost+found
-rw-------. 1 root root 3909996 May 8 2020 System.map-4.18.0-193.el8.x86_64
-rwxr-xr-x. 1 root root 8913656 Aug 15 17:02 vmlinuz-0-rescue-eaab49a3b5f746ae847c443ec9bc62c4
-rwxr-xr-x. 1 root root 8913656 May 8 2020 vmlinuz-4.18.0-193.el8.x86_64
步骤1: 通过lsof 命令查询刚被删除的文件是被哪个程序所使用的, 找到进程的pid
# lsof命令会显示正在被打开的文件信息
# lsof | grep deleted, 定位到被删除的那个文件, 找到进程编号
[root@demo-c8 ~]# lsof | grep deleted
#程序名称 #进程编号
vim 4238 root 5r REG 8,1 809349120 308 /boot/zero.bak (deleted)
步骤2: 找到该程序, 关闭进程或者如果是前台运行的程序, 就把运行窗口关了, 然后在df查看, 磁盘空间就会释放了
# 关闭vim程序
[root@demo-c8 ~]# kill -9 4238
boot/zero.bak" Killed
# 再次通过df查看, boot分区空间已经被释放
[root@demo-c8 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 3.8G 0 3.8G 0% /dev
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 3.9G 9.7M 3.8G 1% /run
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/sda2 40G 4.3G 36G 11% /
/dev/sda5 40G 318M 40G 1% /data
/dev/sda1 976M 189M 721M 21% /boot
tmpfs 779M 1.2M 778M 1% /run/user/42
tmpfs 779M 4.0K 779M 1% /run/user/0
方法1: 通过重定向> 要删除的文件名, 把文件清空, 但是只有bash shell支持重定向, 此方法不通用
方法2: 通用方法, cat是外部命令, 不依赖于shell类型
cat /dev/null > 文件名, 这样就可以清空大文件, 大小为0了 空间就释放了
因此正确删除正在运行的大文件, 立即释放空间的方法
cat /dev/null > FILE, 先把文件清空
rm -rf FILE, 再把文件删除
硬链接本质是给文件起一个新的名称, 实质上硬链接和原始文件都是同一个文件, 没有区别
硬链接特性:
ll命令显示的权限和owner中间的数字就是这个文件的硬链接数量, 也就是同一个文件有几个名字格式:
ln 源文件 硬链接文件
[15:07:52 root@centos8-2 /data/prac]#touch f1.txt
[15:07:57 root@centos8-2 /data/prac]#ln f1.txt f2.txt # ln src dest
[15:08:04 root@centos8-2 /data/prac]#ls
f2.txt f1.txt
[15:08:05 root@centos8-2 /data/prac]#ll
total 0
-rw-r--r-- 2 root root 0 Aug 18 15:07 f2.txt
-rw-r--r-- 2 root root 0 Aug 18 15:07 f1.txt
[15:08:19 root@centos8-2 /data/prac]#ll -i
total 0
67109585 -rw-r--r-- 2 root root 0 Aug 18 15:07 f2.txt
67109585 -rw-r--r-- 2 root root 0 Aug 18 15:07 f1.txt
当f1.txt 是 f2.txt的硬链接时, 实际两个文件是同一个文件的不同名字, 两个文件具有相同的元数据, 也就是inode编号,等其他信息,见上, 元数据相同, 指针相同, 指向磁盘中相同的数据空间

为什么rm无法彻底删除磁盘文件?
如果一个文件有多个硬链接, 那么删除硬链接, 仅仅是删除一个文件名, 哪怕把最后一个文件名也给删了, 也是删除的元数据, 节点编号被收回
但是数据还是保存在磁盘相应的位置, 因此只要给对应的磁盘空间分配节点编号,创建元数据和指针就可以重新访问数据了, 这就是rm删除文件后, 可以恢复的逻辑
硬链接缺点:
# root在/分区, data在/data分区, 无法跨分区创建硬链接
[15:38:12 root@centos8-2 /data/prac]#ln /root/.bashrc /data/test.txt
ln: failed to create hard link '/data/test.txt' => '/root/.bashrc': Invalid cross-device link
软链接
格式:
ln -s src dest
ln -s appv1.0 app
ln -s app testapp
[root@demo-c8 data]# mkdir appv1.0
[root@demo-c8 data]# ln -s appv1.0/ app

# 通过软链接和原始目录, 都可以访问到源目录中的文件
[root@demo-c8 data]# touch appv1.0/file{1..9}.log
[root@demo-c8 data]# ll app/
total 0
-rw-r--r--. 1 root root 0 Aug 19 18:46 file1.log
-rw-r--r--. 1 root root 0 Aug 19 18:46 file2.log
-rw-r--r--. 1 root root 0 Aug 19 18:46 file3.log
-rw-r--r--. 1 root root 0 Aug 19 18:46 file4.log
-rw-r--r--. 1 root root 0 Aug 19 18:46 file5.log
-rw-r--r--. 1 root root 0 Aug 19 18:46 file6.log
-rw-r--r--. 1 root root 0 Aug 19 18:46 file7.log
-rw-r--r--. 1 root root 0 Aug 19 18:46 file8.log
-rw-r--r--. 1 root root 0 Aug 19 18:46 file9.log
[root@demo-c8 data]# ll appv1.0/
total 0
-rw-r--r--. 1 root root 0 Aug 19 18:46 file1.log
-rw-r--r--. 1 root root 0 Aug 19 18:46 file2.log
-rw-r--r--. 1 root root 0 Aug 19 18:46 file3.log
-rw-r--r--. 1 root root 0 Aug 19 18:46 file4.log
-rw-r--r--. 1 root root 0 Aug 19 18:46 file5.log
-rw-r--r--. 1 root root 0 Aug 19 18:46 file6.log
-rw-r--r--. 1 root root 0 Aug 19 18:46 file7.log
-rw-r--r--. 1 root root 0 Aug 19 18:46 file8.log
-rw-r--r--. 1 root root 0 Aug 19 18:46 file9.log
# boot_data在/data分区, 而/boot是单独的分区
[root@demo-c8 data]# ll
total 0
lrwxrwxrwx. 1 root root 5 Aug 19 18:55 boot_data -> /boot
[root@demo-c8 data]# touch f1.txt
[root@demo-c8 data]# ll -i f1.txt # ll -i显示inode编号, 不加-i不显示编号, 无论加不加-i都会显示文件的链接数
133 -rw-r--r--. 1 root root 0 Aug 19 18:55 f1.txt # 链接数为1
[root@demo-c8 data]# ln -s f1.txt f11.txt
[root@demo-c8 data]# ll
total 0
lrwxrwxrwx. 1 root root 6 Aug 19 19:01 f11.txt -> f1.txt
-rw-r--r--. 1 root root 0 Aug 19 18:55 f1.txt # 创建软链接f11.txt后, f1链接数还是1
硬链接和原始文件是平等关系, 把原始文件删了, 硬链接还能用
软链接依赖于原始文件, 原始文件删了, 软链接就无法使用了
[root@demo-c8 data]# ln -s f1.txt /boot/f111.txt
[root@demo-c8 data]# ll /boot/f111.txt
lrwxrwxrwx. 1 root root 6 Aug 19 19:03 /boot/f111.txt -> f1.txt

源文件f1.txt在/data目录下, 软链接文件f111.txt在/boot目录下, 因为创建/boot/f111.txt时, 使用的是相对路径指定的源文件, 所以/boot/f111.txt软链接会认为f1.txt这个源文件和自己一样, 在/boot目录, 但是/boot目录是没有f1.txt文件的, 所以就找不到源文件, 会显示红色, 说明找不到源文件
软链接指向的源文件显示红色可能是因为使用了相对路径, 造成软链接文件找不到原始文件, 也可能是因为原始文件被删除了

一般相对路径都是相对于当前目录, 但是在创建软链接时相对路径是相对于软链接文件的路径
# 相对路径创建软连接案例
[root@demo-c8 data]# touch f1.txt # 创建源文件
[root@demo-c8 data]# ll
total 0
-rw-r--r--. 1 root root 0 Aug 19 19:31 f1.txt
[root@demo-c8 data]# ln -s ../data/f1.txt /boot/f11.txt # 根据目标软链接文件所在的目录, 用相对路径书写源文件所在位置. 目标软链接在/boot目录, /boot上一层是/, 根的下一层是/data, 所以原始文件的路径为 ../data/f1.txt
[root@demo-c8 data]# ll /boot/f11.txt
lrwxrwxrwx. 1 root root 14 Aug 19 19:31 /boot/f11.txt -> ../data/f1.txt
用户使用访问软链接/app这个目录
但是软链接/app这个目录实际指向的目录是在发生变化的
当开发出1.0版本时, 可以创建软链接, ln -s /appv1.0 /app
当/appv2.0准备上线时, 只需要把/app这个软链接删除, 重新再建一个/app软链接指向/appv2.0即可
rm -rf /app
ln -s /appv2.0 /app
因为不能把已经存在的文件, 创建成别的文件的软链接, 所以要先把/app删除再重新创建
删除软连链接时容易造成的误操作
删除软链接目录时,不要tab补全
当给一个目录创建了软链接后, 如果我们想要把软链接删除, 这时不能给软链接目录自动补全, 否则系统会把软链接名字替换成真正的目录名字, 然后把真正目录里的内容都删了, 结果就是软链接不会被删, 真实的目录本身也不会被删除, 但是目录内的内容都没了
# 准备原始目录和文件
[root@demo-c8 data]# mkdir appv1.0
[root@demo-c8 data]# touch appv1.0/f{1..9}.txt
[root@demo-c8 data]# ll appv1.0/
total 0
-rw-r--r--. 1 root root 0 Aug 19 19:18 f1.txt
-rw-r--r--. 1 root root 0 Aug 19 19:18 f2.txt
-rw-r--r--. 1 root root 0 Aug 19 19:18 f3.txt
-rw-r--r--. 1 root root 0 Aug 19 19:18 f4.txt
-rw-r--r--. 1 root root 0 Aug 19 19:18 f5.txt
-rw-r--r--. 1 root root 0 Aug 19 19:18 f6.txt
-rw-r--r--. 1 root root 0 Aug 19 19:18 f7.txt
-rw-r--r--. 1 root root 0 Aug 19 19:18 f8.txt
-rw-r--r--. 1 root root 0 Aug 19 19:18 f9.txt
# 创建软链接
[root@demo-c8 data]# ln -s appv1.0/ app
[root@demo-c8 data]# ll app
lrwxrwxrwx. 1 root root 8 Aug 19 19:19 app -> appv1.0/
[root@demo-c8 data]# ll
total 0
lrwxrwxrwx. 1 root root 8 Aug 19 19:19 app -> appv1.0/
drwxr-xr-x. 2 root root 132 Aug 19 19:18 appv1.0
[root@demo-c8 data]# ll app/
total 0
-rw-r--r--. 1 root root 0 Aug 19 19:18 f1.txt
-rw-r--r--. 1 root root 0 Aug 19 19:18 f2.txt
-rw-r--r--. 1 root root 0 Aug 19 19:18 f3.txt
-rw-r--r--. 1 root root 0 Aug 19 19:18 f4.txt
-rw-r--r--. 1 root root 0 Aug 19 19:18 f5.txt
-rw-r--r--. 1 root root 0 Aug 19 19:18 f6.txt
-rw-r--r--. 1 root root 0 Aug 19 19:18 f7.txt
-rw-r--r--. 1 root root 0 Aug 19 19:18 f8.txt
-rw-r--r--. 1 root root 0 Aug 19 19:18 f9.txt
# 删除app软链接, 并且补全路径分隔符
[root@demo-c8 data]# rm -rf app/ # 补全了分隔符, 会把原始目录内的文件全部删除, 但是软链接目录和原始目录本身会保留
[root@demo-c8 data]# ll
total 0
lrwxrwxrwx. 1 root root 8 Aug 19 19:19 app -> appv1.0/
drwxr-xr-x. 2 root root 6 Aug 19 19:20 appv1.0
[root@demo-c8 data]# ll app/
total 0
[root@demo-c8 data]# ll appv1.0/
total 0
# 在appv1.0中, 先把删除的文件创建出来
[root@demo-c8 data]# touch appv1.0/f{1..9}.txt
[root@demo-c8 data]# ll app
app/ appv1.0/
[root@demo-c8 data]# ll appv1.0/
total 0
-rw-r--r--. 1 root root 0 Aug 19 19:22 f1.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f2.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f3.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f4.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f5.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f6.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f7.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f8.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f9.txt
# 删除时, 不给软链接目录补全路径分隔符
[root@demo-c8 data]# rm -rf app
[root@demo-c8 data]# ll
total 0
drwxr-xr-x. 2 root root 132 Aug 19 19:22 appv1.0 # 这样软链接目录自己会被删除, 而原始目录和文件都会被保存
[root@demo-c8 data]# ll appv1.0/
total 0
-rw-r--r--. 1 root root 0 Aug 19 19:22 f1.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f2.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f3.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f4.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f5.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f6.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f7.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f8.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f9.txt
[root@demo-c8 data]# rm -rf /tmp/*
[root@demo-c8 data]# ls /tmp
[root@demo-c8 data]# cp -av appv1.0/ /tmp
'appv1.0/' -> '/tmp/appv1.0'
'appv1.0/f1.txt' -> '/tmp/appv1.0/f1.txt'
'appv1.0/f2.txt' -> '/tmp/appv1.0/f2.txt'
'appv1.0/f3.txt' -> '/tmp/appv1.0/f3.txt'
'appv1.0/f4.txt' -> '/tmp/appv1.0/f4.txt'
'appv1.0/f5.txt' -> '/tmp/appv1.0/f5.txt'
'appv1.0/f6.txt' -> '/tmp/appv1.0/f6.txt'
'appv1.0/f7.txt' -> '/tmp/appv1.0/f7.txt'
'appv1.0/f8.txt' -> '/tmp/appv1.0/f8.txt'
'appv1.0/f9.txt' -> '/tmp/appv1.0/f9.txt'
[root@demo-c8 data]# ll /tmp
total 0
drwxr-xr-x. 2 root root 132 Aug 19 19:22 appv1.0
[root@demo-c8 data]# ll /tmp/appv1.0/
total 0
-rw-r--r--. 1 root root 0 Aug 19 19:22 f1.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f2.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f3.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f4.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f5.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f6.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f7.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f8.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f9.txt
[root@demo-c8 data]# rm -rf /tmp/*
[root@demo-c8 data]# ll /tmp
total 0
[root@demo-c8 data]# cp -av appv1.0 /tmp
'appv1.0' -> '/tmp/appv1.0'
'appv1.0/f1.txt' -> '/tmp/appv1.0/f1.txt'
'appv1.0/f2.txt' -> '/tmp/appv1.0/f2.txt'
'appv1.0/f3.txt' -> '/tmp/appv1.0/f3.txt'
'appv1.0/f4.txt' -> '/tmp/appv1.0/f4.txt'
'appv1.0/f5.txt' -> '/tmp/appv1.0/f5.txt'
'appv1.0/f6.txt' -> '/tmp/appv1.0/f6.txt'
'appv1.0/f7.txt' -> '/tmp/appv1.0/f7.txt'
'appv1.0/f8.txt' -> '/tmp/appv1.0/f8.txt'
'appv1.0/f9.txt' -> '/tmp/appv1.0/f9.txt'
[root@demo-c8 data]# ll /tmp
total 0
drwxr-xr-x. 2 root root 132 Aug 19 19:22 appv1.0
[root@demo-c8 data]# ll /tmp/appv1.0/
total 0
-rw-r--r--. 1 root root 0 Aug 19 19:22 f1.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f2.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f3.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f4.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f5.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f6.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f7.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f8.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f9.txt
[root@demo-c8 data]# rm -rf /tmp/*
[root@demo-c8 data]# ll /tmp
total 0
[root@demo-c8 data]# cp -av appv1.0/* /tmp
'appv1.0/f1.txt' -> '/tmp/f1.txt'
'appv1.0/f2.txt' -> '/tmp/f2.txt'
'appv1.0/f3.txt' -> '/tmp/f3.txt'
'appv1.0/f4.txt' -> '/tmp/f4.txt'
'appv1.0/f5.txt' -> '/tmp/f5.txt'
'appv1.0/f6.txt' -> '/tmp/f6.txt'
'appv1.0/f7.txt' -> '/tmp/f7.txt'
'appv1.0/f8.txt' -> '/tmp/f8.txt'
'appv1.0/f9.txt' -> '/tmp/f9.txt'
[root@demo-c8 data]# ll /tmp
total 0
-rw-r--r--. 1 root root 0 Aug 19 19:22 f1.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f2.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f3.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f4.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f5.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f6.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f7.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f8.txt
-rw-r--r--. 1 root root 0 Aug 19 19:22 f9.txt
readlink: 判断软链接指向的原始文件, 后面必须跟的是软链接, 否则没有返回结果, 脚本中会使用, 查看软链接指向的原始文件路径
针对目录创建软链接时, 源目录和目标目录都无需/补全, 删除软链接目录时, 不要补全/
硬链接: 本质是同一个文件, 起了多个名字
软链接: 本质不是同一个文件
硬链接: 不支持
软链接: 支持
硬链接: inode相同, 因为本质是同一个文件
软链接: inode不同, 因为本质不是同一个文件
硬链接: 创建新的硬链接, 链接数会增加, 删除硬链接, 链接数减少
软链接: 创建或删除, 链接数不会变化
一个文件的链接数, 指的是硬链接数量, 也就是一个文件有几个名
硬链接: 不支持
软链接: 支持
硬链接: 原始文件相对路径是相对于当前工作目录
软链接: 原始文件的相对路径是相对于链接文件的相对路径
硬链接: 只是链接数减1, 但是链接文件的访问不受影响
软链接: 链接文件将无法访问
硬链接: 和源文件相同
软链接: 链接文件和源文件无关
程序: 指令+数据
读入数据: Input
输出数据: Output
文件描述符: 打开的文件都有一个fd, file descriptor
Linux给程序提供了三个设备, 标准输入, 标准输出, 标准错误, 用文件描述符0,1,2 分别表示, 这三个描述符对应的设备实际是由当前终端窗口实现, 依靠终端窗口来实现, 输入, 输出和错误
当前终端窗口不同, 文件描述符指向的窗口也不同
因此每个窗口都是有独立的文件描述符, 每个窗口内操作的命令不影响其他窗口
范例: 文件描述符
[root@demo-c8 ~]# ll /dev/std*
lrwxrwxrwx. 1 root root 15 Aug 19 11:41 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx. 1 root root 15 Aug 19 11:41 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx. 1 root root 15 Aug 19 11:41 /dev/stdout -> /proc/self/fd/1
[17:07:05 root@centos8-2 ~]#ll /dev/std*
lrwxrwxrwx 1 root root 15 Aug 18 16:34 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Aug 18 16:34 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Aug 18 16:34 /dev/stdout -> /proc/self/fd/1
[17:07:11 root@centos8-2 ~]#ll /proc/self/fd
total 0
lrwx------ 1 root root 64 Aug 18 17:07 0 -> /dev/pts/0 # 当前终端的0,1,2标准输入, 输出, 错误都是指向终端pts/0
lrwx------ 1 root root 64 Aug 18 17:07 1 -> /dev/pts/0
lrwx------ 1 root root 64 Aug 18 17:07 2 -> /dev/pts/0
lr-x------ 1 root root 64 Aug 18 17:07 3 -> /var/lib/sss/mc/passwd
lrwx------ 1 root root 64 Aug 18 17:07 4 -> 'socket:[32968]'
lr-x------ 1 root root 64 Aug 18 17:07 5 -> /var/lib/sss/mc/group
lr-x------ 1 root root 64 Aug 18 17:07 6 -> /proc/1449/fd
[17:07:14 root@centos8-2 ~]#tty
/dev/pts/0 # 当前使用的终端是pts/0, 所以, 在当前终端执行的命令的结果, 已经输入的命令都是只显示在当前终端
[root@demo-c8 ~]# ls # ls的输出为标准输出, fd=1, 显示在当前终端
anaconda-ks.cfg Desktop Documents Downloads initial-setup-ks.cfg Music Pictures Public Templates Videos
[root@demo-c8 ~]# rm anaconda-ks.cfg
rm: remove regular file 'anaconda-ks.cfg'? n # rm的提示为标准输入, 需要用户在当前终端输入信息
[root@demo-c8 ~]# xxx
bash: xxx: command not found... # 错误信息为标准错误, 也是显示在当前终端
Failed to search for file: cannot update repo 'AppStream': Cannot prepare internal mirrorlist: No URLs in mirrorlist
[17:17:49 root@centos8-2 ~]#rm anaconda-ks.cfg > /dev/pts/1
rm: remove regular file 'anaconda-ks.cfg'?
[root@demo-c8 data]# rm test.txt 2> /dev/null
y
[root@demo-c8 data]# ll
total 8
-rw-r--r--. 1 root root 60 Aug 19 20:48 all.log
-rw-r--r--. 1 root root 732 Aug 19 20:49 all.txt
重定向就是把输入,输出或者错误对应的设备进行改变, 由原本的窗口比如pts/0, 转移到pts/1, 这就是重定向. 重定向也可以把输入输出和错误, 定向到文件中
[17:07:17 root@centos8-2 ~]#tty
/dev/pts/0
[17:15:45 root@centos8-2 ~]#hostname > /dev/pts/1
[17:15:58 root@centos8-2 ~]#
[17:09:31 root@centos8-2 ~]#tty
/dev/pts/1
[17:15:48 root@centos8-2 ~]#centos8-2.linux
STDOUT和STDERR可以被重新定向到指定文件, 而非默认的当前终端
格式:
命令 操作符合 文件名
支持的操作符号包括:
1> 或 > 把标准输出STDOUT重定向到指定文件
2> 把标准错误STDERR重定向到指定文件
&> 把标准输出和错误都重定向到指定文件
>& 和&>功能一样, 建议用&>
[17:27:18 root@centos8-2 /data/prac]#clear
[17:27:19 root@centos8-2 /data/prac]#ls /data /dddd > r.txt 2> w.txt
[17:27:46 root@centos8-2 /data/prac]#cat r.txt
/data:
prac
scripts
testing_scripts
[17:27:48 root@centos8-2 /data/prac]#cat w.txt
ls: cannot access '/dddd': No such file or directory
set -C 禁止覆盖, 但可以追加, 不过利用 >| 操作符仍可以强制覆盖
set +C 允许覆盖, 默认就是允许覆盖
追加: >>, 在原有内容基础上, 追加新的内容
把输出和错误重新定向追加到文件中
>> 追加标准输出重定向到文件
2>> 追加标准错误重定向到文件
&> 覆盖重定向
&>> 追加重定向
CMD > test.txt 2>&1
CMD 2> test.txt 1>&2
CMD &> test.txt
vs
CMD 2>&1 > test.txt
前三种实现的效果相同, 都是把输出和错误重定向到test.txt文件中
先把标椎输出重定向到一个文件里, 这样这个文件就生成了
然后再把错误输出重定向到标准输出, 此前标准输出已经是被重定向到test.txt文件
因此这个顺序可以实现标准输出和错误输出都重定向到test.txt文件
第四种写法会有不同结果
如果先把错误输出重定向到标准输出, 这时候还没有文件存放标准输出
因此错误输出直接打印在屏幕, 之后 > test.log将标准输出重定向到文件里
所以这种方法, 错误会直接输出在终端, 只有输出被重定向到了test.txt

[17:27:50 root@centos8-2 /data/prac]#ls /opt /xxx > test1.log 2>&1
[17:33:02 root@centos8-2 /data/prac]#cat test1.log
ls: cannot access '/xxx': No such file or directory
/opt:
[17:33:05 root@centos8-2 /data/prac]#ls /opt /xxx 2>&1 > test1.log
ls: cannot access '/xxx': No such file or directory
[17:33:18 root@centos8-2 /data/prac]#cat test1.log
/opt:
范例: 标准错误重定向
[root@demo-c8 ~]# rm /data/f1.log 2> /data/all.log # 重定向的文件会自动生成
[root@demo-c8 ~]# cat /data/all.log
rm: cannot remove '/data/f1.log': No such file or directory
范例: 合并多个命令的结果到一个文件
# 方法1: 小括号
[root@demo-c8 ~]# (cat /etc/issue; cat /etc/fstab) > /data/all.txt
[root@demo-c8 ~]# cat /data/all.txt
\S
Kernel \r on an \m
#
# /etc/fstab
# Created by anaconda on Mon Aug 15 16:52:19 2022
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
UUID=b1ab1ace-2582-4afd-8693-39bd9855041c / xfs defaults 0 0
UUID=d5131695-82b3-4a23-bc28-5c8a4bf381a0 /boot ext4 defaults 1 2
UUID=bdd66510-e510-4fe7-ba71-e2a35e6dc492 /data xfs defaults 0 0
UUID=05c944fb-d6f9-4544-ba10-8b7bf3cc8fed swap swap defaults 0 0
# 方法2: 花括号
[root@demo-c8 ~]# { ls;hostname; } > /data/test.txt
[root@demo-c8 ~]# cat /data/test.txt
anaconda-ks.cfg
Desktop
Documents
Downloads
initial-setup-ks.cfg
Music
Pictures
Public
Templates
Videos
demo-c8.demo
范例: 清空大文件
cat /dev/null /data/big_file.log
范例: 输出和错误分别重定向
ls /data /xxx > /data/out.log 2> /data/err.log
从文件中导入STDIN, 代替当前终端的输入设备, 使用<来重定向标准输入, 某些命令能够接受从文件中导入的STDIN
当命令执行时, 需要手动输入额外信息时, 可以借助标准输入重定向, 把需要手动输入的信息, 放到一个文件里, 通过标准输入把信息传递给执行的命令. 把人机交互的命令,变成非交互式批量执行
使用标准输入, 要求命令接受标准输入
# rm支持标准输入
[root@demo-c8 data]# echo y > rm.txt
[root@demo-c8 data]# rm aa.txt < rm.txt
rm: remove regular file 'aa.txt'? [root@demo-c8 data]# ll
total 28
-rw-r--r--. 1 root root 60 Aug 19 20:48 all.log
-rw-r--r--. 1 root root 732 Aug 19 20:49 all.txt
-rw-r--r--. 1 root root 7 Aug 19 21:35 a.txt
-rw-r--r--. 1 root root 5 Aug 19 21:40 b.txt
-rw-r--r--. 1 root root 2 Aug 19 21:48 rm.txt
-rw-r--r--. 1 root root 52 Aug 19 21:26 tr.log
-rw-r--r--. 1 root root 4 Aug 19 21:24 tr.txt
[19:58:56 root@centos8-2 /data/prac]#echo 1+2+3+4 > bc.txt
[20:05:15 root@centos8-2 /data/prac]#bc < bc.txt
10
[20:05:46 root@centos8-2 /data/prac]#cat < bc.txt > bc2.txt
[20:05:51 root@centos8-2 /data/prac]#cat bc2.txt
1+2+3+4
连续数字求和
seq -s+ NUMBER
Usage: seq [OPTION]... LAST
or: seq [OPTION]... FIRST LAST
or: seq [OPTION]... FIRST INCREMENT LAST
seq
-s, --separator=STRING use STRING to separate numbers (default: \n)
[20:07:19 root@centos8-2 /data/prac]#seq -s+ 100
1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40+41+42+43+44+45+46+47+48+49+50+51+52+53+54+55+56+57+58+59+60+61+62+63+64+65+66+67+68+69+70+71+72+73+74+75+76+77+78+79+80+81+82+83+84+85+86+87+88+89+90+91+92+93+94+95+96+97+98+99+100
[20:08:21 root@centos8-2 /data/prac]#seq -s+ 100 | bc
5050
[root@demo-c8 data]# seq -s+ 100 > cal.txt
[root@demo-c8 data]# bc < cal.txt
5050
cat支持标准输入重定向, 读进来什么, 就输出什么
[root@demo-c8 data]# seq -s+ 100 > a.txt
[root@demo-c8 data]# cat < a.txt > b.txt # 把a文件内容读到cat里, 再输出给b
[root@demo-c8 data]# cat b.txt
1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40+41+42+43+44+45+46+47+48+49+50+51+52+53+54+55+56+57+58+59+60+61+62+63+64+65+66+67+68+69+70+71+72+73+74+75+76+77+78+79+80+81+82+83+84+85+86+87+88+89+90+91+92+93+94+95+96+97+98+99+100
[20:13:37 root@centos8-2 /data/prac]#cat a.txt
Tue Aug 18 19:58:54 AEST 2020
root
root pts/0 2020-08-18 16:36 (10.0.0.1)
[20:13:39 root@centos8-2 /data/prac]#cat < a.txt > a.txt
[20:13:46 root@centos8-2 /data/prac]#cat a.txt
[20:13:48 root@centos8-2 /data/prac]#
tr命令用于转换和删除字符, 接受标准输入
tr [OPTION]... SET1 [SET2]
SET1表示第一字符串, 包含要替换哪些数字和字母, SET2为第二字符集, 包含修改后的字母或数字
SET1和SET2的字符或数字, 一一对应修
默认, 如果SET1的个数大于SET2, 那么SET1的最后一位会取SET2最后一位的值. 如果加了-t选项, 那么就是一一对应修改, 多出来的字符不会被修改
[:digit:] 相当于0-9, 表示任意单个数字, 范围是0-9
[:lower:] 任意一个小写字母, 和[a-z]不等价
[:upper:] 任意一个大写字母, 和[A-Z]不等价
[:alpha:] 任意一个大写或小写字母
[:blank:] 任意一个水平空白字符
[:space:] 任意一个水平或垂直空白字符
[:punct:] 任意一个标点符号
[:print:] 任意一个可打印字符
[:cntrl:] 任意一个控制(非打印)字符
[:graph:] 图形字符
[:xdigit:] 任意一个16进制字符
显示指定字符集的补集
范例: tr不加选项, 可以实现字符替换, 1-a, 2-b, 3-c, 默认从标准输入读取数据, 输出到标准输出
[20:13:48 root@centos8-2 /data/prac]#tr 123 abc
1a2b3c
aabbcc
1A2B3C
aAbBcC
# 大小写转换
[root@demo-c8 data]# echo {a..z} > lower.txt
[root@demo-c8 data]# tr [a-z] [A-Z] < lower.txt > upper.txt # tr中[a-z]表示小写, [A-Z]是大写, 这里并不是通配符, 因为通配符针对的是文件, 而tr是针对标准输入传进来的内容做修改.
# tr的SET字符集有多种写法, 可以是[a-z], 也可以是'a-z', 都表示范围内的字符
[root@demo-c8 data]# cat upper.txt
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
# 当需要替换的字符个数, 大于替换后的字符个数时, 被替换的最后一个字符的值会按照替换后的最后一个字符取值, 这里4会变成c
[root@demo-c8 data]# tr 1234 abc
1234
abcc
# tr接受标准输入重定向, 可以把输入的内容, 写到文件里, 然后通过标准输入, 传给tr命令. 但此时, tr仅仅是把标准输入里的字符, 进行转换, 然后显示到标准输出上, 并不会修改标准输入的文件内容
[root@demo-c8 data]# cat tr.txt
ABC
[root@demo-c8 data]# tr ABC 123 < tr.txt
123
[root@demo-c8 data]# cat tr.txt
ABC
[20:27:09 root@centos8-2 /data/prac]#echo {a..z} > tr.log
[20:28:09 root@centos8-2 /data/prac]#tr [a-z] [A-Z] < tr.log
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
把标准输入中的abc删除, 如果通过文件标准输入传个tr, 那么并不会真把文件内容修改, 只是转换或者删除后显示在屏幕而已
[20:28:30 root@centos8-2 /data/prac]#tr -d abc < tr.log
d e f g h i j k l m n o p q r s t u v w x y z
把重复且连续的字符(数字和字母和符号)压缩成单个字符, 通常用于压缩空格, 比如配合df命令
[20:30:56 root@centos8-2 /data/prac]#tr -s abc # 只会压缩连续重复的a, b和c
aaaabbbbccccggggaaakkk
abcggggakkk
[20:33:06 root@centos8-2 /data/prac]#tr -s ab12AB
11223311212AABBABA
12331212ABABA
[20:34:25 root@centos8-2 /data/prac]#df | tr -s " " # 压缩空格
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 904560 0 904560 0% /dev
tmpfs 921340 0 921340 0% /dev/shm
tmpfs 921340 8912 912428 1% /run
tmpfs 921340 0 921340 0% /sys/fs/cgroup
/dev/sda2 104806400 2392860 102413540 3% /
/dev/sda5 101660164 741948 100918216 1% /data
/dev/sda1 999320 137624 792884 15% /boot
tmpfs 184268 0 184268 0% /run/user/0
[20:34:45 root@centos8-2 /data/prac]#tr -s " " < df.log
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 904560 0 904560 0% /dev
tmpfs 921340 0 921340 0% /dev/shm
tmpfs 921340 8912 912428 1% /run
tmpfs 921340 0 921340 0% /sys/fs/cgroup
/dev/sda2 104806400 2392860 102413540 3% /
/dev/sda5 101660164 741948 100918216 1% /data
/dev/sda1 999320 137624 792884 15% /boot
tmpfs 184268 0 184268 0% /run/user/0
利用tr -d把回车键\r删除,这样Windows格式就变成了Linux格式

[root@demo-c8 data]# cat a.txt
a
b
c[root@demo-c8 data]# file a.txt
a.txt: ASCII text, with CRLF line terminators # CRLF表示带有回车0d(\r)的Windows文件
[root@demo-c8 data]# tr -d '\r' < a.txt > b.txt
[root@demo-c8 data]# cat b.txt
a
b
c[root@demo-c8 data]# file b.txt
b.txt: ASCII text
[root@demo-c8 data]# hexdump -C a.txt
00000000 61 0d 0a 62 0d 0a 63 |a..b..c|
00000007
[root@demo-c8 data]# hexdump -C b.txt
00000000 61 0a 62 0a 63 |a.b.c|
00000005
利用cat命令实现, 每输入一行,摁回车,输入信息就重定向到文件里
单行重定向只能实现一次重定向一行, 无法批量重定向
输入第一行, 按回车, 查看f1.txt


输入第二行, 按回车, 查看f1.txt


cat命令也可以实现多行重定向, 多行重定向的终止符可以是任何字符, 但是前后必须完全一致
下面案例中, 终止符是efo, 但其可以是任何字符组合, 但是最后一行的结束符必须和起始一致且不能有额外符号, 比如空格
# 默认情况, 会把输入的多行数据, 显示在标准输出
[20:50:29 root@centos8-2 /data/prac]#cat <<efo
> 123
> 456
> efo
123
456
# 也可以把输入的多行数据, 输出到文本
[root@demo-c8 data]# cat > f2.txt <<EOF
> line1
> line2
> line3
> line4
> EOF
[root@demo-c8 data]# cat f2.txt
line1
line2
line
line4
范例: 生成配置文件, 一般直接写到脚本里
[20:58:15 root@centos8-2 /data/prac]#cat > httpd.cnf <<EOF
> [httpd]
> dir=/data
> EOF
[20:58:31 root@centos8-2 /data/prac]#cat httpd.cnf
[httpd]
dir=/data
[20:58:15 root@centos8-2 /data/prac]#cat > httpd.cnf <<-EOF #在脚本里,可以加个-解决文本对齐问题
在Linux中利用特定邮箱往外发邮件
需要Linux安装mailx包, 然后再发件邮件上开启授权, 这里演示利用QQ邮箱向外发邮件,这样就可以以指定的邮箱给任何邮箱发邮件了
[20:58:35 root@centos8-2 /data/prac]#mail -s IloveLinux abc@123.com
i love linux
ha ha ha
. #'.'是邮件结束符
EOT
[21:03:44 root@centos8-2 /data/prac]#No configuration file found at /root/.esmtprc or /etc/esmtprc
如果只像上面那样操作是发不出去的, 因为Linux发邮件,需要特定的服务
而Linux收的邮件是存在 /var/spool/mail/ 对应用户目录下
登录到QQ邮箱, 获取发邮件的授权码
编辑.mairc文件, 放到用户家目录下, 这样只有对应的用户登录时才能使用发邮件的功能, 放到/etc/mail.rc则对所有用户有效
不过, 这个要看邮件应用是以谁的身份来运行, 比如mailx是以root身份运行, 那么不管是把.mailrc放在root家目录还是其他用户家目录, 其他用户都可以利用mail发邮件,因为最终运行程序的是root, mailx会调用root家目录下的mailrc文件. 如果应用是以别的用户身份运行, 那么就会去对应的用户家目录找mailrc文件. 如果想对所有用户都有效, 就放到/etc/mail.rc
[21:23:36 root@centos8-2 ~]#cat .mailrc
set from=abc@123.com #邮件以哪个地址发送
set smtp=smtp.qq.com #腾旭qq邮箱服务器
set smtp-auth-user=abc@123.com #qq邮箱
set smtp-auth-password=fpwmwpjcjcmobfad #授权码
set smtp-auth=login
set smtp-verity=ignore
[21:28:11 root@centos8-2 ~]#yum provides mailx
Last metadata expiration check: 1:39:26 ago on Tue 18 Aug 2020 07:48:53 PM AEST.
mailx-12.5-29.el8.x86_64 : Enhanced implementation of the mailx command
Repo : @System
Matched from:
Provide : mailx = 12.5-29.el8
yum -y install mailx
mailx-12.5-29.el8.x86_64 : Enhanced implementation of the mailx command
Repo : BaseOS
Matched from:
Provide : mailx = 12.5-29.el8
[21:28:19 root@centos8-2 ~]#rpm -ql mailx
/bin/mail
/bin/mailx
/etc/mail.rc
...
[21:28:57 root@centos8-2 ~]#echo linuxtest > mail.txt
[21:30:16 root@centos8-2 ~]#mail -s testmail abc@123.com < mail.txt # -s: 指定邮件标题
或者利用多行重定向
[21:31:55 root@centos8-2 ~]#mail -s testmail2 abc@123.com << EOF
> i love linux
> ha ha ha
> EOF
格式: CMD 1 | CMD 2 | CMD3...
CMD 1必须有标准输出, 否则无法传给管道,因为管道只接收标准输出
CMD 2必须支持标准输入
原本需要标准输入才能执行的命令, 可以利用管道, 将输入信息, 通过管道传给命令, 也就是原本需要标出输入信息才能执行的命令, 都可以通过管道把信息传给该命令, 不需要人机交互执行
[root@demo-c8 data]# seq -s+ 100 | bc
5050
cat /etc/issue | mail -s lalala abc@123.com
[root@demo-c8 data]# echo hello | tr 'a-z' 'A-Z'
HELLO
或者如果不确定前面命令是否会有错误输出, 可以使用 CMD 2>&1 | tr 'a-z' 'A-Z', 把错误先重定向到标准输出,再传给管道
或者 使用xxx |& tr 'a-z' 'A-Z'
[10:17:30 root@centos8-2 ~]#xxx | tr 'a-z' 'A-Z' #正常情况, 错误输出不会传给管道. 因为如果传给管道了, 那么小写字母就会被tr转为大写了
-bash: xxx: command not found
[10:17:18 root@centos8-2 ~]#xxx 2>&1 | tr 'a-z' 'A-Z #添加了 2>&1将错误输出先重'定向到标准输出, 再传给管道. 这样错误输出也可以被传个管道做处理
-BASH: XXX: COMMAND NOT FOUND
[10:17:23 root@centos8-2 ~]#xxx |& tr 'a-z' 'A-Z' #添加了 |& 将错误输出先重定向到标准输出, 再传给管道
-BASH: XXX: COMMAND NOT FOUND
管道可以多次处理
# 该--stdin仅在红帽系统支持
[root@demo-c8 data]# echo "0000" | passwd --stdin wang
Changing password for user wang.
passwd: all authentication tokens updated successfully.
[10:21:45 root@centos8-2 ~]#xxx |& tr 'a-z' 'A-Z' | tr -d ':'
-BASH XXX COMMAND NOT FOUND
echo wang:000000 | chpasswd
重定向和管道仅能实现单一的结果展示方式, 要么把结果输出到标准输出, 在终端展示, 要么重定向到文件里
tee命令既能把输出, 重定向到文件, 也能把输出打印在屏幕上
想把命令结果重定向到文件, 也想看看命令输出结果是什么, 可以用tee命令
如果输出文件存在, 默认会覆盖, tee -a 则追加
格式:
CMD | tee FILE/TO/PATH
[10:29:36 root@centos8-2 ~]#ls | tee /data/prac/ls.log
anaconda-ks.cfg
mail.txt
test.txt
[10:29:42 root@centos8-2 ~]#cat /data/prac/ls.log
anaconda-ks.cfg
mail.txt
test.txt
eg: 利用cat 多行重定向, 编辑文件, 既能把标准输入重定向到文件, 也能在屏幕看到输入内容
[10:29:50 root@demo-c8 ~]#cat << EOF > file.log
> ert
> dfg
> EOF
[root@demo-c8 data]# cat file.log
ert
dfg
[10:32:43 root@demo-c8 ~]#cat << EOF | tee file1.log
> lalala
> hahaha
> ooo
> EOF
lalala
hahaha
ooo
[root@demo-c8 data]# cat file1.log
lalala
hahaha
ooo
-的作用, 把网络上的文件内容显示在屏幕上而非下载到文件里[10:52:07 root@centos8-2 ~]#curl http://abc.123.com/testdir/hello.sh #curl是专门的字符界面浏览器命令
#!/bin/bash
#经典写法
echo "hello, world"
#流行写法
echo 'Hello, world!'
# wget不加选项, 默认把文件下载到当前目录, 同时输出wget命令的输出到屏幕
# -q不显示wget自己的输出信息
# -O 支持把下载的内容写到文档或输出到屏幕, -O -, 把内容打印到标准输出, -O FILE, 输出到指定文件, 文件名可以自己指定
# -O - 文件内容输出到屏幕
# -P 把文件下载到指定目录, 无法修改源文件名
[10:54:10 root@centos8-2 ~]#wget -qO - http://abc.123.com/testdir/hello.sh # wget -qO - 间接实现浏览器功能, 把网上的文件显示到终端
#!/bin/bash
#经典写法
echo "hello, world"
#流行写法
echo 'Hello, world!'
[root@demo-c8 data]# wget -O - http://abc.123.com/testdir/hello.sh 2>/dev/null # 把wget命令本身的输出信息重定向到/dev/null
#!/bin/bash
#经典写法
echo "hello, world"
#流行写法
echo 'Hello, world!
显示/etc目录下, 所有以l开头, 以一个小写字母结尾, 且中间出现至少一位数字的文件或目录列表
ls /etc/l*[0-9]*[[:lower:]] -d
显示/etc目录下, 以任意一位数字开头, 且以非数字结尾的文件或目录列表
ls /etc/[0-9]*[^0-9] -d
显示/etc目录下, 以非字母开头, 后面跟了一个字母及其他任意长度任意字符的文件或目录列表
ls /etc/[^[:alpha:]][[:alpha:]]* -d
显示/etc目录下, 所有以rc开头, 并且后面是0-6之间的数字, 其他为任意字符的文件或目录列表
ls /etc/rc[0-6]* -d

显示/etc目录下, 所有以.conf结尾, 且以m,n,r,p开头的文件或目录列表
ls /etc/[mnrp]*.conf -d

只显示/root下的隐藏文件和目录列表
ls /root/.* -d

只显示/etc下的非隐藏目录列表
ls -ld /etc/[^.]* | grep ^d
ls -d /etc/[^.]*/ # Linux中, 目录是以/结尾的, 而文件的结尾没有/, 所以使用通配符管理文件和目录时, 可以按照结尾是否有/来区分文件和目录

计算, 1-100, 奇数和偶数之和
# seq START INCREMENT STOP
[root@demo-c8 data]# seq -s+ 1 2 100 | bc
2500
[root@demo-c8 data]# seq -s+ 2 2 100 | bc
2550
[root@demo-c8 data]# echo {1..100..2}
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99
[root@demo-c8 data]# echo {1..100..2} | tr -s " " "+" | bc
2500
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
我正在使用i18n从头开始构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在rubyonrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信
我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A