chmod命令目录或文件的属主、属组、其它权限修改

Linux chmod命令

Linux 命令大全 Linux 命令大全

Linux chmod(英文全拼:change mode)命令是控制用户对文件的权限的命令

Linux/Unix 的文件调用权限分为三级 : 文件所有者(Owner)、用户组(Group)、其它用户(Other Users)。

只有文件所有者和超级用户可以修改文件或目录的权限。可以使用绝对模式(八进制数字模式),符号模式指定文件的权限。

使用权限 : 所有使用者

语法

chmod [-cfvR] [--help] [--version] mode file...

参数说明

mode : 权限设定字串,格式如下 :

[ugoa...][[+-=][rwxX]...][,...]

其中:

  • u 表示该文件的拥有者,g 表示与该文件的拥有者属于同一个群体(group)者,o 表示其他以外的人,a 表示这三者皆是。
  • + 表示增加权限、- 表示取消权限、= 表示唯一设定权限。
  • r 表示可读取,w 表示可写入,x 表示可执行,X 表示只有当该文件是个子目录或者该文件已经被设定过为可执行。

其他参数说明:

  • -c : 若该文件权限确实已经更改,才显示其更改动作
  • -f : 若该文件权限无法被更改也不要显示错误讯息
  • -v : 显示权限变更的详细资料
  • -R : 对目前目录下的所有文件与子目录进行相同的权限变更(即以递归的方式逐个变更)
  • –help : 显示辅助说明
  • –version : 显示版本

符号模式

使用符号模式可以设置多个项目:who(用户类型),operator(操作符)和 permission(权限),每个项目的设置可以用逗号隔开。 命令 chmod 将修改 who 指定的用户类型对文件的访问权限,用户类型由一个或者多个字母在 who 的位置来说明,如 who 的符号模式表所示:

who 用户类型 说明
u user 文件所有者
g group 文件所有者所在组
o others 所有其他用户
a all 所用用户, 相当于 ugo

operator 的符号模式表:

Operator 说明
+ 为指定的用户类型增加权限
- 去除指定用户类型的权限
= 设置指定用户权限的设置,即将用户类型的所有权限重新设置

permission 的符号模式表:

模式 名字 说明
r 设置为可读权限
w 设置为可写权限
x 执行权限 设置为可执行权限
X 特殊执行权限 只有当文件为目录文件,或者其他类型的用户有可执行权限时,才将文件权限设置可执行
s setuid/gid 当文件被执行时,根据who参数指定的用户类型设置文件的setuid或者setgid权限
t 粘贴位 设置粘贴位,只有超级用户可以设置该位,只有文件所有者u可以使用该位

八进制语法

chmod命令可以使用八进制数来指定权限。文件或目录的权限位是由9个权限位来控制,每三位为一组,它们分别是文件所有者(User)的读、写、执行,用户组(Group)的读、写、执行以及其它用户(Other)的读、写、执行。历史上,文件权限被放在一个比特掩码中,掩码中指定的比特位设为1,用来说明一个类具有相应的优先级。

# 权限 rwx 二进制
7 读 + 写 + 执行 rwx 111
6 读 + 写 rw- 110
5 读 + 执行 r-x 101
4 只读 r– 100
3 写 + 执行 -wx 011
2 只写 -w- 010
1 只执行 –x 001
0 000

例如, 765 将这样解释:

  • 所有者的权限用数字表达:属主的那三个权限位的数字加起来的总和。如 rwx ,也就是 4+2+1 ,应该是 7。
  • 用户组的权限用数字表达:属组的那个权限位数字的相加的总和。如 rw- ,也就是 4+2+0 ,应该是 6。
  • 其它用户的权限数字表达:其它用户权限位的数字相加的总和。如 r-x ,也就是 4+0+1 ,应该是 5。

实例

将文件 file1.txt 设为所有人皆可读取 :

chmod ugo+r file1.txt

将文件 file1.txt 设为所有人皆可读取 :

chmod a+r file1.txt

将文件 file1.txt 与 file2.txt 设为该文件拥有者,与其所属同一个群体者可写入,但其他以外的人则不可写入 :

chmod ug+w,o-w file1.txt file2.txt

为 ex1.py 文件拥有者增加可执行权限:

chmod u+x ex1.py

将目前目录下的所有文件与子目录皆设为任何人可读取 :

chmod -R a+r *

此外chmod也可以用数字来表示权限如 :

chmod 777 file

语法为:

chmod abc file

其中a,b,c各为一个数字,分别表示User、Group、及Other的权限。

r=4,w=2,x=1

  • 若要 rwx 属性则 4+2+1=7;
  • 若要 rw- 属性则 4+2=6;
  • 若要 r-x 属性则 4+1=5。
chmod a=rwx file

chmod 777 file

效果相同

chmod ug=rwx,o=x file

chmod 771 file

效果相同

若用 chmod 4755 filename 可使此程序具有 root 的权限。

更多说明

命令 说明
chmod a+r file 给file的所有用户增加读权限
chmod a-x file 删除file的所有用户的执行权限
chmod a+rw file 给file的所有用户增加读写权限
chmod +rwx file 给file的所有用户增加读写执行权限
chmod u=rw,go= file 对file的所有者设置读写权限,清空该用户组和其他用户对file的所有权限(空格代表无权限)
chmod -R u+r,go-r docs 对目录docs和其子目录层次结构中的所有文件给用户增加读权限,而对用户组和其他用户删除读权限
chmod 664 file 对file的所有者和用户组设置读写权限, 为其其他用户设置读权限
chmod 0755 file 相当于u=rwx (4+2+1),go=rx (4+1 & 4+1)0 没有特殊模式。
chmod 4755 file 4设置了设置用户ID位,剩下的相当于 u=rwx (4+2+1),go=rx (4+1 & 4+1)。
find path/ -type d -exec chmod a-x {} \; 删除可执行权限对path/以及其所有的目录(不包括文件)的所有用户,使用’-type f’匹配文件
find path/ -type d -exec chmod a+x {} \; 允许所有用户浏览或通过目录path/

Linux 命令大全 Linux 命令大全

1.1.常见权限说明

目录默认权限:755,文件默认权限:644

目录和文件常见权限值:

 

  • 目录:755 750 700
  • 文件:644 640 600

2.系统帮助

  1. 用法:chmod [选项]… 模式[,模式]… 文件…
  2.  或:chmod [选项]… 八进制模式 文件…
  3.  或:chmod [选项]… reference=参考文件 文件…
  4. Change the mode of each FILE to MODE.
  5. With reference, change the mode of each FILE to that of RFILE.
  6.  
  7. c, changes like verbose but report only when a change is made
  8. f, silent, quiet suppress most error messages
  9. v, verbose output a diagnostic for every file processed
  10. nopreserveroot do not treat ‘/’ specially (the default)
  11. preserveroot fail to operate recursively on ‘/’
  12. reference=RFILE use RFILE‘s mode instead of MODE values
  13. -R, –recursive 权限递归
  14. –help 显示此帮助信息并退出
  15. –version 显示版本信息并退出
  16.  
  17. Each MODE is of the form ‘[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=][07]+‘.
  18.  
  19. GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
  20. 请向<http://translationproject.org/team/zh_CN.html> 报告chmod 的翻译错误
  21. 要获取完整文档,请运行:info coreutils ‘chmod invocation

3.图解

chmod命令目录或文件的属主、属组、其它权限修改

文件下载   文件名称:文件权限图.vsdx   文件大小:34.7kb
  下载声明:本站文件大多来自于网络,仅供学习和研究使用,不得用于商业用途,如有版权问题,请联系我!
  下载地址:点击下载

提取密码:

 

注意:本段内容须成功“回复本文”后“刷新本页”方可查看!

 

 

4.示例

4.1.移除用户写权限

  1. [root@itbkz s]#mkdir mulu
  2. [root@itbkz s]#touch mulu/test.txt
  3. [root@itbkz s]#ll -d mulu
  4. drwxrxrx 2 root root 22 12 5 17:00 mulu
  5. [root@itbkz s]#ll mulu/test.txt
  6. rwrr 1 root root 0 12 5 17:00 mulu/test.txt
  7. 方法1
  8. [root@itbkz s]#chmod u=rx mulu
  9. [root@itbkz s]#ll -d mulu
  10. drxrxrx 2 root root 22 12 5 17:00 mulu
  11. 方法2
  12. [root@itbkz s]#chmod u-w mulu
  13. [root@itbkz s]#ll -d mulu
  14. drxrxrx 2 root root 22 12 5 17:00 mulu
  15. 方法3
  16. [root@itbkz s]#chmod 555 mulu
  17. [root@itbkz s]#ll -d mulu
  18. drxrxrx 2 root root 22 12 5 17:00 mulu

4.2.增加属组写权限

  1. 方法1
  2. [root@itbkz s]#chmod g+w mulu
  3. [root@itbkz s]#ll -d mulu
  4. drwxrwxrx 2 root root 22 12 5 17:00 mulu
  5. 方法2
  6. [root@itbkz s]#chmod g=rwx mulu
  7. [root@itbkz s]#ll -d mulu
  8. drwxrwxrx 2 root root 22 12 5 17:00 mulu
  9. 方法3
  10. [root@itbkz s]#chmod 775 mulu
  11. [root@itbkz s]#ll -d mulu
  12. drwxrwxrx 2 root root 22 12 5 17:00 mulu

4.3.增加其它写权限

  1. 方法1
  2. [root@itbkz s]#chmod o+w mulu
  3. [root@itbkz s]#ll -d mulu
  4. drwxrxrwx 2 root root 22 12 5 17:00 mulu
  5. 方法2
  6. [root@itbkz s]#chmod o=rwx mulu
  7. [root@itbkz s]#ll -d mulu
  8. drwxrxrwx 2 root root 22 12 5 17:00 mulu
  9. 方法3
  10. [root@itbkz s]#chmod 757 mulu
  11. [root@itbkz s]#ll -d mulu
  12. drwxrxrwx 2 root root 22 12 5 17:00 mulu

4.4.相同权限修改

  1. 方法1
  2. [root@itbkz s]#chmod go=rwx mulu
  3. [root@itbkz s]#ll -d mulu
  4. drwxrwxrwx 2 root root 22 12 5 17:00 mulu
  5. 方法2
  6. [root@itbkz s]#chmod 777 mulu
  7. [root@itbkz s]#ll -d mulu
  8. drwxrwxrwx 2 root root 22 12 5 17:00 mulu

4.5.不同权限修改

  1. 方法1
  2. [root@itbkz s]#chmod u=rx,g=rwx,o=rwx mulu
  3. [root@itbkz s]#ll -d mulu
  4. drxrwxrwx 2 root root 22 12 5 17:00 mulu
  5. 方法2
  6. [root@itbkz s]#chmod u=rx,go=rwx mulu
  7. [root@itbkz s]#ll -d mulu
  8. drxrwxrwx 2 root root 22 12 5 17:00 mulu
  9. 方法3
  10. [root@itbkz s]#chmod 577 mulu
  11. [root@itbkz s]#ll -d mulu
  12. drxrwxrwx 2 root root 22 12 5 17:00 mulu

4.6.删除全部权限

  1. 方法1
  2. [root@itbkz s]#chmod a= mulu
  3. [root@itbkz s]#ll -d mulu
  4. d——— 2 root root 22 12 5 17:00 mulu
  5. 方法2
  6. [root@itbkz s]#chmod 000 mulu
  7. [root@itbkz s]#ll -d mulu
  8. d——— 2 root root 22 12 5 17:00 mulu
  9. 方法3
  10. [root@itbkz s]#chmod =0 mulu
  11. [root@itbkz s]#ll -d mulu
  12. d——— 2 root root 22 12 5 17:00 mulu

4.7.权限递归

  1. 方法1
  2. [root@itbkz s]#chmod -R 700 mulu
  3. [root@itbkz s]#ll -d mulu mulu/test.txt
  4. drwx—— 2 root root 22 12 6 22:21 mulu
  5. rwx—— 1 root root 0 12 6 22:21 mulu/test.txt
  6. 方法2
  7. [root@itbkz s]#chmod -R u=rwx,go= mulu
  8. [root@itbkz s]#ll -d mulu mulu/test.txt
  9. drwx—— 2 root root 22 12 6 22:24 mulu
  10. rwx—— 1 root root 0 12 6 22:24 mulu/test.txt
将会修改目录和目录下目录及文件的所有权限

