shell - 为什么 sh 对这些命令的解释与 zsh 不同?
问题描述
上下文:我正在尝试获取安装在我的 Linux 机器上的字体名称。名称在两个冒号之间。当我使用 zsh 运行此脚本时,它可以工作。当我切换到 sh 时,它会中断。它可能会删除 \n 字符,因为输出都是一行。
cmd="$(fc-list)"
names="$(echo $cmd | grep -oP "(?<=: ).*?(?=:)")"
echo $names
哪个命令导致问题?它不符合 POSIX 标准吗?
解决方案
为什么 sh 对这些命令的解释与 zsh 不同?
因为它们是不同的shell,所以规则是不同的。
哪个命令导致问题?
echo $cmd
和
echo $names
它不符合 POSIX 标准吗?
该代码本身就是有效的 POSIX 代码。不进行分词的 zsh shell 的行为不符合 POSIX。
在 POSIX shell 中,不带引号的扩展会进行分词。因为默认的 IFS 是空格制表符和换行符,所以这些字符在从扩展结果创建单词时会被删除,并作为单独的单词传递echo
,然后在一行上输出它们。要禁用分词(和文件名扩展),您需要引用扩展。也比较喜欢printf
。echo
cmd="$(fc-list)"
names="$(printf "%s\n" "$cmd" | grep -oP "(?<=: ).*?(?=:)")"
printf "%s\n" "$names"
推荐阅读
- swift - 为 Decodable 类中的属性设置更改名称 | 迅速
- rust - 如何以小写形式显示枚举?
- fortran - 错误:将名称分配给字符串时 (1) 处的不可分类语句
- angular - 角度路由仅显示 404 Not found
- powerbi - 功率 Bi DAX 平均
- python - Python返回夹具而不是调用导入的函数
- arrays - JS数组变异
- django - django rest 框架 - 将扩展的用户数据保存到数据库
- regex - 正则表达式匹配示例代码后的字符串
- c# - ASP.NET Core 5 MVC 和 OpenID Connect - 在远程 Windows 服务器上托管时出错