我正在编写一个充当"会话终端的脚本" (您输入命令并显示输出)到目前为止我的代码是:
#!/bin/bash
while [ 1=1 ]; do
echo -n "~>"
read COMMAND
espeak "$($COMMAND)"
done
它适用于简单的命令:
bash$ ./talkingterminal.sh
~> ls
# espeak says "talkingterminal.sh"
但是当我使用管道等时:
bash$ ./talkingterminal.sh
~>ip addr | grep inet
Command "|" is unknown, try "ip addr help".
~>
并且该命令在bash中工作并提供预期的输出。 任何帮助? 谢谢, 马丁
答案 0 :(得分:0)
这是一种罕见的情况eval
是合适的;您只需将一个薄的包装器放在已经无限制访问命令行的位置。更重要的是,您不会以任何意外的方式修改COMMAND
。用户输入的内容是将要执行的内容。
#!/bin/bash
while : ; do
IFS= read -rp "~> " COMMAND
espeak "$(eval "$COMMAND")"
done
一些注意事项:
read
内置的bash
可以使用-p
选项显示自定义提示。 :
或true
命令设置无限循环。-r
选项和IFS
的空值,确保COMMAND
设置为用户输入的完全行。$COMMAND
,以便将整个字符串传递给eval
,而不进行任何先前的shell解析。 for x in 1 2 3; do
这样的行不会提示您输入循环体。)答案 1 :(得分:-1)
一个简单的解决方案是使用eval
:
#!/bin/bash
while [ 1=1 ]; do
echo -n "~>"
read COMMAND
espeak "$(eval $COMMAND)"
done
然后您也可以轻松地将输出打印到shell:
#!/bin/bash
while [ 1=1 ]; do
echo -n "~>"
read COMMAND
OUTPUT="$(eval $COMMAND)"
echo $OUTPUT
espeak "$($OUTPUT)"
done
答案 2 :(得分:-1)
您是否尝试过使用“-r”选项?此选项可避免解释特殊字符。此外,您必须删除行中的外部$():
espeak "$($COMMAND)"
应该是:
espeak "$(COMMAND)"