5.注意

  1. [root@itbkz s]#chmod 7777 mulu
  2. [root@itbkz s]#ll
  3. 总用量 0
  4. drwsrwsrwt 2 root root 6 12 5 23:34 mulu
  5. [root@itbkz s]#chmod 7666 mulu
  6. [root@itbkz s]#ll
  7. 总用量 0
  8. drwSrwSrwT 2 root root 6 12 5 23:34 mulu

chown命令将目录或文件的拥有者、拥有组改为指定的用户或组

Linux chown 命令

Linux 命令大全 Linux 命令大全

Linux chown(英文全拼:change owner)命令用于设置文件所有者和文件关联组的命令。

Linux/Unix 是多人多工操作系统,所有的文件皆有拥有者。利用 chown 将指定文件的拥有者改为指定的用户或组,用户可以是用户名或者用户 ID,组可以是组名或者组 ID,文件是以空格分开的要改变权限的文件列表,支持通配符。 。

chown 需要超级用户 root 的权限才能执行此命令。

只有超级用户和属于组的文件所有者才能变更文件关联组。非超级用户如需要设置关联组可能需要使用 chgrp 命令。

使用权限 : root

语法

chown [-cfhvR] [--help] [--version] user[:group] file...

参数 :

  • user : 新的文件拥有者的使用者 ID
  • group : 新的文件拥有者的使用者组(group)
  • -c : 显示更改的部分的信息
  • -f : 忽略错误信息
  • -h :修复符号链接
  • -v : 显示详细的处理信息
  • -R : 处理指定目录以及其子目录下的所有文件
  • –help : 显示辅助说明
  • –version : 显示版本

实例

把 /var/run/httpd.pid 的所有者设置 root:

chown root /var/run/httpd.pid

将文件 file1.txt 的拥有者设为 runoob,群体的使用者 runoobgroup :

chown runoob:runoobgroup file1.txt

将当前前目录下的所有文件与子目录的拥有者皆设为 runoob,群体的使用者 runoobgroup:

chown -R runoob:runoobgroup *

把 /home/runoob 的关联组设置为 512 (关联组ID),不改变所有者:

chown :512 /home/runoob

Linux 命令大全 Linux 命令大全

2.系统帮助

  1. 用法:chown [选项]… [所有者][:[组]] 文件…
  2.  或:chown [选项]… reference=参考文件 文件…
  3. Change the owner and/or group of each FILE to OWNER and/or GROUP.
  4. With reference, change the owner and group of each FILE to those of RFILE.
  5.  
  6. c, changes like verbose but report only when a change is made
  7. f, silent, quiet suppress most error messages
  8. v, verbose output a diagnostic for every file processed
  9. dereference affect the referent of each symbolic link (this is
  10. the default), rather than the symbolic link itself
  11. h, nodereference affect symbolic links instead of any referenced file
  12. (useful only on systems that can change the
  13. ownership of a symlink)
  14. from=当前所有者:当前所属组
  15. 只当每个文件的所有者和组符合选项所指定时才更改所
  16. 有者和组。其中一个可以省略,这时已省略的属性就不
  17. 需要符合原有的属性。
  18. nopreserveroot do not treat ‘/’ specially (the default)
  19. preserveroot fail to operate recursively on ‘/’
  20. reference=RFILE use RFILE‘s owner and group rather than
  21. specifying OWNER:GROUP values
  22. -R, –recursive 权限递归
  23.  
  24. The following options modify how a hierarchy is traversed when the -R
  25. option is also specified. If more than one is specified, only the final
  26. one takes effect.
  27.  
  28. -H if a command line argument is a symbolic link
  29. to a directory, traverse it
  30. -L traverse every symbolic link to a directory
  31. encountered
  32. -P do not traverse any symbolic links (default)
  33.  
  34. –help 显示此帮助信息并退出
  35. –version 显示版本信息并退出
  36.  
  37. Owner is unchanged if missing. Group is unchanged if missing, but changed
  38. to login group if implied by a ‘:‘ following a symbolic OWNER.
  39. OWNER and GROUP may be numeric as well as symbolic.
  40.  
  41. 示例:
  42. chown root /u 将 /u 的属主更改为”root”。
  43. chown root:staff /u 和上面类似,但同时也将其属组更改为”staff”。
  44. chown -hR root /u 将 /u 及其子目录下所有文件的属主更改为”root”。
  45.  
  46. GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
  47. 请向<http://translationproject.org/team/zh_CN.html> 报告chown 的翻译错误
  48. 要获取完整文档,请运行:info coreutils ‘chown invocation

3.示例

3.1.更改拥有者

  1. [root@itbkz s]#mkdir mulu
  2. [root@itbkz s]#touch mulu/test.txt
  3. [root@itbkz s]#ll -d mulu
  4. drwxrxrx 2 root root 22 12 5 17:00 mulu
  5. [root@itbkz s]#ll mulu/test.txt
  6. rwrr 1 root root 0 12 5 17:00 mulu/test.txt
  7. [root@itbkz s]#ll
  8. 总用量 0
  9. drwxrxrx 2 root root 22 12 5 17:00 mulu
  10. [root@itbkz s]#chown itbkz mulu
  11. [root@itbkz s]#ll
  12. 总用量 0
  13. drwxrxrx 2 itbkz root 22 12 5 17:00 mulu

3.2.更改拥有组

  1. [root@itbkz s]#chown .itbkz mulu
  2. [root@itbkz s]#ll
  3. 总用量 0
  4. drwxrxrx 2 root itbkz 22 12 5 17:00 mulu

3.3.更改拥有者和组

  1. [root@itbkz s]#chown itbkz:itbkz mulu
  2. [root@itbkz s]#ll
  3. 总用量 0
  4. drwxrxrx 2 itbkz itbkz 22 12 5 17:00 mulu

3.4.拥有用户及组权限递归

  1. 方法1
  2. [root@itbkz s]#chown -R itbkz:itbkz mulu
  3. [root@itbkz s]#ll -d mulu
  4. drwxrxrx 2 itbkz itbkz 22 12 5 17:00 mulu
  5. [root@itbkz s]#ll mulu/test.txt
  6. rwrr 1 itbkz itbkz 0 12 5 17:00 mulu/test.txt
  7. 方法2
  8. [root@itbkz s]#chown -R itbkz.itbkz mulu
  9. [root@itbkz s]#ll -d mulu
  10. drwxrxrx 2 itbkz itbkz 22 12 5 17:00 mulu
  11. [root@itbkz s]#ll mulu/test.txt
  12. rwrr 1 itbkz itbkz 0 12 5 17:00 mulu/test.txt

Linux系统设置开机自动运行脚本

文章标签: linux
版权
方法一:修改 /etc/rc.d/rc.local 文件

/etc/rc.d/rc.local 文件会在 Linux 系统各项服务都启动完毕之后再被运行。所以你想要自己的脚本在开机后被运行的话,可以将自己脚本路径加到该文件里。

但是,首先需要确认你有运行这个文件的权限。

$ chmod +x /etc/rc.d/rc.local
1
为了演示,我们创建了一个脚本,当它被执行之后,将在家目录下写入有特定信息的文件。

$ vim auto_run_script.sh

#!/bin/bash
date >> /home/alvin/output.txt
hostname >> /home/alvin/output.txt
1
2
3
4
5
保存退出后,再给它赋予可执行权限:

$ chmod +x auto_run_script.sh
1
然后,我们再将脚本添加到 /etc/rc.d/rc.local 文件最后一行:

$ vim /etc/rc.d/rc.local

/home/alvin/auto_run_script.sh
1
2
3
方法二:使用 crontab

大家知道,crontab 是 Linux 下的计划任务,当时间达到我们设定的时间时,可以自动触发某些脚本的运行。

我们可以自己设置计划任务时间,然后编写对应的脚本。但是,有个特殊的任务,叫作 @reboot ,我们其实也可以直接从它的字面意义看出来,这个任务就是在系统重启之后自动运行某个脚本。

那它将运行的是什么脚本呢?我们如何去设置这个脚本呢?我们可以通过 crontab -e 来设置。

$ crontab -e

@reboot /home/alvin/auto_run_script.sh
1
2
3
然后,直接重启即可。运行的效果跟上面类似。

方法三:使用 systemd 服务

以上介绍的两种方法,在任何 Linux 系统上都可以使用。但本方法仅适用于 systemd 系统。如何区分是不是 systemd 系统?很简单,只需运行 ps aux 命令,查看 pid 为 1 的进程是不是 systemd 。

为了实现目的,我们需要创建一个 systemd 启动服务,并把它放置在 /etc/systemd/system/ 目录下。

我们创建的 systemd 启动服务如下。请注意,这时后缀是 .service ,而不是 .sh 。

$ vim auto_run_script.service

[Unit]
Description=Run a Custom Script at Startup
After=default.target

[Service]
ExecStart=/home/alvin/auto_run_script.sh

[Install]
WantedBy=default.target
1
2
3
4
5
6
7
8
9
10
11
从服务的内容可以看出来,我们最终还是会调用 /home/alvin/auto_run_script.sh 这个脚本。

然后,我们再把这个脚本放置在 /etc/systemd/systerm/ 目录下,之后我们再运行下面两条命令来更新 systemd 配置文件,并启动服务。

$ systemctl daemon-reload
$ systemctl enable auto_run_script.service
1
2
万事俱备之后,我们就可以重启系统啦。
————————————————
版权声明:本文为CSDN博主「aleihello」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/aleihello/article/details/110759954

Linux xargs 命令与深入分析

Linux 命令大全 Linux 命令大全

1.1 为什么需要xargs

管道实现的是将前面的stdout作为后面的stdin,但是有些命令不接受管道的传递方式,最常见的就是ls命令。有些时候命令希望管道传递的是参数,但是直接用管道有时无法传递到命令的参数位,这时候需要xargs,xargs实现的是将管道传输过来的stdin进行处理然后传递到命令的参数位上。也就是说xargs完成了两个行为:处理管道传输过来的stdin;将处理后的传递到正确的位置上。

可以试试运行下面的几条命令,应该能很好理解xargs的作用了:

[root@xuexi tmp]# echo “/etc/inittab” | cat   # 直接将标准输入的内容传递给cat
[root@xuexi tmp]# echo “/etc/inittab” | xargs cat   # 将标准输入的内容经过xargs处理后传递给cat[root@xuexi tmp]# find /etc -maxdepth 1 -name “*.conf” -print0 | xargs -0 -i grep “hostname” -l {} # 将搜索的文件传递给grep的参数位进行搜索,若不使用xargs,则grep将报错

xargs的作用不仅仅限于简单的stdin传递到命令的参数位,它还可以将stdin或者文件stdin分割成批,每个批中有很多分割片段,然后将这些片段按批交给xargs后面的命令进行处理。

通俗的讲就是原来只能一个一个传递,分批可以实现10个10个传递,每传递一次,xargs后面的命令处理这10个中的每一个,处理完了处理下一个传递过来的批,如下图。

但是应该注意的是,尽管实现了分批处理,但是默认情况下并没有提高任何效率,因为分批传递之后还是一次执行一个。而且有时候分批传递后是作为一个参数的整体,并不会将分批中的信息分段执行。这样看来,实现分批传递的目的仅仅是为了解决一些问题。但事实上,xargs提供了“-P”选项,用于指定并行执行的数量(默认只有一个处理进程,不会提升效率,可以指定为N个子进程,或者指定为0表示尽可能多地利用CPU),这样就能让分批操作更好地利用多核cpu,从而提升效率。例如上面分成了两批,指定”-P 2″可以并发执行这两个批,而非执行完第一批再执行第二批。关于并行处理的详细内容,见后文:高速并行处理之:xargs -P

剩下的就是处理xargs的细节问题了,比如如何分割(xargs、xargs -d、xargs -0),分割后如何划批(xargs -n、xargs -L),参数如何传递(xargs -i)。另外xargs还提供询问交互式处理(-p选项)和预先打印一遍命令的执行情况(-t选项),传递终止符(-E选项)等。

其实这里已经暗示了xargs处理的优先级或顺序了:先分割,再分批,然后传递到参数位。

分割有三种方法:独立的xargs、xargs -d和xargs -0。后两者可以配合起来使用,之所以不能配合独立的xargs使用,答案是显然的,指定了-d或-0选项意味着它不再是独立的。

分批方法从逻辑上说是两种:-n选项和-L选项。但我觉得还应该包含传递阶段的选项-i。假如-i不是分批选项,则它将接收分批的结果。然而事实并非如此,当-i选项指定在-n和-L选项之后,会覆盖-n或-L。后文中我将其当成分批选项来介绍和说明。

