我在目录下写了4个服务文件/etc/systemd/system
,分别是sybase.service
、、、、,它们都sybase-backup.service
工作得很好。sybase-rs.service
sybase-rsm.service
当我尝试使用 列出它们时systemctl list-units sybase*
,它报告:
列出 0 个已加载单位。通过 --all 也可以查看已加载但不活动的单元。
如果我使用systemctl list-units sybase\*
or systemctl list-units "sybase*"
,我会得到正确的结果。
但对于其他一些服务,例如systemctl list-units ssh*
或systemctl list-units "ssh*"
,两者都有效。
那么为什么会有这样的差异呢?
答案1
你必须引用或转义任何特殊字符,如通配符 (*)、脱字号 (^) 或美元符号 ($),当将它们作为参数传递给命令时,否则它们将被 shell 扩展。请参阅扩张有关特殊字符的完整列表,请参阅 bash.1 和 glob.7 手册页的部分。
bash 如何处理*
来自glob.7
联机帮助页
空列表 上面给出的简单明了的规则:“将通配符模式展开到匹配路径名列表中”是最初的 UNIX 定义。它允许人们将模式扩展为一个空列表,如下所示
xv -wait 0 *.gif *.jpg
可能不存在 *.gif 文件(这不是错误)。然而,POSIX 要求通配符模式在语法不正确或匹配路径名列表为空时保持不变。通过 bash,我们可以使用以下命令强制执行经典行为:
*
在 bash 中行为的特定情况下,如果像这样的模式ssh*
可以在当前目录中包含许多文件,例如ssh_config sshd_config
,则它将按原样扩展,或者按原样传递给命令。不应依赖此行为。最好每次都引用或转义特殊字符。
命令分析
systemctl list-units "ssh*" systemctl list-units sybase* 或 systemctl list-units "sybase*" 将给出正确的结果。
这些命令之所以有效,是因为所有“*”都被引用或转义,因此它被传递到systemctl
.
systemctl 列表单元 ssh*
如果当前工作目录不包含任何以 ssh 开头的文件,则此命令将起作用。但是,如果当前工作目录确实包含这些文件,则会失败。
systemctl 列表单位 sybase*
执行此命令的工作目录包含以sybase.
“Therefore”开头的文件,sybase*
已展开为这些文件的列表,然后传递给该systemctl
命令。