我在带有 LEMP 堆栈的 Ubuntu 16.04 (xenial) 中使用 Bash 4.3.48(1)。
我尝试以php.ini
与版本无关的方式使用printf
.
1)版本不可知操作失败:
printf "[PHP]\n post_max_size = 200M\n upload_max_filesize = 200M\n cgi.fix_pathinfo = 0" > /etc/php/*/fpm/zz_overrides.ini
给出以下错误:
bash: /etc/php/*/zz_overrides.ini: 没有这样的文件或目录
2)版本诺斯替操作成功:
printf "[PHP]\n post_max_size = 200M\n upload_max_filesize = 200M\n cgi.fix_pathinfo = 0" > /etc/php/7.0/fpm/zz_overrides.ini
如您所见,除了*
vs之外,两者基本相同7.0
。
- 我没有找到关于这个(正则表达式?)问题的线索
man printf
。 - 我在 Google 中搜索并没有发现任何关于“允许 printf 中的正则表达式”的信息。
为什么与版本无关的操作失败并且是否有任何绕过?
编辑:如果可能的话,对我来说最重要的是使用单行操作。
重定向中模式匹配的行为似乎在 shell 之间有所不同。在我的系统中,dash 和 ksh93 不会扩展模式,因此您会得到一个带有文字
*
. Bash 扩展它(1),但前提是模式匹配一个文件。如果有更多匹配的文件名,它会抱怨。Zsh 就像您提供了多个重定向一样工作,它将输出重定向到所有匹配的文件。(1) 非交互式且处于 POSIX 模式时除外
如果您希望输出转到所有匹配的文件,您可以使用
tee
:如果您希望它只转到一个文件,那么问题是决定使用哪个文件。如果您想检查是否只有一个文件与该模式匹配,请展开整个列表并计算它们。
在 bash/ksh 中:
在标准外壳中,
set
位置参数和$#
用于计数。当然,如果模式与任何文件都不匹配,它会保持原样,并且由于 glob 位于中间,因此结果指向一个不存在的目录。这与尝试创建相同
/path/to/file
,在/path/to
存在之前,它只是在这里我们有/path/*
,而不是字面意思,带有星号。为了解决这个问题,您必须扩展没有文件名的目录名,然后将文件名附加到所有目录。这个有点丑。。。
然后我们可以使用该数组:
或者我们可以采取简单的方法并循环文件名模式。在更一般的情况下,这有点不令人满意,因为它需要为每个输出文件运行一次主命令,或者使用临时文件来保存输出。