当然上述只是一个概括,更具体的还要看具体的选项介绍,而且很可能一个xargs中用不到这么多选项,但是理解这个很重要,否则在分割分批和传递上很容易出现疑惑。

1.2 文本意义上的符号和标记意义上的符号

在解释xargs和它的各种选项之前,我想先介绍一个贯穿xargs命令的符号分类:文本意义上的空格、制表符、反斜线、引号和非文本意义上的符号。我觉得理解它们是理解xargs分割和分批原理的关键。

文本意义上的空格、制表符、反斜线、引号:未经处理就已经存在的符号,例如文本的内容中出现这些符号以及在文件名上出现了这些符号都是文本意义上的。与之相对的是非文本意义的符号,由于在网上没找到类似的文章和解释,所以我个人称之为标记意义上的符号:处理后出现的符号,例如ls命令的结果中每个文件之间的制表符,它原本是不存在的,只是ls命令处理后的显示方式。还包括每个命令结果的最后的换行符,文件内容的最后一行结尾的换行符

如下图,属于标记意义上的符号都用红色圆圈标记出来了。

其实它们的关系有点类似于字面意义的符号和特殊符号之间的关系,就像有时候特殊符号需要进行转义才能表示为普通符号。

因为翻了百度、谷歌和一些书都没说这些方面的分类。但文本和非文本的符号在xargs分割的时候确实是区别对待的,所以我觉得有必要给个称呼好引用并说明它们,也就是说以上称呼完全是我个人的称呼。

1.3 分割行为之:xargs

[root@xuexi tmp]# cd /tmp
[root@xuexi tmp]# rm -fr *
[root@xuexi tmp]# mkdir a b c d test logdir shdir
[root@xuexi tmp]# touch “one space.log”
[root@xuexi tmp]# touch logdir/{1..10}.log
[root@xuexi tmp]# touch shdir/{1..5}.sh
[root@xuexi tmp]# echo “the second sh the second line” > shdir/2.sh
[root@xuexi tmp]# cat <<eof>shdir/1.sh
> the first sh
> the second line
> eof

对于xargs,它将接收到的stdout处理后传递到xargs后面的命令参数位,不写命令时默认的命令是echo。

[root@xuexi tmp]# cat shdir/1.sh | xargsthe first sh the second line
[root@xuexi tmp]# cat shdir/1.sh | xargs echothe first sh the second line

将分行处理掉不是echo实现的,而是管道传递过来的stdin经过xargs处理后的:将所有空格、制表符和分行符都替换为空格并压缩到一行上显示,这一整行将作为一个整体,这个整体的所有空格属性继承xargs处理前的符号属性,即原来是文本意义的或标记意义的在替换为空格后符号属性不变。这个整体可能直接交给命令或者作为stdout通过管道传递给管道右边的命令,这时结果将作为整体传递,也可能被xargs同时指定的分批选项分批处理。

如果想要保存制表符、空格等特殊符号,需要将它们用单引号或双引号包围起来,但是单双引号(和反斜线)都会被xargs去掉。

另外经过我的测试,单引号和双引号的存在让处理变的很不受控制,经常会影响正常的分割和处理。

如果不指定分批选项,xargs的一整行结果将作为一个整体输出,而不是分隔开的。也许看处理的结果感觉是分开处理的,例如下面的第一个命令,但是这是因为ls允许接受多个空格分开的参数,执行第二个命令,可以证明它确实是将整行作为整体传输给命令的。

[root@xuexi tmp]# find /tmp -maxdepth 1 | xargs ls

/tmp/sh.txt

/tmp:

a b c d logdir shdir sh.txt test

/tmp/a:

/tmp/b:

/tmp/c:

/tmp/d:

/tmp/.ICE-unix:

/tmp/logdir:

10.log 1.log 2.log 3.log 4.log 5.log 6.log 7.log 8.log 9.log

/tmp/shdir:

1.sh 2.sh 3.sh 4.sh 5.sh hell sh.txt

/tmp/test:

[root@xuexi tmp]# find /tmp -maxdepth 1 | xargs -p ls   # -p选项后面有解释

ls /tmp /tmp/x.txt /tmp/logdir /tmp/b /tmp/test /tmp/d /tmp/vmware-root /tmp/sh.txt /tmp/c /tmp/shdir /tmp/a /tmp/one space.log /tmp/.ICE-unix ?…

如果对独立的xargs指定分批选项,则有两种分批可能:指定-n时按空格分段,然后划批,不管是文本意义的空格还是标记意义的空格,只要是空格都是-n的操作对象;指定-L或者-i时按段划批,文本意义的符号不被处理。

[root@xuexi tmp]# ls   #one space.log是一个文件的文件名,只是包含了空格

a b c d logdir one space.log shdir sh.txt test vmware-root x.txt

[root@xuexi tmp]# ls | xargs -n 2

a b

c d

logdir one # one和space.log分割开了,说明-n是按空格分割的

space.log shdir

sh.txt test

vmware-root x.txt

[root@xuexi tmp]# ls | xargs -L 2

a b

c d

logdir one space.log # one space.log作为一个分段,文件名中的空格没有分割这个段

shdir sh.txt

test vmware-root

x.txt

[root@xuexi tmp]# ls | xargs -i -p echo {}

echo a ?…

echo b ?…

echo c ?…

echo d ?…

echo logdir ?…

echo one space.log ?… # one space.log也没有被文件名中的空格分割

echo shdir ?…

echo sh.txt ?…

echo test ?…

echo vmware-root ?…

echo x.txt ?…

1.4 使用xargs -pxargs -t观察命令的执行过程

使用-p选项是交互询问式的,只有每次询问的时候输入y(或yes)才会执行,直接按enter键是不会执行的。

使用-t选项是在每次执行xargs后面的命令都会先在stderr上打印一遍命令的执行过程然后才正式执行。

使用-p或-t选项就可以根据xargs后命令的执行顺序进行推测,xargs是如何分段、分批以及如何传递的,这通过它们有助于理解xargs的各种选项。

[root@xuexi tmp]# ls | xargs -n 2 -t

/bin/echo a b # 先打印一次命令,表示这一次只echo两个参数:a和b

a b

/bin/echo c d # 表示这次只打印c和d

c d

/bin/echo logdir one

logdir one

/bin/echo space.log shdir

space.log shdir

/bin/echo sh.txt test

sh.txt test

/bin/echo vmware-root

vmware-root

[root@xuexi tmp]# ls | xargs -n 2 -p

/bin/echo a b ?…y # 询问是否echo a b

/bin/echo c d ?…a b

y # 询问是否echo c d,后面的…a b指示了echo c d是在前一个结果的基础上接着执行的

/bin/echo logdir one ?…c d

y

/bin/echo space.log shdir ?…logdir one

y

/bin/echo sh.txt test ?…space.log shdir

y

/bin/echo vmware-root ?…sh.txt test

y

vmware-root

从上面的-t和-p的结果上都可以知道每次传递两个参数。

1.5 分割行为之:xargs -d

xargs -d有如下行为:

? xargs -d可以指定分段符,可以是单个符号、字母或数字。如指定字母o为分隔符:xargs -d”o”

? xargs -d是分割阶段的选项,所以它优先于分批选项(-n-L-i)。

? xargs -d不是先xargs-d处理的,它是区别于独立的xargs的另一个分割选项。

xargs -d整体执行有几个阶段:

? 替换:将接收stdin的所有的标记意义的符号替换为\n,替换完成后所有的符号(空格、制表符、分行符)变成字面意义上的普通符号,即文本意义的符号。

? 分段:根据-d指定的分隔符进行分段并用空格分开每段,由于分段前所有符号都是普通字面意义上的符号,所以有的分段中可能包含了空格、制表符、分行符。也就是说除了-d导致的分段空格,其余所有的符号都是分段中的一部分。

? 输出:最后根据指定的分批选项来输出。这里需要注意,分段前后有特殊符号时会完全按照符号输出。

从上面的阶段得出以下两结论:

(1)xargs -d会忽略文本意义上的符号。对于文本意义上的空格、制表符、分行符,除非是-d指定的符号,否则它们从来不会被处理,它们一直都是每个分段里的一部分;

(2)由于第一阶段标记意义的符号会替换为分行符号,所以传入的stdin的每个标记意义符号位都在最终的xargs -d结果上分行了,但是它们已经是分段中的普通符号了,除非它们是-d指定的符号。

例如对ls的结果指定”o”为分隔符。

[root@xuexi tmp]# ls

a b c d logdir one space.log shdir sh.txt test vmware-root

[root@xuexi tmp]# ls | xargs -d”o”  #指定字母”o”为分隔符

分段结果如图所示,图中每个封闭体都是一个分段,这些分段里可能包含了分行,可能包含了空格。

如果使用xargs -d时不指定分批选项,则整个结果将作为整体输出。

[root@xuexi tmp]# ls | xargs -d”o” -p

/bin/echo a

b

c

d

l gdir

ne space.l g

shdir

sh.txt

test

vmware-r t

x.txt

?…

如果指定了分批选项,则按照-d指定的分隔符分段后的段分批,这时使用-n、-L或-i的结果是一样的。例如使用-n选项来观察是如何分批的。

[root@xuexi tmp]# ls | xargs -d”o” -n 2 -t

/bin/echo a

b

c

d

l gdir # 每两段是一个批。

a

b

c

d

l gdir

# 注意这里有个空行。是因为段的分隔符处于下一段的行开头,它的前面有个\n符号会按符号输出。

/bin/echo ne space.l g

shdir

sh.txt

test

vmware-r # 打印中间两段

ne space.l g

shdir

sh.txt

test

vmware-r

/bin/echo t # 打印最后一段,

t # 注意t前面有空格,因为是两个分隔符o连在一起分割的,所以前面有个空格需要输出。

下面是最终显示结果。

[root@xuexi tmp]# ls | xargs -d”o” -n 2

a

b

c

d

l gdir

ne space.l g

shdir

sh.txt

test

vmware-r

t

再看看-n 1的输出。

[root@xuexi tmp]# ls | xargs -d”o” -n 1

a

b

c

d

l

gdir

ne space.l

g

shdir

sh.txt

test

vmware-r

t

[root@xuexi tmp]#

1.6 分割行为之:xargs -0

xargs -0的行为和xargs -d基本是一样的,只是-d是指定分隔符,-0是指定固定的\0作为分隔符。其实xargs -0就是特殊的xargs -d的一种,它等价于xargs -d”\0″。

xargs -0行为如下:

? xargs -0是分割阶段的选项,所以它优先于分批选项(-n-L-i)。

? xargs -0不是先xargs-0处理的,它是区别于独立的xargs的另一个分割选项。

? xargs -0可以处理接收的stdin中的null字符(\0)。如果不使用 -0选项或– -null选项,检测到\0后会给出警告提醒,并只向命令传递非\0段。xargs -0– -null是一样的效果。

xargs -0整体执行有几个阶段:

? 替换:将接收stdin的所有的标记意义的符号替换为\n,替换完成后所有的符号(空格、制表符、分行符)变成字面意义上的普通符号,即文本意义的符号。

? 分段:将检测到的null字符(\0)使用标记意义上的空格来分段,由于分段前所有符号都是普通字面意义上的符号,所以有的分段中可能包含了空格、制表符、分行符。也就是说除了-0导致的分段空格,其余所有的符号都是分段中的一部分。

如果没有检测到\0,则接收的整个stdin将成为一个不可分割的整体,任何分批选项都不会将其分割开,因为它只有一个段。

? 输出:最后根据指定的分批选项来输出。这里需要注意,分段前后有特殊符号时会完全按照符号输出。

根据上面的结论可知,xargs -0会忽略所有文本意义上的符号,它的主要目的是处理\0符号。

[root@xuexi tmp]# touch “one space.log”

[root@xuexi tmp]# ls | tr ” ” “\t” | xargs -0  #忽略文本意义上的制表符

a

b

c

d

logdir

one space.log

shdir

sh.txt

test

vmware-root

# 注意有空行,因为命令结尾是一个标记意义上换行符号

[root@xuexi tmp]# ls | tr ” ” ” ” | xargs -0   #忽略文本意义上的空格

a

b

c

d

logdir

one space.log

shdir

sh.txt

test

vmware-root

# 注意有空行

如果检测到\0而没有使用-0或–null处理则给出警告。注意警告后执行哪些文件。

[root@xuexi tmp]# ls | tr ” ” “\0″

a

b

c

d

logdir

