xargs 和命令替换问题

xargs and command substition issues

所以,我有一个可怕的 oneliner,它获取一个 json 值,使用 jq 从中提取数据,然后使用 xargs 迭代数据。最后它应该产生一些 xml

legendary list-installed --json | jq '.[].title' | sed s/"\""/""/g | xargs -n1 -p -d "\n" -I {} echo '<button onclick="'$(legendary list-installed --json | jq 'map(if .title == "'{}'" then .app_name elif .title == "_" then "_" else "_" end)')'">'{}'</button>'

首先,我没有在 jq 中使用 -r 标志,因为我认为问题可能出在它身上。

预期的输出应该是这样的:

<button onclick=app name e.g. Coley> The Escapist 2 </button>

到目前为止一切正常(应用程序名称部分除外,因为那是它开始变得奇怪的地方)

因为我几乎无法在命令替换中使用 jq 进行调试,所以我想测试通过另一个命令替换将什么 xargs 传递到标准输入。我将两个按钮元素 {} 之间的部分更改为 $(echo {}),仍然有效。但是我不小心将它传送到 wc -w,如果 {} 的内容实际上是两个,它会输出一个!

❯ ./test.sh
<layout>
echo 'button onclick="[' '"_",' '"_",' '"_"' ']">Ape Out</button>' ?...^C⏎                                                                                                                                           
> cat test.sh
...'$(echo {})'</button>'

如果我只是回显 {} 的内容,它 return 就是这样(我知道那是无用的回显,只是为了保持一致性): 当我计算 shell 中的字数时,而不是 xargs

中的字数
legendary list-installed --json | jq '.[].title' | head -n 1 | sed s/"\""/""/g | wc -w

它 return 两个。

运行的输出set -x

❯ ./test.sh
+ echo '<layout>'
<layout>
+ legendary list-installed --json
+ jq '.[].title'
+ sed 's/"//g'
++ legendary list-installed --json
++ jq 'map(if .title == "{}" then .app_name elif .title == "_" then "_" else "_" end)'
++ echo '{}'
++ tee lolsu,txt
+ xargs -n1 -p -d '\n' -I '{}' echo 'button onclick="[' '"_",' '"_",' '"_"' ']">{}</button>'
echo 'button onclick="[' '"_",' '"_",' '"_"' ']">Ape Out</button>' ?...

似乎它没有被正确替换...新问题是我如何让它在替换内部用真实的 {} 替换。

TLDR: 计算 xargs returns 的值一个,而管道输入应该是两个词(因为我迭代的是行而不是词) 当 运行 in shell 它 return 两个(不使用 xargs,obv)

写的时候

$(echo {} | wc -w)`

wc -w 命令的输入是字符串 {}。那是一个词,所以结果是 1,然后用它代替 $(echo {} | wc -w)。它 而不是 替换 xargs 中的任何内容,因为首先执行命令替换,然后将结果替换到命令行中。

所以 xargs 收到的参数包含这个 1 已经被替换。