我当前正在运行命令:echo "hello world" | xargs curl http://localhost:8080/function/func_wordcount -d"
它获取标准输出echo "hello world"
,然后通过管道将其传递给func_wordcount
使用-d
选项。该-d
选项用于发送原始数据,myfunc_wordcount
接受原始数据输入并打印单词数和字母数。
例如,当我写入时,echo "hello" | xargs curl http://localhost:8080/function/func_wordcount -d"
输出为: 1, 5 表示有一个单词包含 5 个字母。
但是,当我尝试包含许多单词时,我收到错误。当我写入时,echo "hello world" | xargs curl http://localhost:8080/function/func_wordcount -d"
我得到输出 1, 5,然后是一个带有错误的换行符:curl: (6) could not resolve host: world
。所以我很确定当我使用该选项将标准输出转换为原始数据时,它会将 hello world 分成两个单词-d
。
另外,只是为了表明该函数无需管道和转换即可工作,当我运行函数时,curl http://localhost:8080/function/func_wordcount -d "hello world"
我得到 2, 11 显示有两个单词和 11 个字符。
我的问题是如何解决这个分裂问题。我觉得令人困惑的部分是为什么它只解析输入的前半部分并完成它,然后在第二部分抛出错误而不是只发送一块数据。我只能发送根本不由空格分隔的输入,因此功能的使用变得非常有限。
答案1
就是这样xargs
。它在其标准输入上接受一个单词列表(空白或换行符分隔,也理解某种形式的引用)并传递他们作为它运行的命令的参数。
在这里,如果您想hello word
作为一个参数传递给curl
,您需要:
echo '"hello world"' | xargs curl...
其中xargs
将它们理解为一种引用机制,以防止和"..."
之间的空格被视为参数分隔符。也理解and (与 POSIX shell 的方式不同)。hello
world
xargs
\
'...'
使用 GNU xargs
,您还可以指定分隔符。例如:
echo hello world | xargs -d '\n' curl...
只有换行符才会被理解为分隔符(而不是空格),并且引用机制被禁用。
这使您可以将每一行(而不是每个单词)的内容作为参数传递给命令。
虽然-d
在 GNU 之外很少受支持xargs
,-0
但它的另一个扩展(用于对 NUL 进行定界并禁用引号处理)得到了更广泛的支持。所以你也可以这样做:
echo hello world | tr '\n' '\0' | xargs -0 curl...
如果有多行输入,xargs
会将所有行作为单独的参数传递给curl
.如果您想curl
为每一行调用一个,您可以添加一个-n 1
选项。
您还可以使用:
echo hello world | xargs -I@@ curl... @@
这curl
对每一行调用一个,但请注意,前导空白被删除,并且xargs
仍然进行一些引号处理,因此应该避免任意数据。
答案2
xargs
从标准输入读取项目,分隔符空白(可以用双引号、单引号或反斜杠进行保护)或者 换行符,并使用任何初始参数执行该命令一次或多次,后跟从标准输入读取的项目。
即默认行为是输入中的任何空格都充当分隔符,因此hello world
确实会产生两个参数。
如果你希望 xargs 保持整行完整,请使用 `xargs -d '\n' (在 GNU xargs 中,我不记得其他的了)。
但是,这仍然会导致多行输入给出curl
多个参数。如果您想避免这种情况,并curl
为每个输入行运行一次命令,请使用xargs -d '\n' -n 1
.
如果您的输入仅包含一行,您不妨使用命令替换而不是管道:
curl http://... -d "$(echo "hello world")"