由于所有者为 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
命令。
我的脚本是可执行的,我 运行 它作为 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
命令。