GNU和BSD版本的xargs 分隔符不同

2023-12-18 15:51:04 浏览数 (2)

例子: list="a b c d e"; echo $list |xargs -n1 -I{} echo begin {} end

在Mac上执行结果: begin a end begin b end begin c end begin d end begin e end

在Linux上执行结果: begin a b c d e end

我这里的需求是有一堆输入,要分别以其为参数,执行一些命令,无论是否成功都要对所 有目标执行,所以 1 “一些命令”我选用shell function来实现,在其中读了$1作为本次处理的目标 2 “所有目标”我选用xargs;如果选Parallel还得额外安装

结果发现xargs在切分“以空格为分隔符”的字符串的时候,GNU版本默认不切分,结果把 整个“含空格分隔符的字符串”传给函数,执行了一次,而函数里又选了$1作为本次执行 目标,其综合结果就是只对列表中第一个目标执行了一遍

更惨的是我对比的时候是在Mac上做的对比,怎么看怎么顺眼……

最后请教同事,用xargs的-d参数解决的

代码语言:javascript复制
   This  manual page documents the GNU version of xargs.  xargs reads items from the standard input, delimited by blanks (which can be protected with double or single quotes or a backslash) or newlines

GNU xargs的manpage说支持blanks 按说空格也应该可以啊…… xargs.c的read_line函数里:

代码语言:text复制
  893           /* POSIX: In the POSIX locale, the separators are <SPC> and 
  894            * <TAB>, but not <FF> or <VT>. 
  895            */ 
  896           if (!bc_ctl.replace_pat && ISBLANK (c)) 
  897             { 
  898               *p   = ''; 
  899               len = p - linebuf; 
  900               if (EOF_STR (linebuf)) 
  901                 { 
  902                   eof = true; 
  903                   return first ? -1 : len; 
  904                 } 
  905               bc_push_arg (&bc_ctl, &bc_state, 
  906                            linebuf, len, 
  907                            NULL, 0, 
  908                            initial_args); 
  909               p = linebuf; 
  910               state = SPACE; 
  911               first = false; 
  912               continue; 
  913             } 

这一段状态机代码应该是“之前读到了普通字符,这次读到了空格”的处理,这时候应该把已经读到的这一段作为一个参数加到列表里去 

看它的判断条件if (!bc_ctl.replace_pat && ISBLANK (c))  其实是要求没用-i/-I参数,且本次读到的字符为空白

验证一下,去掉-i之后:

echo a b c d e |xargs -n1  echo begin {} end  运行结果就几乎正确了。虽然丧失了使用占位符的能力,但至少它确实按照空格进行分割了  begin {} end a  begin {} end b  begin {} end c  begin {} end d  begin {} end e  我觉得这个判断条件就是个bug。但是有网友指出:按照POSIX标准、GNU xargs的文档,开启-I就是强制一整行的,我的用法不清真。对此我只能说:满足标准但是不满足需求啊,为什么输出端的参数会影响输入端的行为呢?

0 人点赞