我试图制作一个.sh文件,列出我所有的非开发包,然后将它们复制到其他存储库。所以我带着这个代码:
#!/bin/sh
list_of_all_no_dev_package=$(composer show --no-dev --name-only)
for no_dev_package in $list_of_all_no_dev_package; do
cp -r "vendor/${no_dev_package}" "${export_path}/vendor/${no_dev_package}"
done
为了确保我的cp命令是正确的,我试着在我的终端中回显它,得到了类似的东西
cp -r "vendor/mypackage" "myexportpath/vendor/mypackage"
但是,如果我尝试使用>gt;接线员,我收到了一些非常不同的
cp -r "vendor/https://github.com/mypackage/tree/master/whateverfile.php" "myexportpath/vendor/https://github.com/mypackage/tree/master/whateverfile.php
如何使用composer命令获得第一个输出?为什么这两个结果如此不同?
如果简单的命令替换不能开箱即用(这是可能发生的(,我会考虑在提高shell调试技能的同时,让composers输出更稳定。
我已经在shell脚本中放置了以下全局参数作为注释的一部分:
- 使用
-n
使composer非交互式,如果这是预期用途的话。这使得工厂无法处理许多问题 - 使用
--no-ansi
使composer不输出ansi转义序列(用于为输出着色( - 使用
--no-plugins
禁用插件,您希望在脚本中也将这些插件排除在外
除了那些运行时行为控制参数之外,还有一个用于输出的参数。如果你想确保它是机器可读的,这是很有帮助的。例如,您可以将安装的包名称获取为JSON文本:
$ composer -n --no-plugins --format=json show --no-dev --name-only
{
"installed": [
{
"name": "composer/ca-bundle"
},
{
"name": "composer/metadata-minifier"
},
...
]
}
然后,您可以使用一个实用程序将结果管道传输到能够解析JSON文本并在其他情况下出错的文件中,例如jq(1)
或php(1)
。这里有一个例子w/PHP(7.0+(,因为它可能已经可用:
$ composer -n --no-plugins --format=json show --no-dev --name-only
| php -r
' echo implode("n", array_column('
' json_decode(stream_get_contents(STDIN))->installed, '
' "name")) ?? exit(1), "n";'
composer/ca-bundle
composer/metadata-minifier
...
这是一个很好的过滤器,可以进一步处理脚本中的数据。
在运行任何像这里这样的脚本之前,请对composer.json进行严格的验证,以确保所有包名称都严格符合自几次发布以来一直有效的可移植composer包名称配置文件(但我不知道它扫描的深度,否则会想到pathchk(1)
(。
带有一些shell调试和错误处理的完整示例:
#! /bin/sh
set -x
list_of_all_no_dev_package=$(
composer -nq --no-plugins validate --strict >&2 &&
composer -n --no-ansi --no-plugins --format=json show --no-dev --name-only |
php -r 'echo
implode($terminator = "n",
array_column(
json_decode(stream_get_contents(STDIN))->installed,
"name"
)
) ?? exit(1),
$terminator
;
'
) || exit
for no_dev_package in $list_of_all_no_dev_package; do
printf "no dev package: '%s'n" "${no_dev_package}" >&2
cp -r "vendor/${no_dev_package}"
"${export_path?:export_path unset}/vendor/${no_dev_package}"
done
如果你考虑实际使用/bin/bash
检查你的bash版本,有一些数组,你可以读取它们,比较外壳硬化等。
最近安装的composer似乎出现了问题。它确实发生在实际的最新版本:2.4.1,但没有发生在2.1.2 上
使用composer show --name-only
实际上会返回一个带有完整存储库路径(github或配置文件中设置的任何路径(的结果,并在其中添加2个ESC字符。然后CLI会打印这2个ESC之间的内容。
解决方案是添加全局选项--no-ansi
composer show --name-only --no-dev --no-ansi
将返回供应商文件夹中存储库的目录名。