Relative Content

K4NZDROID

category

「systemd」- 概念、术语

System Instance and User Instance
在阅读「systemd-system.conf」手册时,有这样一段话:

When run as a system instance, systemd interprets the configuration file system.conf and the files in system.conf.d directories; when run as a user instance, systemd interprets the configuration file user.conf and the files in user.conf.d directories.

问题就是:什么是 system instance?什么是 user instance?
「系统服务」是由「系统级 systemd 实例」管理。
「用户服务」是由「用户级 systemd 实例」管理。
「系统级 systemd 实例」只能有一个,它总是运行的,进程ID 为 1 。只有系统管理员才能管理它的服务。
「用户级systemd实例」是以命令systemd –user形式运行,你可以看一下系统中systemd进程数及它们的运行方式,这个在桌面环境下比较明显。它们的进程ID不为 1 。每个用户只有一个实例。
参考文献
systemd/Directives/systemd-system.conf What is the difference between systemd’s user and system services?[……]

READ MORE

「systemd」- 常见问题处理

访问systemd的首页
在Serivce单元文件中使用管道

#!/bin/sh

# 在指令ExecStart的参数中,命令后的内容会被视为参数,所以对于管道应该使用如下形式:

ExecStart=/bin/sh -c ‘/apppath/appname > /filepath/filename 2>&1’

# 下面是一种错误的用法:

ExecStart=/apppath/appname > /filepath/filename 2>&1

# 则systemd会将/apppath/appname视为参数,而“>”、“/filepath/filename”、“2>&1”则会被视为命令参数。

“运行级别”
在 systemd 中,已经没有了以往“运行级别”的概念了,而是“目标(Target)”。下面是“运行级别”和“目标”的对应关系:

Run level 0 is matched by poweroff.target (and runlevel0.target is a symbolic link to poweroff.target).
Run level 1 is matched by rescue.target (and runlevel1.target is a symbolic link to rescue.target).
Run level 3 is emulated by multi-user.target (and runlevel3.target is a symbolic link to multi-user.target).
Run level 5 is emulated by graphical.target (and runlevel5.target is a symbolic link to graphical.target).
Run level 6 is emulated by reboot.target (and runlevel6.target is a symbolic link to reboot.target).
Emergency is matched by emergency.target.

查看默认“目标”:systemctl get-default 设置默认“目标”:systemctl set-default multi-user.target 变更“运行级别”:systemctl isolate multi-user.target
How to Change Runlevels (targets) in SystemD[……]

READ MORE

「systemd」 – 创建和修改单元文件

问题描述
作为一个系统管理员,要遵循系统管理规范,而不能说”能用就行“。本文将介绍如何编写systemd单元文件。
注意事项
这不是一个详细的教程。这篇文章是在我学习如何编写systemd单元文件时的一个摘要笔记。文章的内容只是一个概括,涵盖了创建单元文件可能用到的知识点和相关的参考手册,并不涉及太多的细节,细节上的东西只能去读文档了。
单元文件的存储位置
单元文件的保存位置:Table 10.2, “Systemd Unit Files Locations”
/usr/lib/systemd/system/ Systemd unit files distributed with installed RPM packages.
/run/systemd/system/ Systemd unit files created at run time. This directory takes precedence over the directory with installed service unit files.
/etc/systemd/system/ Systemd unit files created by systemctl enable as well as unit files added for extending a service. This directory takes precedence over the directory with runtime unit files. the /etc/systemd/system/ directory is reserved for unit files created or customized by the system administrator.
单元文件的命名方式
形如:unit_name.type_extension
unit_name:单元名。 type_extension:单元类型。可用的类型参考:Table 10.1, “Available systemd Unit Types”
单元文件结构
单元文件由 [Unit]、[unit type]、[Install] 三部分组成,每个部分都包含多种不同的指令。
[Unit]
解释:包含描述、依赖等指令,是一些更通用的指令,这些指令与单元类型无关。
参考 systemd.unit/[Unit] Section Options 文档,获取 [Unit] 部分的指令说明。
[<unit type>]
参数unit type不是固定的,可以是Service、Timer等等,它代表单元文件的类型。比如,如果服[……]

READ MORE

「使用systemd在开机时自动挂在硬盘」

