描述
包含命令的相同循环chroot
可以在终端中执行,但不能在 shell 脚本中执行。
再生产
创建一个基本(或您的)rootfs
/mnt/myrootfs
创建一个包含以下内容的文件
/mnt/myrootfs/tmp/hello.sh
(并使其可执行):#!/bin/bash echo "i am exiting." exit
创建以下脚本 (
./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
.尽管exit
bash 仍然从 stdin 读取数据,就好像它希望您在提示符下输入一些内容一样。要让 bash 将脚本作为脚本读取,请使用:
sudo chroot /mnt/myrootfs /bin/bash -f /tmp/hello.sh