sh / bash命令替换冻结脚本

时间:2013-12-26 15:57:35

标签: linux bash shell unix sh

有一个简单的单行脚本:

myvar=`nano`

如果我用bash或sh运行它会冻结当前终端会话并且不会显示编辑器。我尝试过其他交互式程序和不同的操作系统(Ubuntu,FreeBSD),结果总是一样的。我认为这是因为那些程序忽略了信号,但我不明白为什么他们不能以这种方式开始。

我需要这种方法,因为我想释放捕获用户文本输入的函数并将其返回给调用者。例如:

function read_text()
{
   local tempfile=`mktemp`
   nano $tempfile
   cat $tempfile
   rm $tempfile
}

echo "Press ENTER to input your comment." 
read # ENTER
comment=`read_text`

更新

感谢tripleee指导我解决此问题的原因。我发现简单的解决方案它是将问题重定向到当前终端线。

有一个简单的单行脚本:

myvar=`nano > $(tty)`

完整示例:

read_text()
{
   local tempfile=`mktemp`
   nano $tempfile > `tty`
   cat $tempfile
   rm $tempfile
}
comment=`read_text`
echo $comment

1 个答案:

答案 0 :(得分:1)

您无法在后退内部运行交互式命令,因为反引号将阻止程序与终端之间的交互式输入和输出。

对你的问题进行合理的重构就是处理调用者中的临时文件,并取消该函数;或者至少减少功能的范围。

local tempfile=$(mktemp)
${VISUAL-nano} "$tempfile"
comment=$(cat "$tempfile")
rm "$tempfile"

另请注意此代码如何使用$VISUAL,并且只有在未设置此标准变量时才会回退到nano

对于大多数真实场景,如果输入任务足够重要以保证使用外部编辑器,那么传递临时文件可能会更好(使用trap将其删除脚本的最后一部分)而不是将其内容抓取到shell变量中。

# At the beginning of your script
tmpdir=$(mktemp -d -t yourscript.XXXXXXXX)
trap 'rm -rf "$tmpdir"' 0
trap 'exit 127' 1 2 3 5 15

:

echo '# Enter your comment here' >"$tmpdir"/comment
${VISUAL-nano} "$tmpdir"/comment

正如您所看到的,这很简单,您实际上并不需要将其封装到单独的函数中。