Recently, I discovered you can mount partitions using systemd.mount by writinga mount unit file. In this blog post, we”ll talk about systemd.mount & how you can use it to mount partitions.
Systemd is gradually becoming the de facto init system & service manager replacing the old sysV init scripts & upstart. Recently, I discovered you can mount partitions using systemd.mount by writing your own .mount systemd unit file.
After RTFM’ing, I realized, under the hood, systemd just runs mount command to mount the specified partition with the specified mount options listed in the mount unit file. Basically, you need to specify the following options in your unit file:

What= a partition name, path or UUID to mount
Where= an absolute path of a directory i.e. path to a mount point. If the mount point is non-existent, it will be created
Type= file system type. In most cases mount_command auto-detects the file

system

Options= Mount options to use when mounting

In the end, you can convert your typical fstab entry such as this:

UUID=86fef3b2-bdc9-47fa-bbb1-4e528a89d222 /mnt/backups ext4 defaults 0 0

to:

[Mou[……]

READ MORE

「systemd」- 配置文件

修改system.conf后,如何生效?
修改/etc/systemd/system.conf文件之后,不要执行systemctl daemon-reload命令。因为该命令是用于重新加载单元文件的,而不是systemd自身的配置。
应该执行systemctl daemon-reexec命令,它将重新执行systemd命令,并加载配置文件。
详细内容可以参考「systemctl/daemon-reexec」手册。
参考文献
reboot or “systemctl daemon-reload” for changes to /etc/systemd/system.conf?[……]

READ MORE

「systemd」- 查看单元文件、分析依赖关系(systemd-analyze)

解决方案
查看所有单元文件:

systemctl -l # –full

分析依赖关系:

systemctl list-dependencies # 虽然能够显示依赖关系,但是不够细微

systemd-analyze plot > startup_order.svg
systemd-analyze dot | dot -Tsvg > systemd.svg

常见问题处理
在磁盘挂载后,再启动服务:

[Unit]

After=local-fs.target

参考文献
yocto – Is there any way to list systemd services in linux “in-the-order-of” they were loaded? – Stack Overflow Running systemd unit directly after local-fs.target and before basic.target – Stack Overflow[……]

READ MORE

「systemd」- 从 systemctl status 中提取个别字段

问题描述
在 Shell Script 中,我们需要判断服务的运行状态,以作出相应的逻辑处理。
该笔记将记录:如何获取 systemd 管理的某个服务的运行状态。
解决方法
我们以 nginx 服务为例,判断服务的运行状态

# systemctl show nginx.service –property ActiveState
ActiveState=inactive

# systemctl start nginx.service

# systemctl show nginx.service –property ActiveState
ActiveState=active

如果希望在 Shell Script 中使用:

eval $(systemctl show nginx.service –property ActiveState)
if [ “$ActiveState” = “active” ]; then
echo “Nginx is running.”
else
echo “Nginx is stopped.”
fi

参考文献
python – how to get individual values from the output of systemctl status – Stack Overflow shell – Run a string as a command within a Bash script – Stack Overflow[……]

READ MORE

「systemd」- 常见错误汇总

# Unit XXX is transient or generated
Failed to enable unit: Unit /run/systemd/generator.late/jenkins.service is transient or generated
#
Jun 19 08:37:38 dns systemd[1]: named-sdb.service: main process exited, code=killed, status=11/SEGV[……]

READ MORE

「Linux」- “无聊”的命令

cowsay
xcowsay
sl
boxes
img2txt
w3m-img
# I couldn’t imagine a better waste of my time.
在终端里…看…视…频…
How to watch films/images without X? https://www.youtube.com/watch?v=EvCkBDuLgxY http://www.annasagrera.com/on-ascii-youtube-and-letting-go (1)Watch YouTube videos in terminal mplayer -vo caca video.mkv[……]

READ MORE

「CentOS」- 禁用「You have new mail in /var/spool/mail/root」提示

问题描述
在CentOS中,进行终端(命令行)操作时,经常会收到「You have new mail in /var/spool/mail/root」消息。该功能有时会影响操作,比如在命令输入的过程中,上面的消息会混进输入内容里,影响对输入内容的阅读及确认。
本文将介绍如何禁用「You have new mail in /var/spool/mail/root」消息。
解决办法
默认情况下,在Bourne shell中,每十分钟检查一次邮件。要在其他的某个时间间隔检查,可以将变量MAILCHECK设置为新的时间间隔(以秒为单位)。
例如,下面的命令告诉Shell每隔55秒检查一次:MAILCHECK=55
一个有用的技巧是将MAILCHECK设置为0值,此时Shell将在打印提示符时进行检查。换句话说,它会在每个命令后检查。在繁忙的系统上这可能会很慢。
如果你不想使用该功能,可以unset MAILCHECK环境变量。
参考文献
Disable “You have new mail” terminal message 21.8.2 For Bourne Shell Users[……]

READ MORE

「Linux / Shell」- 当退出“man”手册后,在屏幕上保留查看的内容

问题描述
当我们执行终端全屏的命令后,在退出时,终端的内容会被清空。比如man find,按“q”退出时,回到我们执行命令之前的状态,而不会在终端上保留执行man find命令产生的输出;
有时这并不方便。因为我们也许需要参照手册的提示内容,来键入后面的命令。因此需要保留命令在终端上的产生的输出;
本文的主要内容就是讨论如何在终端里保留全屏命令产生的输出;
原因分析
为什么屏幕的内容会被“清空”?
实际上并不是”清空“,这种行为来自某些(硬件)终端和大多数(软件)终端仿真器中提供的“备用屏幕(Alternate Screen)”功能。这会发生什么事情是一些“终端感知程序”切换到“备用屏幕”来完成他们的工作,并在他们被退出(或暂停等等)时切换回“正常屏幕”。这有效地清除了这些程序的最终输出,所以看起来像是被清空了;
因此入手点有两个:

禁止程序使用“备用屏幕”。这通过设置特定程序实现;
关闭“备用屏幕”功能。这通过设置终端程序实现;

下面将按照这两方面进行介绍;
通过设置特定程序实现
文章「Exorcising the Evil Alternate Screen」讨论了“备用屏幕”的问题,并提出了几个解决办法;
某些程序通过配置可以禁用“备用屏幕”:

命令 less(1)可以使用-X 选项,或者通过它支持的 LESS 环境变量;
命令 vim(1)可以通过取消 t_ti 和 t_te 变量;
关于 GNOME Terminal 参考「Stop gnome-terminal screen clear」一文;
终端复用程序 screen 可以使用altscreen off配置选项。而 tmux 可以在配置文件中添加set -g alternate-screen off配置行;

有关的详细内容和配置细节请参考对应的手册;
解决方案
通过设置终端程序实现
本部分旨在提用一个在 XTerm 中相对通用的方法,而不是去配置具体的程序来实现“禁用备用屏幕”;
方法一、配置 XTerm 控制序列
本部分参考「Is there any way to exit “less” without clearing the screen?」、「How can I still see the ‘man’ text after I quit man?」文章;
方法二、修改 .Xresource 文件
在$HOME/.Xresources 文件中加入:

XTerm*titleInhibit: true

然后,执行:xrdb $HOME/.Xres[……]

READ MORE

「Zsh」- Z shell (Zsh)

安装 Zsh 程序

# Debian GNU/Linux 10 (buster)
apt-get install zsh

使用 Oh My Zsh 框架(主题工具)
ohmyzsh/ohmyzsh: 🙃 A delightful community-driven (with 1700+ contributors) framework for managing your zsh configuration.
Oh My Zsh,让我们的终端五彩斑斓(然而,我们依旧使用 Bash,只是想体验一下)。通过 OMZ 可以扩展 zsh 功能,增强 zsh 体验。

安装 Oh My Zsh 框架
安装过程如下(这里记录手动安装,更多安装方法参考 ohmyzsh/README.md at master · ohmyzsh/ohmyzsh 文档):

# Debian GNU/Linux 10 (buster)
git clone https://github.com/ohmyzsh/ohmyzsh.git ~/.oh-my-zsh
cp -v ~/.zshrc ~/.zshrc.orig
cp -v ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
# chsh -s $(which zsh) # 我们只是体验 Zsh 因此不会修改默认 Shell 程序
zsh # 之后,会提示相应的初始化步骤

手动升级:omz update 禁用升级提示:echo ‘DISABLE_UPDATE_PROMPT=true’ >> ~/.zshrc 开启自动升级:echo ‘DISABLE_AUTO_UPDATE=true’ >> ~/.zshrc
安装 powerlevel10k 主题
romkatv/powerlevel10k: A Zsh theme
powerlevel10k,让我们的终端(zsh)更加的五彩斑斓(HuaLiHuShao):

我们已经安装 Oh My Zsh 框架,因此采用与之相关的安装方法(其他安装方法参考 powerlevel10k/README.md at master · romkatv/powerlevel10k 文档)

# 第一步、安装字体
mkdir -pv /usr/local/share/fonts/powerlevel10k/
wget -P /usr/local/share/fonts/powerlevel10k/ https://github.com/romkatv/powerlevel10k-media/raw/master/M[……]

READ MORE

「Shell」- 关于「printenv(1)」「env(1)」「set」之间的差异

本文主要介绍这几个命令在环境变量打印方面的差异;
printenv(1)
命令 printenv 用于打印所有或者部分环境变量;
但是,只能打印已经导出的 Shell 环境变量;
env(1)
命令 env 将仅显示已导出的环境变量列表,并且不会显示所有 bash 变量;
set
命令 set 是 Shell 中的一个内建命令,它能够显示当前 Shell 中的变量,已经用户自定义的变量,不管该变量有没有 export。set 命令允许你更改 Shell 选项的值并设置位置参数,或者显示 Shell 变量的名称和值。如果未提供任何选项或参数,则会设置显示所有 Shell 变量和函数的名称和值(按照当前语言环境排序),并且输出的格式可以重新用作设置或重置当前设置变量的输入;
最后总结
在我的 Debian 中,命令 env(1)和 printenv(1)的输出相同,唯一不同的地方是”_“环境变量(执行diff <(env) <(printenv)命令查看);
总的来讲 printenv(1)和 env(1)在环境变量打印方面是类似的。但是在其他方面,比如功能上,env(1)主要用于设置环境变量并运行指定的命令命令,而 printenv(1)是为了打印环境变量;
而 set 是一个 Shell 的内建命令,与 Shell 有关,用于设置 Shell 的属性;[……]

READ MORE

「Linux」- 进行时间校准

为什么每次开机之后,时间都是准确的,不会因为断电而时间不准确了?因为电脑上是有电池的,即使是台式机,主板上也有一颗纽扣电池,该电池是给CMOS模块供电的,而时间和配置相关的信息都保存在CMOS中。但如果电池没电了,或者时间不准确了,想校准时间怎么办?这篇文章会回答这个问题。
使用nptdate命令将系统时间与网络时间同步
ntpdate 如果有网络的话,推荐的做法是使用NTP Server来同步时间。
首先,查找可用的NTP Server 可以在ntp的「Server Pool Project」中查找国内的NTP Server列表,如下(08/10/2017):

server 0.asia.pool.ntp.org
server 1.asia.pool.ntp.org
server 2.asia.pool.ntp.org
server 3.asia.pool.ntp.org

然后,使用ntpupdate来更新时间

ntpdate 0.asia.pool.ntp.org

关于NTP Server的更多细节,查看另外一篇文章“NTP Server”
手动设置系统时间
date 命令date(1)用于打印和设置系统时间。支持以指定的日期格式来打印。但这里介绍的主要内容为使用date(1)命令来设置时间。 date中的-s选项可以用来设置时间,比如:date -s “2015/03/30 12:34:16″。 关于date命令的更多使用细节,参见date(1)手册。
hwclock 命令 date 只能设置系统时间,而修改硬件时间需要使用 hwclock 命令。 hwclock -w 可以将当前的系统时间写入CMOS中。 关于 hwclock 命令命令的更多细节,查看 hwclock(8) 手册。
参考文献
LFS:http://www.linuxfromscratch.org/blfs/view/stable/basicnet/ntp.html vbird:http://linux.vbird.org/linux_server/0440ntp.php NTP Homepage:http://linux.vbird.org/linux_server/0440ntp.php wiki:https://en.wikipedia.org/wiki/Network_Time_Protocol[……]

READ MORE

「NTP」- 常见错误列表

#1 no server suitable for synchronization found

# ntpdate -v 103.213.249.202
5 Apr 23:25:30 ntpdate[32496]: ntpdate 4.2.8p10@1.3728-o (1)
5 Apr 23:25:38 ntpdate[32496]: no server suitable for synchronization found

原因:这个问题的原因可能会有很多种,说以下我遇到的情况:103.213.249.202是我自己的NTP服务,我在服务器中配置了防火墙,导致NTP服务在请求上游的服务器时,数据包被防火墙过滤掉了。解决办法就是添加防火墙规则。
解决:iptables -A INPUT -i eth0 -p udp -m udp –dport 123 –sport 123 -j ACCEPT
#2 the NTP socket is in use, exiting

# ntpdate -v 0.centos.pool.ntp.org
5 Apr 23:35:14 ntpdate[7475]: ntpdate 4.2.6p5@1.2349-o Wed Jul 12 12:22:59 UTC 2017 (1)
5 Apr 23:35:14 ntpdate[7475]: the NTP socket is in use, exiting

原因:本地已经运行了NTP服务。NTP服务运行使使用了123端口,而ntpdate发送查询数据包时默认的源端口也是123。
系统:Ubuntu 14.04.5 LTS
解决:有两种解决方法: 1)停止本地服务即可。执行service ntp stop命令来停止服务,或者使用其他方法来停止。 2)使用ntpdate的-u选项,在发送数据包时使用非特权端口(>1024)。[……]

