分页: 2 / 2

Re: 书上学到的一条命令,将一个目录下的目录树,创建到另一个目录下,但有点不解。

发表于 : 2012-03-28 20:48
fnan
cao627 写了:看过了

代码: 全选

find  ....  -exec mkdir ....{} \;
看来find命令的作者是考虑到并解决了空格文件名带来的麻烦的
#避开了shell的空格分割,用引号也有这效果。

Re: 书上学到的一条命令,将一个目录下的目录树,创建到另一个目录下,但有点不解。

发表于 : 2012-03-28 21:12
lilydjwg
cao627 写了:

代码: 全选

mkdir -vp /home/someone/lt/Whitespace Matters
这条命令会这样执行:
在 /home/someone/lt/目录下创建Whitespace
在当前目录下创建Matters

如果{}只是简单把find找到的内容替换进来,那么我也会在执行find .... -exec mkdir ....{} \;后,在当前目录下生成类似Matters这种由于文件名空格产生的文件
但是没有,说明{}解决了这个问题,而{}是find的一部分,所以 说:“看来find命令的作者是考虑到并解决了空格文件名带来的麻烦的”
find 执行的是这样子的(源码未下载;以下是我的推测):
[c]
int i;
for(i = 0; strcmp(exec_cmd_args, ";") == 0; i++)
if(strcmp(exec_cmd_args, "{}") == 0)
exec_cmd_args = file_path;
exec_cmd_args = NULL;
execvp(exec_cmd_args[0], exec_cmd_args);
[/c]

所以 find 根本不用管文件名中的空格或者什么其它的东西。对于 C 字符串唯一特别的 NULL 字符不会出现在文件名中。

补充:你可以试试以下代码是否会出问题:
[c]
#include<unistd.h>

int main(int argc, char **argv){
execlp("mkdir", "mkdir", "-p", "some/dir contains whitespace", NULL);
return 0;
}
[/c]

Re: 书上学到的一条命令,将一个目录下的目录树,创建到另一个目录下,但有点不解。

发表于 : 2012-03-28 22:00
cao627
自由建客 写了:cao627, 你没理解那个道道
那个道道是是命令最后的\;吗?

\ 的作用是什么呢?

-exec command {} \; 是find命令的一部分吗? 即离开find命令 -exec command {} \;是否有意义?

Re: 书上学到的一条命令,将一个目录下的目录树,创建到另一个目录下,但有点不解。

发表于 : 2012-03-29 13:11
aerofox
cao627 写了:
自由建客 写了:cao627, 你没理解那个道道
那个道道是是命令最后的\;吗?

\ 的作用是什么呢?

-exec command {} \; 是find命令的一部分吗? 即离开find命令 -exec command {} \;是否有意义?
-exec command {} \; 是 find 命令的一部分。\ 的作用是防止 shell 对分号进行解释。

find 并没有刻意去处理文件名中的空格,相反,是 shell 刻意去处理空格,把空格当成参数之间的分隔符,所以才需要加引号。而 find 只是在 -exec 后面遇到 {} 时,把文件名原封不动的传给它调用的命令,而且 {} 对 shell 没有特殊含义,所以从不需要引号。

整个过程是,不管 {} 加不加引号,shell 都把不带引号的 {} 传给 find,然后 find 又把 {} 解释为文件名,换成文件名(不管里面有没有空格、方括号、问号等等对 shell 来说是特殊字符的东西)后,原样传给它启动的命令。

Re: 书上学到的一条命令,将一个目录下的目录树,创建到另一个目录下,但有点不解。

发表于 : 2012-03-29 20:57
自由建客
那个道道是是命令最后的\;吗?

\ 的作用是什么呢?

-exec command {} \; 是find命令的一部分吗? 即离开find命令 -exec command {} \;是否有意义?
剥洋葱一样,只要你明白哪些会被 shell 处理,哪些会被应用程序处理。
末尾的 \; 会被 shell 处理,传给 find 的只有分号。find 就以分号做命令分隔符。

