运行 Nixos 上带有 systemd 计时器的脚本
Run a script with systemd timers on Nixos
我有一个小的 shellscript scrape.sh
可以抓取网站并将生成的数据放入新目录:
website='test.com'
dir_name="datev_data/$(date -u +'%Y-%m-%dT%H:%M:%S')"
mkdir $dirname
wget --directory-prefix="$dir_name" "$website"
(我真的不在乎数据在哪里结束,只要它每次都有一个新目录并且我可以获取数据。因此我将它放入我的主目录 /home/kaligule
中现在。)
运行 这个手动脚本工作正常,所以现在我想 运行 在我的 nixos 服务器上每小时 运行 这个脚本。因此,我将以下内容放入我的配置中(受 this post 启发):
systemd.services.test_systemd_timers = {
serviceConfig.Type = "oneshot";
script = ''
echo "Will start scraping now."
{pkgs.bash}/bin/bash /home/kaligule/scrape.sh
echo "Done scraping."
'';
};
systemd.timers.test_systemd_timers = {
wantedBy = [ "timers.target" ];
partOf = [ "test_systemd_timers.service" ];
timerConfig.OnCalendar = [ "*-*-* *:00:00" ];
};
那我测试一下:
sudo nixos-rebuild switch # everything is fine
sudo systemctl start test_systemd_timers # run it immediatelly for testing
我得到:
Job for test_systemd_timers.service failed because the control process exited with error code.
See "systemctl status test_systemd_timers.service" and "journalctl -xe" for details.
第一个建议的命令给了我这个:
● test_systemd_timers.service
Loaded: loaded (/nix/store/f8348svxpnn6qx08adrv5s7ksc2zy1sk-unit-test_systemd_timers.service/test_systemd_timers.service; linked; vendor preset: enabled)
Active: failed (Result: exit-code) since Fri 2021-04-02 14:50:02 CEST; 2min 36s ago
TriggeredBy: ● test_systemd_timers.timer
Process: 5686 ExecStart=/nix/store/4smyxxxlhnnmw8l6l3nnfjyvmg0wxcwh-unit-script-test_systemd_timers-start/bin/test_systemd_timers-start (code=exited, status=127)
Main PID: 5686 (code=exited, status=127)
IP: 0B in, 0B out
CPU: 11ms
Apr 02 14:50:02 regulus systemd[1]: Starting test_systemd_timers.service...
Apr 02 14:50:02 regulus test_systemd_timers-start[5686]: Will start scraping now.
Apr 02 14:50:02 regulus test_systemd_timers-start[5687]: /nix/store/4smyxxxlhnnmw8l6l3nnfjyvmg0wxcwh-unit-script-test_systemd_timers-start/bin/test_systemd_timers-start: line 3: {pkgs.bash}/bin/bash: No such file or directory
Apr 02 14:50:02 regulus systemd[1]: test_systemd_timers.service: Main process exited, code=exited, status=127/n/a
Apr 02 14:50:02 regulus systemd[1]: test_systemd_timers.service: Failed with result 'exit-code'.
Apr 02 14:50:02 regulus systemd[1]: Failed to start test_systemd_timers.service.
第二个建议的命令给我:
Apr 02 14:54:42 regulus systemd[1]: Starting test_systemd_timers.service...
░░ Subject: A start job for unit test_systemd_timers.service has begun execution
░░ Defined-By: systemd
░░ Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░
░░ A start job for unit test_systemd_timers.service has begun execution.
░░
░░ The job identifier is 34454.
Apr 02 14:54:42 regulus test_systemd_timers-start[5734]: Will start scraping now.
Apr 02 14:54:42 regulus test_systemd_timers-start[5735]: /nix/store/4smyxxxlhnnmw8l6l3nnfjyvmg0wxcwh-unit-script-test_systemd_timers-start/bin/test_systemd_timers-start: line 3: {pkgs.bash}/bin/bash: No such file or directory
Apr 02 14:54:42 regulus systemd[1]: test_systemd_timers.service: Main process exited, code=exited, status=127/n/a
░░ Subject: Unit process exited
░░ Defined-By: systemd
░░ Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░
░░ An ExecStart= process belonging to unit test_systemd_timers.service has exited.
░░
░░ The process' exit code is 'exited' and its exit status is 127.
Apr 02 14:54:42 regulus systemd[1]: test_systemd_timers.service: Failed with result 'exit-code'.
░░ Subject: Unit failed
░░ Defined-By: systemd
░░ Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░
░░ The unit test_systemd_timers.service has entered the 'failed' state with result 'exit-code'.
Apr 02 14:54:42 regulus systemd[1]: Failed to start test_systemd_timers.service.
░░ Subject: A start job for unit test_systemd_timers.service has failed
░░ Defined-By: systemd
░░ Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░
░░ A start job for unit test_systemd_timers.service has finished with a failure.
░░
░░ The job identifier is 34454 and the job result is failed.
Apr 02 14:54:42 regulus sudo[5731]: pam_unix(sudo:session): session closed for user root
因此,因为我在日志中得到了 Will start scraping now.
,所以我认为作业已启动,但无法 运行 脚本。我的问题是:
- 我应该将我的脚本放在哪里(以及使用哪些权限)?
- 我应该如何添加我的配置,以便脚本 运行 如我所描述的那样?
(当然,我很感谢对我的方法的每一个反馈。)
您的问题是,在您的脚本中,{pkgs.bash}
应该是 ${pkgs.bash}
;没有 $
,您将无法获得变量插值。
在 NixOS 上,systemd 服务 运行 具有非常小的默认环境。您可以在 systemd.services.<name>.path
中添加缺少的包
systemd.services.test_systemd_timers = {
serviceConfig.Type = "oneshot";
path = [
pkgs.wget
pkgs.gawk
pkgs.jq
];
script = ''
echo "Will start scraping now."
${pkgs.bash}/bin/bash /home/kaligule/scrape.sh
echo "Done scraping."
'';
};
我有一个小的 shellscript scrape.sh
可以抓取网站并将生成的数据放入新目录:
website='test.com'
dir_name="datev_data/$(date -u +'%Y-%m-%dT%H:%M:%S')"
mkdir $dirname
wget --directory-prefix="$dir_name" "$website"
(我真的不在乎数据在哪里结束,只要它每次都有一个新目录并且我可以获取数据。因此我将它放入我的主目录 /home/kaligule
中现在。)
运行 这个手动脚本工作正常,所以现在我想 运行 在我的 nixos 服务器上每小时 运行 这个脚本。因此,我将以下内容放入我的配置中(受 this post 启发):
systemd.services.test_systemd_timers = {
serviceConfig.Type = "oneshot";
script = ''
echo "Will start scraping now."
{pkgs.bash}/bin/bash /home/kaligule/scrape.sh
echo "Done scraping."
'';
};
systemd.timers.test_systemd_timers = {
wantedBy = [ "timers.target" ];
partOf = [ "test_systemd_timers.service" ];
timerConfig.OnCalendar = [ "*-*-* *:00:00" ];
};
那我测试一下:
sudo nixos-rebuild switch # everything is fine
sudo systemctl start test_systemd_timers # run it immediatelly for testing
我得到:
Job for test_systemd_timers.service failed because the control process exited with error code.
See "systemctl status test_systemd_timers.service" and "journalctl -xe" for details.
第一个建议的命令给了我这个:
● test_systemd_timers.service
Loaded: loaded (/nix/store/f8348svxpnn6qx08adrv5s7ksc2zy1sk-unit-test_systemd_timers.service/test_systemd_timers.service; linked; vendor preset: enabled)
Active: failed (Result: exit-code) since Fri 2021-04-02 14:50:02 CEST; 2min 36s ago
TriggeredBy: ● test_systemd_timers.timer
Process: 5686 ExecStart=/nix/store/4smyxxxlhnnmw8l6l3nnfjyvmg0wxcwh-unit-script-test_systemd_timers-start/bin/test_systemd_timers-start (code=exited, status=127)
Main PID: 5686 (code=exited, status=127)
IP: 0B in, 0B out
CPU: 11ms
Apr 02 14:50:02 regulus systemd[1]: Starting test_systemd_timers.service...
Apr 02 14:50:02 regulus test_systemd_timers-start[5686]: Will start scraping now.
Apr 02 14:50:02 regulus test_systemd_timers-start[5687]: /nix/store/4smyxxxlhnnmw8l6l3nnfjyvmg0wxcwh-unit-script-test_systemd_timers-start/bin/test_systemd_timers-start: line 3: {pkgs.bash}/bin/bash: No such file or directory
Apr 02 14:50:02 regulus systemd[1]: test_systemd_timers.service: Main process exited, code=exited, status=127/n/a
Apr 02 14:50:02 regulus systemd[1]: test_systemd_timers.service: Failed with result 'exit-code'.
Apr 02 14:50:02 regulus systemd[1]: Failed to start test_systemd_timers.service.
第二个建议的命令给我:
Apr 02 14:54:42 regulus systemd[1]: Starting test_systemd_timers.service...
░░ Subject: A start job for unit test_systemd_timers.service has begun execution
░░ Defined-By: systemd
░░ Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░
░░ A start job for unit test_systemd_timers.service has begun execution.
░░
░░ The job identifier is 34454.
Apr 02 14:54:42 regulus test_systemd_timers-start[5734]: Will start scraping now.
Apr 02 14:54:42 regulus test_systemd_timers-start[5735]: /nix/store/4smyxxxlhnnmw8l6l3nnfjyvmg0wxcwh-unit-script-test_systemd_timers-start/bin/test_systemd_timers-start: line 3: {pkgs.bash}/bin/bash: No such file or directory
Apr 02 14:54:42 regulus systemd[1]: test_systemd_timers.service: Main process exited, code=exited, status=127/n/a
░░ Subject: Unit process exited
░░ Defined-By: systemd
░░ Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░
░░ An ExecStart= process belonging to unit test_systemd_timers.service has exited.
░░
░░ The process' exit code is 'exited' and its exit status is 127.
Apr 02 14:54:42 regulus systemd[1]: test_systemd_timers.service: Failed with result 'exit-code'.
░░ Subject: Unit failed
░░ Defined-By: systemd
░░ Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░
░░ The unit test_systemd_timers.service has entered the 'failed' state with result 'exit-code'.
Apr 02 14:54:42 regulus systemd[1]: Failed to start test_systemd_timers.service.
░░ Subject: A start job for unit test_systemd_timers.service has failed
░░ Defined-By: systemd
░░ Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░
░░ A start job for unit test_systemd_timers.service has finished with a failure.
░░
░░ The job identifier is 34454 and the job result is failed.
Apr 02 14:54:42 regulus sudo[5731]: pam_unix(sudo:session): session closed for user root
因此,因为我在日志中得到了 Will start scraping now.
,所以我认为作业已启动,但无法 运行 脚本。我的问题是:
- 我应该将我的脚本放在哪里(以及使用哪些权限)?
- 我应该如何添加我的配置,以便脚本 运行 如我所描述的那样?
(当然,我很感谢对我的方法的每一个反馈。)
您的问题是,在您的脚本中,{pkgs.bash}
应该是 ${pkgs.bash}
;没有 $
,您将无法获得变量插值。
在 NixOS 上,systemd 服务 运行 具有非常小的默认环境。您可以在 systemd.services.<name>.path
systemd.services.test_systemd_timers = {
serviceConfig.Type = "oneshot";
path = [
pkgs.wget
pkgs.gawk
pkgs.jq
];
script = ''
echo "Will start scraping now."
${pkgs.bash}/bin/bash /home/kaligule/scrape.sh
echo "Done scraping."
'';
};