数组的echo元素什么都不输出

时间:2016-10-09 08:15:02

标签: arrays bash shell

这基本上是this question的延续。以下脚本提示用户输入搜索字符串,然后返回包含该字符串的history命令的编号列表。

#!/bin/bash

read -p 'Search history for? ' string

i=0
OLDIFS=$IFS
IFS=$'\n'

HISTFILE="$HOME/.bash_history"
history -r
arr=( "$(history | grep -i "$string" | cut -c8-)" )

for item in ${arr[@]}
do
    echo "$(( i++ )) $item"
done

我想通过要求用户选择列出的命令之一来扩展它

read -p 'select a command or type /q to quit ' n
if [[ $n = '/q' ]]; then
    exit
else
    for cmd in ${arr[$n]}
    do
        echo "$cmd"
    done
fi
IFS=$OLDIFS

但是每次都不会返回任何内容。在成功之前,我已经使用过这种相同的选择方法。为什么在这种特殊情况下这不起作用?

2 个答案:

答案 0 :(得分:1)

也许你想使用内置的选择:

#!/bin/bash

read -p 'Search history for? ' string

i=0
OLDIFS=$IFS
IFS=$'\n'

HISTFILE="$HOME/.bash_history"
history -r
arr=$(history | grep -i "$string" | cut -c8-)

select choice in $arr; do echo "your choice is $choice"; break; done
IFS=$OLDIFS

输出:

...
33) kill -l                  
#? 33
your choice is kill -l

答案 1 :(得分:1)

您的数组arr只有一个元素0,因为您正在分配命令的引用结果。尝试使用索引0.并尝试这个(没有引号):

arr=( $(history | grep -i "$string" | cut -c8-) )

现在原因很清楚,解决方案应该是:

IFS=$'\n' read -d '' -a arr <<<"$(history | grep -i "$string" | cut -c8-)"

或(bash&gt; 4.0):

readarray -t arr <<<"$(history | grep -i "$string" | cut -c8-)"

为什么要改变?将结果拆分为换行符并避免扩展&#39; *&#39;以及其他来自&#34;路径名扩展&#34;。

此外,您不需要循环来打印一个项目,而是使用它:

read -p 'select a command or type /q to quit ' n
[[ $n = '/q' ]] && exit
echo "command for $n -- ${arr[n]}"
IFS=$OLDIFS