在当前目录中查找所有可写文件

32

我希望快速找出目录中所有可写文件。有什么快捷的方法吗?

11个回答

39
find -type f -maxdepth 1 -writable

5
不支持 "writeable"。 - vehomzzz
2
@Pavel,只需交换“-type f”和“-maxdepth 1”即可消除该消息。 - John La Rooy
@bignose:不,它假定当前目录。 @ghostdog74:touch 444 filetouch 555 filechown somebodyelse:somebodyelse file或许多变化,它都找不到它。 - Dennis Williamson
@Dennis,这正是我想的。因此我才问的。 - ghostdog74
3
由于某种原因,旗帜的名称是可以拼写为“writable”而没有字母e。 - h0b0
显示剩余4条评论

19

-writable选项将查找当前用户可写的文件。如果您想查找任何人都可以编写的文件(甚至是其他组合),可以使用-perm选项:

find -maxdepth 1 -type f -perm /222

这将查找由其所有者(无论是谁)可写的文件:

find -maxdepth 1 -type f -perm /200

不同的字符可以用来控制mode参数的含义:

  • / - 任何权限位
  • - - 所有位(-222 表示所有位 - 用户、组和其他人)
  • 无前缀 - 精确指定(222 表示除了写权限没有其他权限)

这是一个非常优雅的解决方案。我该如何修改它以查找仅由所有者可写的文件? - kshenoy
5
一种方法:-perm -u+w ! -perm -g+w ! -perm -o+w - Dennis Williamson
在Mac或任何旧版Linux上,请使用:find -type f +perm 222 - LanDenLabs

4

要查找可写文件,无论所有者、组或其他人,您可以检查ls中文件权限列中的w标志。

ls -l | awk '$1 ~ /^.*w.*/'

$1是第一个字段,也就是ls -l命令的权限块,正则表达式只是查找第一个字段中的字母"w"。就是这样。

如果你想查找所有者的写权限

ls -l | awk '$1 ~ /^..w/'

如果您想查找组写入权限

ls -l | awk '$1 ~ /^.....w/'

如果您想查找其他人的写入权限

ls -l | awk '$1 ~ /w.$/'

波浪号是awk的正则表达式运算符,用于“匹配”。与Perl的=〜正则表达式运算符类似。 - ghostdog74

3

-f会测试文件是否存在

-w会测试文件是否可写

示例:

$ for f in *; do [ -f $f ] && [ -w $f ] && echo $f; done

1
这句话没有说明这些选项应该应用于哪个命令,因此也是无用的。 - bignose
@lexu:这似乎过于苛刻了——我的答案完全有效并包含了所有所需的信息——任何使用*nix系统的人都必须期望简洁接近简练,否则他们走不远。 - Paul R
1
我在Bash提示符下输入了“-f”,然后收到了一个“命令未找到”的错误。/讽刺 - Dennis Williamson
感谢您的编辑,-1已被移除。抱歉,它不让我点赞,不知道为什么? - lexu
2
@Paul R,批评是因为您提供了选项,但没有说明您所指的命令。这些选项不是“bash运算符”,而是test命令的选项,也可以拼写为[命令。 - bignose
显示剩余3条评论

3
如果您在shell中使用,请使用以下命令:
find .  -maxdepth 1 -type f -writable

看到这种类型的问题,您可以在superuser.com或serverfault.com上找到更好的答案。

如果您正在编写代码而不仅仅是使用shell,则可能会对access(2)系统调用感兴趣。

这个问题已经在serverfault上被问过了。

编辑:@ghostdog74问您是否删除了此文件的写权限,是否仍然会找到该文件。 答案是,否,这只会找到可写的文件。

dwaters@eirene ~/temp
$ cd temp

dwaters@eirene ~/temp/temp
$ ls

dwaters@eirene ~/temp/temp
$ touch newfile

dwaters@eirene ~/temp/temp
$ ls -alph
total 0
drwxr-xr-x+ 2 dwaters Domain Users 0 Mar 22 13:27 ./
drwxrwxrwx+ 3 dwaters Domain Users 0 Mar 22 13:26 ../
-rw-r--r--  1 dwaters Domain Users 0 Mar 22 13:27 newfile

dwaters@eirene ~/temp/temp
$ find .  -maxdepth 1 -type f -writable
./newfile

dwaters@eirene ~/temp/temp
$ chmod 000 newfile

dwaters@eirene ~/temp/temp
$ ls -alph
total 0
drwxr-xr-x+ 2 dwaters Domain Users 0 Mar 22 13:27 ./
drwxrwxrwx+ 3 dwaters Domain Users 0 Mar 22 13:26 ../
----------  1 dwaters Domain Users 0 Mar 22 13:27 newfile

dwaters@eirene ~/temp/temp
$ find .  -maxdepth 1 -type f -writable

dwaters@eirene ~/temp/temp

2
我看到你的解决方案出现了以下错误:find: invalid predicate `-writable'。 - vehomzzz
抱歉,之前句子中的句号放错位置了,已经修正。请查看“man find”以了解如何使用该命令。 - David Waters
如果您将文件的所有可写权限都删除,然后使用命令,它是否仍然能够找到该文件?我很好奇。 - ghostdog74

1

查找所有者可写的文件:

find ./ -perm /u+w

查找组可写文件:

find ./ -perm /g+w

查找任何人都可写的文件:

find ./ -perm /o+w

查找具有定义权限的文件:

find ./ -type -d -perm 0777
find ./ -type -d -perm 0755
find ./ -type -f -perm 0666
find ./ -type -f -perm 0644

使用以下方法禁用递归:

-maxdepth 1

1
for  var in `ls`
do
if [ -f $var -a -w $var ]
then
echo "$var having write permission";
else
echo "$var not having write permission";
fi
done

1
不要使用for循环和ls命令来解析文件名。在if/else测试中,也要引用您的变量。 - ghostdog74

1

find -writable 的问题在于它不具备可移植性,而且使用可移植的 find 运算符正确地模拟它也不容易。如果您的 find 版本没有它,您可以使用 touch 来检查文件是否可写,使用 -r 确保您(几乎)不会修改文件:

find . -type f | while read f; do touch -r "$f" "$f" && echo "File $f is writable"; done

touch-r 选项在 POSIX 中,因此可以被认为是可移植的。当然,这比 find -writable 要低效得多。

请注意,touch -r 确实会更新每个文件的 ctime(元数据的最后更改时间),但人们很少关心 ctime。


你尝试过以root身份或者拥有者身份在只读文件上使用touch命令吗?更新时间戳的能力并不意味着该文件是可写的。 - Chris Johnsen
如果您是root用户,可写文件系统上的只读文件是可写的,因此我在这里看不到问题。 - Idelic
在Redhat 4上,我遇到了“while: Expression Syntax”错误。 - jgritty

0
stat -c "%A->%n" *| sed -n '/^.*w.*/p'

0
如果您想查找所有可被Apache等写入的文件,则可以执行以下操作:
sudo su www-data
find . -writable 2>/dev/null 

将 www-data 替换为 nobody 或 apache 或您的 Web 用户是什么。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接