啟動項匯總
定位到 /etc 目錄下, 我們可以發現在這個目錄下,至少有這幾個和啟動有關的文件(夾):
$ ls cron.d/ cron.daily/ cron.deny/ cron.hourly/ cron.monthly/ cron.weekly/ crontab init.d/ inittab profile.d/ profile rc.d/ rc.local/ rc0.d/ rc1.d/ rc2.d/ rc3.d/ rc4.d/ rc5.d/ c6.d/
反正我第一眼看到這張表是完全迷惑的.
那麼接下的博文, 就是要分別介紹, 上述的所有文件(夾).
功能介紹
crontab
組合
工具型软件cron是一款类Unix下的基于时间的任务管理系统。用户们可以通过cron在固定时间、日期、间隔下,运行定期任务(可以是命令和脚本)。cron常用于运维和管理,但也可用于其他地方,如:定期下载文件和邮件。cron该词来源于希腊语chronos(χρόνος),原意是时间。
文件位置
/var/spool/cron/
– 用戶層次/etc/contab
和/etc/cron*
– 系統層次
crontab 格式
# 文件格式說明 # ┌──分鐘(0 - 59) # │ ┌──小時(0 - 23) # │ │ ┌──日(1 - 31) # │ │ │ ┌─月(1 - 12) # │ │ │ │ ┌─星期(0 - 6,表示从周日到周六) # │ │ │ │ │ # * * * * * 用户名 被執行的命令
管理方法
- 直接編輯
/etc/crontab
文件 echo '指令' >> /etc/crontab
- 使用
crontab -e
指令
crontab 和 cron.d
** Manpage(8): **
Like /etc/crontab, the files in the /etc/cron.d directory are monitored for changes. In general, the system administrator should not use /etc/cron.d/, but use the standard system crontab /etc/crontab.
/etc/crontab and the files in /etc/cron.d must be owned by root, and must not be group- or other-writable. In contrast to the spool area, the files under /etc/cron.d or the files under /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly and /etc/cron.monthly may also be symlinks, provided that both the symlink and the file it points to are owned by root. The files under /etc/cron.d do not need to be executable, while the files under /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly and /etc/cron.monthly do, as they are run by run-parts (see run-parts(8) for more information).
從文中我們可以獲取這麼一些信息:
- 我們只需要使用
crontab
文件, 其餘的事情由系統管理 cron.d
和 其他的cron*
文件夾都是放腳本用的, 準確說來, 是放符號連接cron.d
和cron*
的區別是 放在cron.d
目錄下的腳本必須可執行, 後者不需要
init.d
$ cat /etc/init.d/README You are looking for the traditional init scripts in /etc/rc.d/init.d, and they are gone? Here's an explanation on what's going on: You are running a systemd-based OS where traditional init scripts have been replaced by native systemd services files. Service files provide very similar functionality to init scripts. To make use of service files simply invoke "systemctl", which will output a list of all currently running services (and other units). Use "systemctl list-unit-files" to get a listing of all known unit files, including stopped, disabled and masked ones. Use "systemctl start foobar.service" and "systemctl stop foobar.service" to start or stop a service, respectively. For further details, please refer to systemctl(1). Note that traditional init scripts continue to function on a systemd system. An init script /etc/rc.d/init.d/foobar is implicitly mapped into a service unit foobar.service during system initialization. Thank you! Further reading: man:systemctl(1) man:systemd(1) http://0pointer.de/blog/projects/systemd-for-admins-3.html https://www.freedesktop.org/wiki/Software/systemd/Incompatibilities
上述陳述基本已經講清楚了情況:
- 傳統的啟動腳本功能已經整合進了
systemd
, 由systemctl
程序提供給用戶操作 - 現在的
/etc/init.d/
其實是/etc/rc.d/init.d/
的符號鏈接 /etc/init.d/
仍然可以藉由systemd
提供的兼容正常工作
講清楚了這個, 下一個就是看 rc.d
文件夾掉內容了
rc
組合
rc 的意思是 “run command”, d 意味 “sub-directory”, 就是
/etc
下的字目錄的意思
首先要明確的一點是, 上述的 rc*
組合都是指向 /etc/rc.d/rc*
的符號鏈接, 因此我們只要研究 rc.d
文件夾內的結構就可以了. 這樣還不夠明確的話, 可以參考 ll
結果:
$ ll drwxr-xr-x. 10 root root 4096 Dec 18 07:31 rc.d lrwxrwxrwx. 1 root root 13 Dec 18 07:31 rc.local -> rc.d/rc.local lrwxrwxrwx. 1 root root 10 Aug 5 2020 rc0.d -> rc.d/rc0.d lrwxrwxrwx. 1 root root 10 Aug 5 2020 rc1.d -> rc.d/rc1.d lrwxrwxrwx. 1 root root 10 Aug 5 2020 rc2.d -> rc.d/rc2.d lrwxrwxrwx. 1 root root 10 Aug 5 2020 rc3.d -> rc.d/rc3.d lrwxrwxrwx. 1 root root 10 Aug 5 2020 rc4.d -> rc.d/rc4.d lrwxrwxrwx. 1 root root 10 Aug 5 2020 rc5.d -> rc.d/rc5.d lrwxrwxrwx. 1 root root 10 Aug 5 2020 rc6.d -> rc.d/rc6.d lrwxrwxrwx. 1 root root 11 Apr 27 2020 init.d -> rc.d/init.d ...
init.d 文件夾
如之前所述, 所有開機運行的腳本都放在 init.d 裡面,
$ ll -rw-r--r--. 1 root root 1161 Dec 18 07:30 README -rwxr-xr-x. 1 root root 10438 Jun 22 2018 bt -rwxr-xr-x 1 root root 7039 Mar 29 21:37 fail2ban -rw-r--r--. 1 root root 18434 Jul 24 2020 functions -rwxr-xr-x 1 root root 10672 Mar 29 19:44 mysqld -rwxr-xr-x 1 root root 2753 Dec 6 2018 nginx -rwxr-xr-x 1 root root 2361 Mar 29 20:09 php-fpm-56 -rwxr-xr-x 1 root root 1447 Aug 17 2016 pure-ftpd
需要注意的是, init.d 僅僅是一個放腳本的地方, 要讓他開機啟動還是需要在 rc#.d 中調用到他的.
rc#.d 文件夾用途
- 文件夾名稱中的數字, 代表了
run-level
, 也就是 “運行級別”. 詳細的說明可以看 維基百科, 下面簡單的 copy 了維基百科的內容- 0: 停機, 關機
- 1: 單用戶, 無網路鏈接, 無守護進程, 不允許 非超級用戶登陸 (僅root)
- 2: 多用戶, 無網路鏈接, 無守護進程
- 3: 多用戶, 正常啟動系統
- 4: 用戶自定義
- 5: 多用戶, 帶圖形介面
- 6: 重啟
現在在systemd
體系中已經使用 target 來代替 runlevel, 如multi-user.target相当于init 3,graphical.target相当于init 5,但是 runlevel 仍然被 systemd 支持. - 舊版本可以使用 chkconfig 來配置不同的 runlevel 運行的服務.
- 與
init.d
不同,rc#.d
裡面不放腳本, 而是放對應到init.d
中腳本的符號鏈接, 不同的名稱代表的含義不同. 比如說, “K” 開頭意思是 K 掉這個程序, “S” 開頭代表 開始這個程序. “K” 或者 “S” 後面的數字越小, 執行的優先級越高, 下面是我的樹莓派的配置:
[[email protected] rc3.d]$ ll lrwxrwxrwx 1 root root 20 Mar 29 20:09 K50php-fpm-56 -> ../init.d/php-fpm-56 lrwxrwxrwx 1 root root 15 Mar 29 21:49 K55nginx -> ../init.d/nginx lrwxrwxrwx 1 root root 16 Mar 29 19:44 K64mysqld -> ../init.d/mysqld lrwxrwxrwx 1 root root 19 Mar 29 19:48 K85pure-ftpd -> ../init.d/pure-ftpd lrwxrwxrwx 1 root root 18 Mar 29 21:38 S50fail2ban -> ../init.d/fail2ban lrwxrwxrwx 1 root root 12 Mar 29 18:46 S55bt -> ../init.d/bt
(一大堆前面加K的是我禁止了這些服務的自啟, 暫時還用不到.)
不僅是 rc3, 在其他 rc# 文件夾裡面也有大概相同的文件, 所以規則是, 那個 runlevel 用到就加到 rc幾 , 不怕重複的.
- 所以說, 除非有特殊的需求, 這幾個文件夾也是一般用戶不需要碰到的, 可以使用systemd 解決需求.
rc.local 文件用途
可以首先看一下 rc.local 文件裡面寫了什麼.
$ cat /etc/rc.d/rc.local #!/bin/bash # THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES # # It is highly advisable to create own systemd services or udev rules # to run scripts during boot instead of using this file. # # In contrast to previous versions due to parallel execution during boot # this script will NOT be run after all other services. # # Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure # that this script will be executed during boot. touch /var/lock/subsys/local
所以說, 這個文件是很久以前用於開機運行一些命令的(不是 sh文件, 而是一些自定義的命令組合), 現在只為了兼容性保留, 最好不要使用了.
inittab
文件
$ cat inittab # inittab is no longer used. # # ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM. # # Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target # # systemd uses 'targets' instead of runlevels. By default, there are two main targets: # # multi-user.target: analogous to runlevel 3 # graphical.target: analogous to runlevel 5 # # To view current default target, run: # systemctl get-default # # To set a default target, run: # systemctl set-default TARGET.target
這個文件告訴我們, inittab 已經被徹底廢棄了, 甚至都不會兼容它.
這也印證了前面的說法, runlevel 的機制已經被 target 機制取代了.
在廢棄前, inittab 是用來決定默認 runlevel 的.
profile
組合
這個就比較好理解了, 這個其實就是一個所有用戶的Bash變量設置, (不侷限於Bash), 功能於設置當前用戶的 ~/.profile 是相似的. 所以說他雖然是啟動項, 但是是專門設置終端環境的, 我也許會以後專門寫一篇來做介紹.
至於 profile.d
, 就把 profile 裡面寫不下的專門拿出來模塊化加載, 可以看一下他的內容:
[[email protected] profile.d]$ ls colorgrep.csh colorls.sh colorzgrep.csh gawk.csh lang.sh sh.local which2.csh colorgrep.sh colorxzgrep.csh colorzgrep.sh gawk.sh less.csh vim.csh which2.sh colorls.csh colorxzgrep.sh csh.local lang.csh less.sh vim.sh
都是一些關於終端環境的設置.
明確它的功能之後, 以下討論不會再涉及 profile.
各個方案對比
那麼現在匯總一下開機運行程序的所有方案:
名稱 | 隸屬於 | 機制 | 支持格式 | 應用場景 |
---|---|---|---|---|
/etc/crontab | crontab | – | 命令 | 開機 @reboot 定時運行任務 |
/etc/cron.d/ | crontab | – | 腳本 | 無須手動配置 |
/etc/cron.*/ | crontab | – | 腳本(符號鏈接) | 無須手動配置 |
/etc/init.d/ | rc.d | runlevel | 可執行腳本 | 放置要用到的腳本供rc#.d調用 |
/etc/rc#.d/ | rc.d | runlevel | 指向init.d中腳本的符號鏈接 | 指定腳本的運行場景和優先級 |
/etc/rc.local | rc.d | runlevel | 命令 | 執行自定義指令 |
systemd | – | target | service | 開機執行任務 定時執行任務 特定條件執行任務 |
systemd 對比 init
之前已經提到, init 已經被 systemd 取代了, 現在的 rc.d 目錄內的一切事務全部由 systemd 代為執行.
(就是說, systemd 替代 init 作為系統最開始啟動的進程 )
所以這沒什麼可比性. 你仍然可以往 init.d 裡面灌腳本然後到 rc#.d 裡面創建符號鏈接 — 一般用在服務器上, 用來啟動程序已經夠了, 但是顯然, 這樣的方式沒有 service 來的靈活.
systemd 對比 crontab
這兩個東西, 功能有重疊, 具體如下:
- systemd timer 可以定時完成任務
- crontab 設置條件為
@reboot
可以開機執行命令
在匯總了網上的問答之後, 以及我的親身體驗, 我總結出如下結論:
- 機械化的定時執行任務, 首選 crontab, 直觀可靠
- 一句話開機執行任務, 也可以使用 crontab, 原因如上
- 執行複雜的腳本, 使用 systemd 更為方便.
也就是說, 能用 crontab 就避免使用 systemd, systemd timer 其實可以被 crontab 替代.
資料
在寫這篇博文時, 我搜索了很多資料, 也因此學到了很多, 以下列出我參考過的資料(可能有一點點亂):
- rc.local
- https://unix.stackexchange.com/questions/59929/whats-the-difference-between-etc-rc-local-and-etc-init-d-rc-local
- http://c.biancheng.net/view/1023.html
- https://mustgeorge.blogspot.com/2012/02/ubuntu-rclocal.html
- Init.d
- https://www.jianshu.com/p/0dff9247d878
- inittab
- https://www.networkworld.com/article/2693438/unix-how-to-the-linux-etc-inittab-file.html
- https://docs.oracle.com/cd/E19683-01/817-3814/6mjcp0qgh/index.html
- Cron vs systemd
- https://www.reddit.com/r/linuxadmin/comments/7ea2mj/cron_vs_systemd/
- https://serverfault.com/questions/92783/init-d-vs-cron-which-to-use
- runlevel and target
- https://blog.csdn.net/zyjiscainiao/article/details/54410286
- https://blog.csdn.net/soonfly/article/details/72876001
- systemd
- https://blog.csdn.net/xing_huo95/article/details/90246050
- http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html
- http://www.ruanyifeng.com/blog/2018/03/systemd-timer.html
- https://cloud.tencent.com/developer/article/1516125
- https://www.linux.com/training-tutorials/understanding-and-using-systemd/
- https://unix.stackexchange.com/questions/206315/whats-the-difference-between-usr-lib-systemd-system-and-etc-systemd-system
- https://zh.wikipedia.org/wiki/Systemd
- profile
- https://unix.stackexchange.com/questions/64258/what-do-the-scripts-in-etc-profile-d-do