READ MORE

「Linux」- 时区设置

本笔记将记录常见 Linux 发行的时区查看与设置方法。
CentOS 6.x(通用方法)
Setup Timezone and NTP on CentOS 6 How to check which timezone in Linux?
查看当前时区,如下输出表示当前市区为 Asia/Shanghai:

# date ‘+%Z %z’
CST +0800

设置时区:

ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime[……]

READ MORE

「Linux」- 同步系统时间(基于 systemd 管理)

问题描述
很早之前,系统时间同步是通过 NTP 服务并配合 Cron(定时任务来完成的)。
现在,在较新的 Linux 发行版中,如果操作系统通过 systemd 进行服务管理,那多半也使用 systemd 提供的工具进行系统时间管理。
解决方案
systemd-timesyncd
systemd-timesyncd – ArchWiki
实现 SNTP 客户端,能够进行系统时间的管理 不提供 NTP Server 功能,
查看当前时钟设置(查看)
通常使用 timedatectl 设置操作系统时间。
使用 timedatectl 查看时间同步状态:

# timedatectl
Local time: Mon 2020-05-25 10:58:29 EDT
Universal time: Mon 2020-05-25 14:58:29 UTC
RTC time: Mon 2020-05-25 14:58:28
Time zone: America/New_York (EDT, -0400)
NTP enabled: yes
NTP synchronized: yes
RTC in local TZ: no
DST active: yes
Last DST change: DST began at
Sun 2020-03-08 01:59:59 EST
Sun 2020-03-08 03:00:00 EDT
Next DST change: DST ends (the clock jumps one hour backwards) at
Sun 2020-11-01 01:59:59 EDT
Sun 2020-11-01 01:00:00 EST

