Linux 文件命令
文件与目录
witch
没有这个 witch (巫婆) 命令啦,老是将 which (哪一个) 打成 witch。
那卡住了怎么办? ls 应该记得起来吧,另再记两个目录 /bin、/usr/bin。
$ls \bin\w*
ls: cannot access 'binw*': No such file or directory/)。$ls /bin/w*
/bin/wdctl  /bin/which  /bin/whiptail好!看到了 which 是在 /bin/which。
/bin/which 去找 which/bin/which which/usr/bin/which
疑?用 /bin/which 去找 which 结果是 /usr/bin/which。
path。$echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin原来运行 which 时是按 path 搜索,先找 /usr/bin 再找 /bin,缺省行为是找到后就不再继续运行。
which 有没有可以找出全部的 path 的参数?$which -h
Illegal option -h
Usage: /usr/bin/which [-a] args$which --help Illegal option -h Usage: /usr/bin/which [-a] args
-a 吧,一个说明都要这么省。which -a which/usr/bin/which /bin/which
/usr/bin/which$ls /usr/bin/which -l
lrwxrwxrwx 1 root root 10 2019-10-21 13:23 /usr/bin/which -> /bin/which/usr/bin/which 是链接至 /bin/which,不过这里有点疑问,linux 已经把 /bin 纳入 PATH 了,
不知道为什么还要在 /usr/bin 做链接,也许是要让学习 linux 困难一点?
journalctl 这个命令这么长,老是忘记,来一个 ls 吧!$ls /bin/j*
/bin/journalctljournalctl 又有链接? 幸好没有,要不然全乱了。$which -a journalctl
/bin/journalctlwhich 太方便了,好吧!建一个 Windows which。
@setlocal @set P2=.;%PATH% @for %%e in (%PATHEXT%) do @for %%i in (%~n1%%e) do @if NOT "%%~$P2:i"=="" echo %%~$P2:i
不过也不需要啦,Windows 用 where 即可。
ls 查看目录与文件
ls [选项] [文件或目录]
| 
 | 以每行列出详细数据 | 
| 
 | 以高可读性显示文件容量大小 (如 1K 2M 3G)。 | 
| 
 | 显示所有文件,含隐藏档。 | 
| 
 | 显示所有文件,但不包括  | 
| 
 | 列出该目录而不是目录内的文件。 | 
| 
 | 递归,含目录内的所有文件。 | 
| 
 | 排序时倒序。 | 
| 
 | 依时间排序。 | 
| 
 | 依文件容量大小排序。 | 
| 
 | 加入指示字符,如将目录后置  | 
| 
 | 列出实际保存于文件系统中的索引码,可参阅后文的硬链接。 | 
export TIME_STYLE=long-iso
for F in $(ls *.txt); do \
echo $F; \
donecp 拷贝
cp [参数] 来源 目的
| 
 | 递归,含目录内的所有文件。 | 
| 
 | 拷贝文件 (或目录) 的拥有者及群组 (ownership),文件权限 (mode) 及时间 (timestamps),拥有者及群组仅限超级用户 (即为 root) 才会拷贝。 | 