onespace.log # 这里实际上是one\0space.log

shdir

sh.txt

test

vmware-root

[root@xuexi tmp]# ls | tr ” ” “\0” | xargs

xargs: Warning: a NUL character occurred in the input. It cannot be passed through in the argument list. Did you mean to use the –null option?

a b c d logdir one shdir sh.txt test vmware-root # 执行时将space.log忽略了,其余都执行

再例如,将所有的换行符换成null字符,结果中除了最前面的字母a和由于空格而不被\0影响的space.log,其余的由于全部有\0全部被忽略。

[root@xuexi tmp]#  ls | tr “\n” “\0”

a bcdlogdirone space.logshdirsh.txttestvmware-root # 只有a的前面和space.log的前面是没有\0的

[root@xuexi tmp]#  ls | tr “\n” “\0” | xargs

xargs: Warning: a NUL character occurred in the input. It cannot be passed through in the argument list. Did you mean to use the –null option?

a space.log # 所以只执行这两个

使用-0或–null来解决问题,也可以使用等价的xargs -d”\0″来解决。

[root@xuexi tmp]# ls | tr “\n” “\0” | xargs -0

或者

[root@xuexi tmp]# ls | tr “\n” “\0″ | xargs -d”\0”

a b c d logdir one space.log shdir sh.txt test vmware-root

如果使用xargs -0时不指定分批选项(-n、-L、-i),则处理后的结果将作为一个整体输出。

如果指定了分批选项,并且检测到了null字符,则以\0位的空格分段划批,这时使用-n、-L或-i的结果是一样的。例如使用-n选项来观察是如何分批的。

[root@xuexi tmp]# ls | tr “\n” “\0” | xargs -0 -n 3

a b c

d logdir one space.log

shdir sh.txt test

vmware-root x.txt

如果指定了分批选项,但没有检测到null字符,则整个结果将称为一个不可分割整体,这时使用分批选项是完全无意义的。

[root@xuexi tmp]# ls | xargs -0 -n 3 -p

/bin/echo a

b

c

d

logdir

one space.log

shdir

sh.txt

test

vmware-root

x.txt

?…

1.7 分批行为

分批用于指定每次传递多少个分段。有三种分批选项:-n,-L和-i。在本文的开头已经指明了为什么-i是分批选项,但是这里还是要介绍它逻辑上定义的功能:参数替换。

既然三种选项都是分批选项,如果在一个xargs中使用了多个分批选项,则它们之间必然会冲突,它们的规则是写在后面的生效,前面的分批选项被忽略

1.7.1 xargs -n

xargs -n分两种情况:和独立的xargs一起使用,这时按照每个空格分段划批;和xargs -d或xargs -0一起使用,这时按段分批,即不以空格、制表符和分行符分段划批。

[root@xuexi tmp]# ls | xargs -n 3 -p   #和独立的xargs一起使用,以空格分段划批

/bin/echo a b c ?…

/bin/echo d logdir one ?… # one和space.log被割开了

/bin/echo space.log shdir sh.txt ?…

/bin/echo test vmware-root x.txt ?…

/bin/echo ?…

[root@xuexi tmp]# ls | xargs -d”o” -n 3 -p  # 和xargs -d一起使用,按段分批

/bin/echo a

b

c

d

l gdir

ne space.l ?…

/bin/echo g

shdir

sh.txt

test

vmware-r t

x.txt

?…

/bin/echo ?…

1.7.2 xargs -L

和-n选项类似,唯一的区别是-L永远是按段划批,而-n在和独立的xargs一起使用时是按空格分段划批的。

该选项的一个同义词是-l,但是man推荐使用-L替代-l,因为-L符合POSIX标准,而-l不符合。使用–max-lines也可以。

也许你man xargs时发现-L选项是指定传递时最大传递行数量的,man的结果如下图。但是通过下面的实验可以验证其实-L是指定传递的最大段数,也就是分批。

[root@xuexi tmp]# ls | xargs -L 3 -p   #如果是指定传递的最大行数量,则一行就输出完了,这里却分了多行输出

/bin/echo a b c ?…

/bin/echo d logdir one space.log ?… # 这里可以证明-L和-n的区别

/bin/echo shdir sh.txt test ?…

/bin/echo vmware-root x.txt ?…

[root@xuexi tmp]# ls | xargs -d”o” -L 3 -p  # 这就更能证明是指定最大传递的段数量了

/bin/echo a

b

c

d

l gdir

ne space.l ?…

/bin/echo g

shdir

sh.txt

test

vmware-r t

x.txt

?…

1.7.3 xargs -ixargs -I

xargs -i选项在逻辑上用于接收传递的分批结果。

如果不使用-i,则默认是将分割后处理后的结果整体传递到命令的最尾部。但是有时候需要传递到多个位置,不使用-i就不知道传递到哪个位置了,例如重命名备份的时候在每个传递过来的文件名加上后缀.bak,这需要两个参数位。

使用xargs -i时以大括号{}作为替换符号,传递的时候看到{}就将被结果替换。可以将{}放在任意需要传递的参数位上,如果多个地方使用{}就实现了多个传递。

xargs -I(大写字母i)和xargs -i是一样的,只是-i默认使用大括号作为替换符号,-I则可以指定其他的符号、字母、数字作为替换符号,但是必须用引号包起来。man推荐使用-I代替-i,但是一般都使用-i图个简单,除非在命令中不能使用大括号,如touch {1..1000}.log时大括号就不能用来做替换符号。

例如下面的重命名备份过程。

[root@xuexi tmp]# ls logdir/

10.log 1.log 2.log 3.log 4.log 5.log 6.log 7.log 8.log 9.log

[root@xuexi tmp]# ls logdir/ | xargs -i mv ./logdir/{} ./logdir/{}.bak   # 将分段传递到多个参数位

[root@xuexi tmp]# ls logdir/

10.log.bak 1.log.bak 2.log.bak 3.log.bak 4.log.bak 5.log.bak 6.log.bak 7.log.bak 8.log.bak 9.log.bak

但是我将“-i”选项划分在分批选项里,它默认一个段为一个批,每次传递一个批也就是传递一个段到指定的大括号{}位上。在稍后的分批选项的生效规则部分我会给出我的理由。

由于-i选项是按分段来传递的。所以尽管看上去等价的xargs echo和xargs -i echo {}并不等价。

[root@xuexi tmp]# ls | xargs echo

a b c d logdir one space.log shdir sh.txt test vmware-root

[root@xuexi tmp]# ls | xargs -i echo {}

a

b

c

d

logdir

one space.log

shdir

sh.txt

test

vmware-root

既然使用-i后是分段传递的,这就意味着指定了它就无法实现按批传递多个参数了;并且如果使用多个大括号,意味着必须使用-i,那么也无法分批传递。

例如,想将数字1-10每3个数显示在start和end之间。效果如下:

start 1 2 3 end

start 4 5 6 end

start 7 8 9 end

start 10 end

由于指定了参数传递位置,所以必须使用-i,那么就无法一次传递3个数。要解决这个问题,就要想办法让每三个数分一次段然后使用-i传递,方法也就随之而来了。可以将每三个数分一次行写入一个文件。如:

[root@xuexi tmp]# cat <<eof>logdir/1.log

> 1 2 3

> 4 5 6

> 7 8 9

> 10

> eof

再使用xargs -i分批传递。

[root@xuexi tmp]# cat logdir/1.log | xargs -i echo “start {} end”

start 1 2 3 end

start 4 5 6 end

start 7 8 9 end

start 10 end

也可以使用多次xargs。很多时候无法解决分段的问题都可以通过多次使用xargs来解决。

[root@xuexi tmp]# echo {1..10} | xargs -n 3 | xargs -i echo “start {} end”

1.7.4 分批选项的生效规则

-i-L-n选项都是分批选项。它们的生效规则是,谁指定在后面,谁就生效。

下面给出证明。

下面-i放在-n、-L之后,结果是-n、-L被忽略。

[root@xuexi tmp]# ls | xargs -d”o” -n 2 -p -i echo {}

echo a

b

c

d

l ?… # 说明是一段一段输出,而不是两段一批输出,即-n选项被忽略

echo gdir

?…

echo ne space.l ?…

echo g

shdir

sh.txt

test

vmware-r ?…

echo ?…

echo t

x.txt

?…

[root@xuexi tmp]# ls | xargs -d”o” -L 3 -i -p echo {}   # 和上面的结果是一模一样的,说明-L选项被忽略

echo a

b

c

d

l ?…

echo gdir

?…

echo ne space.l ?…

echo g

shdir

sh.txt

test

vmware-r ?…

echo ?…

echo t

x.txt

?…

下面是-L放在-n后,结果是-n被忽略。

[root@xuexi tmp]# ls | xargs -d”o” -n 2 -p -L 1 echo  # 结果也是一段一段输出的,说明-n选项被忽略

echo a

b

c

d

l ?…

echo gdir

?…

echo ne space.l ?…

echo g

shdir

sh.txt

test

vmware-r ?…

echo ?…

echo t

x.txt

?…

根据上面的证明,其实也就给出了我认为-i选项是分批选项的理由,因为它覆盖了-n和-L,实际上在新的man xargs中已经给出了解释,它隐含”-L 1″。其实如果-i包含分批并传递这两个作用更严格一点

1.7.5 分批选项的一个典型应用

分批选项有时特别有用,例如脚本规定每次只能传输三个参数。有时候rm -rf的文件数量特别多的时候会提示参数列表太长而导致失败,这时就可以分批来按批删除,不仅rm -rf,其他很多本身就可以实现批量操作的命令都有可能出现这种参数列表过长的错误,如touch {1..10000000}也会提示错误。

假设目前在/tmp/longshuai/下有29W个.log文件,如果直接删除将会提示参数列表过长。

[root@xuexi tmp]# rm -fr /tmp/longshuai/*.log

-bash: /bin/rm: Argument list too long

这时如果使用xargs就可以分批丢给rm -fr处理了。下面一批10000个,删除29批。

[root@xuexi tmp]# cd /tmp/longshuai/ && ls | xargs -n 10000  rm -rf

如果不使用分批直接交给rm -rf也是一样可以执行成功的。如果想知道为什么可以请看后文xargs -s。

[root@xuexi tmp]# cd /tmp/longshuai/ && ls | xargs rm -rf

这里说下如何统计某个目录下的文件数量?ll后使用”-“开头来过滤出文件,然后使用wc统计行数。

[root@xuexi tmp]# ll /tmp/longshuai/ | grep “^-” | wc -l

1.8 终止行为之:xargs -E

指定终止符号,搜索到了指定的终止符就完全退出传递,命令也就到此结束。

-e选项也是,但是官方建议使用-E替代-e,因为-E是POSIX标准兼容的,而-e不是。

-E会将结果空格、制表符、分行符替换为空格并压缩到一行上显示。

据我测试,-E似乎只能和独立的xargs使用,和-0、-d配合使用时都会失效。那么稍后我就只测试和独立的xargs配合使用的情况了。

-E优先于-n、-L和-i执行。如果是分批选项先执行,则下面的第二个结果将压缩在一行上。

指定的终止符必须是完整的,例如想在遇到“xyz.txt”的符号终止时,只能指定完整的xyz.txt符号,不能指定.txt或者txt这样的符号。如何判断指定的终止符号是否完整,就-E与独立的xargs配合的情况而言分两种情况:如果没指定分批选项或者指定的分批选项是-n或者-L时,以空格为分割符,两个空格之间的段都是完整的;如果指定的分批选项是-i,则以段为分割符。

例如,下面的示例。观察实验结果中的one space.log分割的情况。

[root@xuexi tmp]# ls

a b c d logdir one space.log shdir sh.txt test vmware-root x.txt

[root@xuexi tmp]# ls | xargs -E one     #不指定分批选项

a b c d logdir

[root@xuexi tmp]# ls | xargs -n 2 -E one      #指定-n,one后面的所有的都终止传递

a b

c d

logdir

[root@xuexi tmp]# ls | xargs -L 2 -E”one”      #同-n 选项

a b

c d

logdir

[root@xuexi tmp]# ls | xargs -i -E”one space.log” echo {}         #和-i配合使用时指定完整的段才可以

a

b

c

d

logdir

[root@xuexi tmp]# ls | xargs -i -E”one”  -p echo {}          #非完整段终止失效

echo a ?…

echo b ?…

echo c ?…

echo d ?…

echo logdir ?…

echo one space.log ?…

echo shdir ?…

echo sh.txt ?…

echo test ?…

echo vmware-root ?…