选择并设置时区(时区)
时区信息由 NANA 维护,但是时区采用地区命名,即使用在时区中的某个地区代表这个时区。这带来的问题的就是我们不知道使用哪个地区名,比如到底是 Asia/Beijing 还是 Asia/Shanghai 代表我们的时区。使用 tzselect 命令,根据提示进行选择,最后可以确定要使用的时区。该命令用于确定时区,但是不会修改时区。
使用 timedatectl set-timezone 设置:

timedatectl set-timezone Asiz/Shanghai

直接修改时间信息(时间)
使用 timedatectl set-time 设置,时[……]

READ MORE

「Linux」- 使用 systemd-timesyncd 同步时间

systemd-timesyncd
内建于 systemd 的、用于时间同步的、轻量级的组件。
注意事项,该组件只能用于时间同步,而不能像 ntpd 一样作为时间服务器。
实验环境概述
操作系统:Debian 10 软件版本:systemd 241 (241)
该操作不适用与 CentOS 7.x 系列: 根据 Systemd TimeSyncd 与 CentOS 7.2 Minimal Time synchronization timedated and/or ntpd/chrony 的描述,RedHat 在编译 systemd 时,移除 systemd-timesyncd 特征。对于 CentOS 7.x 系列,建议使用 chrony 服务。
第一步、卸载其他时间服务
根据 systemd-timesyncd.service 定义,当存在 ntpd、chronyd 等等服务时,无法启动 systemd-timesyncd 服务。可以使用 systemctl cat systemd-timesyncd.service 命令查看 [Unit] 部分来了解。
因此我们需要卸载其他时间服务,卸载方法这里不再展开,这里只列举几种需要卸载的时间服务:

