描述

描述

描述

包含命令的相同循环chroot可以在终端中执行,但不能在 shell 脚本中执行。

再生产

  1. 创建一个基本(或您的)rootfs/mnt/myrootfs

  2. 创建一个包含以下内容的文件/mnt/myrootfs/tmp/hello.sh(并使其可执行):

    #!/bin/bash
    echo "i am exiting."
    exit 
    
  3. 创建以下脚本 ( ./chroot-poll.sh):

    #!/bin/bash
    while sleep 1; do 
        echo "chrooting into the target..."
        sleep 1    
        sudo chroot /mnt/myrootfs /bin/bash --rcfile /tmp/hello.sh
    done
    

结果

控制台输出如下:

$ ./chroot-poll.sh 
chrooting into the target...
i am exiting
chrooting into the target...

[1]+  Stopped                 ./chroot-poll.sh

为什么这会停止?将其置于前台使其fg再次迭代,然后再次停止。

在终端中运行可以正常工作:

将内容复制./chroot-poll.sh并直接粘贴到终端中可以按预期工作:

$ while sleep 1; do      echo "chrooting into the target...";     sleep 1    ;     sudo chroot /mnt/myrootfs /bin/bash --rcfile /tmp/hello.sh; done
chrooting into the target...
i am exiting
chrooting into the target...
i am exiting
chrooting into the target...
i am exiting
chrooting into the target...
i am exiting
chrooting into the target...
^C

问题

为什么脚本的内容可以在终端中运行,而脚本本身却无法执行?

答案1

关于这个问题,我无法完全补充一些内容,我相信它与文本有关:

[1]+  Stopped                 ./chroot-poll.sh

&在后台运行进程时,我只见过这样的文本,但问题中没有任何地方,并且您没有提到在后台运行作业。正如其他人指出的那样,我无法重现您的错误除了如果我在后台运行脚本。

当我尝试运行你的脚本而./chroot-poll.sh &不仅仅是./chroot-poll.sh我得到与你类似的结果时,所以我只能假设你正在后台运行它。

通常,作业Stopped在后台运行时会进入并尝试从标准输入中读取数据。对此的非常简单的解决方法可以是让它读取/dev/null

./chroot-poll.sh < /dev/null

这样,当任何东西尝试读取时,它将从标准输入读取/dev/null,而不是从标准输入读取。


我相信这最终会发生,因为您正在交互模式下运行 bash。您并不是要求它执行脚本,而只是覆盖~/.bashrc.尽管exitbash 仍然从 stdin 读取数据,就好像它希望您在提示符下输入一些内容一样。要让 bash 将脚本作为脚本读取,请使用:

sudo chroot /mnt/myrootfs /bin/bash -f /tmp/hello.sh

相关内容