echo x.txt ?…

1.9 xargs的处理总结

总结只有一张表。算是用来复习前面所述。

分割行为 特殊符号处理方式 分段方法 配合分批选项 分批方法
xargs 空格、制表符、分行符替换为空格,引号和反斜线删除。处理完后只有空格。如果空格、制表符和分行符使用引号包围则可以保留 结果继承处理前的符号性质(文本符号还是标记意义符号)。 -n 以分段结果中的每个空格分段,进而分批。不管是文本还是标记意义的空格,只要是空格
-L、-i 以标记意义上的空格分段,进而分批
不指定 结果作为整体输出
xargs -d xargs -d 不处理文本意义上的符号,所有标记意义上的符号替换为换行符\n,将-d指定的分割符替换为标记意义上的空格。结果中除了最后的空行和-d指定的分割符位的分段空格,其余全是文本意义上的符号 按照-d指定的符号进行分段,每个段中可能包含文本意义上的空格、制表符、甚至是分行符。 -n、-L、-i 以标记意义上的符号(即最后的空行和-d指定分隔符位的空格)分段,进而分批。分段结果中保留所有段中的符号,包括制表符和分行符。
不指定 结果作为整体输出
xargs -0 不处理文本意义上的符号,将非\0的标记意义上的符号替换为\n,将\0替换为空格。结果中除了最后空行和\0位的空格,其余都是文本意义上的符号 以替换\0位的空格分段,每个段中可能包含文本意义上的空格、制表符、甚至是分行符。如果没检测到\0,则只有一个不可分割的段。 -n、-L、-i 检测到\0时,以标记意义上的符号(即最后的空行和\0位的空格)分段,进而分批。分段结果中保留所有段中的符号,包括制表符和分行符。
未检测到\0时,整个结果作为不可分割整体,使用分批选项是无意义的
不指定 结果作为整体输出

1.10 xargsfind的结合

xargs和find同属于一个rpm包findutils,xargs原本就是为find而开发的,它们之间的配合应当是天衣无缝的。

一般情况下它们随意结合都无所谓,按正常方式进行即可。但是当删除文件时,特别需要将文件名含有空白字符的文件纳入考虑。

[root@xuexi tmp]# touch one;touch space.log

[root@xuexi tmp]# ls

a b c d logdir one one space.log shdir sh.txt space.log test vmware-root

现在假设通过find搜索到了one space.log。

[root@xuexi tmp]# find -name “* *.log”

./one space.log

如果直接交给xargs rm -rf,由于xargs处理后不指定分批选项时以空格分段,所以改名了的行为将是rm -rf ./one space.log,这表示要删除的是当前目录下的one和当前目录下的space.log,而不是one space.log。

有多种方法可以解决这个问题。思路是让找到的“one space.log”成为一个段,而不是两个段。我给出了常见的两种。

方法一:通过常用的find的-print0选项使用\0来分隔而不是\n分隔,再通过xargs -0来配对保证one space.log的整体性。因为-print0后one space.log的前后各有一个\0,但是文件名中间没有。

[root@xuexi tmp]# find -name “* *.log” -print0 | xargs -0 rm -rf

当然,能使用-0肯定也能使用-d了。

[root@xuexi tmp]# find -name “* *.log” -print0 | xargs -d “x” rm -rf     #随意指定非文件名中的字符都行,不一定非要\0

方法二:不在find上处理,在xargs上处理,只要通过配合-i选项,就能宣告它的整体性。

[root@xuexi tmp]# find -name “* *.log” | xargs -i rm -rf “{}”

相较而言,方法一使用的更广泛更为人所知,但是方法二更具有通用性,对于非find如ls命令也可以进行处理。

还可以使用tr将find的换行符换成其他符号再xargs分割配对也行。

除了find -print0可以输出\0字符,Linux中还有其他几个命令配合参数也可以实现:locate -0,grep -zgrep -Z,sort -z

1.11 xargs -s之为什么ls | xargs rm -rf能执行成功?

使用下面的示例配合图来解释。

[root@xuexi tmp]# cd logdir

[root@xuexi logdir]# touch {1..1000000}

-bash: /bin/touch: Argument list too long

[root@xuexi logdir]# echo {1..1000000} | xargs  touch      #执行的时候记得使用-p选项,否则慢慢等吧。

问题一:正常创建批量文件touch {1..1000000}是无法执行成功的,会提示参数列表过长。但是上面的最后一个命令为什么能执行成功?

问题二:xargs处理后如果不指定-n选项,那么它是整体传递的,如果这个整体非常非常大,如上面的100W个参数,按理说touch也是无法成功的。为什么成功了?

xargs有一个默认的选项-s,它指定每次传递的最大字节数,如果不显式指定-s,系统默认是128KB。也就是说如果一次传递的参数很多很大,那么将由系统自动分割为每128KB传递一次。这就是上面的命令能执行成功的原因。

上面的100W个参数,以差不多每个参数5个数字位加一个分段位空格共6个字节计算,128K有128*1024/6=21845个数字,这和我使用-p测试的询问位置是接近的,如下图,由于前10000个数字少于5个字节,所以比21845多一点。第二次停止的位置是45539,45539-23695=21844,这次传递的全是5个字节的,这和计算的结果几乎完全相同。

同理“ls | xargs rm -rf”也是一样的,如果参数列表非常大,则每次传递128K的参数给rm。

1.12 创建文件名包含分行符的文件

创建文件名包含空格的文件是一件很轻松的事情,但是想创建包含制表符、分行符甚至是其他特殊符号的文件呢?

因为xargs允许传递参数到命令的任意参数位,并且传递的参数还可以变换为包含各种形式的特殊符号,所以使用它可以轻松实现。例如创建包含分行符的文件。

[root@xuexi tmp]# ls

a b c d logdir one space.log shdir sh.txt test vmware-root

[root@xuexi tmp]# ls | xargs -0

a

b

c

d

logdir

one space.log

shdir

sh.txt

test

vmware-root

在此基础上创建一个.sh文件,这个文件将奇形怪状,因为文件名竟然包含了分行符(Linux中文件名除了“/”“\0”外所有字符都允许包含在内)

[root@xuexi tmp]# ls | xargs -0 -i touch {}.sh

[root@xuexi tmp]# ls

a b d one space.log sh.txt vmware-root

a?b?c?d?logdir?one space.log?shdir?sh.txt?test?vmware-root?.sh c logdir shdir test

看上去只是有几个问号,但是使用?是无法定位它的。

[root@xuexi tmp]# find -name “*[\?]*”        #搜索没结果

 

或者

 

[root@xuexi tmp]# rm -rf a     #按两次tab键

a/

a^Jb^Jc^Jd^Jlogdir^Jone space.log^Jshdir^Jsh.txt^Jtest^Jvmware-root^J.sh

现在使用xargs就可以轻松显示它的文件名。

[root@xuexi tmp]# ls | xargs -0

a

a

b

c

d

logdir

one space.log

shdir

sh.txt

test

vmware-root

.sh

b

c

d

logdir

one space.log

shdir

sh.txt

test

vmware-root

不能直接使用xargs显示,因为它会压缩空白符号成空格。

[root@xuexi tmp]# ls | xargs

a a b c d logdir one space.log shdir sh.txt test vmware-root .sh b c d logdir one space.log shdir sh.txt test vmware-root

删除它。

[root@xuexi tmp]# rm -f a*.sh

如果想创建文件名只包含下面结果的abcd前四行的.sh文件呢?

[root@xuexi tmp]# ls | xargs -0

a

b

c

d

logdir

one space.log

shdir

sh.txt

test

vmware-root

参考下面的。

[root@xuexi tmp]# ls | xargs -n 1 -e”logdir” | xargs -0 -i touch {}.sh

这就需要理解前面介绍的xargs的分割和传递方法了。

也可以使用下面更简单容易理解的:

[root@xuexi tmp]# ls | head -n 4 | xargs -0 -i touch {}.sh

[root@xuexi tmp]# echo -e “a\nb\nc\nd” | xargs -0 -i touch {}.log

那么以相同的方法创建文件名中包含制表符的文件就easy了。

[root@xuexi tmp]# echo  -e “a\tb\tc\td” | xargs -0 -i touch {}.log

1.13 高速并发处理之:xargs -P

使用xargs的分批行为,除了可以解决一些问题,还可以一次性将多个分批交给不同进程去处理,这些进程可以使用多个cpu执行,效率可谓大幅提高。

“-P N”选项可以指定并行处理的进程数量为N。不指定”-P”时,默认为1个处理进程,也就是串行执行。指定为0时,将尽可能多地开启进程数量。当xargs正在运行时(也就是还有分批正在处理),可以发送SIGUSR1信号给xargs进程,表示增加一个处理进程,同样,可以向xargs进程发送SIGUSR2进程,表示减少一个处理进程。但需要注意,即使发送SIGUSR2信号,xargs也不会中断正在执行任务的进程,也就是说,在某个进程处理当前分批任务结束之前,不会被中断,只有当前分批任务执行完毕,准备接下一个分批任务时,才会被xargs给杀掉。

例如,一个简单的sleep命令,在不使用”-P”的时候,默认是一个进程按批的先后进行处理:

[root@xuexi ~]# time echo {1..4} | xargs -n 1 sleep

 

real    0m10.011s

user    0m0.000s

sys     0m0.011s

总共用了10秒,因为每批传一个参数,第一批睡眠1秒,然后第二批睡眠2秒,依次类推,还有3秒、4秒,共1+2+3+4=10秒。

如果使用-P指定4个处理进程:

[root@xuexi ~]# time echo {1..4} | xargs -n 1 -P 4 sleep

 

real    0m4.005s

user    0m0.000s

sys     0m0.007s

结果总共才用了4秒,因为这4个分批同时交给了4个进程同时处理,所以取最长睡眠时间。

以下是一次并行执行过程中,CPU的使用情况:

[root@xuexi ~]# ps -eo pid,args,psr,pcpu | grep slee[p]

25566 xargs -n 1 -P 5 sleep         3  0.0

25567 sleep 20                      1  0.0

25568 sleep 21                      2  0.0

25569 sleep 22                      0  0.0

25570 sleep 23                      2  0.0

25571 sleep 24                      3  0.0

在上面的结果中,启动了5个sleep进程,这5个进程分别用了cpu0、cpu1、cpu2和cpu3共4个cpu,因为我的虚拟机只给分配了4核心cpu。

那么,xargs的哪些选项可以通过”-P”的并行能力来提升效率?其实,只要能分批的选项,都可以使用”-P”,包括”-n”、”-L”和”-i”。在man xagrs中,只提到了”-n”和”-L”可以结合”-P”,并没有提到”-i”,但我前面已经验证过了,”-i”其实也是分批行为,也能结合”-P”的并行功能使用。

下面的示例,可以验证”-i -P”结合:

[root@xuexi ~]# time echo -n {1..4} | xargs -d” ” -i -P 4 sleep {}

 

real    0m4.003s

user    0m0.000s

sys     0m0.005s

如果需要发送信号,来增、减并行进程数量,可以向xargs进程发送SIGUSR1和SIGUSR2信号,例如:

kill -USR1 `pgrep -f “xargs”`

虽然xargs提供了这样的并行处理能力,但说实话,用到的机会并不多,它毕竟只是一个参数传递工具。我也专门写了一篇关于xargs高效并行的文章,见shell高效处理文本:xargs并行处理。另一个gnu工具parallel(装上epel源,yum -y install parallel即可)在并行处理上用的比较多,比如对一个巨大的文件利用sort进行排序时,使用parallel并行排序,可以大幅提升效率,即使sort自身已经足够完美。非常幸运的是,在你把xargs学到了这里,使用parallel将非常简单,因为它的选项和行为模式和xargs是基本一致的。

1.14 xargs一次性传递多个参数

默认情况下,xargs每次只能传递一条分割的数据到命令行中作为参数。但有时候想要让xargs一次传递2个、3个参数到命令行中。

例如有一个文件保存了wget想要下载的大量链接和链接对应要保存的文件名,一行链接一行文件名。格式如下:

https://www.xxx.yyy/a1

filename1

https://www.xxx.yyy/a2

filename2

https://www.xxx.yyy/a3

filename3

现在想要通过读取这个文件,将每一个URL和对应的文件名传递给wget去下载:

wget ‘{URL}’ -O ‘{FILENAME}’

xargs自身的功能无法一次性传递多个参数(parallel命令可以,而且方式多种),只能寻求一些技巧来实现。

