如何分离一行多命令的输出?

时间:2017-09-03 14:34:44

标签: bash

我在macOS Sierra上安装了一些GNU软件包,其中包括bashcoreutilswhich等。现在我可以使用which -a bash | xargs -I % echo % "--version" | sh检查所有版本信息bash,但两个版本信息之间没有分离:

$ which -a bash | xargs -I % echo % "--version" | sh
GNU bash, version 4.4.12(1)-release (x86_64-apple-darwin16.3.0)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
# There should be one or more blank lines as separation.
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)
Copyright (C) 2007 Free Software Foundation, Inc.

我尝试了... echo -e % "--version\n" ...,但它不起作用。请帮助我,谢谢。

2 个答案:

答案 0 :(得分:0)

要进一步控制输出,请使用循环:

which -a bash |
while read cmd; do
    printf '%s\t----------\n' "$cmd"
    command "$cmd" --version
    echo
done

答案 1 :(得分:0)

我写的如下:

IFS=: read -r -a path_entries <<<"$PATH"
find "${path_entries[@]}" -maxdepth 1 -name bash -type f -exec '{}' --version ';'

注意:

  • 不使用which。这不是一个用bash构建的shell,因此它不会给你type带来的任何好处(即对函数和别名的意识);并且因为它的输出是面向行的,所以它不能明确地发出所有可能的文件名(例如那些包含换行符的文件名 - 是的, 有效)。
  • 一般而言,不依赖于面向行的内容。当占位符({})作为单个标记传递时,find -exec将替换为该标记返回的确切文件名。因为可能的argv值域(所有有效的C字符串,也就是说,没有包含NUL的字符串)与通用系统上可能的文件名域匹配,所以这可以避免引入潜在的错误。
  • 不向译员生成文本和管道。这是一种容易出错的技术,会导致shell注入漏洞:考虑如果PATH包含/tmp/$(rm -rf ~)会发生什么,并且该目录包含bash可执行文件。