我编写了一个函数,其行为方式与此类似,tee
但也预先添加了日期戳。一切工作正常,除非我想输出到一个只能根可写的文件(在我的例子中是一个日志文件/var/log
)。我简化了以下代码片段,仅包含不起作用的部分:
#!/bin/bash
#script ~/test_logger.sh
logfile=/var/log/test.log
logger()
{
while read data
do
echo $data >> $logfile
done
return 0
}
sudo ls ~ | logger
如果我像这样运行整个脚本,它就可以正常工作sudo ~/test_logger.sh
,但我不能总是这样做,因为我想在~/.bash_logout
自动运行的文件中使用记录器功能。我尝试将其放在sudo
while 循环中的 echo 前面,但这不起作用。有任何想法吗?
答案1
sudo
放入脚本通常是不好的做法。更好的选择是使用sudo
from~/.bash_logout
或任何您想要使用它的其他地方(如果必须的话)调用脚本,或者更好的是使/var/log/test.log
世界可写。
答案2
正如您所发现的,sudo command >out
它不起作用,因为“命令”是由 sudo 运行的,但“>out”是 shell 的函数,而不是“命令”。因此,您需要升级 shell 本身:
sudo sh -c "echo $data >>$logfile"
请注意,您想要非常非常确定 $data 中的内容:
~$ export data='good; touch /tmp/reallybad'
~$ echo $data
good; touch /tmp/reallybad
~$ sudo sh -c "echo $data>>/tmp/happy"
good
~$ ls /tmp/happy /tmp/reallybad
/tmp/happy /tmp/reallybad
因此西蒙发出了警告。
答案3
sudo
当您使用重定向或管道运算符时,它的工作方式可能与您想象的不同。流更改不是在sudo
有权限的情况下执行的。这就是为什么
sudo echo foo >> bar
如果 bar 只能 root 可写,则不起作用。
当您在 下运行脚本时sudo
,脚本中的所有内容都会获得超级用户权限,因此在这种情况下它可以正常工作。
解决方法是执行此操作以确保写入命令在以下环境下运行sudo
:
sudo echo foo | sudo tee bar > /dev/null
但请记住,这不会附加到文件中。它会覆盖该文件。
答案4
如果您查看 sudo 的手册页,您可以看到如何在脚本中使用它的示例... -c 选项可以执行命令。