通过systemd服务中的Exec管道输出脚本?

Jos*_*son 8 bash systemd services systemd-timer

所以我试图建立一个 systemd 服务,以便每天从基于日期的目录中启动一组文件(不同类型的期刊)。例如,今天的待办事项列表将位于:

~/Documents/Journals/2019/1/23/ToDo.md 
Run Code Online (Sandbox Code Playgroud)

现在最简单的方法是把它放在一个单独的目录中,比如今天,然后让一个 bash 脚本将它移动到适当的位置,在上次修改时间不再是它被创建的时候,或者文件的大小比模板文件大。但是虽然这会更容易,但我想知道是否可以编写一个脚本来返回要通过服务中执行的命令通过管道传输的文件的目录。类似的东西:

ExecStart=/usr/bin/atom | /Path/To/Script/Todays_Dir Todo.md 
Run Code Online (Sandbox Code Playgroud)

它将文件作为参数并根据日期返回目录/文件路径(与创建目录和文件的方式相同)。

这是可能的,还是我应该坚持已经提出的解决方案?

fil*_*den 12

是的,您可以直接写入目标目录。

您不能真正将管道直接用作ExecStart=命令的一部分,因为 systemd 并没有真正实现完整的 shell。但是您可以显式调用 shell,这将使其工作。例如:

ExecStart=/bin/sh -c '/usr/bin/atom | /Path/To/Script/Todays_Dir Todo.md'
Run Code Online (Sandbox Code Playgroud)

但事实证明这有点尴尬,因为Todays_Dir最终必须运行cat以写入其参数的完整路径。实际上,您在这里并不真正需要管道,您只需要确定目录的名称并atom使用正确的重定向运行。

考虑只在脚本中实现所有内容并直接从 systemd 单元运行它。

就像是:

#!/bin/bash
set -e  # exit on error
dated_dir=$HOME/Documents/Journals/$(date +%Y/%-m/%-d)
mkdir -p "${dated_dir}"
exec atom >"${dated_dir}/ToDo.md"
Run Code Online (Sandbox Code Playgroud)

然后在 systemd 单元中:

ExecStart=/Path/To/Script/GenerateMarkdownToTodaysDir.sh
Run Code Online (Sandbox Code Playgroud)

exec在shell脚本的结束使得外壳采用替换本身atom的程序,使systemd最终会在运行atom安装程序后直接。对于这种情况,它不是那么重要,因此可以省略它(特别是如果您有兴趣在atom运行后进行某种后处理。)