定时任务 cron
第一个命令是查询当前用户的任务列表
crontab -l
未设置任务自然显示没有任务
crontab -e
编辑任务,如果系统里有多个编辑器,会让你选择一个,比如nano,vim等,根据个人喜好选择编辑器,然后进入编辑界面。
* * * * * command
这是crontab的格式,前5个设置时间,从左至右分别为分,时,天,月,星期,最后一个定时执行的命令。其中 * 表示是任意值。
1列:取值0-59,代表几分,当然也可使用 * 代表所有(下同)
2列:取值0-23,代表几点
3列:取值1-31,代表几号
4列:取值1-12,代表月份
5列:取值0-7,代表星期几,0或7都表示星期天,比如5表示星期五
如下面这行:
5 9 15 8 5 echo "hello world"
代表每年8月15日9点5分执行echo “hello world”命令,实际这一天不一定是星期五,所以每年不一定会执行一次。
我们可以其中的一列改成*,甚至全改成* 都可以。全部改成 * 表示每一分钟都执行。
也可不必全部输入时间的5列,如:
@hourly echo “hello world”
表示每小时执行一次
@reboot echo “hello world”
表示重启时执行
默认执行crontab -e是编辑当前用户的计划任务,如果想编辑其他用户,加上 u 参数即可
sudo crontab -u root -e
然后给 root添加一行定时任务
* * * * * apt install -y tmux
保存退出。
sudo crontab -u root -l
检查这行已加入。
等一分钟后,执行
which tmux
发现已安装好,说明定时任务在起作用了。
查看日志下:
cat /var/log/syslog | grep cron
小写的cron可以查到系统尝试运行、编辑crontab的事件。
cat /var/log/syslog | grep CRON
查找的大写CRON可以查到crontab中执行的具体命令
安装tmux这些工作一般手动执行更合适,放在cron不太适当,我们删除这条,在root用户增加一条
sudo crontab -u root -e
* * * * * date >>/root/date.txt
查看该文件,平均一分钟左右增加一行
下面我看一例实际中用到的,我们定期备份apache网站:
选安装apache2
apt install apache2
测试网站能用。
apache2默认会创建 www-data用户,我们查看一下
cat /etc/passwd | grep www-data
我们尝试切换到www-data用户
sudo su – www-data
提示不可用,原因是该用户是nologin的,这是故意设置的安全考虑,防止有人以该用户登录删除整个网站。
即便用户不能登录,我们也是可以设置定期任务的。
sudo crontab -u www-data -e
到文本最后添加一行
0 3 * * * /usr/local/bin/website_backup.sh
设置每天凌晨3点整运行该脚本备份网站,我们假设有该脚本,其功能是备份网站。注意命令的路径是全路径,建议写全。
有一个不错的网站可以生成 crontab
Linux通用应用程序
Linux通用应用程是什么?一般有三种:
- AppImage
- Flatpak
- Snaps
当开发人员开软件时,一般会瞄准两个平台:MacOS和Windows,极少是为Linux开发的,为什么?因为在centos平台下,需要编译成 yum包,而在ubuntu下,需要编辑成apt包,开发人员没这么多时间。而通用应用程序达到的目的是,开发人员只需开发一个包就可以在不同的Linux发行版平台上运行!
不少人可能会认为,我使用各发行版自己的包管理器很好啊为何要用通用应用程序包,比如在ubuntu中,我用apt install firefox就很方便安装了。但各Linux发行版用的是稳定不滚动的版本,如果想用最新的技术则会有问题,apt会提供安全更新,但不会使用最新的技术,比如libreoffce,如果用apt安装用不了最新的技术,而用通过dnf安装通用的包则可以。
另外一点重要的是,各发行版发布的包通常依赖于发行版的内核各包,与用户其他应用程序共享,如果依赖包出问题了,软件也将不能用。而通用应用则不会,它相对独立,也就更稳定。
有人说了,通用应用占空间更大,比如A和B两个通用应用都依赖C,那在A和B中都要复制C,这是可能的,但一般不会使占用空间增加太多。现在硬盘价格低廉,多增加点空间根本不是什么问题。
主题问题。通用应用程自带依赖包,界面可能自成体系,这也可以使主题界面方便在另外的Linux发行版中运行,当然也会出现界面粗糙的问题,但相信会越来越好。
开头提到的三种应用程序包各有优缺点。
AppImage:
优点:简单,甚至不用安装。下载,赋予可执行权限,运行即可。
缺点:可能存在后门或安全隐患,可能不是最新的版本,不太容易看出来。
Snaps:
类似apt,可以用 snap install或 snap find等方法安装和查找。使用方便。
但主要有以下观点的抱怨:一是没法选择,其实snap由Canonical公司开发免费提供,他没法保同时开发多套,比如谷歌浏览器更新了,他就得去开发一个snap包。二是太慢了,snap始终需要运行,启动确实有点慢。三是snap是专有技术,只能去Canonical公司的存储库下载,这确实是个问题。
Flatpak:
没有专用限制,可以有第三方存储库,但目前只有一个,可能是没人愿费心去打造。flathub.org
比起snap,Flatpak更开放。比如我们可以用Flatpak安装最新的firefox,Linux发行版一般不会提供最新版。
小结:
通用应用程序是未来Linux软件分发的趋势,因为可以用到最新的特性,同时不依赖于系统特定的包,出错崩溃的可能性也越小。
- AppImage最易安装
- Snap很酷,但比其他应用程序打开会慢一些,而且只能有一个应用商店。
- Flatpak没有Snap的缺点,非常不错。
任wsk通用应用程序包都会比apt包要大,但这通常不算问题。
AWK
这一节来学习AWK,与其说AWK命令不如说是脚本。
AWK可以创建过滤器,可以创建脚本接受来自标准输入的数据,通过某种方式修改它,再过标准输出将数据发送出去。
一般而言,标准输入是文本文件,标准输出是屏幕。
我们也可以将命令链接到 AWK中。
假设我们有一个文件文件tmnt.txt,文本内容如下:
该文本有四行,代表4个神龟🐢。
默认情况下,awk将空格视为分隔符,所以每一行都为三个字段,分别表示名字、头巾颜色和个性。
第一个awk命令:awk后面需要输一个命令,然后是输入,比如是这个文件
awk ‘{print}’ tmnt.txt
将输出tmnt.txt的内容。这跟cat命令一样,当然AWK可强大得多,我们再试一个
awk ‘{print $1}’ tmnt.txt
加上$1 将显示每一行的第一个字段。
我们改成$2或$3显示各行的第2个和第3个字段。
awk 后跟的{}里面的是脚本,可以编辑更复杂的脚本。
awk ‘{ print $0}’ tmnt.txt
我们将改成$0,表示是全部内容,这跟不加$0是一样的。
我们也可以输出多个字段,以下命令输出每一行的第一个字段和第三个字段
awk ‘{ print $1,$3 }’ tmnt.txt
awk输入未必需要是文件,可以串接到命令之中。
ls -l | awk ‘{print $1,$2}’
echo “hello from kelemi” | awk ‘{print$1,$3}’
我们再看一个awk的用法
awk ‘{print $NF}’ tmnt.txt
$NF表示最后一个字段,将输入每一行的最后一个字段
有些文本不是以空格或制表符分隔的,比如 /etc/passwd就是以 : 分隔的,该如何做呢?也是简单的,加上F参数即可。
awk -F’:’ ‘{print $1}’ /etc/passwd
sed命令
sed是流编辑器的缩写,可以过滤和修改文本文件。
sed ‘s/Pineapple/Feta/’ toppings.txt
这条命令将toppings.txt文件中的Pineapple修改成Fetad。我们可以在屏幕上看到修改后的结果。我们当然可以用nano或vim打开再修改,但sed明显更快。
我们再用cat toppings.txt查看文件,却发现文件内容并未改变,还是之前的Pineapple。
默认情况下sed不改变原文件,只送到标准输出(屏幕)。如果需要修改文件的话,我们可以在后面加上重定向 > 到该文件,更简单的办法是加上 -i
sed -i ‘s/Pineapple/Feta/’ toppings.txt
我们看到这里的命令用 / 作为分隔符,实际可以用空格 ,点 或竖线都是可以的,如下面三条命令都是可以成功执行的。sed命令将自动将 s 后面的符号作为分隔符。
sed -i ‘s Pineapple Feta ‘ toppings.txt
sed -i ‘s.Pineapple.Feta.’ toppings.txt
sed -i ‘s|Pineapple|Feta|’ toppings.txt
这其实是有意义的,比如替换的文本中有 / 符号,如果还用 / 作为分隔符则会出错,就需要用到其它分隔符。比如我们准将test2.txt文件中的 所有/etc去掉(相当于替换为空),我们该如何做呢?
用 / 作为分隔符的命令将是:
sed ‘s//etc//’ tests.txt ,这条命令不会执行成功的。
所以我们将分隔离换成比如 .
sed ‘s./etc.. test2.txt
这样就达到将test2.txt中的所有 /etc去掉。
sed当然也可跟命令连接,不一定输入都是文件
echo “hello” | sed ‘s/hello/goodbye/’