我写了一个脚本,它带有一堆选项(-d,-v,-l,以及--version, - leader等等),然后其余的文本($ *)可以是任何东西。该脚本处理文本并将其重新格式化。它很长,所以这是一个浓缩版本:
## ------------------------- [myScript.sh] --------------- ----------- ##
declare -- v='1.0' FS=$':\n\r\v\f\t' Application='Finder' Files s='s'
declare -i errors=0 element=0 counter=0 n L=2
until [[ -z "$1" || "$1" == '--' || "${1:0:1}" != '-' ]]; do
[ "$Input" ] && unset Input
if [[ "$1" =~ ^(-[Ww]|--[Ww]idth=)([0-9]+)? ]]; then
Input=$(echo "$1" | gsed -re 's|--?W(idth=)?||I' | grep -Eoe '^(0|[1-9][0-9]*)$')
[ -z "$Input" ] && echo "$2" | grep -Eoe '^(0|[1-9][0-9]*)$' && Input="$2" && shift 1
(( Input >= 0 )) && Width="$Input" || unset Width
elif [[ "$1" =~ ^((-[LlIi]|--(([Ll]ead(er|ing)?)?([Ii]n(dent)?)|[Ll]ead(er|ing)?)=)([0-9]+)?)$ ]]; then
Input=$(echo "$1" | gsed -re 's|--?[a-z]+=?||I' | grep -Eoe '^(0|[1-9][0-9]*)$')
[ -z "$Input" ] && echo "$2" | grep -Eoe '^(0|[1-9][0-9]*)$' && Input="$2" && shift 1
(( Input >= 0 )) && L="$Input" || unset L
...
else printf "$(Bold 'Error:') Unrecognized option: '$(Tbrown "$1")'\n\n" >&2
exit 2
fi
shift 1
done
IFS=''
[ -n "${*}" ] && declare Text="${*}" || Text="$(cat)" ## could also use read instead of cat ##
[ -z "$Text" ] && printf "$(Bold 'Error:') No text entered...\n\n" >&2 && exit 2
Text="$(echo "$Text" | gsed -rne '1h;1!H;$g;s|[\x0A-\x0D]+| |g;$p' | expand -t4 )"
echo "$Text" ## (temporary) ##
exit 0 ## (temporary) ##
... ## (process text) ##
... ## (process more) ##
./myScript.sh -L10 --width=20 'This is a test'
> This is a test
echo 'This is a test' | ./myScript.sh -L10 --width=20
> This is a test
./myScript.sh -L10 --width=20 < <( echo 'This is a test' )
> This is a test
./myScript.sh -L10 --width=20
##* Want to stop this *##> (No output)... hangs waiting on cat (or read) for a ^D
echo 'This is a test' >( ./myScript.sh )
> This is a test /dev/fd/63
> <B>Error:</B> No text entered...
./myScript.sh -L10 --width=20 <<<'This is a test'
> This is a test
echo "This is a test" | tee >( ./myScript.sh -L10 --width=20 ) >( ./myScript.sh )
> This is a test
> This is a test
> This is a test
答案 0 :(得分:1)
我认为你想要的是避免从终端阅读:
if test -t 0; then
echo "Not reading from terminal. Pipe through cat if you really want to do this" >&2
exit 1
fi
无法检测到没有专门为程序提供任何输入源的一般情况;所有重定向都由shell完成,你的程序无法判断它的标准输入是专门给它还是从shell继承。
答案 1 :(得分:0)
搞定了!谢谢geekosaur!在您的帮助下,这是我的解决方案:
IFS=''
if [ -n "${*}" ]; then
declare Text="${*}"
elif [ -t 0 ]; then
TempT="$(mktemp -t 'Entered Text')"
printf "\n$(Bold Enter text here:)\n\t** Note - To $(Tred stop) reading from stdin, enter $(Tred '/EOT')\n$(Twhite '∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞')\n"
counter=0
until [[ "$line" == /[Ee][0Oo][Tt] ]]; do
(( counter++ ))
read -rp "$(printf "$(Twhite '⋇')$(Taqua "%%7s")$(Twhite '⋇ ')" "$(frame 0 7 "[$counter]" 0 - --no)")" -e line
echo "$line" >>"$TempT"
done
readarray -t EnteredtText <"$TempT"
( set -u; [[ -f "$TempT" && "$TempT" =~ ^(/private)?/tmp/ ]] && { mv -f "$TempT" "$HOME/.Trash/" || rm -f "$TempT"; } ) &>'/dev/null'
IFS=$'\n'
declare Text="$(echo "${EnteredtText[*]}" | gsed -e '$d')"
else Text="$(cat)"
fi
在这个问题上,我有另一个问题:IFS=''
if [ -n "${*}" ]; then
declare Text="${*}"
elif [ -t 0 ]; then
TempT="$(mktemp -t 'Entered Text')"
printf "\n$(Bold Enter text here:)\n\t** Note - To $(Tred stop) reading from stdin, enter $(Tred '/EOT')\n$(Twhite '∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞')\n"
counter=0
until [[ "$line" == /[Ee][0Oo][Tt] ]]; do
(( counter++ ))
read -rp "$(printf "$(Twhite '⋇')$(Taqua "%%7s")$(Twhite '⋇ ')" "$(frame 0 7 "[$counter]" 0 - --no)")" -e line
echo "$line" >>"$TempT"
done
readarray -t EnteredtText <"$TempT"
( set -u; [[ -f "$TempT" && "$TempT" =~ ^(/private)?/tmp/ ]] && { mv -f "$TempT" "$HOME/.Trash/" || rm -f "$TempT"; } ) &>'/dev/null'
IFS=$'\n'
declare Text="$(echo "${EnteredtText[*]}" | gsed -e '$d')"
else Text="$(cat)"
fi
exec 7<&0
exec 0<Temp ## Perhaps some process sub? ##
until [[ "$line" == '/EOT' ]]; do
read line
done >Temp ## or sub here? ##
exec 0<&7
exec 7<&-
mapfile Text <Temp
exec 7<&0
exec 0<Temp ## Perhaps some process sub? ##
until [[ "$line" == '/EOT' ]]; do
read line
done >Temp ## or sub here? ##
exec 0<&7
exec 7<&-
mapfile Text <Temp
也许这里有一个 - while read line; do
[[ "$line" != '/EOT' ]] && readarray Text <( echo "$line" )
done
- 类型的命令?我已经编写了不到2年的脚本,对于我的生活,我无法理解I / O重定向(超出基础)。在许多不同的书籍/表格中重新阅读这一章总是导致大量的测试,我没有得到它[我想你看到了;]],我感到沮丧,最后我找到另一种方式来做我的事情想。除了0/1/2之外,那个神秘的命令while read line; do
[[ "$line" != '/EOT' ]] && readarray Text <( echo "$line" )
done
和所有文件desriptors都没有在我的任何脚本中使用......但是我知道有一种方法可以在没有文件创建和后续删除的情况下回答这个问题。 p>
谢谢!