我有以下脚本:
#!/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
阅读以下参考文献后:
- https://unix.stackexchange.com/questions/61183/bash-script-that-reads-filenames-from-a-pipe-or-from-command-line-args
- http://www.linuxjournal.com/content/working-stdin-and-stdout
- http://mockingeye.com/blog/2013/01/22/reading-everything-stdin-in-a-bash-script/
我对上述脚本进行了如下编辑:
#!/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 等),所以我可以忍受它。