我想用bash-对话框创建一个简单的对话框。我使用(X)DSL和bash-3.2。最新的(X)DSL基于Linux 2.4.31,附带bash-2.05,但是bash-3.2可以从MyDSL/ latest下载。因此,我的脚本运行在‘#!bin/bash-3.2/bin/bash’下。
用户可以从数据库中选择的菜单项。
例如数据库文件“armatures”:
室内照明室内照明 户外照明户外照明
我将数据从“armatures”文件中检索到数组“options”中,其中:
“options=”($(awk-F“AC.26”'{ print $1,$2 }‘armatures)
在终端“回声”数组中:
回显${options@}
这表明:
“室内电枢”“室内照明”“户外电枢”“户外照明”
这看起来可以用作带有“鞭尾”的选择菜单,但事实并非如此。
惠氏-清晰-标题“电枢”-菜单“选择一个电枢”50 80 10美元{options@}
显示:
第1栏-第2栏 室内电枢 照明用 室内使用 户外电枢 照明用 户外使用
代替:
第1栏-第2栏 室内电枢.室内照明 户外电枢.户外用电缆
似乎带有双引号的数组元素被忽略了,或者没有被“鞭尾”看到。我也尝试过"${options@}“,但这总是会导致第一个单词'Indoor‘。
除了‘鞭尾’,我尝试了‘对话框’,但它们是相同的:版本信息显示‘c对话框(ComeOn对话框!)版本1.1-20080316’在这两种情况下。
我的资源非常有限,我不想冒险(还)进入‘x对话框’,'zenity','dzen‘等等,即使这会解决这个问题。由于XDSL (对于XBOX),我也仅限于Linux2.4.31。
我上网浏览了很多次,但都没有用。使用“鞭尾/对话”的解决方案是什么?
发布于 2013-06-03 17:11:20
您所遇到的基本问题来自shell解析命令行的顺序:它在用变量的值替换变量之前解析(并移除)引号和转义,并且从不对替换值中的任何引号或转义进行返回和重新解析。考虑一下这个例子:
var='"foo bar"' # Note that the single-quotes will be removed, and the
# double-quotes will be treated as part of the variable value.
somecmd $var # This runs cmd with 2 arguments: '"foo' and 'bar"'在您的例子中,我不确定双引号来自何处;它们不在您提供的文件列表中,而awk命令不会添加它们。但是在任何情况下,您都不希望它们作为值的一部分存储,而是希望它们围绕变量引用:
var='foo bar' # Again, the single-quotes are removed.
somecmd "$var" # This runs cmd with a single argument: 'foo bar'您的情况比较复杂,因为您使用的是数组,但同样的原则也适用。请注意,变量的echo具有很高的误导性;如果它显示出正确的引用,这实际上意味着出现了可怕的错误,因为它应该在移除引号后显示参数。
那你是怎么解决的?试试这个:
options=()
while IFS="|" read col1 col2 || [ -n "$col1" ]; do
options+=("$col1" "$col2") # Note the double-quotes around the variable references
done <armatures
echo "options:"
printf " '$s'\n" "${options[@]}" # This prints each array element on a separate line
whiptail --clear --title "Armatures" --menu "Choose an armature" 50 80 10 "${options[@]}" # Again, double-quotes around the referenceUPDATE:我添加了一个测试([ -n "$col1" ])来执行数据库文件中未终止的最后一行的循环。
如果双引号实际上在数据库文件中,则必须删除它们;最简单的处理方法可能是在将字符串添加到数组时去掉引号,使用bash在构建数组时替换字符串的能力(将‘“替换为空白):
options=()
while IFS="|" read col1 col2 || [ -n "$col1" ]; do
options+=("${col1//'"'/}" "${col2//'"'/}")
done <armatures发布于 2016-01-30 02:08:25
主要问题在于bash (或任何其他shell)将命令行拆分为“word”的方式,正如第一个答案中提到的那样。行分割是基于IFS --内部字段分隔器--在默认情况下设置为。开发早期shell的聪明人(Stephen等)显然认为用户能够改变它是个好主意。这也是很好的,它可以设置为一个多字符的值。
因此,您真正需要做的就是将字段分隔符设置为换行符,运行awk脚本,然后将其设置回原来的位置。在使用数组时,还应该引用它。
这应该适用于bash:
IFS=$'\n'
options=($(awk -F"|" '{ print $1,$2 }' armatures)
IFS=$' \t\n'现在正确定义了数组成员。然后:
whiptail --clear --title "Armatures" --menu "Choose an armature" 50 80 10 "${options[@]}"对于更原始的Shell (如Bourne ),您可能需要输入"IFS=“(没有引号),打开单引号,按下,然后用单引号结束,从而设置IFS。要重新设置它,输入"IFS=“(没有引号),打开单引号,输入a,引号(例如Ctrl)a,点击,然后用单引号关闭。
https://stackoverflow.com/questions/16897697
复制相似问题