Bash读取用户y / n应答不起作用(在循环读取查找输出时读取命令)

时间:2020-12-28 15:42:27

I have a problem here. Seems like my Bash script is ignoring everything that is between do and done. Don't know why, maybe you will see the problem. Thanks in advance.

我这里有问题。好像我的Bash脚本忽略了do和done之间的所有内容。不知道为什么,也许你会看到问题。提前致谢。

katalogas=$1
find $katalogas -type f -mtime +3 | while read $failai
do
read -p "Run command $foo? [yn]" answer
if [[ $answer = y ]] ; then
  rm $failai
fi
done

3 个解决方案

#1


7  

Try to replace

尝试更换

read -p "Run command $foo? [yn]" answer

by

read -p "Run command $foo? [yn]" answer </dev/tty

to avoid reading from stdin.

避免从标准输入读取。

Update with Will's suggestion:

Will的建议更新:

katalogas=$1
read -p "Run command $foo? [yn]" answer
if [[ $answer = y ]] ; then
  find "$katalogas" -type f -mtime +3 | while read failai
  do
    rm "$failai"
  done
fi

#2


1  

So the first problem I see is that your while read $failai should be while read failai (without the $). Try this:

所以我看到的第一个问题就是你在阅读failai的同时阅读failai(没有$)。试试这个:

katalogas="$1"
find "$katalogas" -type f -mtime +3 | while read failai; do
    read -p "Run command ${foo}? [yn]" answer
    if [[ "$answer" = "y" ]]; then
        echo labas
    fi
done

As far as prompting for yes or no, though, I usually use something like this:

至于提示是或否,我通常使用这样的东西:

function prompt_yn()
{
    local default=""
    local prompt="y/n"
    local input

    # If $2 specifies a default choice, configure options accordingly.
    if [[ "${2:-}" = "Y" ]]; then
        prompt="Y/n"
        default="Y"
    elif [[ "${2:-}" = "N" ]]; then
        prompt="y/N"
        default="N"
    fi

    # Prompt the user until they give an appropriate answer.
    while true; do
        read -p "$1 [${prompt}] " input
        [[ -z "$input" ]] && input="$default"

        case "$input" in
            [Yy]* ) return 0;;
            [Nn]* ) return 1;;
            * ) echo "Please answer yes or no.";;
        esac
    done
}

So, if you used the code above, your code would look like this:

因此,如果您使用上面的代码,您的代码将如下所示:

katalogas="$1"
find "$katalogas" -type f -mtime +3 | while read failai; do
    if prompt_yn "Run command ${foo}?"; then
        echo labas
    fi
done

You can also add a "Y" or a "N" after the "Run command ${foo}?" to specify a default value if the user just presses Enter.

您还可以在“运行命令$ {foo}?”之后添加“Y”或“N”。如果用户只按Enter键,则指定默认值。

EDIT: It seems I missed the point about part of this. Cyrus's answer is the solution to the read not working inside the loop. This * post explains it well also. However, based on your comment, @semkius, it seems you only want to ask the question once, outside of the loop.

编辑:我似乎错过了部分内容。 Cyrus的答案是读取不在循环内部工作的解决方案。这篇*文章也很好地解释了它。但是,基于你的评论@semkius,似乎你只想在循环之外问一次这个问题。

#3


0  

use the command reset and then execute your shell script.

使用命令reset然后执行shell脚本。

#1


7  

Try to replace

尝试更换

read -p "Run command $foo? [yn]" answer

by

read -p "Run command $foo? [yn]" answer </dev/tty

to avoid reading from stdin.

避免从标准输入读取。

Update with Will's suggestion:

Will的建议更新:

katalogas=$1
read -p "Run command $foo? [yn]" answer
if [[ $answer = y ]] ; then
  find "$katalogas" -type f -mtime +3 | while read failai
  do
    rm "$failai"
  done
fi

#2


1  

So the first problem I see is that your while read $failai should be while read failai (without the $). Try this:

所以我看到的第一个问题就是你在阅读failai的同时阅读failai(没有$)。试试这个:

katalogas="$1"
find "$katalogas" -type f -mtime +3 | while read failai; do
    read -p "Run command ${foo}? [yn]" answer
    if [[ "$answer" = "y" ]]; then
        echo labas
    fi
done

As far as prompting for yes or no, though, I usually use something like this:

至于提示是或否,我通常使用这样的东西:

function prompt_yn()
{
    local default=""
    local prompt="y/n"
    local input

    # If $2 specifies a default choice, configure options accordingly.
    if [[ "${2:-}" = "Y" ]]; then
        prompt="Y/n"
        default="Y"
    elif [[ "${2:-}" = "N" ]]; then
        prompt="y/N"
        default="N"
    fi

    # Prompt the user until they give an appropriate answer.
    while true; do
        read -p "$1 [${prompt}] " input
        [[ -z "$input" ]] && input="$default"

        case "$input" in
            [Yy]* ) return 0;;
            [Nn]* ) return 1;;
            * ) echo "Please answer yes or no.";;
        esac
    done
}

So, if you used the code above, your code would look like this:

因此,如果您使用上面的代码,您的代码将如下所示:

katalogas="$1"
find "$katalogas" -type f -mtime +3 | while read failai; do
    if prompt_yn "Run command ${foo}?"; then
        echo labas
    fi
done

You can also add a "Y" or a "N" after the "Run command ${foo}?" to specify a default value if the user just presses Enter.

您还可以在“运行命令$ {foo}?”之后添加“Y”或“N”。如果用户只按Enter键,则指定默认值。

EDIT: It seems I missed the point about part of this. Cyrus's answer is the solution to the read not working inside the loop. This * post explains it well also. However, based on your comment, @semkius, it seems you only want to ask the question once, outside of the loop.

编辑:我似乎错过了部分内容。 Cyrus的答案是读取不在循环内部工作的解决方案。这篇*文章也很好地解释了它。但是,基于你的评论@semkius,似乎你只想在循环之外问一次这个问题。

#3


0  

use the command reset and then execute your shell script.

使用命令reset然后执行shell脚本。