由于所有者为 root 的环境中的重定向,无法正确执行 bash 脚本

Cannot properly execute bash script because of a redirection in an environment where root is the owner

我的脚本是可执行的,我 运行 它作为 sudo。我尝试了“>>”运算符的许多解决方法和替代方法,但似乎没有任何效果。

我的脚本:

#! /bin/bash
if [[ -z "" || -z "" ]]; then
  exit 1
else
  root=
  fileExtension=
fi
$(sudo find $root -regex ".*\.${fileExtension}") >> /home/mux/Desktop/AllFilesOf${fileExtension}.txt

我尝试了 tee、sed 和 dd,我还尝试了 运行使用 bash -c 或在 sudo -i 中使用它,但没有任何效果。我得到一个空文件或权限被拒绝错误。 我彻底搜索并阅读了许多命令手册,但我无法让它工作

$() 运算符执行命令替换。当整个命令行展开时,括号内的命令被执行,整个构造被命令的输出替换。执行所有扩展后,结果行作为命令执行。

那么,考虑一下您的命令的这个简化版本:

$(find /etc -regex ".*\.conf") >> /home/mux/Desktop/AllFilesOfconf.txt

在我的系统上,将扩展为形式巨大的命令

/etc/rsyslog.conf /etc/pnm2ppa.conf ... /etc/updatedb.conf >> /home/mux/Desktop/AllFilesOfconf.txt

此时请注意,重定向与命令替换中的命令是分开的,因此独立于命令。因此,扩展命令替换不会导致将任何内容写入目标文件。

但我们还没有完成!那只是扩张。 Bash 现在尝试将结果作为命令执行。特别是,在上面的示例中,它尝试将 /etc/rsyslog.conf 作为命令执行,将所有其他文件名作为参数,并按指定重定向输出。但是 /etc/rsyslog.conf 不可执行,因此会失败,并生成 "permission denied" 消息。我相信您可以从那里推断出不同的扩展会产生什么影响。

我认为您根本不是要执行命令替换,而只是 运行 命令并将其输出重定向到给定文件。那就是这样:

sudo find $root -regex ".*\.${fileExtension}" >> /home/mux/Desktop/AllFilesOf${fileExtension}.txt

更新:

正如@CharlesDuffy 所观察到的,这种情况下的重定向是在用户/进程的权限下执行的 运行 脚本,就像在您的原始示例中一样。我认为这是有意且正确的——即脚本由用户 'mux' 或另一个有权访问 mux 的 Desktop 目录和任何现有文件的用户 运行脚本可能会尝试创建或更新它。如果不是这种情况,并且您也需要重定向才能获得特权,那么您可以这样实现:

sudo -s <<END
find $root -regex ".*\.${fileExtension}" >> /home/mux/Desktop/AllFilesOf${fileExtension}.txt
END

运行 是一个通过 sudo 的交互式 shell,其输入是从 heredoc 重定向而来的。变量扩展在执行 sudo 的主机 shell 中执行。在这种情况下,重定向是使用通过 sudo 获得的身份执行的,这会影响访问控制以及文件的所有权(如果创建新文件)。如果您不希望输出文件归 root 所有,您可以添加 chown 命令。