And*_*ea 6 filesystem command-line
最近我在求职面试中被问到“如何在文件系统的所有文件夹中创建一个零大小的文件[我认为这意味着一个空文件]?” 我发现这个问题有点奇怪,我想到了一个循环来列出所有目录并使用,touch或者转到根目录并使用touch递归选项。你有什么想法?
Rin*_*ind 17
那可能是...
find . -type d -exec touch {}/emptyfile \;
Run Code Online (Sandbox Code Playgroud)
-type d 意思是“目录”exec执行命令touch 并创建一个名为“emptyfile”的文件{}什么是发现从结果的替代品find。该/是让一个有效的路径+ filenane和逃脱; 是关闭命令(否则变成“空文件;”)结果 ...
rinzwind@schijfwereld:~/t$ mkdir 1 2 3 4 5 6 7 8 9 10
rinzwind@schijfwereld:~/t$ ls -ltr */*
ls: cannot access '*/*': No such file or directory
rinzwind@schijfwereld:~/t$ find . -type d -exec touch {}/emptyfile \;
rinzwind@schijfwereld:~/t$ ls -ltr */*
-rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 5/emptyfile
-rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 9/emptyfile
-rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 1/emptyfile
-rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 8/emptyfile
-rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 3/emptyfile
-rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 2/emptyfile
-rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 10/emptyfile
-rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 7/emptyfile
-rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 6/emptyfile
-rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 4/emptyfile
Run Code Online (Sandbox Code Playgroud)
我的工作正常,但 Peter Cordes 的回答更好:)
为了有效地做到这一点,您希望避免touch为要创建的每个文件生成一个新进程。
这是xargs好处的一部分,将 args 批处理成尽可能大的块,而小到足以适应单个进程的命令行。(现代 Linux 有相当大的限制,所以它不再是一个问题,xargs 很少需要多次实际运行你的命令来处理所有的 args,但它也可以让你避免文件名像 in 那样受到 shell 分词foo $(bar)。)
我们可以使用 find 自己的-printf来格式化每个目录路径上的其他内容,特别是我们想要的文件名。在xargs -0使用了'\0',所以这是任意文件名的安全,甚至包括换行符字节作为分隔符。如果您没有使用自定义 printf 格式,则可以仅用于-print0打印以 0 分隔的路径。
find . -xdev -type d -printf '%p/empty\0' | xargs -0 echo touch
Run Code Online (Sandbox Code Playgroud)
(在测试目录,即打印touch ./empty ./2/empty ./1/empty,不touch ./empty, touch ./1/empty等等。所以它的运行一个touch为多个文件。)
mktemp只接受一个模板,但如果我们希望在命名中具有一些随机性以减少偶然接触现有文件的机会,您可以这样做。
find . -xdev -type d -printf "%p/empty.$RANDOM\0" | xargs -0 echo touch
Run Code Online (Sandbox Code Playgroud)
请注意,它在每个目录中都是相同的15 位随机数,因为"$RANDOM"在 find 开始之前被 bash 扩展了一次。您可以使用$(date +%s).$RANDOM或任何您想要的作为文件名的一部分。
对于 SSD 或 tmpfs,CPU 可能是这里的瓶颈。或者,如果您很幸运,并且磁盘上的元数据 I/O 碰巧大部分是连续的,因为您正在接触每个目录(并分配一堆新的 inode),那么即使是旋转磁盘也可能保持一定程度的体面。尽管您可能没有按照它们在磁盘上的排列顺序接触目录。
无论如何,没有必要浪费大量 CPU 时间来启动应该受到 I/O 限制的进程。
行不通的方法:
find -exec touch {} +批量 args,但-exec touch {}/empty +在{}不单独工作时拒绝工作。
xargs -I {} echo touch {}/emptyfile暗示-L 1(对于命令的每次调用,仅处理一个“行”输入,无论是实际行还是以 0 分隔的字符串xargs -0)。因此,如果我们想利用 xargs 对 args 进行批处理,我们不能使用 xargs 来修改每个 args。
find /mountpoint -xdev -type d -exec mktemp -p {} \;
Run Code Online (Sandbox Code Playgroud)
一个非常明显的方面是您可能需要也可能不需要 root 访问权限才能在/mountpoint.
有两个不明显的方面:
你说的“在文件系统的所有文件夹中”,所以我们从具体开始,/mountpoint不进入其他文件系统(-xdev)。
如果在树中安装了其他文件系统,例如 in /mountpoint/foo/another/mntpoint,-xdev则将阻止我们进入它们。尽管如此,这些文件系统可能会掩盖属于相关文件系统的整个子树。在最好的情况下,挂载的文件系统会/mountpoint/foo/another/mntpoint屏蔽相关文件系统的空mntpoint目录。所以我们不能轻易到达“文件系统的所有文件夹”。
有了 root 访问权限,我们就可以mount --bind /mountpoint /somewhere/else提前了。与--bind(相对于--rbind,请参阅man 8 mount)mntpoint深入/somewhere/else不会从/mountpoint/foo/another/mntpoint. 这样我们就可以访问mntpoint属于有问题的文件系统。
这还不够。如果有问题的文件系统是 Btrfs,那么可能 /mountpoint会访问某些子卷,但不能访问整个文件系统(比较这个问题)。
通常,任何(?)挂载的文件系统的子树都可以绑定挂载到另一个目录。卸载原始挂载点后,另一个目录将提供对文件系统片段的访问权限。我们/mountpoint可能首先是“另一个目录”,因此它可能无法访问整个文件系统。你事先不知道这一点。
结论是:如果短语严格来说是“文件系统的所有文件夹”(而不是“所有子目录”,这是非常简单的),那么您需要确保不会遗漏文件系统的任何部分。然后才使用find …本答案开头给出的命令。
左右的解决方案touch emptyfile不一定“创建零大小的文件”。如果面试官已经emptyfile在其中一个目录中创建了一个非空怎么办?陷阱!如果非空emptyfile存在,则touch既不会创建它,文件也不会为空。实际上,您将严格无法在带有陷阱的目录中“创建零大小文件”。这就是我使用mktemp. 该工具将努力真正创建一个新的空常规文件。
| 归档时间: |
|
| 查看次数: |
1878 次 |
| 最近记录: |