如果回显或重定向到某个文件,Composer显示的输出会有所不同



我试图制作一个.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脚本中放置了以下全局参数作为注释的一部分:

  1. 使用-n使composer非交互式,如果这是预期用途的话。这使得工厂无法处理许多问题
  2. 使用--no-ansi使composer不输出ansi转义序列(用于为输出着色(
  3. 使用--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将返回供应商文件夹中存储库的目录名。

最新更新