Re: 书上学到的一条命令,将一个目录下的目录树,创建到另一个目录下,但有点不解。

发表于 : 2012-03-30 12:13
cao627
然后 find 又把 {} 解释为文件名,换成文件名(不管里面有没有空格、方括号、问号等等对 shell 来说是特殊字符的东西)后,原样传给它启动的命令。
问题是:

比如

用find命令找到唯一的文件夹/somedir/Whitespace Matters

继续 -exec mkdir /somepath {} \;

然后/somedir/Whitespace Matters会替换掉{}对吗?

然后mkdir命令执行的是 makdir /somepath/somedir/Whitespace Matters对吗

makdir /somepath/somedir/Whitespace Matters 会被shell解析成:

mkdir /somepath/somedir/Whitespace 和 mkdir Matters
即当前目录下莫名其妙被创建个Matters目录

但实验结果是只在/somepath/somedir/下创建’Whitespace Matters‘

如果你用管道把find 的结果传给 mkdir
那么就会在执行这条管道命令的当前目录下创建Matters了

问题是 find ... -exec mkdir /somepath/ {} \; 中Whitespace Matters问题是怎么被解决的?

13楼
find 并不会调用 shell,而是直接 execv,所以毫无问题
应该是在解释这个问题
似乎这样理解:
find查找到的内容使用-exec后并不是调用shell 把“表达”打印到屏幕上{}的位置
是经过execv直接把“观念”传给{}的
find 并没有刻意去处理文件名中的空格,相反,是 shell 刻意去处理空格,把空格当成参数之间的分隔符,所以才需要加引号。
看来aerofox 也在试图向我说明这点
但没有类比的描述,这个问题对于普通用户确实有点难说清的
谢谢

Re: 书上学到的一条命令,将一个目录下的目录树,创建到另一个目录下,但有点不解。

发表于 : 2012-03-30 14:48
lilydjwg
cao627 写了:
问题是:

比如

用find命令找到唯一的文件夹/somedir/Whitespace Matters

继续 -exec mkdir /somepath {} \;

然后/somedir/Whitespace Matters会替换掉{}对吗?

然后mkdir命令执行的是 makdir /somepath/somedir/Whitespace Matters对吗

makdir /somepath/somedir/Whitespace Matters 会被shell解析成:

mkdir /somepath/somedir/Whitespace 和 mkdir Matters
即当前目录下莫名其妙被创建个Matters目录

但实验结果是只在/somepath/somedir/下创建’Whitespace Matters‘

如果你用管道把find 的结果传给 mkdir
那么就会在执行这条管道命令的当前目录下创建Matters了

问题是 find ... -exec mkdir /somepath/ {} \; 中Whitespace Matters问题是怎么被解决的?

13楼
find 并不会调用 shell,而是直接 execv,所以毫无问题
应该是在解释这个问题
似乎这样理解:
find查找到的内容使用-exec后并不是调用shell 把“表达”打印到屏幕上{}的位置
是经过execv直接把“观念”传给{}的
你看了我在 17 楼贴的第二段代码没?

Re: 书上学到的一条命令,将一个目录下的目录树,创建到另一个目录下,但有点不解。

发表于 : 2012-03-30 15:07
cao627
你看了我在 17 楼贴的第二段代码没?
恩懂了
mkdir 并没有刻意去处理文件名中的空格,相反,是 shell 刻意去处理空格,把空格当成参数之间的分隔符,
mkdir /Whitespace Matters
是shell解释这条命令将Whitespace Matters中的空格做分割符了
而在find ... -exec mkdir {} \; (如果find ... 查找的结果是/Whitespace Matters)
执行mkdir时 shell已经不再介入,去误导mkdir “你先去/下创建Whitespace 然后再在当前目录创建Matters”
mkdir只是安安静静在执行它的本质 execlp("mkdir", "mkdir", "-p", "findout", NULL);