Linux中apt与apt-get命令的区别与解释

Ubuntu 16.04 发布时,一个引人注目的新特性便是 apt 命令的引入。其实早在 2014 年,apt 命令就已经发布了第一个稳定版,只是直到 2016 年的 Ubuntu 16.04 系统发布时才开始引人关注。

随着 apt install package 命令的使用频率和普遍性逐步超过 apt-get install package,越来越多的其它 Linux 发行版也开始遵循 Ubuntu 的脚步,开始鼓励用户使用 apt 而不是 apt-get。

那么,apt-get 与 apt 命令之间到底有什么区别呢?如果它们有类似的命令结构,为什么还需要新的 apt 命令呢?是否 apt 真的比 apt-get 更好?普通用户应该使用新的 apt 命令还是坚持旧有习惯继续使用 apt-get 呢?

系统极客将在本文中解释所有这些问题,我们希望本文结束时,你将会有一个更清晰的了解。

apt与apt-get

在开始对比 apt 与 apt-get 命令的区别之前,我们先来看看这两个命令的背景,以及它们要试图达到的目的。

Debian 作为 Ubuntu、Linux Mint 和 elementary OS 等 Linux 操作系统的母板,其具有强健的「包管理」系统,它的每个组件和应用程序都内置在系统中安装的软件包中。Debian 使用一套名为 Advanced Packaging Tool(APT)的工具来管理这种包系统,不过请不要把它与 apt 命令混淆,它们之间是其实不是同一个东西。

在基于 Debian 的 Linux 发行版中,有各种工具可以与 APT 进行交互,以方便用户安装、删除和管理的软件包。apt-get 便是其中一款广受欢迎的命令行工具,另外一款较为流行的是 Aptitude 这一命令行与 GUI 兼顾的小工具。