# Debian 10
apt-get purge chrony

第二步、启用 systemd-timesyncd 服务

systemctl start systemd-timesyncd
systemctl enable systemd-timesyncd

# 查看服务状态
systemctl status systemd-timesyncd

如果不卸载其他时间服务程序,命令 systemctl status systemd-timesyncd 将返回 condition failed 错误信息。
第三步、查看时间同步状态
使用 timedatectl 查看时间同步状态:

# timedatectl
Local time: Mon 2020-05-25 16:19:29 CST
Universal time: Mon 2020-05-25 08:19:29 UTC
RTC time: Mon 2020-05-25 08:19:29
Time zone: Asia/Shanghai (CST, +0800)
System clock synchronized: yes
NTP service: active
RTC in l[……]

READ MORE

「基于时间的任务调度器」

任务调度器(Job Scheduler)包含的门类很广,基于时间的任务调度只是其中的一个门类。
系统管理
经常用到的基于时间的任务调度器有以下几个: 1)At 2)Cron 3)systemd Timer
At,可以在特定时间点执行任务。Cron,可以用于进行周期性任务。sytemd Timer,可以同时实现二者的功能,并且能将时间粒度控制到秒。
参考文献
Wikipedia/Job scheduler[……]

READ MORE

「Cron and Anacron」- 基于时间的任务调度器