cat url.txt | xargs -n2 bash -c ‘wget “$1” -O “$2″‘

1.15 xargs的不足之处(此处必看)

其实是xargs的限制和缺点,但因为通过”-i”选项方便演示,所以此处使用”-i”选项。注意,不是”-i”选项的缺陷。

由于xargs -i传递数据时是在shell执行xargs命令的时候,根据shell解析命令行的流程 ,xargs后的命令如果有依赖于待传递数据的表达式,则无法正确执行。

例如,无法通过xargs传递数值做正确的算术扩展:

[root@xuexi logdir]# echo 1 | xargs -I “x” echo $((2*x))

0

无法将数据传递到命令替换中。

[root@xuexi ~]# echo /etc/fstab | xargs -i `cat {}`
cat: {}: No such file or directory

参考下图的shell命令行解析过程。

这时要通过xargs正确实现目标,只能改变方法或寻找一些小技巧,例如:

[root@xuexi ~]# echo 1 | xargs -i expr 2 \* {}   # 感谢楼下评论者提供的expr思路
2
[root@xuexi ~]# echo /etc/fstab | xargs -i cat $(echo {})

另外,xargs无法处理bash内置命令。例如:

[root@xuexi ~]# echo /etc | xargs -i cd {}
xargs: cd: No such file or directory

 

Linux 命令大全 Linux 命令大全

 

Vmware 平台虚拟机导入到PVE平台上

 

PVE(Proxmox VE)是新的开源虚拟化平台,具有较多优点,如群集功能、容器等,但是实际操作中也有不少bug或不如意的地方。

现有一台vmware虚拟化平台的windows 2012R2 虚拟机,为了不重新安装操作系统和应用,因此希望通过直接转化的方法导入到PVE主机内。

检查pve资料,pve说可以通过两种方式导入,一种是通用ovf格式,另一种是直接加载vmdk磁盘。后来确认两种方式结果是几乎一样的。

我总结的导入过程如下:

1、将vmware下的windows2012R2虚拟机导出为OVF (略),但是要注意,不能导出成单个的ova文件,因为PVE中不认识达成包的OVA文件。但是导出ovf会生产三个文件,都需要拷贝出来。

2、将生成的三个ovf文件导入到pve的local存储上。正常可以使用local存储上“上传”的方法,选择*.*文件格式。也可以使用ssh工具,通过SFTP协议将文件上传只PVE 的ISO目录,该目录位于PVE机器的/var/lib/vz/template/iso   。

(注意:ssh secure shell client 3.2.9版本不行哦,我是用secure CRT 中SFTP上传的)

 

3、上传后就用PVE介绍的方式来导入虚拟机,说一种简单一点的方法,执行以下命令:

qm importovf 999  WindowsServer2012.ovf  local-lvm

其中999是导入虚拟机的ID,WindowsServer2012.ovf是虚拟机导入文件,local-lvm是放置虚拟机的磁盘卷。导入成功后,最后有100%的提示。

 

4、启动虚拟机,发现能看到windows 2012窗口,提示修复,反复重启,无法进入最后的操作系统界面,按照提示操作也几乎无法进行下去。

检查PVE文档,官网这样说:“除了格式问题之外,如果模拟的硬件从一个虚拟机监控程序到另一个虚拟机监控程序的变化太大,则从其他虚拟机监控程序导入磁盘映像可能会失败。Windows VM对此特别关注,因为OS对硬件的任何更改都很挑剔。可以通过在导出之前安装Internet上可用的MergeIDE.zip实用程序来解决此问题,并在引导导入的Windows VM之前选择IDE的硬盘类型。”

5、文档提示用IDE硬盘,就把硬盘类型从scsi改成IDE。

把原有硬盘从scsi上卸除。把硬盘挂载到ide0的总线上了,命令如下:

qm set 999 –ide0 local-lvm:vm-999-disk-0

 

6、可以挂PE,可对认到的IDE硬盘进行CHKDSK 的磁盘扫描,去除坏块等。方法如下:

chkdsk  /f:   e:   , 修正了一些小故障,重启还是不行,继续找问题。

 

7、突然想到应该要进安全模式,去除不合理的驱动,这样系统应该就能起来了。但是win2012启动时候缺省不响应F8,无法进入安全模式。

8、等待启动进入到了高级模式,找到命令行,在命令式模式下键入:bcdedit /set {default} bootmenupolicy legacy    这条命令是允许在win2012菜单出来之前可以按F8进入安全模式。

 

9、重启,在菜单出来之前按键F8进入安全模式。

10、可以进入到windows的安全模式,问题初步解决。找到“计算机管理”中的“设备管理器”,把里面没有用的驱动全部删除掉,特别是有vmware和HyperV字样的驱动,直至没有黄色的感叹号出现。

11、退出安全模式,再重新启动,终于出现了久违的Windows 2012 R2的画面。
————————————————
linux 迁移

VMware完美迁移PVE方法(两条命令解决)

未来村长 2021-05-05 15:07:40 20 收藏
分类专栏: 虚拟化 文章标签: 虚拟机 vmware pve
版权
一、为什么要迁移
因为VMware是收费的,PVE是免费的,就是这么简单粗暴,没有太多理由。
Proxmox优势:
Proxmox的主要特性,去中心化、超融合、高可用、开源低成本、易于实施管理,前面几个特性都和open stack一样,但是最后一点易于实施管理,open stack却做得不是特别好,对于易于实施管理这一点,主要有以下几个方面(引述):
1、proxmox以iso文件提供下载,刻录到u盘,安装方便高效。
2、创建集群,只需登陆每个系统执行一条指令,马上就能看到效果。
3、支持分布式存储,创建ceph存储池,也是寥寥几步就可完成,并很快可以在管理界面看到效果。
4、轻松实现高可用,web界面组成对象高可用(ha),也是易如反掌。
5、方便扩容,重复执行相同创建扩容命令即可完成。
6、统一界面。一个web入口,管理节点、存储、网络、虚拟机等所有资源,完成绝大部分用户操纵,无需要安装客户端。

1.迁移方法
(1)首先,把镜像从VMware虚拟机导出OVF格式
我用的是浏览器,客户端方法一样

(2)镜像已经导出成功,然后把导出来的镜像上传到PVE的镜像存储里面,上传的话,可以用FTP等,我用的是finalshell直接拉进去,保存路径是/var/lib/vz/template/iso/,后面根据自己实际保存路径来分。

 

(3)然后打开PVE,新建一个空白虚拟机,配置根据实际需要来配就行。

 

 

 

 

 

(4)然后用命令登录到PVE的节点node,用命令把镜像导入到刚才新建的虚拟机121里面,知道100%完成。
qm importdisk 121 /var/lib/vz/template/iso/test.vmdk local-zfs
qm set 121 –ide0 local-zfs:vm-121-disk-0
1
2
这里类型根据你虚拟机硬盘类型来选ide0还是scsi0,我就在这里翻车了,排查了很久才找到原因,所以,这里要注意。

 

(5)然后修改下刚才新建虚拟机的引导,放到第一个,不然的话,开机会找不到引导,一直重启。

 

(6)然后再开机,刚才导入进来的镜像已经可以开机运行了。

————————————————

Ubuntu安装Nginx和正确卸载Nginx Nginx相关

1.Ubuntu下安装Nginx比较简单

敲入下列命令即可:

    sudo apt-get update
    sudo apt-get install nginx

 

 

2.Ubuntu下卸载,稍不注意就会入坑

 

复制代码
    sudo apt-get remove nginx nginx-common # 卸载删除除了配置文件以外的所有文件。

    sudo apt-get purge nginx nginx-common # 卸载所有东东,包括删除配置文件。

    sudo apt-get autoremove # 在上面命令结束后执行,主要是卸载删除Nginx的不再被使用的依赖包。

    sudo apt-get remove nginx-full nginx-common #卸载删除两个主要的包。

  sudo service nginx restart  #重启nginx
复制代码

 

上面的命令基本上都能解决你在Ubuntu下安装卸载Nginx的问题。

 

 

3.查看nginx进程

复制代码
ps aux|grep nginx

在虚拟环境下安装uwsgi
pip install uwsgi

######启动Nginx服务
[root@typecodes ~]# service nginx start
######停止Nginx服务
[root@typecodes ~]# service nginx stop
######重启Nginx服务
[root@typecodes ~]# service nginx restart
######Nginx服务的状态
[root@typecodes ~]# service nginx status
######在Nginx服务启动的状态下,重新加载nginx.conf这个配置文件
[root@typecodes ~]# service nginx reload



复制代码

 

 

 

 

 

 

Django的部署可以有很多方式,采用nginx+uwsgi的方式是其中比较常见的一种方式。

在这种方式中,我们的通常做法是,将nginx作为服务器最前端,它将接收WEB的所有请求,统一管理请求。nginx把所有静态请求自己来处理(这是NGINX的强项)。然后,NGINX将所有非静态请求通过uwsgi传递给Django,由Django来进行处理,从而完成一次WEB请求。

可见,uwsgi的作用就类似一个桥接器。起到桥梁的作用。

Linux的强项是用来做服务器,所以,下面的整个部署过程我们选择在Ubuntu下完成。

 

一、安装Nginx                                                                        

Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好。

Nginx同样为当前非常流行的web服务器。利用其部署Django,我们在此也做简单的介绍。

Nginx官网:http://nginx.org/

打开ubuntu控制台(ctrl+alt+t)利用Ubuntu的仓库安装。

fnngj@ubuntu:~$ sudo apt-get install nginx  #安装

启动Nginx:

fnngj@ubuntu:~$ /etc/init.d/nginx start  #启动
fnngj@ubuntu:~$ /etc/init.d/nginx stop  #关闭
fnngj@ubuntu:~$ /etc/init.d/nginx restart  #重启

 

修改Nginx默认端口号,打开/etc/nginx/nginx.conf 文件,修改端口号。

复制代码
复制代码
 server {
    listen       8088;    # 修改端口号
    server_name  localhost;

    #charset koi8-r; 

    #access_log  logs/host.access.log  main;

    location / {
        root   html;
        index  index.html index.htm;
    }
复制代码
复制代码

大概在文件36行的位置,将默认的80端口号改成其它端口号,如 8088。因为默认的80端口号很容易被其它应用程序占用。

然后,通过上面命令重启nginx。访问:http://127.0.0.1:8088/

如果出现如上图,说明Nginx启动成功。

 

二、安装uwsgi

通过pip安装uwsgi。

root@ubuntu:/etc# python3 -m pip install uwsgi

 

测试uwsgi,创建test.py文件:

def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"]

 

通过uwsgi运行该文件。

fnngj@ubuntu:~/pydj$ uwsgi --http :8001 --wsgi-file test.py

 

接下来配置Django与uwsgi连接。此处,假定的我的django项目位置为:/home/fnngj/pydj/myweb

fnngj@ubuntu:~/pydj$ uwsgi --http :8001 --chdir /home/fnngj/pydj/myweb/ --wsgi-file myweb/wsgi.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191

 

常用选项:

http : 协议类型和端口号

processes : 开启的进程数量

workers : 开启的进程数量,等同于processes(官网的说法是spawn the specified number ofworkers / processes)

chdir : 指定运行目录(chdir to specified directory before apps loading)

wsgi-file : 载入wsgi-file(load .wsgi file)

stats : 在指定的地址上,开启状态服务(enable the stats server on the specified address)

threads : 运行线程。由于GIL的存在,我觉得这个真心没啥用。(run each worker in prethreaded mode with the specified number of threads)

master : 允许主进程存在(enable master process)

daemonize : 使进程在后台运行,并将日志打到指定的日志文件或者udp服务器(daemonize uWSGI)。实际上最常用的,还是把运行记录输出到一个本地文件上。

pidfile : 指定pid文件的位置,记录主进程的pid号。

vacuum : 当服务器退出的时候自动清理环境,删除unix socket文件和pid文件(try to remove all of the generated file/sockets)

 

三、Nginx+uwsgi+Django                                         

接下来,我们要将三者结合起来。首先罗列一下项目的所需要的文件:

myweb/

├── manage.py

├── myweb/

│   ├── __init__.py

│   ├── settings.py

│   ├── urls.py

│   └── wsgi.py

└── myweb_uwsgi.ini

在我们通过Django创建myweb项目时,在子目录myweb下已经帮我们生成的 wsgi.py文件。所以,我们只需要再创建myweb_uwsgi.ini配置文件即可,当然,uwsgi支持多种类型的配置文件,如xml,ini等。此处,使用ini类型的配置。

复制代码
复制代码
# myweb_uwsgi.ini file
[uwsgi]

# Django-related settings

socket = :8000

# the base directory (full path)
chdir           = /home/fnngj/pydj/myweb

# Django s wsgi file
module          = myweb.wsgi

# process-related settings
# master
master          = true

# maximum number of worker processes
processes       = 4

# ... with appropriate permissions - may be needed
# chmod-socket    = 664
# clear environment on exit
vacuum          = true
复制代码
复制代码

这个配置,其实就相当于在上一小节中通过wsgi命令,后面跟一堆参数的方式,给文件化了。

socket  指定项目执行的端口号。

chdir   指定项目的目录。

module  myweb.wsgi ,可以这么来理解,对于myweb_uwsgi.ini文件来说,与它的平级的有一个myweb目录,这个目录下有一个wsgi.py文件。

其它几个参数,可以参考上一小节中参数的介绍。

 

接下来,切换到myweb项目目录下,通过uwsgi命令读取myweb_uwsgi.ini文件启动项目。

复制代码
复制代码
fnngj@ubuntu:~$ cd /home/fnngj/pydj/myweb/
fnngj@ubuntu:~/pydj/myweb$ uwsgi --ini myweb_uwsgi.ini 
[uWSGI] getting INI configuration from myweb_uwsgi.ini
*** Starting uWSGI 2.0.12 (32bit) on [Sat Mar 12 13:05:06 2016] ***
compiled with version: 4.8.4 on 26 January 2016 06:14:41
os: Linux-3.19.0-25-generic #26~14.04.1-Ubuntu SMP Fri Jul 24 21:18:00 UTC 2015
nodename: ubuntu
machine: i686
clock source: unix
detected number of CPU cores: 2
current working directory: /home/fnngj/pydj/myweb
detected binary path: /usr/local/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
chdir() to /home/fnngj/pydj/myweb
your processes number limit is 15962
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uwsgi socket 0 bound to TCP address :8000 fd 3
Python version: 3.4.3 (default, Oct 14 2015, 20:37:06)  [GCC 4.8.4]
*** Python threads support is disabled. You can enable it with --enable-threads ***
Python main interpreter initialized at 0x8b52dc0
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 319920 bytes (312 KB) for 4 cores
*** Operational MODE: preforking ***
WSGI app 0 (mountpoint='') ready in 1 seconds on interpreter 0x8b52dc0 pid: 7158 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 7158)
spawned uWSGI worker 1 (pid: 7160, cores: 1)
spawned uWSGI worker 2 (pid: 7161, cores: 1)
spawned uWSGI worker 3 (pid: 7162, cores: 1)
spawned uWSGI worker 4 (pid: 7163, cores: 1)
复制代码
复制代码