| 
 | 保留文件链接 (跟  | 
| 
 | 保留文件链接。 | 
| 
 | 连同特殊属性 (拥有者、群组、文件权限、时间、链接、xattr) 一并拷贝,拥有者及群组仅限超级用户 (即为 root) 才会正确。 | 
| 
 | 跟  | 
| 
 | 拷贝链接档的实际文件。 | 
| 
 | 拷贝软链接 (never follow symbolic links in SOURCE)。 | 
| 
 | 保留来源目录结构。 | 
| 
 | 强制运行,在无法写入目的文件时,尝试删除目的文件后,再次重新拷贝 (同时具有  | 
| 
 | 先删除目的文件,再运行拷贝。 | 
| 
 | 不要覆盖现有的文件。 | 
| 
 | 在覆盖文件之前,先询问。 | 
| 
 | 更新,当来源比「目的」新或「目的」缺少才会拷贝。 | 
| 
 | 将文件拷贝成硬链接。 | 
| 
 | 将文件拷贝成软链接。 | 
| 
 | 指定备份档的结尾名称,未指定为  | 
| 
 | 备份目的文件 (若目的文件已存在,将目的文件名增加结尾名称,如果结尾名称的文件已存在,先删除再改名)。 | 
- 基本操作
- 
文件拷贝cp 来源文件 目的文件 将文件拷贝到其他目录,可指定目的目录 (保留源文件案名称)cp 来源文件 已存在的目的目录/ 多档拷贝cp 来源档1 来源档2 来源档3 已存在的目的目录/ 拷贝目录cp -r /path/folder 添加的目的目录 当目的目录不存在时则拷贝至该目的目录。 
 但如果目的目录存在则拷贝至该目录内,递归拷贝目录内容,需在来源目录后增加一个*(通配字符)。递归拷贝目录内容cp -r /path/folder/* 已存在的目的目录 (1)1 若 /path/folder/*改为/path/folder/,则拷贝至已存在的目的目录/folder。
- cp 缺省行为
- 
- 
拥有者及群组 (ownership) 权限为操作帐户。 
- 
拷贝文件权限 (mode) 
- 
将硬链接转成一般文件。 
- 
拷贝软链接。 
- 
覆盖文件且不会询问。 
- 
不会删除目的目录的多余文件。 
 
- 
- 不要覆盖现有的文件
- 
不要覆盖现有的文件-n,文件已存在,并不会运行拷贝。cp -n source.txt dest.txt或者在覆盖文件之前,先询问-i。$cp -i source.txt dest.txt cp: overwrite 'dest.txt'? 更新文件 (-u),来源文件的修改时间比目的文件还新,或者目的文件缺少,则更新文件cp -u source.txt dest.txt以-iur来得知目录内那些文件需要更新$cp -iur source/* dest cp: overwrite 'dest/source.txt'? 
- 强制覆盖文件
- 
如果目的文件文件无法写入(如权限为唯读),则无法运行拷贝。$cp soruce.txt dest.txt cp: cannot create regular file 'dest.txt': Permission denied 以-f强制运行cp -f soruce.txt dest.txt 以--remove-destination先删除目的文件,再运行拷贝。cp --remove-destination soruce.txt dest.txt 
- 备份目的文件
- 
覆盖目的文件时,若需备份可采用 -b备份目的文件。备份目的文件-bcp -b source.txt dest.txt缺省会将目的文件的结尾名称加上 ~,例如dest.txt会备份至 (改名为)dest.txt~,如果dest.txt~已存在,则先删除dest.txt~再将dest.txt改名。指定备份结尾文件名以-S来设置。指定备份目的文件-S .bakcp -b -S .bak source.txt dest.txt dest.txt则备份至dest.txt.bak,如果dest.txt.bak已存在,则先删除dest.txt.bak再将dest.txt改名。
- 拷贝链接文件
- 
拷贝文件时,拷贝连接文件的目标文件,可采用 -L拷贝链接档的目标文件,拷贝后为一般文件。
 如link.txt是指向source.txt的链接档,dest.txt实际上是拷贝source.txt。-L拷贝链接档的目标文件。cp -L link.txt dest.txt 在拷贝软链接文件时,将软链接直接拷贝,可采用 -P拷贝软链接,如soft-link是一个软链接,拷贝后的dest.txt亦为软链接文件。这里为什么要强调是软链接? 
 因为硬链接会拷贝成一般文件。-P拷贝软链接cp -P soft-link.txt dest.txt 保留文件链接 -d的情况比较复杂,当硬链接的目标文件在相同的目录一起被拷贝时,则以硬链接拷贝,其他情况则转成一般文件。
 如在source目录内,文件source.txt的硬链接为link.txt,在目录中创建硬链接other-link.txt链接至other/source.txt列出测试目录的内容$ls other source -liU other: total 4 2935287 -rw-rw-r-- 2 ubuntu ubuntu 4 1970-01-01 08:00 source.txt source: total 12 2935287 -rw-rw-r-- 2 ubuntu ubuntu 4 1970-01-01 08:00 other-link.txt 2935285 -rw-rw-r-- 2 ubuntu ubuntu 4 1970-01-01 08:00 source.txt 2935285 -rw-rw-r-- 2 ubuntu ubuntu 4 1970-01-01 08:00 link.txt 以保留文件链接-d,将目录source拷贝至目录dest。$cp -rd source dest $ls dest/source.txt dest/link.txt dest/other-link.txt -liU 2935289 -rw-rw-r-- 2 ubuntu ubuntu 4 2023-03-12 13:43 dest/source.txt (1) 2935289 -rw-rw-r-- 2 ubuntu ubuntu 4 2023-03-12 13:43 dest/link.txt (1) 2935290 -rw-rw-r-- 1 ubuntu ubuntu 4 2023-03-12 13:43 dest/other-link.txt (2) 1 硬链接的源文件一起被拷贝,则会以硬链接拷贝。 2 不在相同的目录则会转成一般文件。 以参数-d拷贝dest/link.txt至dest/dest.txt,dest/dest.txt视为一般文件。$cp -d dest/link.txt dest/dest.txt $ls dest/dest.txt -li 2935291 -rw-rw-r-- 1 ubuntu ubuntu 4 2023-03-12 14:42 dest/dest.txt 
- 以软、硬链接拷贝文件
- 
以参数 -s将文件拷贝成软链接,等同于ln -s命令创建链接,link.txt是一个指向source.txt的链接档。将文件拷贝成软链接-s。cp -s source.txt link.txt以参数 -l将文件拷贝成硬链接,等同于ln命令创建链接,link.txt是source.txt的分身 (inode 相同)。将文件拷贝成硬链接-l。cp -l source.txt link.txt以cp创建链接比ln的好处是可一次创建目录下多个链接。cp -sr $PWD/source soft-dest cp -lr source hard-dest
- 拷贝拥有者及群组、文件权限及时间
- 
拷贝拥有者、群组、文件权限及时间 -p或-a,以超级用户 (即为 root) 运作时,拥有者及群组权限才会拷贝。拷贝文件权限及时间-psudo cp -p source.txt dest.txt拷贝文件权限及时间及保留链接-asudo cp -a source.txt dest.txt
- 保留来源目录结构
- 
--parents保留来源目录结构。mkdir -p path/to touch path/to/source.txt mkdir dir-parents cp --parents path/to/source.txt dir-parents/$tree path (1) path └── to └── source.txt $tree dir-parents dir-parents └── path └── to └── source.txt1 若没有 tree命令,以sudo apt install tree安装。
scp 安全拷贝远程目录与文件
scp 是 secure copy 的缩写,基于 ssh 安全通信拷贝远程的文件 (目录)。
scp 命令的语法跟 cp 类似,scp 可在主机之间拷贝文件,其语法为:scp [[来源帐号@]来源主机:]来源文件或目录 [[目的帐号@]目的主机:]目的文件或目录
省略帐号与主机,表示本机的文件,只省略帐号表示本地端的用户帐号跟远程帐号一样。
| 
 | 递归,含目录内的所有文件。 | 
| 
 | 保留文件时间 | 
| 
 | 压缩之后再发送 | 
| 
 | 限制网络带宽,单位为 Kbit/s。 | 
| 
 | 拷贝源文件案的修改时间、访问时间和文件权限 (mode)。 | 
- 基本操作
- 
以 ubuntu帐号登录192.168.1.1主机,将主机上的/path/file拷贝到本地端的/path/file。
 本地端的用户帐号跟远程的用户帐号一样时,可省略用户帐号。从远程文件拷贝到本地端scp ubuntu@192.168.1.1:/path/file /path/file在运行命令时,会以 SSH 登录远程的主机,需输入ubuntu@192.168.1.1的密码 (公开密钥连接 SSH 服务器除外):ubuntu@192.168.1.1's password: 从远程文件拷贝到本地端,省略帐号scp 192.168.1.1:/path/file /path/file拷贝方向相反也类似。 由本地端文件拷贝到远程scp /path/file 192.168.1.1:/path/file从远程目录拷贝到本地端scp -r 192.168.1.1:/path/folder 添加的目的目录 当目的目录不存在时则拷贝至该目的目录。 
 但如果目的目录存在则拷贝至该目录内,递归拷贝目录内容,需在来源目录后增加一个 * (通配字符)。递归拷贝目录内容scp -r 192.168.1.1:/path/folder/* 已存在的目的目录 (1)1 若把 /path/folder/*改成/path/folder/,则拷贝至已存在的目的目录/folder。
-p。scp -p 192.168.1.1:/path/file /path/filescp -l 100 192.168.1.1:/path/file /path/file (1)| 1 | -l跟数字之间,可不需要空白字符。 | 
-C。scp -C 192.168.1.1:/path/file /path/filescp -P 222 192.168.1.1:/path/file /path/filerm (删除)、mv (移动或改名)
- rm
- 
rm 移除的文件或目录 rm 选项 -r, -R递归,含目录内的所有文件。 -f强制删除不会询问。 
- mv
- 
mv 移动(或改名)来源 目的 mv 是 move 的缩写,除了移动的功能外也可以重命名。将「来源」移动至「目的」,如果「目的」为存在的文件则会被覆盖。 
ln 文件链接
通过链接文件,不同的文件名可以指向同一个文件。链接类型分为硬链接 (hard link) 和符号链接 (symbolic link) 两种,符号链接也称软链接 (soft link),缺省的链接类型是硬链接。
- 软链接
- 
软链接为一个独立的文件或目录,类似于 Windows 操作系统中的快捷方式方式。 
 软链接本身有文件属性及权限。
 软链接可以跨文件系统。
 软链接可以对目录进行链接。
 删除软链接并不影响目标文件,若目标文件被删除,则相关软链接被称为已断开的悬挂链接 (dangling link),当重新创建目标时则悬挂链接可恢复为正常。
 创建不存在目标的软链接 (跟悬挂链接相似),不会提示错误 (注:ls会将指向显示成红色)。
 绝对路径所创建的链接档,在搬移软链接档时目标位置会相同,而以相对路径创建的链接档,其目标位置则会变动。
- 硬链接
- 
只能处理文件链接。 
 创建硬链接,事实上是在文件系统中创建分身,在文件系统中不同文件的索引码 inode 相同。
 删除其中一个分身,只要有一个分身存在,那么文件实体就不会被删除。
 删除所有分身,文件实体则被删除。
ln [参数] 目标(TARGET) 链接名称(LINK_NAME)
本文中将「链接名称」指向的文件 (或目录) 称为「目标」。
「链接名称」为「软链接」或「硬链接」。
| 
 | 创建软链接。 | 
| 
 | 创建相对路径的软链接。 | 
| 
 | 创建成硬链接 (默认值,不需指定本参数)。 | 
| 
 | 强制运行 (链接存在时先删除文件)。 | 
| 
 | 交互模式,链接存在时提示是否取代。 | 
| 
 | 指定备份文件名的结尾名称,未指定为  | 
| 
 | 备份链接文件 (若链接文件已存在,将链接文件名增加结尾名称,如果结尾名称的文件已存在,先删除再改名)。 | 
| 
 | 显示详细的处理过程 | 
- 创建软链接
- 
以参数 -s,将source.txt创建softlink.txt软链接档。创建软链接-sln -s source.txt softlink.txt链接至不同目录,创建的「目标」是相对于「链接名称」的路𠇹。 在source目录中创建一个source.txt文件,并创建一个dest目录mkdir source echo 123 > source/source.txt mkdir dest在dest目录中,创建相对路径目标../source/source.txt的软链接RelLink1.txtcd dest ln -s ../source/source.txt RelLink1.txt在目录中,创建的目标很直觉会采用正确的相对路径。 
 但如果在目录外往往会出错。创建错误的软链接 ErrorLink.txtcd .. ln -s source/source.txt dest/ErrorLink.txt正确的「目标」是「链接名称」位置的相对路𠇹 (当做目前路径是「链接名称」的目录内)。ln -s ../source/source.txt dest/RelLink2.txt或者以-r创建相对路径的软链接。ln -sr source/source.txt dest/RelLink3.txt创建绝对路径的AbsLink.txtln -s $PWD/source/source.txt dest/AbsLink.txt显示dest目录内置立的软链接文件。$ls dest -li total 0 2906099 lrwxrwxrwx 1 ubuntu ubuntu 35 2023-03-12 20:32 AbsLink.txt -> /home/ubuntu/demo/source/source.txt 2893916 lrwxrwxrwx 1 ubuntu ubuntu 17 2023-03-12 20:31 ErrorLink.txt -> source/source.txt 2893902 lrwxrwxrwx 1 ubuntu ubuntu 20 2023-03-12 20:31 RelLink1.txt -> ../source/source.txt 2894388 lrwxrwxrwx 1 ubuntu ubuntu 20 2023-03-12 20:31 RelLink2.txt -> ../source/source.txt 2894401 lrwxrwxrwx 1 ubuntu ubuntu 20 2023-03-12 20:32 RelLink3.txt -> ../source/source.txt 
- 创建硬链接
- 
创建目标为source/source.txt的dest/HardLink.txt硬链接ln -P source/source.txt dest/HardLink.txt (1)1 -P为默认值,可不需要该参数。硬链接是使用相同的 inode,没有相对路径的问题。 显示source/source.txtdest/HardLink.txt的 inode$ls source/source.txt dest/HardLink.txt -lU --inode 2935285 -rw-rw-r-- 2 ubuntu ubuntu 4 2023-03-12 20:05 source/source.txt 2935285 -rw-rw-r-- 2 ubuntu ubuntu 4 2023-03-12 20:05 dest/HardLink.txt 两个不同文件,实际保存于文件系统中的索引码 (inode) 为 2935285,在文件权限后面的数字 2 表示该文件有 2 个硬链接。 删除硬连接 (应该说删除其中一个分身)$rm source/source.txt (1) $ls dest/HardLink.txt -lU --inode 2935285 -rw-rw-r-- 1 ubuntu ubuntu 4 2023-03-12 21:05 dest/HardLink.txt 1 或者以 unlink删除连接,运行unlink source/source.txt。删除 source/source.txt后,前面范例的软连接已变成了悬挂链接 (dangling link)。
 删除 (以rm或unlink)dest/HardLink.txt后,由于文件实体没有分身,则为实际删除该文件。重建source/source,回复原始状态。$ln dest/HardLink.txt source/source.txt $ls source/source.txt dest/HardLink.txt -lU --inode 2935285 -rw-rw-r-- 2 ubuntu ubuntu 4 2023-03-12 21:05 source/source.txt 2935285 -rw-rw-r-- 2 ubuntu ubuntu 4 2023-03-12 21:05 dest/HardLink.txt 
find 找出合乎模式的文件
搜索目录之下合乎条件的文件或目录。
find [path…] [expression],expression 包含了林林总总的各式参数,全部混在一起。
find --help
find ... [path...] [expression]
expression may consist of: operators, options, tests, and actions
operators ...
      EXPR1 -o EXPR2   EXPR1 -or EXPR2   EXPR1 , EXPR2
normal options (在其他参数之前先指定 options):
      -depth --help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf
tests ...
      -ilname PATTERN -iname PATTERN -inum N -iwholename PATTERN -iregex PATTERN
actions: -delete -print0 -printf FORMAT -fprintf FILE FORMAT -print
find 的参数有不少,可用 man find 取得详细说明。
- tests (测试参数)
- 
- 名称符合
- 
-name PATTERN: 文件名称符合 PATTERN,-iname 不区分大小写。 
 -path PATTERN: 目录名称符合 PATTERN,-ipath 不区分大小写。
 目录名称包含了/(斜线),如-ipath '*/some-path/*'表示找出目录名称some-path的文件,而-ipath '*/some*/*'则找出目录名称前置some。文件、目录名称符合 PATTERN 的外框需加单引号 ( ') 或双引号 (")。否则;要转译正规表示法的特殊字符如'*.txt'要转译成\*\.txt。
- 文件类型符合
- 
-type [bcdpflsD]: 类型参数 f 文件,l 链接档,d 目录… 。 
- 文件时间符合
- 
-amin 读取分钟,-atime 读取天数,-cmin 修改分钟,-ctime 修改天数 
 -ctime n: 文件在 n 天前修改过。
 -ctime +1: +n 大于 n,所以是 2 天前修改过。
 -ctime -n: 「减」表示跟目前的时间比较,在最近的 n 天内修改过的文件。
- 文件大小符合
- 
-size +10M -size -20M,大于 10M 小于 20M 文件。单位:k Kilobytes,M Megabytes,G Gigabytes。 
 测试参数可不少直接查阅 find --help,像找出拥有者 -user,拥有群组 -group,文件权限 -perm。找出目前路径及子路径内的 .txt 文件find . -iname '*.txt' (1)1 目前路径可以不输入 .。
- operators (表达式)
- 
- -a、- -and
- 
AND (及) 逻辑,可不需要该表达式, expr1 -a expr2跟expr1 expr2相同找出最近一分钟修改的 .txtfind -iname '*.txt' -a -cmin -1 find -iname '*.txt' -cmin -1
- -o、- -or
- 
OR (或) 逻辑 找出 .txt 或 .doc 文件: find -iname '*.txt' -o -iname '*.doc' 找出 .txt 或 .doc 文件,以长格式显示: find -iname '*.txt' -ls -o -iname '*.doc' -ls 当表达式同时有 AND、NOT、OR 时,AND、NOT 先判断之后再判断 OR。 
 如果 OR 两边有相同条件,两边都要加入;另外 actions 也一样两边都要加入。
- !、- -not
- 
NOT (否定) 逻辑 找出不为 .txt 的文件: find ! -name '*.txt' 找出拥有者不为 www-data 的文件: find ! -user 'www-data' 找出文件权限不为 775 或目录权限不为 775: find -type f -not -perm 775 -o -type d -not -perm 775 find -type f -not -perm 775 -ls -o -type d -not -perm 775 -ls 
 
- actions (动作)
- 
find -iname '.log' -ctime 7 -delete (1) find -iname '.log' -ctime -7 -ls (2)1 删除 7 天前 .log 文件 2 以长格式列出 7 天内的 .log 文件 -exec 运行命令语法格式- 
-exec 命令 {} \;
- 
-exec 命令 {} +
 先 (前置) 输出文件名称,再运行命令。
 其中的字符串 {}会替换成文件名称。找出 7 天内有 error 记录的 .log 文件find -iname '.log' -ctime -7 -exec grep error {} \; find -iname '.log' -ctime -7 -exec grep error {} +
- 
- options (选项)
- 
-maxdepth LEVELS,最大阶层。 
 -mindepth LEVELS,最小阶层。
 注:options需要在其他参数之前先指定。找出目前路径的 .txt 文件find . -maxdepth 1 -iname '*.txt'
rsync 远程同步文件与目录
rsync 主要用于同步 (镜像) 文件与目录,传输时比对内容仅拷贝差异文件,可减少数据传输量。
可保留文件的拥有者、群组与权限设置,删除多余的目的文件或目录。
rsyncapt install rsyncrsync [[来源帐号@]来源主机:]来源文件或目录 [[目的帐号@]目的主机:]目的文件或目录
省略帐号与主机,表示本机的文件,只省略帐号表示本地端的用户帐号跟远程帐号一样。
| 
 | 备份模式;递归备份所有子目录下的目录与文件,保留链接档、文件的拥有者及群组 (ownership)、文件权限 (mode) 以及时间戳记,跟  | 
| 
 | 递归,含目录内的所有文件。 | 
| 
 | 保留软链接。 | 
| 
 | 保留文件权限 (mode)。 | 
| 
 | 保持时间戳记。 | 
| 
 | 保留拥有群组 (仅限超级用户,即为 root)。 | 
| 
 | 保留拥有者 (仅限超级用户,即为 root)。 | 
| 
 | same as --devices --specials | 
| 
 | preserve device files (仅限超级用户,即为 root)。 | 
| 
 | preserve special files. | 
| 参数  | |
| 
 | 保留硬链接。 | 
| 
 | 详细模式输出。 | 
| 
 | 以可读性较高的方式来显示 (需配合 -v)。 | 
| 
 | 不拷贝空目录。 | 
| 
 | 传输过程中压缩文件。 | 
| 
 | 测试运行。 | 
| 
 | 删除多余的目的文件或目录。 | 
| 
 | 设置文件或目录权限,如  | 
| 
 | 设置拥有者及群组,如  | 
| 
 | 传输时以单行显总体进度 ( | 
| 
 | 显示每个文件的变动摘要。 | 
| 
 | 设置远程登录指令。 | 
| 
 | 限制网络带宽,RATE 可指定如 1.5m,未指定单位时如 100,则为 100K。 | 
- 基本操作
- 
同步文件,将文件file同步至dest/file,会自动创建dest目录。rsync -a /path/to/file dest/ 同步目录,将目录d1同步至d2/d1,会自动创建d2目录。rsync -a /path/to/d1 d2 若需将目录 d1同步至目录d2,同步目录内容需在来源目录后增加/(斜线) 或是/*(斜线及通配字符)。
 当需要目录拷贝 (同步) 至目录时,可采用rsync并在来源目录增加/,不管目的目录是否存在,只会拷贝至目的目录。同步来源目录内容,将目录d1同步至目录d2,会自动创建d2目录。rsync -a /path/to/d1/ d2 rsync -a /path/to/d1/* d2以 ubuntu帐号登录192.168.1.1主机,将主机上的/path/folder拷贝到本地端的dest。
 本地端的用户帐号跟远程的用户帐号一样时,可省略用户帐号。
 可增加-z参数,将数据压缩后再传输,减少网络传输的数据量。从远程目录同步到本地端rsync -az ubuntu@192.168.1.1:/path/folder/ dest 在运行命令时,会以 SSH 登录远程的主机,需输入ubuntu@192.168.1.1的密码 (公开密钥连接 SSH 服务器除外):ubuntu@192.168.1.1's password: 
- 同步拥有者及群组、文件权限
- 
-a已经具备了该功能,以超级用户 (即为 root) 运行rsync时则能同步。同步本地目录文件用户权限sudo rsync -a /path/to/d1/ d2 以ubuntu同步远程目录rsync -az /path/to/folder/ ubuntu@192.168.1.1:/path/to/folder 同步远程帐户为ubuntu,若目的已存在而拥有者及群组不为ubuntu时则会引发错误,如下rsync: failed to set permissions rsync: failed to modify permissions rsync: failed to set times on 远程帐户为root,远程目的文件或目录的拥有者会同步。rsync -az /path/to/folder/ root@192.168.1.1:/path/to/folder 同步时指定目的权限为775,拥有者及群组为www-data:www-data。rsync -az --chmod=775 --chown=www-data:www-data /path/to/folder/ root@192.168.1.1:/path/to/folder 当本地的文件权限超出了登录帐户权限,而以sudo运行时,也表示远程帐户也需要以root帐户登录,那么可不需要「目的帐号」。sudo rsync -az /path/to/folder/ 192.168.1.1:/path/to/folder 
- 显示文件变动摘要 (--itemize-change、-i)
- 
$rsync --itemize-change -a /path/to/d1 d2 .d..tp..... ./ >f+++++++++ f1.txt >f..tp..... fh1.txt >f..tp..... fh2.txt cL+++++++++ fs1.txt -> f1.txt cL+++++++++ fs2.txt -> ../d2/f2.txt >f..t...... r1.txt 文件项目之前会多出 11 个字符,分别为 YXcstpoguax。
 意义如下:Y 异动类型 <文件发送至远程 >本地端接收文件 c代表本地端变动(如创建目录、软链接) h代表本地端创建硬链接(hard link) .代表没有变动(但可能有变动其他属性) *代表其余字段有包含消息(例如 deleting) X 文件型态 f一般文件 d目录 L软链接档 D设备档(device) S特殊文件(如 sockets 或 fifo)。 cstpoguax 说明 c内容变更。 s大小变更。 t时间戳记变更。 o拥有者变更。 p文件权限 (mode) 变更。 g群组变更。 u保留字段。 aACL 变更。 x扩充属性(extended attribute)变更。 其他值 .无变更 +添加文件或目录 - YXcstpoguax 示例
- 
- .d..t......
- 
.项目没有变动(尽管它变更了其他属性)
 d目录类型
 t时间变更
- >f.st......
- 
>接收文件
 f一般文件
 s大小变更
 t时间变更
- cd+++++++++
- 
c创建目录
 d目录类型
 +++++++++添加目录
- >f+++++++++
- 
>接收文件
 f一般文件
 +++++++++添加文件
- cL+++++++++
- 
c创建软链接档
 L软链接档
 +++++++++添加软链接档
- hf..t......
- 
h创建硬链接
 f一般文件
 t时间变更
 
 可以同时测试运行(--dry-run、-n),事先得知同步的情况$rsync --dry-run -ai /path/to/d1 d2 created directory d2 cd+++++++++ ./ >f+++++++++ f1.txt sent 236 bytes received 63 bytes 598.00 bytes/sec total size is 30 speedup is 0.10 (DRY RUN) 
- 设置远程登录指令 (-e)
- 
如192.168.1.1主机的 SSH 服务连接端口为222,以选项-e设置远程登录指令rsync -az -e 'ssh -p 222' ubuntu@192.168.1.1:/path/folder/ dest 远程登录的缺省指令为 ssh,参考ssh命令加入选项-p,将指令变更为ssh -p 222以连接端口222登录 SSH。
- 同步扩展名及阶层
- 
同步多个扩展名,原始目录下 (第一层) 的文件,子目录并不会同步rsync \ --include="*.svg" \ (1) --include="*.png" \ --include="*.jpg" \ --include="*.jpeg" \ --exclude='*' \ (2) $srcPath $destPath1 指定合乎的扩展名。 2 最后条件请按范例。 拷贝原始目录 (所有) 第 2 层的扩展名rsync \ --include='/*/' \ (1) --exclude='/*' \ (2) --include="*.svg" \ --include="*.png" \ --include="*.jpg" \ --include="*.jpeg" \ --exclude='*' \ $srcPath $destPath1 包含 1 ~ 2 层 ( 第 1 层是指原始目录下的文件,第 2 层为原始目录的子目录 )。 2 排除第 1 层 (先包含阶层再排除)。 包含阶层说明rsync \ --include='*/' \ (1) rsync \ --include='/*/' \ (2) --include='/*/*/' \ (3) --include='/*/*/*/' \ (4)1 包含所有阶层 2 包含 1 ~ 2 层。 3 包含第 3 层 (必须先包含 1 ~2 层,才有作用)。 4 包含第 4 层 (必须先包含 1 ~2 层及第 3 层,才有作用)。 排除阶层rsync \ --include='*/' \ (1) --exclude='/*' \ (2) --exclude='/*/*' \ (3) --exclude='/*/*/*' \ (4)1 先包含所有阶层再排除 2 排除第 1 层 (个别指定) 3 排除第 2 层 (个别指定,不需要先排除第 1 层) 4 排除第 3 层 (个别指定,不需要先排除第 1 或 2 层) 
diff 列出文件差异
列出两个文件或目录的差异。
diff [参数] ... 文件或目录
| 
 | 显示差异的文件,不显示差异内容,可用于比对两个目录的文件。 | 
| 
 | 递归,含目录内的所有文件。 | 
| 
 | 以「上下文输出格式」显示源文件及新文件修改的情况,同时列出未变更的行数 (缺省为 3)。 | 
| 
 | 以「统一格式」输出源文件修改情况,同时列出未变更的行数 (缺省为 3)。 | 
| 
 | 以 RCS 格式显示 (以新文件的角度列出修改情况)。 | 
| 
 | 忽略大小写。 | 
| 
 | 不检查空白字符。 | 
| 
 | 忽略所有空白字符,跟  | 
| 
 | 忽略空行。 | 
-qdiff -q folder1/ folder2/
Only in folder1: f1.txt Only in folder2: f2.txt Files folder1/f3.txt and folder2/f3.txt differ
-r 选项diff -qr folder1/ folder2/
cat > org.txt << EOF
line1-org
line2-same
del1
line3-org
del2
line4-same
del3
del4
line5-same
EOF
cat > new.txt << EOF
line1-mod
line2-same
line3-mod
line4-same
line5-same
line6-append
line7-append
EOFdiff org.txt new.txt1c1
< line1-org
---
> line1-mod
3,5c3
< del1
< line3-org
< del2
---
> line3-mod
7,8d4
< del3
< del4
9a6,7
> line6-append
> line7-append1c1 (1) < line1-org (2) --- > line1-mod (2)
| 1 | 1c1表示 (源文件的) 第 1 行换成了 (新文件的) 第 1 行。 | 
| 2 | <源文件内容,>新档内容。 | 
3,5c3 (1) < del1 < line3-org < del2 --- > line3-mod
| 1 | 3,5c3(源文件的) 3 至 5 行换成了 (新文件的) 第 3 行。,表示某行至某行,如3,5c3,3跟本例一样,当然开发者不会这样写;会合并相同行数。 | 
7,8d4 (1) < del3 < del4
| 1 | 7,8d4(源文件的) 第 7 至 8 行删除成 (新文件的) 第 4 行。 | 
9a6,7 (1) > line6-append > line7-append
| 1 | 9a6,7(源文件的) 第 9 行添加至 (新文件的) 6 至 7 行。 | 
-u (Unified context) 以「统一格式」输出源文件修改情况diff -u org.txt new.txt--- org.txt 2020-10-18 14:49:06.997670700 +0800 +++ new.txt 2020-10-18 14:49:07.935176100 +0800 @@ -1,9 +1,7 @@(1) -line1-org +line1-mod line2-same -del1(2) -line3-org -del2 +line3-mod line4-same -del3 -del4 line5-same +line6-append +line7-append
| 1 | 提供给 patch 的数据,当未变更的行数设成 0 时 ( -u0),可以发现还是存在@@这些行,该行数据并非是「未变更」。 | 
| 2 | 采用 -u的表现只有+-及空白没有仿真两可的修改情况,del1(文件内容) 为删除。 | 
+ - (不输出其他) 采用自订输出diff org.txt new.txt \
--old-line-format=$'-%l\n' \
--new-line-format=$'+%l\n' \
--unchanged-line-format=''-c (Copied context) 以「上下文输出格式」显示源文件及新文件修改的情况diff -c org.txt new.txt*** 1,9 **** ! line1-org line2-same ! del1 (1) ! line3-org ! del2 line4-same - del3 - del4 line5-same --- 1,7 ---- ! line1-mod line2-same ! line3-mod line4-same line5-same + line6-append + line7-append
| 1 | 字符符号说明: !(修改)+(添加)-(删除)、空白(未变更)。del1(文件内容) 是修改跟前面3,5c3虽然一致,但是并没有同时列示该组修改情况,并不知道del1实际上是删除,
采用-c需注意该问题,!可能是删除 (注:选项-u则会标示成删除-)。 | 
-n (RCS format) 以新文件的角度列出修改情况diff -n org.txt new.txtd1 1 (1) a1 1 (2) line1-mod d3 3 (3) a5 1 line3-mod d7 2 a9 2 line6-append line7-append
| 1 | 采用 -n是以新文件的角度列示,d1 1在第 1 行删除 1 行。 | 
| 2 | a1 1在第 1 行添加 1 行,不会有修改的情况,「修改」为先「删除」再「添加」。 | 
| 3 | del1(文件内容) 为删除,以新文件的角度列示;不关心源文件,只列出d3 3在 3 行删除 3 行。 | 
patch 补丁
patch [OPTION]... [ORIGFILE [PATCHFILE]]
| 
 | 输出补丁后的文件至 FILE。 | 
| 
 | 读取 PATCHFILE 补丁文件 (取代标准输入  | 
| 
 | 回复补丁 (已补丁的文件以 PATCHFILE 回复成补丁前的内容)。 | 
diff 将 org.txt 及 new.txt 产生补丁档 org.patchdiff -u org.txt new.txt > org.patch (1)| 1 | 注意!diff 中的 -unified[NUM]一并列出未变更的行数,不应设置 0,若补丁只有添加时,重复运行可能不会引发错误。另外 org.patch
即为前面 Unified context 内容, | 
org.txt 以 org.patch 补丁patch org.txt org.patch
org.txt 以 org.patch 补丁,输出至另一个文件 orgmod.txtpatch org.txt -i org.patch -o orgmod.txt
orgmod.txt 跟 new.txt 应该相同 (即无输出).diff -u orgmod.txt new.txt
-R,将 orgmod.txt 回复成 org.txtpatch orgmod.txt -R -i org.patch
orgmod.txt 跟 org.txt 应该相同diff -u orgmod.txt org.txt
输入与输出重新导向
输入与输出 (I/O) 重新导向是 Linux 系统中非常重要的功能,能够任意组合各种命令的输入和输出及串接任意的「命令管道」(command pipeline)。
在运行命令时,先创建好输出管道,再创建输入管道及串接管道。(大部份的命令在) 处理时并非将输入全部读取,而是读取一定的数据量,参与管道的命令「平行处理」输入与输出。
- >、- >>管道输出
- 
ls > output.txt (1) date >> output.txt (2)1 将 ls「标准输出」至 output.txt 文件,这里为什么称为 「标准输出」,因为命令的输出事实上有「标准输出」及「错误输出」。 2 把 日期输出附加在文件尾端 (如果文件不存在,则会创建新文件)。
- <管道输入
- 
cat < input.txt (1) cat < input.txt > output.txt (2)1 cat 取得 (由管道输入) input.txt 数据后输出至主控台 (显示于屏幕上)。 2 cat 取得 input.txt 数据后,标准输出至 output.txt。 
 一般情况不会这样写,会采用由命令读取文件的方式cat input.txt > output.txt。当输入文件跟输出文件相同时,如果以下列方式运行:cat file.txt > file.txt将得到一个空的 file.txt,其原因在于创建管道时,输出管道> file.txt会先运行将创建一个空的file.txt。
- <<管道输入终止字符串
- 
cat > output.txt (1) cat << EOF (2) ... EOF1 cat 需要标准输入管道,在没有重导的情况下,表示由主控台 (键盘) 输入,直到输入终止字符 Ctrl+d。 2 由主控台输入,直到输入终止字符串 EOF。终止字符串,可任意命名。line1='I am the first row' line2='I am the second row' cat > output.txt << EOF (1) $line1 $line2 EOF (1)1 终止字符串没有双 (单) 引号的情况下会替换变量。 output.txt 的内容如下I am the first row I am the second row 接上例,把 EOF 改成 "EOF"或者'EOF'cat > output.txt << "EOF" (1) $line1 $line2 EOF1 终止字符串有双 (单) 引号的情况下不会替换变量。 output.txt 的内容如下$line1 $line2 另外可不采用双 (单) 引号的终止字符串,以反斜线 (\) 禁止转译变量。cat > output.txt << EOF \$line1 \$line2 EOF
- |串接管道
- 
串接命令操作字符 |将多个命令串接。串接前一个命令的正确输出管道;并不能处理错误的管道输出。命令处理后,再传递给下一个命令作为标准输入。串接管道的运行顺序是由左至右。ls | cat -n (1) ls | cat -n | grep -P '1\t' > output.txt (2)1 ls输出给cat -n加上行号后输出至主控台。2 串接多个「命令管道」后标准输出至 output.txt,输出管道最先运行 (创建),串接管道的运行顺序是由左至右,先运行 ls、cat -n再运行grep -P '1\t'。输入及输出管道 (各别) 最多只能一个,不可能有多个,下列是将ls输出至cat文件。ls > cat -n > output.txt 
标准及错误输出
- 一般的 Linux 命令会有三个输入与输出的管道,分别为:
- 
- 
标准输入 ( stdin,代号 0):程序输入管道。
 注:一般命令都具有读取文件的功能,读取文件并不需要采用<来读取。
- 
标准正常输出 ( stdout,代号 1):命令正常输出管道。
- 
标准错误输出 ( stderr,代号 2):命令出错或状态消息 (可能) 以错误管道输出。
 
- 
- Linux 特殊文件:
- 
- 
/dev/null是 Linux 空设备,写入这个文件的数据会被直接丢弃,如果从这个文件读取数据,则会像读取空文件一样。
- 
/dev/stdout标准正常输出,即为主控台。
- 
/dev/stderr标准错误输出,也是主控台。
 
- 
ls 列出不存在的文件输出至 output.txt$ls nonexistent > output.txt ls: cannot access 'nonexistent': No such file or directory
上述的错误消息就是来自于 ls 的标准错误输出,output.txt 文件也会创建,不过内容是空的,因为命令没有任何标准正常输出。
输出管道可以采用操作符把正常管道 1> 输出至指定设备,或者是错误管道 2> 的输出设备。
注:标准输出管道 1> 可不需要指定操作符,1> 跟 > 相同。
ls 列出不存在的文件输出至 output.txt,错误输出至 error.txtls nonexistent 1> output.txt 2> error.txtls 1> output.txt 2> error.txt nonexistent运行后,主控台看不到任何消息。
error.txtls: cannot access 'nonexistent': No such file or directory
>& 或 &>,将消息全部写入 all.txt:ls output.txt nonexistent &> all.txt
all.txtls: cannot access 'nonexistent': No such file or directory output.txt
/dev/null,不会得到任何消息。ls output.txt nonexistent &> /dev/null
- 合并管道
- 
在运行命令时,可先设置合并管道。 
 2>&1,将管道 2 导入管道 1。
 1>&2,将管道 1 导入管道 2。
 要注意 linux 创建输出管道的顺序,是最右边先创建,「合并管道」要最先运行。
ls output.txt nonexistent 1> all.txt 2>&1all.txt 的内容跟前面的「所有消息在 all.txt」一样。
ls output.txt nonexistent 2>&1 1> all.txt (1)
| 1 | 在主控台可看到错误消息,因为顺序不正确。合并管道 2>&1要最先运行才有作用 (创建输出管道的顺序,是最右边先创建)。 | 
- 输出重导至标准输出发生权限错误
- 
$echo 123 > /dev/stdout bash: /dev/stdout: Permission denied $echo 123 > /dev/stderr bash: /dev/stderr: Permission denied 当登录为 user1 以 su 切换至另一个 user2 用户,是造成本问题的原因su user2 dev/stdout是一个符号链接到/proc/self/fd/1,再以符号链接至伪终端,例如:dev/pts/1。伪终端权限是在登录时授予,当以su user2切换至不同的帐户时,伪终端的拥有权并不会更改,user2没有写入权限。
 注:su root不会错误,超级用户不受权限影响。user2的伪终端权限$ls /dev/stdout /proc/self/fd/1 /dev/pts/1 -lU lrwxrwxrwx 1 root root 15 2023-03-10 04:25 /dev/stdout -> /proc/self/fd/1 lrwx------ 1 user2 user2 64 2023-03-15 11:58 /proc/self/fd/1 -> /dev/pts/1 crw--w---- 1 user1 tty 136, 1 2023-03-15 11:58 /dev/pts/1 
文件内容查阅
cat 显示文件所有内容。 head 显示文件开头的内容。 tail 显示文件尾端的内容。 more 一页一页向后显示内容 (可向上翻页仅限文件,管线无作用)。 less 与 more 类似,但比 more 更容易操作,可前后翻页。
上述的命令与本文编辑器 (例如 nano 或 vim) 相比,启动时不需要读取整个文件,加载时间会大大缩短,可用于打开大文件。
cat [参数] [文件] -n 打印出行号 -E 将行尾的断行字符以 $ 显示 -T 将字符 tab 以 ^I 显示
head -n20 /var/log/auth.log -n 20, 显示 20 行,缺省为 10 行。
tail -n20 -f /var/log/auth.log
-n 20, 显示 20 行,缺省为 10 行。
-f 持续监控文件内容,当有新数据时即时显示。离开监控模式需按下 Ctrl+c 中断监控。
more 查看命令
more /var/log/auth.log| Shortcut | Purpose | 
|---|---|
| q | 离开 more | 
| h | 显示说明 | 
| Enter | 向下一行 | 
| 空白键 或 f | 向下翻页 | 
| b 或 Ctrl+b | 向上翻页 (仅限文件,管线无作用) | 
| / 字符串 | 向前搜索「字符串」 | 
| n | 重复上一个搜索 (向前),跟 / 有关。 没有向后的功能。 | 
less 查看命令
less 一次显示一页文件或命令输出 (pipe) 的内容,跟 more 相似但具有更好的功能;如可翻页内容。
less /var/log/auth.logrsync --help | less| Shortcut | Purpose | 
|---|---|
| q | 离开 less | 
| h | 显示说明,离开说明则按下q。 | 
| PageDown 、 空白键 或 f | 向下翻页 | 
| PageUp 或 b | 向上翻页 | 
| g | 至文件开头 | 
| Shift+G | 至文件尾端 | 
| / 字符串 | 向前搜索「字符串」 | 
| ? 字符串 | 向后搜索「字符串」 | 
| n | 重复上一个搜索 (向前),跟 / ? 有关。 | 
| Shift+N | 反向重复先前的搜索 (向后),跟 / ? 有关。 | 
| - i | 切换搜索是否区分大小写,缺省为区分大小写。 | 
| - N | 切换是否显示行号 | 
grep 找出符合模式的「行」
grep [选项]... PATTERN(模式) [文件]...
| Pattern selection and interpretation: | |
| 
 | 以 PATTERN 进行匹配 | 
| 
 | PATTERN 为延伸正规表示法 (ERE) | 
| 
 | PATTERN 匹配单词,如匹配 word,words 则不匹配。 | 
| 
 | 不区分大小写 | 
| Miscellaneous: | |
| -v, --invert-match | 反向匹配,找出不合乎符合模式的「行」。 | 
| Output control: | |
| 
 | 递归,含目录内的所有文件 | 
| 
 | 打印行号 | 
| 
 | 将字符 tab 以  | 
| 
 | 仅列出文件内容符合模式的文件名 | 
| 
 | 仅搜索 GLOB 匹配 FILE_PATTERN 的文件 | 
| Context control: | |
| 
 | 列出匹配前 NUM 行数 | 
| 
 | 列出匹配后 NUM 行数 | 
grep 'Pattern1\|Pattern2' file...
grep -E 'Pattern1|Pattern2' file...grep -rl PATTERN/etc 目录内的特定文本 (hosts):grep -rw hosts /etcgrep 如果按语法顺序,可不需要 -e 选项,但习惯在把路径写在前面,则加入 -e 选项,并把表示法加上单引号比较清楚。grep /etc -e 'hosts' -rw/etc 目录内特定扩展名 (GLOB 匹配) 中的单词 (w) 文本 (hosts):grep /etc -e 'hosts' -rw --include=*.allow --include=*.deny
grep /etc -e 'hosts' -rw --include=*.{allow,deny}cut 截取部份字符或字段
cut 选项... [文件]...
| 
 | 以定界字符区分出字段,截取字段。 | 
| 
 | 截取字符。 | 
| 
 | 截取字节。 | 
| 
 | 定界字符,缺省为制表字符 (Tab 键),只允许一个字符。 | 
| 
 | 补集参数,将指定的部份删除,留下剩余的部份。 | 
| 
 | 将定界字符取代成 STRING | 
| 
 | 只打印具有定界字符的行。 | 
-f、-c 及 -b 的 LIST 的参数可以是整数、以逗号分隔的多个整数,或者是范围、以逗号分隔的多个范围。
| 
 | 第 n 个字段、字符或字节。 | 
| 
 | 第 n 个字段、字符或字节到 (该行的) 结尾。 | 
| 
 | 由第 n 至第 m 个字段、字符或字节。 | 
| 
 | 由第一个至第 m 个字段、字符或字节。 | 
- 选项 -c,截取字符
- 
如截取前面 6 个字符为 1-6,截取第 7 个字符至结束如7-。数据如下$grep ubuntu /etc/passwd ubuntu:x:1000:1000::/home/ubuntu:/bin/bash 截取字符-c范例grep ubuntu /etc/passwd | cut -c 1-6 (1) grep ubuntu /etc/passwd | cut -c -6 (1) grep ubuntu /etc/passwd | cut -c 7- (2) grep ubuntu /etc/passwd | cut -c 1-6 --complement (3)1 截取前面 6 个字符 ubuntu 2 截取第 7 个字符至结束 :x:1000:1000::/home/ubuntu:/bin/bash 3 去掉前面 6 个字符,留下剩余的部份。 :x:1000:1000::/home/ubuntu:/bin/bash 
- 选项 -d指定定界字符
- 
以选项-d指定定界字符:,将数据标示出字段如下:ubuntu:x:1000:1000::/home/ubuntu:/bin/bash 1 :2:3 :4 ::6 :7 定界字符-d为:,截取字段-fgrep ubuntu /etc/passwd | cut -d : -f 1,6 (1) grep ubuntu /etc/passwd | cut -d : -f 1,6 --output-delimiter=' ' (2)1 截取字段 1、6。 ubuntu:/home/ubuntu 2 截取字段 1、6,将定界字符取代成空白。 ubuntu /home/ubuntu 
-s) 的行ls /bin -l | cut -d '>' -s -f 1,2awk 找出符合字段的「行」
本文已移至 awk
sed
本文已移至 sed