我的inode在哪里被使用?
如何找出哪些目录负责咀嚼所有的inode?
最终根目录将负责最大数量的inode,所以我不知道我想要什么样的答案..
基本上,我用完inode并需要find一个不需要的目录来剔除。
谢谢,抱歉,这个模糊的问题。
所以基本上你正在寻找哪些目录有很多文件? 这是第一次刺穿它:
find . -type d -print0 | xargs -0 -n1 count_files | sort -n
其中“count_files”是一个shell脚本(谢谢乔纳森)
echo $(ls -a "$1" | wc -l) $1
如果你不想创build一个新文件(或者因为你没有用完inode),你可以运行这个查询:
for i in `find . -type d `; do echo `ls -a $i | wc -l` $i; done | sort -n
作为内部人员在另一个答案中提到,使用解决scheme与发现将更快,因为recursionls是相当慢,请检查下面的解决scheme! (信贷到期信贷!)
提供的recursionls方法非常慢。 只是为了快速find消耗我使用的大部分inode的父目录:
cd /partition_that_is_out_of_inodes for i in *; do echo -e "$(find $i | wc -l)\t$i"; done | sort -n
这是我的承担。 它和其他的没有太大的区别,但是输出结果很好,我认为它比其他的(目录和符号链接)更有效的inode。 这将计算工作目录的每个子目录中的文件数量; 它将输出分类并格式化为两列; 并打印总计(显示为“。”,工作目录)。 这不会遵循符号链接,但会计算以点开头的文件和目录。 这不包括设备节点和特殊文件,如命名pipe道。 只要删除“-type l -o -type d -o -type f”testing,如果你也要计算这些。 因为这个命令被分成两个查找命令,所以它不能正确地区分在其他文件系统上挂载的目录(-mount选项将不起作用)。 例如,这应该真的忽略“/ proc”和“/ sys”目录。 你可以看到,在“/”中运行这个命令的时候,包含“/ proc”和“/ sys”会严重扭曲总计数。
for ii in $(find . -maxdepth 1 -type d); do echo -e "${ii}\t$(find "${ii}" -type l -o -type d -o -type f | wc -l)" done | sort -n -k 2 | column -t
例:
# cd / # for ii in $(find -maxdepth 1 -type d); do echo -e "${ii}\t$(find "${ii}" -type l -o -type d -o -type f | wc -l)"; done | sort -n -k 2 | column -t ./boot 1 ./lost+found 1 ./media 1 ./mnt 1 ./opt 1 ./srv 1 ./lib64 2 ./tmp 5 ./bin 107 ./sbin 109 ./home 146 ./root 169 ./dev 188 ./run 226 ./etc 1545 ./var 3611 ./sys 12421 ./lib 17219 ./proc 20824 ./usr 56628 . 113207
我用下面的方法来解决(在我的同事James的帮助下),我们有大量的PHP会话文件需要在一台机器上删除:
1.我已经使用了多less个inode?
root@polo:/# df -i Filesystem Inodes IUsed IFree IUse% Mounted on /dev/xvda1 524288 427294 96994 81% / none 256054 2 256052 1% /sys/fs/cgroup udev 254757 404 254353 1% /dev tmpfs 256054 332 255722 1% /run none 256054 3 256051 1% /run/lock none 256054 1 256053 1% /run/shm none 256054 3 256051 1% /run/user
2.这些inode在哪里?
root@polo:/# find / -xdev -printf '%h\n' | sort | uniq -c | sort -k 1 -n [...] 1088 /usr/src/linux-headers-3.13.0-39/include/linux 1375 /usr/src/linux-headers-3.13.0-29-generic/include/config 1377 /usr/src/linux-headers-3.13.0-39-generic/include/config 2727 /var/lib/dpkg/info 2834 /usr/share/man/man3 416811 /var/lib/php5/session root@polo:/#
最后一行是很多PHP会话文件。
3.如何删除所有这些文件?
删除超过1440分钟(24小时)的目录中的所有文件:
root@polo:/var/lib/php5/session# find ./ -cmin +1440 | xargs rm root@polo:/var/lib/php5/session#
它有效吗?
root@polo:~# find / -xdev -printf '%h\n' | sort | uniq -c | sort -k 1 -n [...] 1088 /usr/src/linux-headers-3.13.0-39/include/linux 1375 /usr/src/linux-headers-3.13.0-29-generic/include/config 1377 /usr/src/linux-headers-3.13.0-39-generic/include/config 2727 /var/lib/dpkg/info 2834 /usr/share/man/man3 2886 /var/lib/php5/session root@polo:~# df -i Filesystem Inodes IUsed IFree IUse% Mounted on /dev/xvda1 524288 166420 357868 32% / none 256054 2 256052 1% /sys/fs/cgroup udev 254757 404 254353 1% /dev tmpfs 256054 332 255722 1% /run none 256054 3 256051 1% /run/lock none 256054 1 256053 1% /run/shm none 256054 3 256051 1% /run/user root@polo:~#
幸运的是,我们有一个敏感的警报,通知我们我们的索引节点已经用完了。
这是一个简单的Perl脚本,可以做到这一点:
#!/usr/bin/perl -w use strict; sub count_inodes($); sub count_inodes($) { my $dir = shift; if (opendir(my $dh, $dir)) { my $count = 0; while (defined(my $file = readdir($dh))) { next if ($file eq '.' || $file eq '..'); $count++; my $path = $dir . '/' . $file; count_inodes($path) if (-d $path); } closedir($dh); printf "%7d\t%s\n", $count, $dir; } else { warn "couldn't open $dir - $!\n"; } } push(@ARGV, '.') unless (@ARGV); while (@ARGV) { count_inodes(shift); }
如果你希望它像du
一样工作(其中每个目录计数也包括子目录的recursion计数),那么改变recursion函数return $count
,然后在recursion点说:
$count += count_inodes($path) if (-d $path);
一个实际的function -xdev
(GNU发现,其他types的发现,你需要你自己的等价的-xdev
留在同一个FS。)
find / -xdev -type d | while read -ri; do printf "%d %s\n" $(ls -a "$i" | wc -l) "$i"; done | sort -nr | head -10
尾巴显然是可定制的。
与其他许多build议一样,这将只显示每个目录中的条目数量,而不是recursion的。
PS
快速但不精确的单行(按目录节点大小检测):
find / -xdev -type d -size +100k
因为我在迪尔。[01] 做 find$ i -printf“%i \ n”| sort -u | wc -l | xargs echo $ i - DONE
dir.0 – 27913
dir.1 – 27913
简单的说一下,当你最终find一个邮件缓冲目录并且想要删除那里的所有垃圾时,如果文件太多,rm *将不能工作,你可以运行以下命令来快速删除该目录中的所有内容:
*警告*这将删除所有的文件快速的情况下,当rm不工作
find . -type f -delete
perl脚本是好的,但要注意符号链接 – 只有当-l filetest返回false时,才会recursion,否则你最多只会重复计数,最坏的情况是无限期地递增(这可能会引起撒旦1000年的统治)。
当有多个链接超过一小部分文件时,在文件系统树中统计inode的整个想法就会分崩离析。
只是想提一下,也可以使用目录大小间接进行search,例如:
find /path -type d -size +500k
如果你有很多大目录,500k可以增加。
请注意,此方法不是recursion的。 这只会帮助你,如果你有一个单一的目录很多文件,但不是如果文件均匀分布在其后代。
这将统计当前目录下的文件。 这应该工作,即使文件名包含换行符。 它使用GNU Awk。 改变d的值以获得想要的最大分离path深度。 0表示无限深度。
find . -mount -not -path . -print0 | gawk -vd=2 ' BEGIN{RS="\0";FS="/";SUBSEP="/";ORS="\0"} { s="./" for(i=2;i!=d+1 && i<NF;i++){s=s $i "/"} ++n[s] } END{for(val in n){print n[val] "\t" val "\n"}}' | sort -gz -k 1,1
同样由Bash 4; 这在我的经验中明显较慢:
declare -A n; d=2 while IFS=/ read -d $'\0' -r -aa; do s="./" for ((i=2; i!=$((d+1)) && i<${#a[*]}; i++)); do s+="${a[$((i-1))]}/" done ((++n[\$s])) done < <(find . -mount -not -path . -print0) for j in "${!n[@]}"; do printf '%i\t%s\n\0' "${n[$j]}" "$j" done | sort -gz -k 1,1
使用
ncdu -x <path>
然后按Shitf + c按项目的数量对文件进行sorting
这个命令适用于你的目录结构与我的目录结构完全不同的情况:
find / -type f | grep -oP '^/([^/]+/){3}' | sort | uniq -c | sort -n