注意查看uwsgi的启动信息,如果有错,就要检查配置文件的参数是否设置有误。

 

再接下来要做的就是修改nginx.conf配置文件。打开/etc/nginx/nginx.conf文件,添加如下内容。

复制代码
复制代码
……
server {
    listen         8099; 
    server_name    127.0.0.1 
    charset UTF-8;
    access_log      /var/log/nginx/myweb_access.log;
    error_log       /var/log/nginx/myweb_error.log;

    client_max_body_size 75M;

    location / { 
        include uwsgi_params;
        uwsgi_pass 127.0.0.1:8000;
        uwsgi_read_timeout 2;
    }   
    location /static {
        expires 30d;
        autoindex on; 
        add_header Cache-Control private;
        alias /home/fnngj/pydj/myweb/static/;
     }
 }
……
复制代码
复制代码

listen 指定的是nginx代理uwsgi对外的端口号。

server_name  网上大多资料都是设置的一个网址(例,www.example.com),我这里如果设置成网址无法访问,所以,指定的到了本机默认ip。

在进行配置的时候,我有个问题一直想不通。nginx到底是如何uwsgi产生关联。现在看来大概最主要的就是这两行配置。

include uwsgi_params;

uwsgi_pass 127.0.0.1:8000;

include 必须指定为uwsgi_params;而uwsgi_pass指的本机IP的端口与myweb_uwsgi.ini配置文件中的必须一直。

 

现在重新启动nginx,翻看上面重启动nginx的命令。然后,访问:http://127.0.0.1:8099/

通过这个IP和端口号的指向,请求应该是先到nginx的。如果你在页面上执行一些请求,就会看到,这些请求最终会转到uwsgi来处理。

 

=============

ps: 这个过程本应不算复杂,之前花两天时间没搞定,索性放到了一边,这次又花了两天时间才算搞定。网上搜到的文章比较乱,有些太简单的看不懂,有些又太啰嗦的不知道核心的几步是什么,希望本文能帮到你。

 

Linux中apt与apt-get命令的区别与解释apt方式卸载软件

apt方式卸载删除命令

apt-get –purge remove
删除已安装包(不保留配置文件)。
如软件包a,依赖软件包b,则执行该命令会删除a,而且不保留配置文件

apt-get autoremove
删除为了满足依赖而安装的,但现在不再需要的软件包(包括已安装包)。
如软件包a,依赖软件包b,则执行该命令会同时删除软件包a,b

apt-get remove
删除已安装的软件包(保留配置文件)。
如软件包a,依赖软件包b,则执行该命令会删除a,且保留配置文件

apt-get autoclean
APT的底层包是dpkg, 而dpkg 安装Package时, 会将 *.deb 放在 /var/cache/apt/archives/中.
apt-get autoclean 只会删除 /var/cache/apt/archives/ 已经过期的deb.

