前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >GNU和BSD版本的xargs 分隔符不同

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

作者头像
julyclyde
发布2023-12-18 15:51:04
1200
发布2023-12-18 15:51:04
举报

例子: 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++ = '\0'; 
  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就是强制一整行的,我的用法不清真。对此我只能说:满足标准但是不满足需求啊,为什么输出端的参数会影响输入端的行为呢?

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-01-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档