「Cron」
「Cron」是一个用于创建周期任务的工具包。其中,包含一个执行调度任务的守护进程的cron命令是,用于周期执行脚本;包含的crontab命令用于管理周期任务。
如果你有什么任务需要周期性的在后台执行,那就可以使用Cron来执行该任务。通过向Cron的配置文件中添加一个条目,条目中指明需要周期执行的命令或脚本即可。
「Anacron」
与「Cron」一样,「Anacron」也是周期性的执行命令。
有所不同的是「Anacron」不会假定”系统是不间断运行的“。就是说,如果关机了,在Cron中,错过的任务不会再执行,而在Anacron中,开机后,错过的任务也会保证被执行。
二者之间的关系
但是这二者并不是互相替代的,他们是互相协作的。
「anacron」本身不作为服务/守护进程运行,而是作为「cron」的作业,/etc/cron.d/anacron,存在的。 因此,「cron」会为每日、每周、每月任务检查是否存在「anacron」,而不是每小时任务。「Cron」运行每小时的任务。
关于「Anacron」一些误区
「anacron」本身不作为服务/守护进程运行,而是作为「cron」的作业,/etc/cron.d/anacron,存在的。
「anacron」不会用于”在确切时间运行作业“。它最好用于,例如,确保维护脚本以近似频率运行,如每日、每周、每月。它没有低于一天的时间分辨率。
参考文献
Who runs scripts inside /etc/cron.hourly if anacron is enabled? Is it possible to set one job to run at precise hour with anacron[……]

READ MORE

「Cron」- 安装及注意事项

系统环境:Kali GNU/Linux Rolling
#1 安装服务

#!/bin/sh

# 安装Cron服务:
apt-get install cron

# 启动并开机自启动Cron服务:
systemctl enable cron
systemctl start cron

# 查看服务状态:
systemctl status cron

# 如果手动启动Cron服务可以执行:
cron &

# 推荐使用systemd的方式来启动cron服务。

#2 启动服务

#!/bin/sh

# 安装服务
apt-get install cron

# 启动并开机自启动服务
systemctl enable cron
systemctl start cron

# 如果手动启动Cron服务可以执行:
cron &

# 推荐使用systemd的方式来启动cron服务。

#3 查看服务状态

# 查看服务状态:
systemctl status cron[……]

READ MORE

「Cron and Anacron」- 常见问题处理

在CentOS 7中的cron.daily/weekly/monthly的执行由/etc/anacrontab描述。
创建周期任务
如果要添加「Cron」周期任务,则需要修改/etc/crontab配置文件。配置Cron周期任务的关键就是熟悉配置文件/etc/crontab的语法,这个文件并不复杂。
假如我们要每隔5分钟向/tmp/datelist文件中输出当前时间,那么向/etc/crontab文件添加如下行:

5 * * * * root date >> /tmp/datelist

有关crontab配置文件的语法,参考「关于crontab表文件的格式」一文,或者参考crontab(5)手册。
参考文献
When does `cron.daily` run?[……]

READ MORE

「crontab」- 周期任务的配置文件

配置文件crontab中描述了需要命令cron周期执行的任务。
配置文件的位置
系统级别的配置文件为/etc/crontab。通常由系统管理员编辑,执行系统维护相关的周期任务。
用户级别的配置文件位于/var/spool/cron/crontabs/中。每个用户在该目录中都有自己的crontab文件,单独存放。使用命令crontab(1)进行编辑。这其中任何给定的crontab中的命令都将使用拥有crontab文件的用户身份来执行。
文件内容概述
文件crontab中包含了cron(8)守护程序的指令,一般形式为:“此日期此时运行此命令”。
Uucp和News通常都有自己的crontabs,因此无需显式运行su(1)作为cron命令的一部分。
配置文件的内容分为第三部分:

注释行;
环境变量设置;
周期任务指定;