如果你已阅读过我们的 apt-get 命令指南(https://www.sysgeek.cn/linux-package-management/),可能已经遇到过许多类似的命令,如apt-cache、apt-config 等。如你所见,这些命令都比较低级又包含众多功能,普通的 Linux 用户也许永远都不会使用到。换种说法来说,就是最常用的 Linux 包管理命令都被分散在了 apt-get、apt-cache 和 apt-config 这三条命令当中。

apt 命令的引入就是为了解决命令过于分散的问题,它包括了 apt-get 命令出现以来使用最广泛的功能选项,以及 apt-cache 和 apt-config 命令中很少用到的功能。

在使用 apt 命令时,用户不必再由 apt-get 转到 apt-cache 或 apt-config,而且 apt 更加结构化,并为用户提供了管理软件包所需的必要选项。

简单来说就是:apt = apt-get、apt-cache 和 apt-config 中最常用命令选项的集合。

apt与apt-get之间的区别

通过 apt 命令,用户可以在同一地方集中得到所有必要的工具,apt 的主要目的是提供一种以「让终端用户满意」的方式来处理 Linux 软件包的有效方式。

apt 具有更精减但足够的命令选项,而且参数选项的组织方式更为有效。除此之外,它默认启用的几个特性对最终用户也非常有帮助。例如,可以在使用 apt 命令安装或删除程序时看到进度条。

未分类

apt 还会在更新存储库数据库时提示用户可升级的软件包个数。

未分类

如果你使用 apt 的其它命令选项,也可以实现与使用 apt-get 时相同的操作。

apt和apt-get命令之间的区别

虽然 apt 与 apt-get 有一些类似的命令选项,但它并不能完全向下兼容 apt-get 命令。也就是说,可以用 apt 替换部分 apt-get 系列命令,但不是全部。

未分类

当然,apt 还有一些自己的命令:

未分类

需要大家注意的是:apt 命令也还在不断发展, 因此,你可能会在将来的版本中看到新的选项。

apt-get已弃用?

目前还没有任何 Linux 发行版官方放出 apt-get 将被停用的消息,至少它还有比 apt 更多、更细化的操作功能。对于低级操作,仍然需要 apt-get。

我应该使用apt还是apt-get?

既然两个命令都有用,那么我该使用 apt 还是 apt-get 呢?作为一个常规 Linux 用户,系统极客建议大家尽快适应并开始首先使用 apt。不仅因为广大 Linux 发行商都在推荐 apt,更主要的还是它提供了 Linux 包管理的必要选项。

最重要的是,apt 命令选项更少更易记,因此也更易用,所以没理由继续坚持 apt-get。

小结

最后结大家提供两点使用上的建议:

  • apt 可以看作 apt-get 和 apt-cache 命令的子集, 可以为包管理提供必要的命令选项。
  • apt-get 虽然没被弃用,但作为普通用户,还是应该首先使用 apt。

如何在 Ubuntu Linux 中使用 RAR 文件

RAR 是一种非常好的归档文件格式。但相比之下 7-zip 能提供了更好的压缩率,并且默认情况下还可以在多个平台上轻松支持 Zip 文件。不过 RAR 仍然是最流行的归档格式之一。然而 Ubuntu 自带的归档管理器却不支持提取 RAR 文件,也不允许创建 RAR 文件。

办法总比问题多。只要安装 unrar 这款由 RARLAB 提供的免费软件,就能在 Ubuntu 上支持提取 RAR 文件了。你也可以安装 rar 试用版来创建和管理 RAR 文件。

提取 RAR 文件

在未安装 unrar 的情况下,提取 RAR 文件会报出“未能提取”错误,就像下面这样(以 Ubuntu 18.04为例):

未分类

Error in RAR extraction in Ubuntu

如果要解决这个错误并提取 RAR 文件,请按照以下步骤安装 unrar:

打开终端并输入:

sudo apt-get install unrar

安装 unrar 后,直接输入 unrar 就可以看到它的用法以及如何使用这个工具处理 RAR 文件。

最常用到的功能是提取 RAR 文件。因此,可以通过右键单击 RAR 文件并执行提取,也可以借助此以下命令通过终端执行操作:

unrar x FileName.rar

结果类似以下这样:

未分类

Using unrar in Ubuntu

如果压缩文件没放在家目录中,就必须使用 cd 命令移动到目标目录下。例如 RAR 文件如果在 Music目录下,只需要使用 cd Music 就可以移动到相应的目录,然后提取 RAR 文件。

创建和管理 RAR 文件

未分类

Using rar archive in Ubuntu Linux

unrar 不允许创建 RAR 文件。因此还需要安装 rar 命令行工具才能创建 RAR 文件。

要创建 RAR 文件,首先需要通过以下命令安装 rar:

sudo apt-get install rar

按照下面的命令语法创建 RAR 文件:

rar a ArchiveName File_1 File_2 Dir_1 Dir_2

按照这个格式输入命令时,它会将目录中的每个文件添加到 RAR 文件中。如果需要某一个特定的文件,就要指定文件确切的名称或路径。

默认情况下,RAR 文件会放置在家目录中。

以类似的方式,可以更新或管理 RAR 文件。同样是使用以下的命令语法:

rar u ArchiveName Filename

在终端输入 rar 就可以列出 RAR 工具的相关命令。

总结

现在你已经知道如何在 Ubuntu 上管理 RAR 文件了,你会更喜欢使用 7-zip、Zip 或 Tar.xz 吗?

在 Linux 下截屏并编辑的最佳工具

有几种获取屏幕截图并对其进行添加文字、箭头等编辑的方法,这里提及的的屏幕截图工具在 Ubuntu 和其它主流 Linux 发行版中都能够使用。

当我的主力操作系统从 Windows 转换到 Ubuntu 的时候,首要考虑的就是屏幕截图工具的可用性。尽管使用默认的键盘快捷键也可以获取屏幕截图,但如果使用屏幕截图工具,可以更方便地对屏幕截图进行编辑。

本文将会介绍在不适用第三方工具的情况下,如何通过系统自带的方法和工具获取屏幕截图,另外还会介绍一些可用于 Linux 的最佳截图工具。

方法 1:在 Linux 中截图的默认方式

你想要截取整个屏幕?屏幕中的某个区域?某个特定的窗口?

如果只需要获取一张屏幕截图,不对其进行编辑的话,那么键盘的默认快捷键就可以满足要求了。而且不仅仅是 Ubuntu ,绝大部分的 Linux 发行版和桌面环境都支持以下这些快捷键:

  • PrtSc – 获取整个屏幕的截图并保存到 Pictures 目录。
  • Shift + PrtSc – 获取屏幕的某个区域截图并保存到 Pictures 目录。
  • Alt + PrtSc –获取当前窗口的截图并保存到 Pictures 目录。
  • Ctrl + PrtSc – 获取整个屏幕的截图并存放到剪贴板。
  • Shift + Ctrl + PrtSc – 获取屏幕的某个区域截图并存放到剪贴板。
  • Ctrl + Alt + PrtSc – 获取当前窗口的 截图并存放到剪贴板。

如上所述,在 Linux 中使用默认的快捷键获取屏幕截图是相当简单的。但如果要在不把屏幕截图导入到其它应用程序的情况下对屏幕截图进行编辑,还是使用屏幕截图工具比较方便。

方法 2:在 Linux 中使用 Flameshot 获取屏幕截图并编辑

未分类

功能概述:

  • 注释 (高亮、标示、添加文本、框选)
  • 图片模糊
  • 图片裁剪
  • 上传到 Imgur
  • 用另一个应用打开截图

Flameshot 在去年发布到 GitHub,并成为一个引人注目的工具。

如果你需要的是一个能够用于标注、模糊、上传到 imgur 的新式截图工具,那么 Flameshot 是一个好的选择。

下面将会介绍如何安装 Flameshot 并根据你的偏好进行配置。

如果你用的是 Ubuntu,那么只需要在 Ubuntu 软件中心上搜索,就可以找到 Flameshot 进而完成安装了。要是你想使用终端来安装,可以执行以下命令:

sudo apt install flameshot

如果你在安装过程中遇到问题,可以按照官方的安装说明进行操作。安装完成后,你还需要进行配置。尽管可以通过搜索来随时启动 Flameshot,但如果想使用 PrtSc 键触发启动,则需要指定对应的键盘快捷键。以下是相关配置步骤:

  • 进入系统设置中的“键盘设置”
  • 页面中会列出所有现有的键盘快捷键,拉到底部就会看见一个 “+” 按钮
  • 点击 “+” 按钮添加自定义快捷键并输入以下两个字段:
    • “名称”: 任意名称均可。
    • “命令”: /usr/bin/flameshot gui
  • 最后将这个快捷操作绑定到 PrtSc 键上,可能会提示与系统的截图功能相冲突,但可以忽略掉这个警告。

配置之后,你的自定义快捷键页面大概会是以下这样:

未分类

方法 3:在 Linux 中使用 Shutter 获取屏幕截图并编辑

未分类

功能概述:

  • 注释 (高亮、标示、添加文本、框选)
  • 图片模糊
  • 图片裁剪
  • 上传到图片网站

Shutter 是一个对所有主流 Linux 发行版都适用的屏幕截图工具。尽管最近已经不太更新了,但仍然是操作屏幕截图的一个优秀工具。

在使用过程中可能会遇到这个工具的一些缺陷。Shutter 在任何一款最新的 Linux 发行版上最常见的问题就是由于缺少了任务栏上的程序图标,导致默认禁用了编辑屏幕截图的功能。 对于这个缺陷,还是有解决方案的。你只需要跟随我们的教程在 Shutter 中修复这个禁止编辑选项并将程序图标在任务栏上显示出来。问题修复后,就可以使用 Shutter 来快速编辑屏幕截图了。

同样地,在软件中心搜索也可以找到进而安装 Shutter,也可以在基于 Ubuntu 的发行版中执行以下命令使用命令行安装:

sudo apt install shutter

类似 Flameshot,你可以通过搜索 Shutter 手动启动它,也可以按照相似的方式设置自定义快捷方式以 PrtSc 键唤起 Shutter。

如果要指定自定义键盘快捷键,只需要执行以下命令:

shutter -f

方法 4:在 Linux 中使用 GIMP 获取屏幕截图

未分类

功能概述:

  • 高级图像编辑功能(缩放、添加滤镜、颜色校正、添加图层、裁剪等)
  • 截取某一区域的屏幕截图

如果需要对屏幕截图进行一些预先编辑,GIMP 是一个不错的选择。

通过软件中心可以安装 GIMP。如果在安装时遇到问题,可以参考https://www.gimp.org/downloads/

要使用 GIMP 获取屏幕截图,需要先启动程序,然后通过 “File-> Create-> Screenshot” 导航。

打开 Screenshot 选项后,会看到几个控制点来控制屏幕截图范围。点击 “Snap” 截取屏幕截图,图像将自动显示在 GIMP 中可供编辑。

方法 5:在 Linux 中使用命令行工具获取屏幕截图

这一节内容仅适用于终端爱好者。如果你也喜欢使用终端,可以使用 “GNOME 截图工具”或 “ImageMagick” 或 “Deepin Scrot”,大部分流行的 Linux 发行版中都自带这些工具。

要立即获取屏幕截图,可以执行以下命令:

GNOME 截图工具(可用于 GNOME 桌面)

gnome-screenshot

GNOME 截图工具是使用 GNOME 桌面的 Linux 发行版中都自带的一个默认工具。如果需要延时获取屏幕截图,可以执行以下命令(这里的 5 是需要延迟的秒数):

gnome-screenshot -d -5

ImageMagick

如果你的操作系统是 Ubuntu、Mint 或其它流行的 Linux 发行版,一般会自带 ImageMagick 这个工具。如果没有这个工具,也可以按照官方安装说明使用安装源来安装。你也可以在终端中执行这个命令:

sudo apt-get install imagemagick

安装完成后,执行下面的命令就可以获取到屏幕截图(截取整个屏幕):

import -window root image.png

这里的 “image.png” 就是屏幕截图文件保存的名称。

要获取屏幕一个区域的截图,可以执行以下命令:

import image.png

Deepin Scrot

Deepin Scrot 是基于终端的一个较新的截图工具。和前面两个工具类似,一般自带于 Linux 发行版中。如果需要自行安装,可以执行以下命令:

sudo apt-get install scrot

安装完成后,使用下面这些命令可以获取屏幕截图。

获取整个屏幕的截图:

scrot myimage.png

获取屏幕某一区域的截图:

scrot -s myimage.png

总结

以上是一些在 Linux 上的优秀截图工具。当然还有很多截图工具没有提及(例如用于 KDE 发行版的 Spectacle),但相比起来还是上面几个工具更为好用。

如果你有比文章中提到的更好的截图工具,欢迎讨论!

Linux中 MySQL 授权远程连接

说明:当别的机子(IP )通过客户端的方式在没有授权的情况下是无法连接 MySQL 数据库的,如果需要远程连接 Linux 系统上的 MySQL 时,必须为其 IP 和 具体用户 进行 授权 。一般 root 用户不会提供给开发者。如:使用 Windows 上的 SQLyog 图形化管理工具连接 Linux 上的 MySQL 数据库,必须先对其进行授权。

1、在虚拟机中使用 root 用户登录 mysql 数据库

mysql -u root -p

说明:root 用户密码一般设置为 root

2、使用 mysql 命令为 root 用户授权 mysql 远程连接服务

mysql> grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option;

说明:此命令是为密码为 root 、IP(%)任意的 root 用户授权。(%:模糊查询,所有 IP 都可以,,可指定其他主机 IP;BY 后的 ‘root’ 为密码)

3、将配置写入 mysql 授权表中

mysql> flush privileges;

Linux实用工具总结之UFW

UFW,即Uncomplicated Firewall,是基于iptables实现的防火墙管理工具,所以实际上UFW修改的是iptables的规则。之所以不直接使用iptables,而要通过UFW进行管理是因为iptables的规则对于新手入门来说有点难,UFW做了很好的包装。
本文测试环境为Ubuntu 16.04,其他系统可做参考。

Ubuntu系统默认已经安装了UFW,如果没有ufw,可以手动安装:

$ sudo apt-get update
$ sudo apt-get install ufw

允许UFW管理IPV6

sudo vim /etc/default/ufw

确保你的IPV6选项为yes即可:

...
IPV6=yes
...

设置默认规则

UFW默认情况下允许所有的出站连接,拒绝所有的入站连接,所以这里首先将UFW设置为默认规则:

$ sudo ufw default deny incoming
$ sudo ufw default allow outgoing

ufw default也允许使用reject参数

允许SSH连接

一旦启用UFW之后,如果没有允许SSH连接,将无法再通过SSH远程访问主机,所以在开启防火墙之后要确认SSH连接已经设置为允许:

$ sudo ufw allow ssh

这里创建一条规则,允许ssh连接,其实是允许22端口的连接,等价于:

$ sudo ufw allow 22

UFW通过/etc/services知道ssh服务使用的默认端口为22,如果你的SSH服务使用的端口不是22,则应该修改为相应 的端口号。

查看防火墙状态

通过以下命令查看防火墙状态:

$ sudo ufw status verbose

也可以不带verbose,当防火墙处于关闭状态时只会显示inactive
可以查看刚刚添加的防火墙规则:

$ sudo ufw show added

show后面还可以跟其他几项参数,可以通过man手册查看REPORTS

启用UFW命令:

$ sudo ufw enable

该命令默认会将UFW设置为开机启动,如果发现重启后UFW并没有自动启动,可以手动设置UFW服务开机自动启动:

$ sudo systemctl start ufw
$ sudo systemctl enable ufw

记得查看防火墙当前的状态:

$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
22                         ALLOW       Anywhere
22 (v6)                    ALLOW       Anywhere (v6)

禁用UFW:

$ sudo ufw disable

该命令会禁用防火墙并关闭其开机自动启动

启用防火墙日志:

$ sudo ufw logging on

可以指定日志级别sudo ufw logging low|medium|high
日志文件在/var/log/ufw.log
内容形如:

Sep 16 15:08:14 <hostname> kernel: [UFW BLOCK] IN=eth0 OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:00:00 SRC=123.45.67.89 DST=987.65.43.21 LEN=40 TOS=0x00 PREC=0x00 TTL=249 ID=8475 PROTO=TCP SPT=48247 DPT=22 WINDOW=1024 RES=0x00 SYN URGP=0

其中前面列出了主机防火墙日志的日期、时间、主机名,后面的内容意思是:

  • [UFW BLOCK]:表示事件描述的开始以及是何种事件。在此例中,它表示阻止了连接。
  • IN:如果它包含一个值,那么代表该事件是传入事件
  • OUT:如果它包含一个值,那么代表事件是传出事件
  • MAC:目的地和源 MAC 地址的组合
  • SRC:IP数据包的源IP
  • DST:目的地的IP
  • LEN:数据包长度
  • TTL:数据 TTL,或称为time to live。
  • PROTO:数据包的协议
  • SPT:数据包的源端口
  • DPT:目标端口
  • WINDOW:发送方可以接收的数据包的大小
  • SYN URGP:指示是否需要三次握手。 0 表示不需要。

禁用防火墙日志:

$ sudo ufw logging off

默认情况下ufw的allow不加in允许连接是指允许入站连接,如果要指定允许出站,可以加上out,如:

$ sudo ufw allow in port #允许port入站
$ sudo ufw allow out port #允许port出站

允许指定端口的所有连接协议

通过刚才设置ssh的规则,可以知道直接allow就是允许连接
允许HTTP 80端口的所有连接:

$ sudo ufw allow http

等价于:

$ sudo ufw allow 80

同样可以允许https的连接:

$ sudo ufw allow https

等价于:

$ sudo ufw allow 443

允许指定端口的指定协议连接

FTP默认端口为21,连接协议为tcp,那么可以这样:

$ sudo ufw allow ftp

等价于:

$ sudo ufw allow 21/tcp

允许指定范围内的端口的指定协议的连接

例如,X11的连接端口范围是6000-6007:

$ sudo ufw allow 6000:6007/tcp
$ sudo ufw allow 6000:6007/udp

允许指定IP的连接

通过查看防火墙状态可以看出有个From:

$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
22                         ALLOW       Anywhere                  
21/tcp                     ALLOW       Anywhere                  
22 (v6)                    ALLOW       Anywhere (v6)             
21/tcp (v6)                ALLOW       Anywhere (v6)

默认情况是相应端口允许所有IP的连接,可以通过后跟from指定允许某IP的所有连接:

$ sudo ufw allow from 15.15.15.51

允许15.15.15.51的所有入站连接,命令后面跟to any port 22允许端口22的所有连接:

$ sudo ufw allow from 15.15.15.51 to any port 22

允许子网的连接

如果要允许IP段15.15.15.1到15.15.15.254的所有连接:

$ sudo ufw allow from 15.15.15.0/24

并指定连接端口:

$ sudo ufw allow from 15.15.15.0/24 to any port 22

指定允许通过某个网卡的连接

通过命令中加入allow in on即可
首先查看系统中的所有网卡:

$ ip addr

或者:

$ ifconfig

假设这里允许eth0的80端口连接:

$ sudo ufw allow in on eth0 to any port 80

允许出站连接

允许相应端口的出站连接,直接allow后面跟out即可:

$ sudo ufw allow out 34

与允许连接一样,只需要将相应的allow换成deny即可,如拒绝http端口的所有连接:

$ sudo ufw deny http

等价于:

$ sudo ufw deny 80

拒绝指定ip的连接:

$ sudo ufw deny from 15.15.15.51

UFW有两种方式删除防火墙规则,既可以通过规则号删除,也可以通过实际规则删除,通过规则号删除更容易。

通过规则号删除

首先查看所有规则的规则号:

$ sudo ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 22                         ALLOW IN    Anywhere                  
[ 2] 21/tcp                     ALLOW IN    Anywhere                  
[ 3] 34                         ALLOW IN    Anywhere                  
[ 4] 34                         ALLOW OUT   Anywhere                   (out)
[ 5] 22                         ALLOW OUT   15.15.15.51                (out)
[ 6] 22 (v6)                    ALLOW IN    Anywhere (v6)             
[ 7] 21/tcp (v6)                ALLOW IN    Anywhere (v6)             
[ 8] 34 (v6)                    ALLOW IN    Anywhere (v6)             
[ 9] 34 (v6)                    ALLOW OUT   Anywhere (v6)              (out)

然后直接delete即可,例如删除ftp(21)的连接规则:

$ sudo ufw delete 2
$ sudo ufw delete 7

因为即有ipv6,又有ipv4,所以需要删除2个

通过规则删除

删除allow http规则:

$ sudo ufw delete allow http

等价于:

$ sudo ufw delete allow 80
$ sudo ufw reset

该命令将禁用UFW,并且删除所有已经定义的规则,不过默认该命令会对已经设置的规则进行备份

UFW的所有规则文件都在路径/etc/ufw/,其中before.rules规则为UFW在运行用户自定义的规则之前运行的规则,相应的before6.rules对应IPV6。after.rules为UFW启用用户自定义规则之后运行的规则。user.rules即为用户自定义的规则。
/etc/default/ufw文件为UFW的配置文件。
所以可以通过直接备份这些配置文件的方式来备份防火墙规则,需要备份的文件有:

/etc/ufw/*.rules
/lib/ufw/*.rules

/etc/default/ufw # 这个配置文件如果没有修改过,可以不备份
修改配置文件之后通过以下命令重新加载配置文件:

$ sudo ufw reload

批量禁止IP

$ while read line; do sudo ufw deny from $line; done < file.txt

file.txt里面是一个需要禁止的IP列表

Linux应用之crontab定时任务的设置

|实现Linux定时任务有:cron、anacron、at等,这里主要介绍cron服务。

名词解释:

cron是服务名称,crond是后台进程,crontab则是定制好的计划任务表。

软件包安装:

要使用cron服务,先要安装vixie-cron软件包和crontabs软件包,两个软件包作用如下:

vixie-cron软件包是cron的主程序。
crontabs软件包是用来安装、卸装、或列举用来驱动 cron 守护进程的表格的程序。

查看是否安装了cron软件包: rpm -qa|grep vixie-cron

查看是否安装了crontabs软件包: rpm -qa|grep crontabs

如果没有安装,则执行如下命令安装软件包(软件包必须存在)
rpm -ivh vixie-cron-4.1-54.FC5*
rpm -ivh crontabs*

如果本地没有安装包,在能够连网的情况下可以在线安装

yum install vixie-cron
yum install crontabs

查看crond服务是否运行:

pgrep crond

/sbin/service crond status

ps -elf|grep crond|grep -v "grep"

crond服务操作命令:

/sbin/service crond start //启动服务  
/sbin/service crond stop //关闭服务  
/sbin/service crond restart //重启服务  
/sbin/service crond reload //重新载入配置

配置定时任务:

cron有两个配置文件,一个是一个全局配置文件(/etc/crontab),是针对系统任务的;一组是crontab命令生成的配置文件(/var/spool/cron下的文件),是针对某个用户的.定时任务配置到任意一个中都可以。

查看全局配置文件配置情况: cat /etc/crontab

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# run-parts
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly

查看用户下的定时任务:crontab -l或cat /var/spool/cron/用户名

crontab任务配置基本格式:

*   *  *  *  *  command
分钟(0-59) 小时(0-23) 日期(1-31) 月份(1-12) 星期(0-6,0代表星期天)  命令

第1列表示分钟1~59 每分钟用*或者 */1表示
第2列表示小时1~23(0表示0点)
第3列表示日期1~31
第4列表示月份1~12
第5列标识号星期0~6(0表示星期天)
第6列要运行的命令

在以上任何值中,星号(*)可以用来代表所有有效的值。譬如,月份值中的星号意味着在满足其它制约条件后每月都执行该命令。

整数间的短线(-)指定一个整数范围。譬如,1-4 意味着整数 1、2、3、4。
用逗号(,)隔开的一系列值指定一个列表。譬如,3, 4, 6, 8 标明这四个指定的整数。
正斜线(/)可以用来指定间隔频率。在范围后加上 / 意味着在范围内可以跳过 integer。譬如,0-59/2 可以用来在分钟字段定义每两分钟。间隔频率值还可以和星号一起使用。例如,*/3 的值可以用在月份字段中表示每三个月运行一次任务。
开头为井号(#)的行是注释,不会被处理。

例子:

0 1 * * * /home/testuser/test.sh
每天晚上1点调用/home/testuser/test.sh

*/10 * * * * /home/testuser/test.sh
每10钟调用一次/home/testuser/test.sh

30 21 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每晚的21:30重启apache。

45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每月1、10、22日的4 : 45重启apache。

10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每周六、周日的1 : 10重启apache。

0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。

0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每星期六的11 : 00 pm重启apache。

* */1 * * * /usr/local/etc/rc.d/lighttpd restart
每一小时重启apache

* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart
晚上11点到早上7点之间,每隔一小时重启apache

0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart
每月的4号与每周一到周三的11点重启apache

0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart
一月一号的4点重启apache

*/30 * * * * /usr/sbin/ntpdate 210.72.145.44
每半小时同步一下时间

配置用户定时任务的语法:

crontab [-u user]file

crontab [-u user] [-l| -r | -e][-i]

参数与说明:

crontab -u//设定某个用户的cron服务

crontab -l//列出某个用户cron服务的详细内容

crontab -r//删除没个用户的cron服务

crontab -e//编辑某个用户的cron服务

例子:

假设当前用户是root,要建立root用户的定时任务

crontab -e

选择编辑器,编辑定时任务(这里假设是编辑器是vi)

按i进入编辑模式

0 1 * * * /root/test.sh

按esc退出编辑模式进入普通模式,输入:x或:wq保存退出

查看刚刚输入的定时任务

crontab -l 或 cat /var/spool/cron/root

根用户以外的用户可以使用 crontab 工具来配置 cron 任务。所有用户定义的 crontab 都被保存在 /var/spool/cron 目录中,并使用创建它们的用户身份来执行。要以某用户身份创建一个 crontab 项目,登录为该用户,然后键入 crontab -e 命令,使用由 VISUAL 或 EDITOR 环境变量指定的编辑器来编辑该用户的 crontab。该文件使用的格式和 /etc/crontab 相同。当对 crontab 所做的改变被保存后,该 crontab 文件就会根据该用户名被保存,并写入文件 /var/spool/cron/username 中。

cron 守护进程每分钟都检查 /etc/crontab 文件、etc/cron.d/ 目录、以及 /var/spool/cron 目录中的改变。如果发现了改变,它们就会被载入内存。这样,当某个 crontab 文件改变后就不必重新启动守护进程了。

重启crond:

/sbin/service crond restart

查看cron服务是否起作用:

如果我们要查看定时任务是否准时调用了可以/var/log/cron中的运行信息

cat /var/log/cron

grep .*.sh /var/log/cron

搜索.sh类型文件信息

sed -n '/back.*.sh/p' /var/log/cron

格式sed -n ‘/字符或正则表达式/p’ 文件名

我们在日志中查看在约定的时间是否有相应的调用信息,调用信息类似:

Sep 19 1:00:01 localhost crond[25437]: (root) CMD (/root/test.sh)

查看shell脚本是否报错:

如果/var/log/cron中准时调用了shell脚本,而又没有达到预期结果,我们就要怀疑shell脚本是否出错

cat /var/spool/mail/用户名

例子:

cat /var/spool/mail/root

test.sh

#!/bin/sh

echo "$(date '+%Y-%m-%d %H:%M:%S') hello world!" >> /root/test.log

要追踪shell调用的全过程:

bash -xv test.sh 2>test.log

test.sh的调用过程都会写到test.log中

改写test.sh

#!/bin/sh

set -xv

echo "$(date '+%Y-%m-%d %H:%M:%S') hello world!" >> /root/test.log

sh ./test.sh 2>tt.log

网上查询到的资料crontab不执行的问题:

第一,脚本的原因:大多数情况下,我们要相信科学,相信计算机,不是有鬼,就是我们的脚本的问题,这种问题导致crontab不能执行的概率占到 70%以上。因为程序执行到某一步导致crontab终止执行,我就碰到一次在迁移代码的时候将数据库连错了。导致无法访问而死在那里了。

第二,执行环境问题,当我们碰到第一情况下,一般都可以通过手动执行程序将问题扼杀在摇篮里,一般情况下高手是不应该犯第一种错误的。问题是当我们 手动执行成功而crontab不能执行的时候,笔者碰到一次就是执行环境的问题,例如相关路径的设置问题。解决方案:在代码最前面执行 source /home/user/.bash_profile

第三,系统时间不正确。这种问题最好理解,也是比较常见和隐蔽的问题,解决方案:date -s ********

第四,就是我们的脚本是否有可执行权限。必须保证执行脚本的用户有执行改文件的权限。

第五,crontab 守护进程死掉了。这种情况是极少发生的,但也不排除,当我们实在是找不到其他原因的时候可以用。解决方案:重启该进程。

第六,crontab不执行的问题困扰了好长时间,脚本写的都正确,但是就是不执行,最终解决方法如下:
crontab -u root /var/spool/cron/root
这样root用户的crontab就生效了
service crond restart
重启下服务就好了

第七,crond没有启动

第八,脚本编码问题,脚本在window下编写,传到linux下后报“锘?!/bin/bash”,用vi编辑器新建新shell脚本,输入内容后保存。

Linux 系统 Crontab 的安装及定时任务的命令详解

前言

很多时候我们的VPS运行脚本或者重启某些软件的时候都需要用到定时功能,这时候就要用到Crontab定时软件了,这里简单的说下安装和使用方法。

安装

一般我们使用的Centos或者Debian都自带Crontab定时软件,如果没有,那我们就需要安装了。

1、centos 安装 crontab

yum install vixie-cron crontabs   #安装Crontab
chkconfig crond on   #设置开机启动Crontab
service crond start   #启动Crontab

2、debian 安装 crontab

apt-get install cron   #安装Crontab
/etc/init.d/cron restart   #重启Crontab

使用方法

1、基本命令

crontab -e   #编辑定时任务
crontab -r   #移除定时任务
crontab -l   #查看定时任务

2、使用命令

添加的命令必须以如下格式:

* * * * * /root/rats.sh   #前5个*指时间,后面为命令

前5个*分别表示:

分钟:0-59
小时:1-23
日期:1-31
月份:1-12
星期:0-6(0表示周日)

还可以用一些特殊符号:

*: 表示任何时刻
,: 表示分割
-:表示一个段,如:1-5,就表示1到5点
/n : 表示每个n的单位执行一次,如:*/1, 就表示每隔1个小时执行一次命令。也可以写成1-23/1

3、定时任务设置举例

43 21 * * *   #21:43 执行
15 05 * * *   #05:15 执行
0 17 * * *    #17:00 执行
0 17 * * 1    #每周一的17:00 执行
0,10 17 * * 0,2,3    #每周日,周二,周三的17:00和17:10 执行
0-10 17 1 * *    #毎月1日从17:00到7:10毎隔1分钟 执行
0 0 1,15 * 1    #毎月1日和15日和一日的0:00 执行
42 4 1 * *   #毎月1日的4:42分 执行
0 21 * * 1-6   #周一到周六21:00 执行
0,10,20,30,40,50 * * * *   #每隔10分 执行
*/10 * * * *   #每隔10分 执行
* 1 * * *   #从1:0到1:59每隔1分钟 执行
0 1 * * *   #1:00 执行
0 */1 * * *   #毎时0分每隔1小时 执行
0 * * * *   #毎时0分 执行
2 8-20/3 * * *   #8:02,11:02,14:02,17:02,20:02 执行
30 5 1,15 * *   #1日和15日的5:30 执行

Linux搭建ELK日志收集系统:FIlebeat+Redis+Logstash+Elasticse

Centos7部署ELK日志收集系统

一、ELK概述

ELK是一组开源软件的简称,其包括Elasticsearch、Logstash 和 Kibana。ELK最近几年发展迅速,已经成为目前最流行的集中式日志解决方案。

  • Elasticsearch: 能对大容量的数据进行接近实时的存储,搜索和分析操作。 本项目中主要通过Elasticsearch存储所有获取的日志。
  • Logstash: 数据收集引擎,它支持动态的的从各种数据源获取数据,并对数据进行过滤,分析,丰富,统一格式等操作,然后存储到用户指定的位置。
  • Kibana: 数据分析与可视化平台,对Elasticsearch存储的数据进行可视化分析,通过表格的形式展现出来。
  • Filebeat: 轻量级的开源日志文件数据搜集器。通常在需要采集数据的客户端安装Filebeat,并指定目录与日志格式,Filebeat就能快速收集数据,并发送给logstash进行解析,或是直接发给Elasticsearch存储。
  • Redis:NoSQL数据库(key-value),也数据轻型消息队列,不仅可以对高并发日志进行削峰还可以对整个架构进行解耦

传统ELK的经典框架

未分类

单一的架构,logstash作为日志搜集器,从数据源采集数据,并对数据进行过滤,格式化处理,然后交由Elasticsearch存储,kibana对日志进行可视化处理。

新型ELK框架

未分类

Filebeats是一种轻量级的日志搜集器,其不占用系统资源,自出现之后,迅速更新了原有的elk架构。Filebeats将收集到的数据发送给Logstash解析过滤,在Filebeats与Logstash传输数据的过程中,为了安全性,可以通过ssl认证来加强安全性。之后将其发送到Elasticsearch存储,并由kibana可视化分析。

二、新型ELK搭建详细过程

实验环境:

未分类

下面是搭建过程中所需程序安装包:
https://pan.baidu.com/s/1w02WtUAqh9yX4TChyMLa5Q 密码:g0p9

1.客户端部署filebeat:

yum -y install filebeat
#查看配置文件所在位置
rpm -qc filebeat

2.修改配置文件使filebeat获取的日志进入redis:

注:此处演示获取spring cloud框架中eureka日志,其他程序日志都可相同方法获取

vim /etc/filebeat/filebeat.yml
#修改的内容有一家几个字段
enabled:true
paths:程序日志路径
output.redis:日志输出地方
                    hosts:redis所在服务器IP
                    port:redis端口
                    key:redis中的key

未分类

3.源码安装redis:

解压redis程序包:

tar zxf redis-3.2.9.tar.gz –C /usr/local/src

编译redis:

cd /usr/local/src/redis-3.2.9
make && make install
ln –s /usr/local/src/redis-3.2.9 /usr/local/redis

注:redis安装时有的缺少语言环境会出错,有的会出现奇奇怪怪的问题,只要复制Error到往上搜索下就能轻易解决,在此不多做解释

修改redis配置文件:

vim /usr/local/redis/redis.conf
#修改内容如下:
daemonize yes                           #开启后台运行
timeout 120                                #超时时间
bind 0.0.0.0                                #任何地址IP都可以登录redis
protected-mode no                     #关闭redis保护机制否则在没有密码校验情况下redis远程登录失败

注:此处是做演示,如果是线上部署elk建议开启持久化机制,保证数据不丢失

4.登录测试redis是否可以正常写入数据:

未分类

5.启动filebeat看看redis是否能接收到数据:

启动filebeat:

systemctl start filebeat

6.进入redis查看是否有数据:

#执行命令:
keys *                          #查看所有key,此操作为慢查询,若redis跑了大量线上业务请不要进行此操做
lrange eureka-log 0 -1 #查询key所有数据,若filebeat启动时间过长请勿进行此操作

未分类

7.安装jdk1.8:

解压jdk安装包并创建软连接:

tar zxf /usr/local/src/jdk-8u131-linux-x64.tar.gz –C /usr/local/
ln -s /usr/local/jdk1.8.0_91/ /usr/local/jdk

配置环境变量:

vim /etc/profile
#修改内容如下:
JAVA_HOME=/usr/local/jdk
export JRE_HOME=/usr/local/jdk/jre
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin

重新载入环境变量:

source /etc/profile

查看jdk是否安装成功:

java -version

未分类

8.安装Elasticsearch:

解压安装包并改名:

unzip elasticsearch-5.6.3.zip -d /usr/local/
mv /usr/local/ elasticsearch-5.6.3 /usr/local/elasticsearh

修改ES配置文件:

vim /usr/local/elasticsearch/config/elasticsearch.yml

#这里指定的是集群名称,需要修改为对应的,开启了自发现功能后,ES会按照此集群名称进行集群发现
cluster.name: my-application
node.name: node-1

#目录需要手动创建
path.data: /opt/elk/data
path.logs: /opt/elk/logs

#ES监听地址任意IP都可访问
network.host: 0.0.0.0
http.port: 9200

#若是集群,可在里面引号中添加,逗号隔开
discovery.zen.ping.unicast.hosts: [“192.168.3.205”]

# enable cors,保证_site类的插件可以访问es    
http.cors.enabled: true             #手动添加
http.cors.allow-origin: “*”         #手动添加

# Centos6不支持SecComp,而ES5.2.0默认bootstrap.system_call_filter为true进行检测,所以导致检测失败,失败后直接导致ES不能启动
bootstrap.memory_lock: false        #手动添加
bootstrap.system_call_filter: false     #手动添加

注:ES启动的时候回占用特别大的资源所以需要修改下系统参数,若不修改资源启动会异常退出

9.修改系统参数:

vim /etc/sysctl.conf
#添加参数
vm.max_map_count=655360

重新载入配置:

sysctl –p

10.修改资源参数:

vim /etc/security/limits.conf
#修改

*   soft    nofile  65536
*   hard        nofile  131072  
*   soft        nproc   65536
*   hard        nproc   131072 

如:

未分类

11.设置用户资源参数:

vim /etc/security/limits.d/20-nproc.conf
#添加
elk     soft    nproc       65536

12.创建用户并赋权:

useradd elk
groupadd elk
useradd elk -g elk

13.创建数据和日志目录并修改目录权限:

mkdir –pv /opt/elk/{data,logs}
chown –R elk:elk /opt/elk
chown –R elk:elk /usr/local/elasticsearch

14.切换用户并后台启动ES:(elk用户修改了资源参数,如不切位elk用户启动会暴毙)

su elk
nohup /opt/app/elasticsearch-5.6.3/bin/elasticsearch >> /dev/null 2>&1 &

15.查看ES状况:

方法一、
curl 'http://[ES IP]:9200/_search?pretty'

方法二、
#网页访问:
http://[ES IP]:9200/_search?pretty

16.安装logstash:

解压并创建软连接:

tar /usr/local/src/logstash-5.3.1.tar.gz –C /usr/local/
ln –s /usr/local/logstash-5.3.1 /usr/local/logstash

测试logstash是否可用:

/usr/local/logstash/bin/logstash -e 'input { stdin { } } output { stdout {} }'

未分类

在此创建主配文件进行测试:

vim /usr/local/logstash/config/logstash-simple.conf
#内容如下:
input { stdin { } }
output {
    stdout { codec=> rubydebug }
}

使用logstash参数-f读取配置文件进行测试:

/usr/local/logstash/bin/logstash -f /usr/local/logstash/config/logstash-simple.conf

未分类

此时说明我们的logstash是完全没有问题了,可以进行日志收集了

17.创建配置文件获取redis日志的数据:

配置文件如下:

vim /usr/local/logstash/config/redis-spring.conf 
input {
  redis {
    port => "6379"
    host => "192.168.3.205"
    data_type => "list"
    type => "log"
    key => "eureka-log"
  }
}
output {
  elasticsearch {
     hosts => "192.168.3.205:9200"
     index => "logstash1-%{+YYYY.MM.dd}"
  }
}

通过配置文件启动服务查看效果:

/usr/local/logstash/bin/logstash -f /usr/local/logstash/config/redis-spring.conf

结果如下:

未分类

此时我们再去查看reids中key:(此时已经没有数据了,数据已经被logstash取完)

未分类

18.使用curl 查看ES是否接受到数据

curl http://192.168.3.205:9200/_search?pretty

结果如下:

未分类

此时说明我们logstash从redis中取数据,在把数据推到ES中是ok的!

19.安装ES插件:(elasticsearch-head)

注:head安装需要从国外网站拉去东西,可能网速过慢导致安装失败(可以多试几次),下面有几种方法安装:

方法一、
导入node-v8.2.1.tar.gz phantomjs-2.1.1-linux-x86_64.tar.bz2 安装包
安装node:
tar zxvf node-v8.2.1.tar.gz
cd node-v8.2.1/
./configure && make && make install 

安装phantomjs:
tar jxvf phantomjs-2.1.1-linux-x86_64.tar.bz2
cd phantomjs-2.1.1-linux-x86_64/bin/
cp phantomjs /usr/local/bin/

导入es-head程序包并解压:
unzip master.zip –d /usr/local/
cd elasticsearch-head/
npm install
npm run start &

查看端口状态:(端口默认9100)
netstat –anpt | grep 9100

方法二、
git clone git://github.com/mobz/elasticsearch-head.git
cd elasticsearch-head
npm install
npm run start
netstat –anpt | grep 9100

方法三、
拉镜像:
docker push mobz/elasticsearch-head:5
启动镜像:
docker run -p 9100:9100 mobz/elasticsearch-head:5
web访问测试:
http://IP:9100

20.Elasticsearch-head安装成功Web访问结果如下:

未分类

查看刚刚从logstash推到ES中的数据:

未分类

21.安装kibana

解压并安装kibana:

tar -zxvf /usr/local/src/kibana-5.3.1-linux-x86_64.tar.gz -C /usr/local/

修改kibana配置文件:

vim /usr/local/kibana-5.3.1-linux-x86_64/config/kibana.yml

修改内容如下:

server.port: 5601                                                            #开启默认端口5601
server.host: “192.168.3.205”                                    #kibana站点IP
elasticsearch.url: http://192.168.3.205:9200        #只想ES服务所在IP Port
kibana.index: “.kibana”

后台启动kibana:

nohup /usr/local/kibana-5.3.1-linux-x86_64/bin/kibana >> /dev/null 2>&1 &

查看端口监听:

netstat –anot | grep 5601

结果如:(此结果表示kibana启动成功)

未分类

使用Web访问kibana:

http://[Kibana IP]:5601

初次访问结果如:(刚访问的时候没有创建索引所以没有看不到数据)

未分类

根据logstash配置文件中index设置索引:
首先查看logstash中的index:

未分类

Kibana中创建index:

未分类

下面按照1,2,3,4顺序进行设置:

未分类

此时我们在返回Discover在里面我们就可以看到数据了:

未分类

至此我们的ELK就安装OK了。

Linux命令之grep/sed/awk等行转列

行转列

样例文件如下

cat file.txt
a b c
d e f
g h i

1、cat file.txt |xargs -n1

2、xargs -n 1 < file.txt

3、tr " " "n" < file.txt

4、sed 's/ /n/g' file.txt
此命令在Linux上执行正常,在Mac上执行无效,原因是因为Mac上的sed是BSD版本,Linux上的是Gnu版本,在Mac上需要使用sed -e ‘s/ /’$’n/g’ file.txt

5、sed 's/ /n/g' file.txt 同上

6、awk '{for(i=1;i<=NF;i++)print $i}' file.txt

7、awk -vOFS="n" '$1=$1' file.txt Linux上正常,Mac上无效

8、awk '{OFS=RS}NF=NF' file.txt Linux上正常,Mac上无效

列转行

样例文件如下

cat file.txt
a
b
c
d
e
f

1、cat file.txt | tr "n" ","

Linux三大利器grep、sed、awk

一. grep和正则表达式

grep

grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。

选项

-d<进行动作> 当指定要查找的是目录而非文件时,必须使用这项参数,否则grep命令将回报信息并停止动作。

-i 忽略字符大小写的差别。

-l 列出文件内容符合指定的范本样式的文件名称。

-n 在显示符合范本样式的那一列之前,标示出该列的编号。

-R/-r 此参数的效果和指定“-d recurse”参数相同。

-v 反转查找。

1、-r递归查找

root@siguorui-OptiPlex-7010:/home/xhprof/trunk# grep -r XHProfRuns_Default *
examples/sample.php:$xhprof_runs = new XHProfRuns_Default();
xhprof_html/callgraph.php:$xhprof_runs_impl = new XHProfRuns_Default();
xhprof_html/typeahead.php:$xhprof_runs_impl = new XHProfRuns_Default();

2、-I的使用,显示文件名称

root@siguorui-OptiPlex-7010:~# grep -I root abc.txt 123.txt passwd 
passwd:root:x:0:0:root:/root:/bin/bash

3、-n

root@siguorui-OptiPlex-7010:~# grep -n 'root' passwd 
1:root:x:0:0:root:/root:/bin/bash

正则表达式

1、正则表达式单字符

  • 特定字符
    • grep ‘a’ passwd
  • 范围内字符
    • grep ‘[a-z]’ passwd
    • grep ‘[A-Za-z0-9]’ passwd
    • grep ‘[^0-9]’ passwd 取反,除去数字之外的字符
  • 任意字符
    • grep ‘.’ passwd

但是在grep ‘[.]’中,.只是代表点这样的字符,注意区别。如果要使用.的本意,采用.的方式

  • 以上三种组合

2、正则表达式其他符号

  • 边界字符 头尾字符
    • ^字符,头字符,放在一串字母前边,代表以此开头。grep ‘^root’ passwd
    • $符号,如false$,代表以false字符结束
    • ^$ 代表空行,grep ‘^$’ passwd
  • 元字符
    • w:匹配任何字类字符,包括下划线。相当于([A-Za-z0-9_])
    • W:大写的W,匹配任何非字类字符。相当于([^A-Za-z0-9_])
    • b 代表单词分隔。如,grep ‘bxb’ passwd,可以将单个前后分隔的x字符选出来,但不会选择单词中出现的x
  • 正则表达式字符组合
    • 重复
* : 零次或多次匹配前面的字符或子表达式。例子:grep 'se*' test.txt
+ : 一次或多次匹配前面的字符或表达式.例子:grep 'se+' test.txt.注意这里加号前面要加反斜杠
? : 零次或一次匹配前面的字符或表达式.如:grep 'se?' test.txt.注意?前面也要加反斜杠
括号的使用 :grep '(se)*' test.txt。注意括号前面要加反斜杠
指定重复次数 : grep '[0-9]{2,3}' passwd 

二.sed 行编辑器

sed是一种流编辑器,它是文本处理中非常重要的工具,能够完美的配合正则表达式使用,功能不同凡响。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。

命令格式

sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)

options常用选项

-e<script>或--expression=<script>:以选项中的指定的script来处理输入的文本文件;

-n或--quiet或——silent:仅显示script处理后的结果;

command常用

a 在当前行下面插入文本。
i 在当前行上面插入文本。
c 把选定的行改为新的文本。
d 删除,删除选择的行。
n 读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。
s 替换指定字符
p 打印模板块的行。
q 退出Sed。
r file 从file中读行。
w file 写并追加模板块到file末尾。  

1、p 打印相关的行

nl passwd|sed -n '10p' //打印第10行内容
sed -n 'p' passwd
sed -n '/root/p' passwd //正则匹配打印
nl passwd|sed -n '10,20p' //打印第10行到20行
nl passwd|sed -n '/news/,/nobody/p' //用正则来指定一个行的范围
nl passwd|sed -n '10,20!p'  //不选择10到20行,!代表取反
nl passwd|sed -n '1~2p' //间隔行,会输出1,3,5....行

注意,这里一定要加上-n选项,否则每条数据会显示同样的2行。并且无关的其他内容也会显示出来

2、a 在行后面增加内容

root@siguorui-OptiPlex-7010:~# nl passwd|sed '2a **************'
     1    root:x:0:0:root:/root:/bin/bash
     2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
**************
     3    bin:x:2:2:bin:/bin:/usr/sbin/nologin

nl passwd|sed '1,2a **************' //在范围内的每一行后面都插入

3、i在行前面插入

root@siguorui-OptiPlex-7010:~# nl passwd|sed '1,2i **************'
**************
     1    root:x:0:0:root:/root:/bin/bash
**************
     2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

4、c把选定的行改为新的文本

root@siguorui-OptiPlex-7010:~# nl passwd|sed '1c abcd'
abcd
     2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

 //与a,i不同的时,如果这里是一个行的范围则是把这个范围内容替换为当前内容   
root@siguorui-OptiPlex-7010:~# nl passwd|sed '1,3c abcd'
abcd
     4    sys:x:3:3:sys:/dev:/usr/sbin/nologin

5、d删除行

root@siguorui-OptiPlex-7010:~# nl passwd | sed '/root/d'
     2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
     3    bin:x:2:2:bin:/bin:/usr/sbin/nologin

应用案例

在文件的末尾插入2行
nl passwd | sed '$a     abcd n    linux'

    49    memcache:x:126:132:Memcached,,,:/nonexistent:/bin/false
    50    postfix:x:127:133::/var/spool/postfix:/bin/false
    51    mongodb:x:128:65534::/var/lib/mongodb:/bin/false
    abcd 
    linux


    删除文件中的空行,^$直接相连代表空行
    nl passwd | sed '/^$/d'

6、s替换命令

sed 's/false/true/' passwd 
输出:
...
sphinxsearch:x:124:131::/home/sphinxsearch:/bin/true
sshd:x:125:65534::/var/run/sshd:/usr/sbin/nologin
memcache:x:126:132:Memcached,,,:/nonexistent:/bin/true
postfix:x:127:133::/var/spool/postfix:/bin/true

sed 's/:/%/g' passwd  //加g全局替换
输出:
sphinxsearch%x%124%131%%/home/sphinxsearch%/bin/false
sshd%x%125%65534%%/var/run/sshd%/usr/sbin/nologin
memcache%x%126%132%Memcached,,,%/nonexistent%/bin/false
postfix%x%127%133%%/var/spool/postfix%/bin/false

过滤ifconfig中的ip

eno1      Link encap:以太网  硬件地址 f8:b1:56:c5:e7:44  
          inet 地址:172.19.5.175  广播:172.19.5.255  掩码:255.255.255.0
          inet6 地址: fe80::c422:e82d:ad66:7a92/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  跃点数:1
          接收数据包:35171885 错误:53864 丢弃:0 过载:0 帧数:29047
          发送数据包:25049325 错误:0 丢弃:0 过载:0 载波:0
          碰撞:0 发送队列长度:1000 
          接收字节:8124495140 (8.1 GB)  发送字节:4549284803 (4.5 GB)
          中断:20 Memory:f7f00000-f7f20000 

 ifconfig eno1 | sed -n '/inet /p'|sed 's/inet.*地址://'|sed 's/广播.*$//'

 输出:
 172.19.5.175

高级操作命令

1、多个sed命令,用{}包住,‘;’隔开

删除44-48行内容,然后将false替换为true
nl passwd|sed '{44,48d;s/false/true/}'

    41    statd:x:121:65534::/var/lib/nfs:/bin/true
    42    mysql:x:1001:1001::/home/mysql:/sbin/nologin
    43    www:x:1002:1002::/home/www:/sbin/nologin
    49    memcache:x:126:132:Memcached,,,:/nonexistent:/bin/true
    50    postfix:x:127:133::/var/spool/postfix:/bin/true
    51    mongodb:x:128:65534::/var/lib/mongodb:/bin/true

2、n 读取下一个输入行

//n的用法
root@siguorui-OptiPlex-7010:~# nl passwd|sed -n '{p;n}'
     1    root:x:0:0:root:/root:/bin/bash
     3    bin:x:2:2:bin:/bin:/usr/sbin/nologin
     5    sync:x:4:65534:sync:/bin:/bin/sync
     7    man:x:6:12:man:/var/cache/man:/usr/sbin/nologin

提示: nl passwd|sed -n '{1~2p}'  前面讲到的,~也可以实现同样的效果

3、&替换固定字符串,&代表前面匹配到的字符

//姓名和后面的内容加空格隔开
root@siguorui-OptiPlex-7010:~# sed 's/^[a-z_]+/&     /' passwd
root     :x:0:0:root:/root:/bin/bash
daemon     :x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin     :x:2:2:bin:/bin:/usr/sbin/nologin


//用户名的首字母转换为大写
//元字符u l(对首字母大小写转换) U L(对一串字符大小写转换),转换为大写小写字符

//小写u,替换用户名首字母
root@siguorui-OptiPlex-7010:~# sed 's/^[a-z_]+/u&/' passwd
Root:x:0:0:root:/root:/bin/bash
Daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
Bin:x:2:2:bin:/bin:/usr/sbin/nologin

//大写U,用户名全部替换为大写
root@siguorui-OptiPlex-7010:~# sed 's/^[a-z_]+/U&/' passwd
ROOT:x:0:0:root:/root:/bin/bash
DAEMON:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
BIN:x:2:2:bin:/bin:/usr/sbin/nologin

4、()的使用

//从passwd文件中,提取出username,uid,gid.  1,2,3代表前面()匹配到字符
root@siguorui-OptiPlex-7010:~# sed 's/(^[a-z_-]+):x:([0-9]+):([0-9]+):.*$/USER:1    UID:2   GID:3/' passwd
USER:root    UID:0   GID:0
USER:daemon    UID:1   GID:1
USER:bin    UID:2   GID:2
USER:sys    UID:3   GID:3
USER:sync    UID:4   GID:65534

5、-r复制指定文件插入到匹配行。-w复制匹配行拷贝到指定文件

//123.txt文件中有3行,全是数字。abc.txt文件中有3行,全是字母
//下面命令的实现结果,读取123.txt的内容,复制到匹配的abc.txt文件的第一行,文件内容均不改变
root@siguorui-OptiPlex-7010:~# sed '1r 123.txt' abc.txt 
qwefadssa
1232323223
32343434
23333
trwrda
asdfasdf

//下面命令的实现结果,匹配abc.txt文件的第二行,写入到123.txt文件中。123.txt文件会发生变化,abc.txt文件内容不变
root@siguorui-OptiPlex-7010:~# sed '2w 123.txt' abc.txt 
qwefadssa
trwrda
asdfasdf
root@siguorui-OptiPlex-7010:~# cat 123.txt 
trwrda


//总结
sed '2w或2r 文件A' 文件B
匹配的文件都是针对文件B来说的,读或写都是针对文件A来说的

6、q找到指定结果后就提前退出

root@siguorui-OptiPlex-7010:~# nl passwd |sed '2q'
     1    root:x:0:0:root:/root:/bin/bash
     2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
root@siguorui-OptiPlex-7010:~# nl passwd |sed '/root/q'
     1    root:x:0:0:root:/root:/bin/bash
root@siguorui-OptiPlex-7010:~# 

三、awk

AWK是一种处理文本文件的语言,是一个强大的文本分析工具。特点是处理灵活,功能强大。可实现统计、制表以及其他功能。

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

格式

命令行格式
awk [options] 'command' file(s)

脚本格式
awk -f awk-script-file file(s)

命令形式:

awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file
  • [-F|-f|-v] 大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=value

' ' 引用代码块

  • BEGIN 初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符
  • // 匹配代码块,可以是字符串或正则表达式
  • {} 命令代码块,包含一条或多条命令
  • ; 多条命令使用分号分隔
  • END 结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息

常用内置参数

  • $0,$1,$2… 表示整个当前行
  • $1 每行第一个字段
  • NF 字段数量变量
  • NR 每行的记录号,多文件记录递增
  • FILENAME 文件名

1、常用内置参数,$1,$2….。通过分隔符指定,按顺序依次为$1,$2…。默认分隔符为空格

awk -F ':' '{print "USERNAE:"$1"t""UID:"$3}' passwd

2、NR,NF,FILENAME

awk -F ':' '{print "Line:"NR,"Col:"NF,"USER:"$1}' passwd

3、运用printf指定格式来打印

awk -F ':' '{printf("Line:%3s Col:%s User:%sn",NR,NF,$1)}' passwd

root@siguorui-OptiPlex-7010:~# awk -F ':' '{printf("Line:%3s Col:%s User:%sn",NR,NF,$1)}' passwd
Line:  1 Col:7 User:root
Line:  2 Col:7 User:daemon
Line:  3 Col:7 User:bin
Line:  4 Col:7 User:sys
...

4、使用if

awk -F ':' '{if ($3>100) printf("Line:%3s Col:%s User:%sn",NR,NF,$1)}' passwd

5、正则和命令结合使用

awk -F ':' '/root/{print $1}' passwd

root@siguorui-OptiPlex-7010:~# awk -F ':' '/root/{print $1}' passwd
root

6、使用BEGIN和END来制表

awk -F ':' 'BEGIN{print "line col user"}{print NR" |"NF" |"$1}END{print "----------------"FILENAME}' passwd

7、使用BEGIN和END来统计一个目录下文件总计大小

ls -l|awk 'BEGIN{size=0}{size+=$5}END{print " size is "size/1024/1024"M"}'

8、统计passwd中不为空的行数。$1!~,~代表匹配后面的正则,!~代表不匹配。/^$/正则匹配空行

awk -F ':' 'BEGIN{count=0}$1!~/^$/{count++}END{print " count ="count}' passwd

9、统计结果放到数组中,并打印输出

awk -F ':' 'BEGIN{count=0}{if ($3>100) name[count++]=$1}END{for(i=0;i<count;i++) print i,name[i]}' passwd 

root@siguorui-OptiPlex-7010:~# awk -F ':' 'BEGIN{count=0}{if ($3>100) name[count++]=$1}END{for(i=0;i<count;i++) print i,name[i]}' passwd 
0 nobody
1 systemd-network
2 systemd-resolve
3 systemd-bus-proxy
4 syslog