apt-get clean
使用 apt-get clean 会将 /var/cache/apt/archives/ 的 所有 deb 删掉.
类似于 rm /var/cache/apt/archives/*.deb

linux卸载apache安装nginx部署

 

劲枫 2018-12-18 19:59:54 1577 收藏
分类专栏: 笔记
版权
sudo service apache2 stop

update-rc.d -f apache2 remove

sudo apt-get remove apache2

sudo apt-get update

sudo apt-get install nginx

nginx流量拆分、端口映射、静态资源代理
————————————————
版权声明:本文为CSDN博主「劲枫」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/TCF_JingFeng/article/details/85063297

linux系统部署Nginx

linux系统部署Nginx

一、linux系统部署Nginx

1、准备工作
Nginx的安装依赖于以下三个包,意思就是在安装Nginx之前首先必须安装一下的三个包,注意安装顺序如下:
1 SSL功能需要openssl库,直接通过yum安装:
 yum install openssl
2 gzip模块需要zlib库,直接通过yum安装:
 yum install zlib
3 rewrite模块需要pcre库,直接通过yum安装:
 yum install pcre
2、安装Nginx依赖项和Nginx
1 
使用yum安装nginx需要包括Nginx的库,安装Nginx的库
rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
2 
使用下面命令安装nginx
yum install nginx
3 
启动Nginx
service nginx start
nginx -s reload  :修改配置后重新加载生效
3、直接浏览器访问localhost就会出现Nginx的欢迎界面表示你安装成功了,否则就是安装失败了
4、配置Nginx
CentOS安装Nginx后,安装在了
/etc/nginx/目录下,你可以打开/etc/nginx/conf.d/default/conf查看里面的配置,包括监听端口,域名和nginx访问的根目录

二、linux下配置nginx使用service nginx start 服务

1:接下来我们简单的为它提供一个服务脚本吧!
# vim  /etc/init.d/nginx

2:新建文件/etc/rc.d/init.d/nginx,内容如下:

#!/bin/bash
# chkconfig:235 85 15
# description: Nginx is an HTTP server

. /etc/rc.d/init.d/functions

start() {

        echo "Start..."

        /usr/local/nginx/sbin/nginx &> /dev/null

        if [ $? -eq 0 ];then

                echo "Start successful!"

        else

                echo "Start failed!"

        fi

}

 

stop() {

        if killproc nginx -QUIT ;then

                echo "Stopping..."

        fi

}

 

restart() {

        stop

        sleep 1

        start

}

 

reload() {

        killproc nginx -HUP

        echo "Reloading..."

}

 

configtest() {

        /usr/local/nginx/sbin/nginx -t

}

 

case $1 in

start)

        start ;;

stop)

        stop ;;

restart)

        restart ;;

reload)

        reload ;;

configtest)

        configtest ;;

*)

        echo "Usage: nginx {start|stop|restart|reload|configtest}"

        ;;

esac

之后给这个文件可执行权限:

chmod  +x  /etc/init.d/nginx

现在可以使用 start,stop 这些参数控制Nginx服务了

Nginx编译安装时常见错误分析

Nginx编译安装时常见错误分析 – a2796749的专栏 – CSDN博客​blog.csdn.net

linux如何查看nginx是否启动

第一种方法:查看进程列表并过滤

 ps -ef | grep nginx 

第二种方法:使用netstat命令

netstat -anp | grep :80

nginx卸载

    yum remove nginx 

linux系统上nginx安装及简单的反向代理配置

1. 更改配置文件

其配置文件位置: /application/nginx/conf/nginx.conf

2.重启nginx

先 ps -ef | grep nginx ,会出现5个关于nginx的进程,如果5个进程的id分别为 100、101、102、103、104
杀掉所有nginx进程 kill -9 101 102 103 104 
进入目录 cd /usr/sbin
重启   nginx -c /etc/nginx/nginx.conf

至于 nginx -s  reload 不建议使用,本人亲试,有时候无效

启动nginx的时候也可以 cd  /usr/sbin,然后直接 nginx , (-c 配置文件,表示根据指定文件启动,如果该配
置文件和安装的nginx命令不是一个版本,会报错) 启动后,nginx -t  可以查看是根据那个配置文件启动的,
所以建议linux系统里只保留一个nginx.conf文件, 以免出现冲突,一般nginx.conf在两个位置,
分别是/usr/local/nginx/conf/nginx.conf和/etc/nginx/nginx.conf

nginx.conf 配置如下:

http{
        .........
    server{
        listen      80;
        server_name    192.16.10.10;
        location / {
            proxy_pass http://localhost:8081
        }
      }

      server{
            listen      80;
            server_name      www.acdf.com;
            location / {
                    proxy_pass http://localhost:8082
        }
     }
}                                            

疑问:

1.需要两个tomcat实例共用 80 端口,是不是 监听  listen  都为 80 ?
2.nginx 是怎样根据请求地址 来正则匹配 到不同的 虚拟主机的?我的理解是申请两个域名都绑定到我
映射的同一 ip,然后在不同的 server{} 中的 server_name 填入两个域名,通过域名匹配再转到本地的
http://localhost:8081 
3.就是 server_name  ,这个到底是什么意思,该怎么填写?网上有说填 localhost 的,也有 像我第一种
配置直接写ip:port   192.16.10.10:8081 的。如果是这种ip:port 方式的话,我的前端请求地址该如何写
,是直接写我映射的地址  http://192.16.10.10   还是  http://192.16.10.10:8081  ? 但是这样写的话
,我监听的 80 端口还有作用吗? 我的 server_name 又该怎样写?
server下的节点:
server_name :基于域名的虚拟主机,转发到哪个地址
listen:监听80端口
proxy_pass:代理到哪个地址

nginx 启动错误”nginx: [emerg] host not found in upstream “解决方案

利用nginx进行反向代理的时候,我们会配置proxy_pass。在启动nginx的时候,会报
nginx: [emerg] host not found in upstream "yq.object.com" in 
/usr/local/nginx/conf/vhost/yq.nginx.com.conf:19 这个错误。
其实nginx配置语法上没有错误的,只是系统无法解析这个域名,所以报错.
解决办法就是添加dns到/etc/resolv.conf 或者是/etc/hosts,让其能够解析到IP。具体步骤如下:
vim /etc/hosts
修改hosts文件,在hosts文件里面加上一句
127.0.0.1       localhost.localdomain   yq.object.com

linux shell 命令获取字符串/文件的MD5值

字符串“hello”的MD5:

$ echo -n 'hello'|md5sum|cut -d ' ' -f1
  • 1

得到的MD5值:

5d41402abc4b2a76b9719d911017c592
  • echo -n 'admin'|md5sum|cut -d ' ' -f1
  • echo -n 'qss20180219'|md5sum|cut -d ' ' -f1

命令解释:
md5sum: 显示或检查 MD5(128-bit) 校验和,若没有文件选项,或者文件处为”-“,则从标准输入读取。
echo -n : 不打印换行符。
cut: cut用来从标准输入或文本文件中剪切列或域。剪切文本可以将之粘贴到一个文本文件。
-d 指定与空格和tab键不同的域分隔符。-f1 表示第一个域。参考这里。

获取文件的MD5值:

$ md5sum linuxmint-12-gnome-dvd-32bit.iso|cut -d ' ' -f1
  • 1

得到的MD5值:
ee3d6e2ca498bc7685b7f17cdb5f2eea

使用MD5校验iso文件:

$ md5sum linuxmint-12-gnome-dvd-32bit.iso >linuxmint-12-gnome-dvd-32bit.md5
  • 1

注意linuxmint-12-gnome-dvd-32bit.md5的内容是:

ef3d6e2ca498bc7685b7f17cdb5f2eea linuxmint-12-gnome-dvd-32bit.iso
  • 1

把linuxmint-12-gnome-dvd-32bit和其验证文件
linuxmint-12-gnome-dvd-32bit.md5放到同一目录下用下面的命令:

$ md5sum -c linuxmint-12-gnome-dvd-32bit.md5
  • 1

如果校验正确则输出:

linuxmint-12-gnome-dvd-32bit.iso: 确定
  • 1

如果校验错误则输出:

linuxmint-12-gnome-dvd-32bit.iso: 失败
md5sum: 警告:1/1 生成的校验和不匹配
  • 1
  • 2

命令解释:
md5 -c: 从文件中读取MD5 的校验值并予以检查

Message Digest Algorithm MD5为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。该算法的文件号为RFC 1321(R.Rivest,MIT Laboratory for Computer Science and RSA Data Security Inc. April 1992)
keywords:Hash,SHA,Ronald L. Rivest,MD5,IETF(Internet Engineering Task Force)

Linux awk 命令

Linux 命令大全 Linux 命令大全

AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。

之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。

语法

awk [选项参数] 'script' var=value file(s)

awk [选项参数] -f scriptfile var=value file(s)

选项参数说明:

  • -F fs or –field-separator fs
    指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:。
  • -v var=value or –asign var=value
    赋值一个用户定义变量。
  • -f scripfile or –file scriptfile
    从脚本文件中读取awk命令。
  • -mf nnn and -mr nnn
    对nnn值设置内在限制,-mf选项限制分配给nnn的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。
  • -W compact or –compat, -W traditional or –traditional
    在兼容模式下运行awk。所以gawk的行为和标准的awk完全一样,所有的awk扩展都被忽略。
  • -W copyleft or –copyleft, -W copyright or –copyright
    打印简短的版权信息。
  • -W help or –help, -W usage or –usage
    打印全部awk选项和每个选项的简短说明。
  • -W lint or –lint
    打印不能向传统unix平台移植的结构的警告。
  • -W lint-old or –lint-old
    打印关于不能向传统unix平台移植的结构的警告。
  • -W posix
    打开兼容模式。但有以下限制,不识别:/x、函数关键字、func、换码序列以及当fs是一个空格时,将新行作为一个域分隔符;操作符**和**=不能代替^和^=;fflush无效。
  • -W re-interval or –re-inerval
    允许间隔正则表达式的使用,参考(grep中的Posix字符类),如括号表达式[[:alpha:]]。
  • -W source program-text or –source program-text
    使用program-text作为源代码,可与-f命令混用。
  • -W version or –version
    打印bug报告信息的版本。

基本用法

log.txt文本内容如下:

2 this is a test
3 Are you like awk
This's a test
10 There are orange,apple,mongo

用法一:

awk '{[pattern] action}' {filenames}   # 行匹配语句 awk '' 只能用单引号

实例:

# 每行按空格或TAB分割,输出文本中的1、4项
 $ awk '{print $1,$4}' log.txt
 ---------------------------------------------
 2 a
 3 like
 This's
 10 orange,apple,mongo
 # 格式化输出
 $ awk '{printf "%-8s %-10s\n",$1,$4}' log.txt
 ---------------------------------------------
 2        a
 3        like
 This's
 10       orange,apple,mongo
 

用法二:

awk -F  #-F相当于内置变量FS, 指定分割字符

实例:

# 使用","分割
 $  awk -F, '{print $1,$2}'   log.txt
 ---------------------------------------------
 2 this is a test
 3 Are you like awk
 This's a test
 10 There are orange apple
 # 或者使用内建变量
 $ awk 'BEGIN{FS=","} {print $1,$2}'     log.txt
 ---------------------------------------------
 2 this is a test
 3 Are you like awk
 This's a test
 10 There are orange apple
 # 使用多个分隔符.先使用空格分割,然后对分割结果再使用","分割
 $ awk -F '[ ,]'  '{print $1,$2,$5}'   log.txt
 ---------------------------------------------
 2 this test
 3 Are awk
 This's a
 10 There apple

用法三:

awk -v  # 设置变量

实例:

 $ awk -va=1 '{print $1,$1+a}' log.txt
 ---------------------------------------------
 2 3
 3 4
 This's 1
 10 11
 $ awk -va=1 -vb=s '{print $1,$1+a,$1b}' log.txt
 ---------------------------------------------
 2 3 2s
 3 4 3s
 This's 1 This'ss
 10 11 10s

用法四:

awk -f {awk脚本} {文件名}

实例:

 $ awk -f cal.awk log.txt

运算符

运算符 描述
= += -= *= /= %= ^= **= 赋值
?: C条件表达式
|| 逻辑或
&& 逻辑与
~ 和 !~ 匹配正则表达式和不匹配正则表达式
< <= > >= != == 关系运算符
空格 连接
+ – 加,减
* / % 乘,除与求余
+ – ! 一元加,减和逻辑非
^ *** 求幂
++ — 增加或减少,作为前缀或后缀
$ 字段引用
in 数组成员

过滤第一列大于2的行

$ awk '$1>2' log.txt    #命令
#输出
3 Are you like awk
This's a test
10 There are orange,apple,mongo

过滤第一列等于2的行

$ awk '$1==2 {print $1,$3}' log.txt    #命令
#输出
2 is

过滤第一列大于2并且第二列等于’Are’的行

$ awk '$1>2 && $2=="Are" {print $1,$2,$3}' log.txt    #命令
#输出
3 Are you

内建变量

变量 描述
$n 当前记录的第n个字段,字段间由FS分隔
$0 完整的输入记录
ARGC 命令行参数的数目
ARGIND 命令行中当前文件的位置(从0开始算)
ARGV 包含命令行参数的数组
CONVFMT 数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组
ERRNO 最后一个系统错误的描述
FIELDWIDTHS 字段宽度列表(用空格键分隔)
FILENAME 当前文件名
FNR 各文件分别计数的行号
FS 字段分隔符(默认是任何空格)
IGNORECASE 如果为真,则进行忽略大小写的匹配
NF 一条记录的字段的数目
NR 已经读出的记录数,就是行号,从1开始
OFMT 数字的输出格式(默认值是%.6g)
OFS 输出记录分隔符(输出换行符),输出时用指定的符号代替换行符
ORS 输出记录分隔符(默认值是一个换行符)
RLENGTH 由match函数所匹配的字符串的长度
RS 记录分隔符(默认是一个换行符)
RSTART 由match函数所匹配的字符串的第一个位置
SUBSEP 数组下标分隔符(默认值是/034)
$ awk 'BEGIN{printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n","FILENAME","ARGC","FNR","FS","NF","NR","OFS","ORS","RS";printf "---------------------------------------------\n"} {printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",FILENAME,ARGC,FNR,FS,NF,NR,OFS,ORS,RS}'  log.txt
FILENAME ARGC  FNR   FS   NF   NR  OFS  ORS   RS
---------------------------------------------
log.txt    2    1         5    1
log.txt    2    2         5    2
log.txt    2    3         3    3
log.txt    2    4         4    4
$ awk -F\' 'BEGIN{printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n","FILENAME","ARGC","FNR","FS","NF","NR","OFS","ORS","RS";printf "---------------------------------------------\n"} {printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",FILENAME,ARGC,FNR,FS,NF,NR,OFS,ORS,RS}'  log.txt
FILENAME ARGC  FNR   FS   NF   NR  OFS  ORS   RS
---------------------------------------------
log.txt    2    1    '    1    1
log.txt    2    2    '    1    2
log.txt    2    3    '    2    3
log.txt    2    4    '    1    4
# 输出顺序号 NR, 匹配文本行号
$ awk '{print NR,FNR,$1,$2,$3}' log.txt
---------------------------------------------
1 1 2 this is
2 2 3 Are you
3 3 This's a test
4 4 10 There are
# 指定输出分割符
$  awk '{print $1,$2,$5}' OFS=" $ "  log.txt
---------------------------------------------
2 $ this $ test
3 $ Are $ awk
This's $ a $
10 $ There $

使用正则,字符串匹配

# 输出第二列包含 "th",并打印第二列与第四列
$ awk '$2 ~ /th/ {print $2,$4}' log.txt
---------------------------------------------
this a

~ 表示模式开始。// 中是模式。

# 输出包含 "re" 的行
$ awk '/re/ ' log.txt
---------------------------------------------
3 Are you like awk
10 There are orange,apple,mongo

忽略大小写

$ awk 'BEGIN{IGNORECASE=1} /this/' log.txt
---------------------------------------------
2 this is a test
This's a test

模式取反

$ awk '$2 !~ /th/ {print $2,$4}' log.txt
---------------------------------------------
Are like
a
There orange,apple,mongo
$ awk '!/th/ {print $2,$4}' log.txt
---------------------------------------------
Are like
a
There orange,apple,mongo

awk脚本

关于 awk 脚本,我们需要注意两个关键词 BEGIN 和 END。

  • BEGIN{ 这里面放的是执行前的语句 }
  • END {这里面放的是处理完所有的行后要执行的语句 }
  • {这里面放的是处理每一行时要执行的语句}

假设有这么一个文件(学生成绩表):

$ cat score.txt
Marry   2143 78 84 77
Jack    2321 66 78 45
Tom     2122 48 77 71
Mike    2537 87 97 95
Bob     2415 40 57 62

我们的 awk 脚本如下:

$ cat cal.awk
#!/bin/awk -f
#运行前
BEGIN {
    math = 0
    english = 0
    computer = 0
 
    printf "NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL\n"
    printf "---------------------------------------------\n"
}
#运行中
{
    math+=$3
    english+=$4
    computer+=$5
    printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}
#运行后
END {
    printf "---------------------------------------------\n"
    printf "  TOTAL:%10d %8d %8d \n", math, english, computer
    printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}

我们来看一下执行结果:

$ awk -f cal.awk score.txt
NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL
---------------------------------------------
Marry  2143     78       84       77      239
Jack   2321     66       78       45      189
Tom    2122     48       77       71      196
Mike   2537     87       97       95      279
Bob    2415     40       57       62      159
---------------------------------------------
  TOTAL:       319      393      350
AVERAGE:     63.80    78.60    70.00

另外一些实例

AWK 的 hello world 程序为:

BEGIN { print "Hello, world!" }

计算文件大小

$ ls -l *.txt | awk '{sum+=$5} END {print sum}'
--------------------------------------------------
666581

从文件中找出长度大于 80 的行:

awk 'length>80' log.txt

打印九九乘法表

seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}'

更多内容:

Linux 命令大全 Linux 命令大全

1 篇笔记 写笔记

  1.    z977690557

      977***557@qq.com

    102

    awk、sed、grep更适合的方向:

    •  grep 更适合单纯的查找或匹配文本
    •  sed 更适合编辑匹配到的文本
    •  awk 更适合格式化文本,对文本进行较复杂格式处理

    关于awk内建变量个人见解,简单易懂

    解释一下变量:

    变量:分为内置变量和自定义变量;输入分隔符FS和输出分隔符OFS都属于内置变量。

    内置变量就是awk预定义好的、内置在awk内部的变量,而自定义变量就是用户定义的变量。

    •  FS(Field Separator):输入字段分隔符, 默认为空白字符
    •  OFS(Out of Field Separator):输出字段分隔符, 默认为空白字符
    •  RS(Record Separator):输入记录分隔符(输入换行符), 指定输入时的换行符
    •  ORS(Output Record Separate):输出记录分隔符(输出换行符),输出时用指定符号代替换行符
    •  NF(Number for Field):当前行的字段的个数(即当前行被分割成了几列)
    •  NR(Number of Record):行号,当前处理的文本行的行号。
    •  FNR:各文件分别计数的行号
    •  ARGC:命令行参数的个数
    •  ARGV:数组,保存的是命令行所给定的各参数

    自定义变量的方法

    •  方法一:-v varname=value ,变量名区分字符大小写。
    •  方法二:在program中直接定义。