下面将分别介绍这三部分。
配置中使用注释
空白行会被忽略;前导的空格和TAB也会被忽略;以井号(#)开始的行会被忽略。
注意事项 注释不允许和命令在同一行。就是说一行条目,要么是命令,要么是注释。下面的格式是不正确的:
09,39 * * * * root date >> /var/log/date # comment…

同样的,注释也不能和环境变量设置在同一行。
配置文件中的环境变量
文件crontab中可以指定命令执行的环境变量。
文件crontab从上到下进行解析,因此任何环境变量设置都只会影响文件中它们下面的cron命令。环境变量设置的形式:
name = value

等号(=)周围的空格是可选的,value中任何后续的非前导空格都是分配给name的值的一部分。value字符串可以放在引号中(单引号或双引号,但要成对出现)以保留前导或尾随空白。要定义空变量,必须使用引号。对于环境替换、变量替换都不会进行不解析,因此类似:
PATH = $HOME/bin:$PATH

的行不会按照你的期望进行解析。下面的这些也不会奏效:
A=1
B=2
C=$A $B

在最后一个值C中,不会替换定义的变量,因此C就是字面上的“$A $B”。
设置命令路径PATH的另一种方法是:即许多shell会将代字号(~)视为$HOME的代替,因此如果您将BASH用于任务,则可以使用:
SHELL=/bin/bash
PATH=~/bin:/usr/bin/:/bin

守护进程cron(8)自动设置了几个环境变量。SHELL设置为/bin/sh;LOGNAME和HOME是从文件crontab的所有者的/etc/p[……]

READ MORE

「Cron」- 使用技巧

如何每秒执行任务?
没有直接的解决方案。因为在Cron中,最小的时间帧是分钟,不能进行每秒钟执行某个任务。
# 方案一:systemd Timer
可以使用systemd Timer,它支持以秒为时间帧来执行任务。
# 方案二:Shell Script
在Cron中,最小的时间帧是分钟。因此可以写一个Shell脚本:在循环中,休眠一秒钟,创建一个后台任务,共计60秒。
创建后台任务是为了不让任务的执行循环执行,否则极可能出现脚本执行时间超过60秒的情况。
# 方案三:Shell Script
与「方案二」类似,创建一个脚本。不同的是脚本的写法:

(sleep 5 && /path/to/task) &
(sleep 10 && /path/to/task) &
(sleep 15 && /path/to/task) &
(sleep 20 && /path/to/task) &
(sleep 25 && /path/to/task) &
(sleep 30 && /path/to/task) &
(sleep 35 && /path/to/task) &
(sleep 40 && /path/to/task) &
(sleep 45 && /path/to/task) &
(sleep 50 && /path/to/task) &
(sleep 55 && /path/to/task) &
(sleep 60 && /path/to/task) &

上面的示例是每隔五秒中执行,要不要使用这个方案,需要根据自己的需求把握。
「方案二」和「方案三」存在相同的问题:任务越靠后,时延越大,因为即使是放入后台运行也需要消耗时间。
参考文献
Seting cron to run a script every second How to run scripts every 5 seconds? systemd as a replacement for cron every 10 seconds Run timer exactly every second with systemd systemd.timer — Timer unit configuration[……]

READ MORE

「Cron」- 执行日志

根据文档所述:

cron logs its action to the syslog facility ‘cron’, and logging may be controlled using the standard syslogd(8) facility.

所以,具体的日志文件位置还要看/etc/syslog.conf中的配置。
在Kali GNU/Linux Rolling中,「Cron」的日志文件位于/var/log/cron.log中。
在就是,在我的系统(Kali GNU/Linux Rolling)中「Cron」是前台运行(-f)的,所以可以使用journalctl(1)来查看日志。
而在Ubuntu中,默认安装后,日志位于/var/log/syslog中,使用grep CRON /var/log/syslog来查看。
参考文献
Where is the cron / crontab log?[……]

READ MORE

「systemd.timer」

systemd.timer,是由systemd提供的定时任务,类似于Cron功能。
简单描述
文件命名
该单元文件以.timer为文件后缀。单元文件命名为<timer>.timer。其中,<timer>为具体的任务名,而.timer为固定的文件后缀。
文件结构
本文不涉及单元文件的[Unit]部分与[Install]部分,有关内容参考systemd.unit(5)手册。
本文只包含[Timer]部分的指令,主要摘自systemd.tiemr(5)手册。特定于定时器的配置选项都位于单元文件的[Timer]部分中。
# 其他方面
对于每个定时器文件,必须存在匹配的单元文件,描述了计时器经过时要激活的单元文件。默认情况下,激活与计时器同名的服务(除了后缀)。例如,计时器foo.timer将执行foo.service服务。需要指定要执行的单元,通过Unit=指令来指定。
!!!在计时器经过时,要激活的任务已经激活,它不会被重新开始,而是仍然保持运行。在这种情况下不会产生新的实例。因此服务中使用了RemainAfterExit=(即使主进程退出了也保持存在状态)不适合通过计时器来激活,因为他们只会被激活一次,然后一直存在,服务不退出就无法进行下一次任务。
自动依赖
隐含依赖
定时器单元会在它们应该激活的服务上自动获得一个Before=依赖。
默认依赖
除非设置了DefaultDependencies=no,否则会添加以下依赖:

计时器会自动获得在sysinit.target上的Requires=和After=的依赖,一个timers.target上的Before=类型的依赖,以及shutdown.target上的Conflicts=和Before=依赖(以确保系统在关闭期间能干净的停止)。只有涉及早期启动或延迟系统关闭的计时器单元才应禁用DefaultDependencies=选项。

对于具有至少一个OnCalendar=指令的定时器单元,将在time-sync.target上具有额外的After=依赖,以避免“在正确设置系统时钟之前”启动。

命令支持的选项及含义
计时器文件必须包含一个[Timer]部分,该部分包含了计时器的定义。特定于[Timer]部分的选项如下:
OnActiveSec=, OnBootSec=, OnStartupSec=, OnUnitActiveSec=, OnUnitInactiveSec= 定义相对于不同起点的单调计时器:

OnActiveSec=:定义计时器,相对于计时器单元本身被激活的时刻。[……]

READ MORE

「systemd」- Timer:由systemd提供的定时任务

该文章概述了在systemd中使用Timer来设置定时任务的方法,并提及了一些细节上的东西。
!!!这篇文章是一个概要,而不是一份详细的教程。
在Linux中,任务调度器Cron广为认知。但是Cron的粒度只能控制到分钟,不能到秒,但是systemd的Timer可以。
第一步、创建单元文件
创建Timer单元文件。假设以mytimer.timer为文件名,格式大体如下:

[Unit]
Description=Runs mytimer every hour

[Timer]
OnUnitActiveSec=1h
Unit=mytimer.service

[Install]
WantedBy=multi-user.target

如上所示,在systemd的Timer单元文件中,它并不包含具体要执行的命令,而是指定了一个要执行的Service单元。比如,上面的mytimer.service单元,该Service单元文件中包含了具体要执行的任务,所以你要先创建Service单元文件。这里就不再展开。
该mytimer.tiemr文件要放在/etc/systemd/system目录中。
第二步、启动定时任务
同样的,执行sytemctl start mytimer.timer来启动定时任务。
如果要开机自启动,则可以执行systemctl enable mytimer.timer命令。
常见问题
#1 定时任务没有立即启动
执行systemctl start foo.timer以后,没有立即执行对应的单元,原因参考「Systemd timer not starting its service unit」一文。
解决办法 在foo.timer单元文件的[Unit]部分加入Requires=bar.service部分。
参考文献
Systemd 定时器教程 如何使用 systemd 中的定时器 linux基础命令介绍十四:定时任务 systemd.timer 中文手册 Systemd 定时器教程 如何使用 systemd 中的定时器 systemd/Timers[……]

READ MORE

「Linux」- 用户与组的管理

用户操作
修改用户(改)

usermod –append -G vboxusers virtmgr # 将用户 virtmgr 添加到 vboxusers 组中;

进入用户家目录
进入用户 zheng 的家目录:

# cd ~zheng

如果要在终端中输入制表符,可以先按下 Ctrl+v,然后在按下 TAB 键;
常见问题汇总
已为用户设置 Group 权限,但是用户在访问时依旧没有权限
Group permissions allow, but still get permission denied How to apply changes of newly added user groups without needing to reboot?
假设配置正确,并且使用 id 命令可以看到用户属于该组;
解决办法: 或,用户需要重新登录(桌面环境,使用该方法); 或,如果由于某些原因无法重新登录,可以使用 sudo login 命令重新登录; 或,使用 newgrp “<group-name>” 来更新当前会话的组,该方式能保持当前会话的环境配置; 或,使用 sg “<group-name>” -c “command” 来执行命令(类似 su 命令,sg 用于组);[……]

READ MORE