如何使 shell 脚本感知管道

如何使 shell 脚本感知管道

我有以下脚本:

#!/bin/sh

[ "${#}" -eq "0" ] && (printf "%s\\n" "${0}: word ..." >&2; exit 1)

_whats()
{
    [ -z "${1}" ] && return 1
    [ -z "${2}" ] && more_than_one="1"

    for word; do
        response="$(dig +short txt ${word}.wp.dg.cx)"
        printf "%s\\n" "${response}"
        if [ -z "${more_than_one}" ]; then
            printf "\\n%s\\n\\n" ":::::::::::::::::::::::::::::::::::::::::"
        fi
    done
}

_whats "${@}"

当我这样调用它时,它效果很好:

whats shell\ script dns #it ouputs two definitions (shell script and dns)

不过我也想这样称呼它:

echo shell\ script dns | whats

我只是习惯了它,所有其他 unix 命令都可以做到这一点,您将如何在 shell 脚本中实现它?

答案1

阅读以下参考文献后:

我对上述脚本进行了如下编辑:

#!/bin/sh

if [ ! -t 0 ]; then
    #there is input comming from pipe or file, add to the end of $@
    set -- "${@}" $(cat)
fi

[ "${#}" -eq "0" ] && (printf "%s\\n" "${0}: word ..." >&2; exit 1)

_whats()
{
    [ -z "${1}" ] && return 1
    [ -z "${2}" ] && more_than_one="1"

    for word; do
        response="$(dig +short txt ${word}.wp.dg.cx)"
        printf "%s\\n" "${response}"
        if [ -z "${more_than_one}" ]; then
            printf "\\n%s\\n\\n" ":::::::::::::::::::::::::::::::::::::::::"
        fi
    done
}

_whats "${@}"

这将在 $@ 中连接 args + stdin,因此现在它将在以下场景中工作:

whats dns script #it outputs two definitions
echo dns script | whats #same outputs as above
echo dns script | whats ip #outputs ip, dns and script definition in that order

它将正确解析作为参数的空格

whats shell\ script dns #output two definitions

但是当这些参数通过管道传递时则不然:

echo shell\ script dns | whats #output three definitions

然而其他 unix 实用程序也存在这个问题(-print0、-0 等),所以我可以忍受它。

相关内容