为啥 sudo 在 while 循环中使用时将阻塞命令更改为非阻塞命令?
Posted
技术标签:
【中文标题】为啥 sudo 在 while 循环中使用时将阻塞命令更改为非阻塞命令?【英文标题】:Why does sudo change a blocking command to a non-blocking command when used in a while-loop?为什么 sudo 在 while 循环中使用时将阻塞命令更改为非阻塞命令? 【发布时间】:2012-12-28 11:56:41 【问题描述】:或者:如何防止 sudo 的 rsync 在 while 循环中无限触发? 因为这就是(感觉)正在发生的事情,我不明白。
我正在尝试设置一个手表来同步修改的文件,它工作正常。但是,一旦我将所需的sudo
引入rsync
命令,单个inotify
事件就会导致rsync
命令无限期地触发。
#!/usr/bin/env bash
inotifywait -m -r --format '%w%f' -e modify -e move -e create -e delete /var/test | while read line; do
sudo rsync -ah --del --progress --stats --update "$line" "/home/test/"
done
当您编辑文件时,rsync
进入快速射击模式。但是丢失sudo
(当然要使用您有权访问的文件夹)并且脚本会按预期工作。
-
这是为什么呢?
如何使用
sudo
命令使其正常工作?
【问题讨论】:
当你应用 sudo 时,我怀疑 rsync 正在等待输入密码。这就是您认为 rsync 无限期运行的方式。您是否尝试过在命令提示符下将 sudo'ed rsync 作为独立命令运行?它要求输入密码吗?如果是,您可能需要使用 expect 命令自动输入密码。 该命令无需密码即可正常工作 - 我在sudoers
和 nopassword
中允许使用 rsync
。该命令也可以正确执行,它会同步文件。但它会一遍又一遍地这样做,直到我破坏脚本。
啊!!有你的问题!问题是当您编辑任何文件时,大多数编辑器都会创建交换文件甚至更新时间戳。这会向“inotifywait”发出许多修改通知,您应该将“-e close_write”开关传递给inotifywait 命令。事实上,只是不要寻找修改。看,***.com/questions/10300835/…
不幸的是,这无关紧要。否则,此行为也会影响非 sudo 变体。此外,我还想监视创建、删除和移动。我正在使用echo test > test.txt
进行测试,这里没有临时文件或属性更改。
没错,echo 不会那样做。尝试“vim /var/test/a.txt”并在脚本运行时继续编辑它。每当您在 vim 中按 enter 时,您都会看到 rsync 正在运行。没有?
【参考方案1】:
我有答案,通过实验找到的。但我不知道为什么会这样。请有人告诉我为什么 sudo
在这个循环中会破坏预期的阻塞行为。
由于sudo
破坏了脚本,我们可以通过使用包装器与sudo
保持距离:这是正确的:
inotifywait -m -r --format '%w%f' -e modify /var/test | while read line; do
sh -c 'sudo rsync -ah "$line" "/home/test/"'
done
奇怪的是:将sudo
从包装器中拉出来,我们又遇到了旧的错误行为。很奇怪。这是错误的:
inotifywait -m -r --format '%w%f' -e modify /var/test | while read line; do
sudo sh -c 'rsync -ah "$line" "/home/test/"'
done
【讨论】:
以上是关于为啥 sudo 在 while 循环中使用时将阻塞命令更改为非阻塞命令?的主要内容,如果未能解决你的问题,请参考以下文章