我有一个小程序,我想确保它适用于写保护文件和取消写保护文件。因此,我没有使用echo $text > $file
or echo $text >> $file
,而是被迫分别使用echo $text | sudo tee $file
和echo $text | sudo tee --append $file
。当我使用 时sudo tee
,即使我更改了权限,每当我rm
在文件上使用时,它都会提示我,如下所示:
$ ls
someFile writeProtectedFile
$ rm someFile
$ ls
writeProtectedFile
$ rm writeProtectedFile
rm remove write-protected regular file 'writeProtectedFile'? yes
$ ls
然后我在网上闲逛,寻找可能的解决方案来解决我的困境。我只能找到两个:不正确的权限,或一组已更改的权限。我知道权限大小写是不正确的,因为我可以通过运行轻松更改权限sudo chmod xxx filename
,这将导致权限更改成功。然后我假设文件属性有问题,所以我运行lsattr
该文件,它会输出-------------e--
,与目录中的每个其他文件相同。
更新
我使用的原因tee
是回显文本来写入受保护的文件,但作为副作用,它也会写入受保护的常规文件...我的目标实际上是做类似的事情sudo echo "whatever" >> /etc/someFile
,这不起作用,所以我找到了一个解决方案在echo "whatever" | sudo tee /etc/someFile
。
答案1
当该命令tee
传递一个不存在的文件作为参数时,将在将输出写入该文件之前创建该文件。通过在该命令前面加上sudo
,您将要求 shell 将tee
命令运行为root
。结果是创建的文件由tee
启动命令的用户拥有:root
,因此对于其他用户来说是只读的。如果您运行ls -l
并查看user
和group
列,您可以自己看到这一点。
$ rm -f writeProtectedFile # Removing the file in case it already exists
$ echo $text | sudo tee writeProtectedFile
yourtext
$ ls -l
total 4
-rw-r--r-- 1 root root 9 22.07.2015 14:26 writeProtectedFile
有几种选择可以克服这个问题:
tee
在要求写入文件之前,以标准用户身份创建该文件。tee
然后将截断或简单地--append
截断它,而不改变其所有权:$ touch writeProtectedFile # creates the file as standard user $ echo $text | sudo tee writeProtectedFile $ rm writeProtectedFile
在尝试删除文件之前更改文件的所有权:
$ echo $text | sudo tee writeProtectedFile $ sudo chown $(whoami) writeProtectedFile # `whoami` returns the current user name $ rm writeProtectedFile
告诉
rm
忽略文件被写保护的事实,使用-f, --force
:$ echo $text | sudo tee writeProtectedFile $ rm --force writeProtectedFile
答案2
如果您正在创建的文件位于 中/etc
,则无论如何您都将无法删除它。也就是说,如果我们是普通用户,我们这样做:
$ sudo touch /etc/foobar
$ rm /etc/foobar
可以touch
工作,但rm
会失败,因为我们没有对该/etc
目录的写权限。
在操作系统内核级别,文件的写权限与其删除(或重命名/移动)无关。关于删除写保护文件的提示只是rm
程序中内置的应用程序级功能。当您y
对提示说时,rm
调用操作系统(很可能是该unlink
函数)来清除文件,而不首先更改其权限。 (请注意,由于您不拥有该文件,因此甚至不允许更改其权限!)
但是,任何更改目录内容的操作(例如添加或删除文件)都需要对该目录的写入权限。
所以,总而言之,这里要做的事情是:
$ sudo rm -f /etc/foobar
必须sudo
是 root,以便拥有所需的写入权限/etc
并-f
抑制提示rm
。
答案3
你说你的目标相当于
sudo echo "whatever" >> /etc/someFile
但随着重定向>>
也赋予了root权限。你有没有考虑过这个替代方案
sudo sh -c "echo 'whatever' >> /etc/someFile"
我在表达式周围使用了双引号,以便在调用之前sudo sh
对 shell 变量(如果有)进行插值,而不是尝试延迟sh
.这主要是因为sudo
削减了环境,因此某些变量可能不存在,而其他变量可能已重置。例如,$$
将显示调用者的 pid,而不是sh
.