检测 stdin 是否通过管道传输到 shell 函数

检测 stdin 是否通过管道传输到 shell 函数

我在命令行环境和 shell 脚本中使用了许多 shell 函数。我希望其中两个upperlower的行为有所不同,具体取决于数据是否通过管道传输给它们。当前编写的这两个函数都通过传递给它们的参数接收输入。

这是以下的定义upper

upper () {
    my_echo "${1}" | tr "[:lower:]" "[:upper:]"
    return 0
}

这是以下的定义lower

lower () {
    my_echo "${1}" | tr "[:upper:]" "[:lower:]"
    return 0
}

(my_echo是我编写的一个 Python 脚本,作为 的替代品echo。它应该输出作为参数传递给它的任何内容,同时将转义序列转换为其文字。我可以打印任何字符串,而无需将其解释为选项,例如Unix 控制台的工作方式阻碍了这个目标,所以我搁置了它,所以你可以忽略它。-eecho

这些函数有几个过去的版本。这些是在标准输入上运行的版本的定义:

upper () {
    tr "[:lower:]" "[:upper:]"
}

lower () {
    tr "[:upper:]" "[:lower:]"
}

如果函数被通过管道传输,那么它应该像上面那样操作。如果不是,它应该读取第一个参数。

答案1

你的代码:

upper () {
    my_echo "${1}" | tr "[:lower:]" "[:upper:]"
    return 0
}

如果没有参数,要从标准输入读取:

upper () {
    ( (( $# )) && printf '%s\n' "$@" || cat ) |
    tr '[:lower:]' '[:upper:]'
}

这会测试$#位置参数的数量,如果该数量为零,则使用cat从标准输入流读取的数据,否则使用printf位置参数。然后将其通过管道传输到tr.

我删除了,return 0因为您可能想知道管道的真实退出状态。

在 中bash,你可以这样做

upper () {
    (( $# )) && printf '%s\n' "${@^^}" || tr '[:lower:]' '[:upper:]'
}

当有参数时,这tr根本不会使用,而是使用 Bash 的${parameter^^pattern}替换将所有参数转换为大写(使用,,小写)。

您可能想也可能不想更改printf格式字符串,这样它就'%s '取决于'%s\n'您想要实现的目标。

相关内容