一般问题
我想编写一个与用户交互的脚本,即使该脚本位于管道链的中间。
具体例子
具体来说,它用file
或来stdin
显示行(带有行号),要求用户输入选择或行号,然后将相应的行打印到stdout
。我们将此脚本称为selector
。然后,基本上,我希望能够
grep abc foo | selector > myfile.tmp
如果foo
包含
blabcbla
foo abc bar
quux
xyzzy abc
然后selector
向我展示(在终端上,而不是在myfile.tmp
!中)带有选项
1) blabcbla
2) foo abc bar
3) xyzzy abc
Select options:
之后我输入
2-3
并以
foo abc bar
xyzzy abc
作为的内容myfile.tmp
。
我已经启动并运行了一个选择器脚本,如果我不重定向输入和输出,则基本上可以正常运行。所以
selector foo
表现得像我想要的。但是,当像上面的示例中那样将内容管道在一起时,selector
将显示的选项打印到myfile.tmp
并尝试从grepped输入中读取选择。
我的方法
我尝试使用的-u
标志read
,如
exec 4< /proc/$PPID/fd/0
exec 4> /proc/$PPID/fd/1
nl $INPUT >4
read -u4 -p"Select options: "
但这并没有达到我的期望。
问:如何获得实际的用户交互?
cmd | { some processing; read var </dev/tty; } | cmd
alias selector='{ TMPFILE=$(mktemp); cat > $TMPFILE; nl -s") " $TMPFILE | column -c $(tput cols); read -e -p"Select options: " < /dev/tty; rangeselect -v range="$REPLY" $TMPFILE; rm $TMPFILE; }'
一个很好的作品。但是grep b foo | selector | wc -l
在这里休息。任何想法如何解决?顺便rangeselect
说一句,我使用的可以在pastebin.com/VAxTSSHs上找到。这是一个简单的AWK脚本,可打印与给定范围的行号对应的文件行。(范围可以是“ 3-10、12、14、16-20”之类的东西。)
alias
那样,而是selector() { all of that stuff...; }
变成一个函数。alias
es重命名简单命令,而函数将复合命令打包为单个简单命令。