正在跳过bash脚本中的"读取"命令

7 bash user-input

我正在创建一个脚本来更新我的linux发行版,如果我需要擦除HD或我需要在另一台机器上安装Linux.所以这个脚本基本上安装了我通常需要的所有程序.在开始时有一个"读取"命令,询问我是否要自动安装所有软件包.如果我不选择,对于每个未找到的程序,它应该问我是否要安装它并使用此代码

if [[ $installall == "yes" ]]; then
    echo " Installing $sciprog..."
    sudo apt-get install -y $sciprog >/dev/null
    {
        scitest=`dpkg -s $sciprog | grep Status`
    } 2>${HOME}/musthave.errorlog
    if [[ $scitest != "Status: install ok installed" ]]; then
        echo " I've encountered problems installing $sciprog that I can't resolve. "
        echo " Consider installing $sciprog manually. "
        {
            echo "=========="
            echo " $sciprog"
        } >>${HOME}/musthave.notinstalled
    else
        echo " $sciprog installed correctly!"
        {
            echo "=========="
            echo " $sciprog"
        } >>${HOME}/musthave.installed
    fi
else
    echo " Seems like $sciprog is not installed... Do you want to download it?"
    echo " Type 'y' for yes."

    read secondyn ### THIS IS THE GUILTY COMMAND ###

    if [[ $secondyn == "y" ]]; then
        echo " Installing $sciprog ..."
        sudo apt-get install -y $sciprog >/dev/null
        {
            checkinstall=`dpkg -s $sciprog | grep Status`
        } 2>>${HOME}/musthave.errorlog
        if [[ $checkinstall != "Status: install ok installed" ]]; then
            echo " I've encountered problems installing $sciprog that I can't resolve. "
            echo " Consider installing $sciprog manually. "
            {
                echo "=========="
                echo " $sciprog"
            } >>${HOME}/musthave.notinstalled
        else
            echo " $sciprog installed correctly!"
            {
                echo "=========="
                echo " $sciprog"
            } >>${HOME}/musthave.installed
        fi
    else
        echo " Skipping $sciprog ..."
        {
            echo "=========="
            echo " $sciprog"
        } >>${HOME}/musthave.notinstalled
    fi
### some more code which works as expected. All the code above is inside a 
### while...do...done loop which reads line by line the file at the end
done <${HOME}/file.list
Run Code Online (Sandbox Code Playgroud)

但是如果我运行脚本,它会跳过else子句中的"read"命令并假设它是"n"......

我无法弄清楚为什么,在if...then...else...fi循环内部还有其他读取功能,它们按预期工作...

有任何想法吗?

jw0*_*013 13

代码的相关部分仍然不完整,但基于我将猜测你的while循环的注释

while read -r ... ; do 
    # do stuff ...

    # read user input
    read -r var

done < file
Run Code Online (Sandbox Code Playgroud)

从这个问题可以立即看出:内部read是从外部循环获取其输入,即从重定向的stdin file,而不是用户.对于不依赖于内核级支持的稍微更便携的替代方案/dev/tty,只需使用stdin以外的其他文件描述符作为while循环.

while read -r ... <&9; do
    # loop stuff

    # stdin still attached to the terminal untouched, 
    # so this reads from the terminal as expected
    read -r var 

done 9< file
Run Code Online (Sandbox Code Playgroud)

请注意,此示例使用fd 9作为文件,仅保留fd 0(stdin).有关详细信息,请查看BashFAQ 089.


小智 7

尝试从控制终端设备读取:

read secondyn </dev/tty
Run Code Online (Sandbox Code Playgroud)