我正在尝试使用以下方法将字符串文字读入标准输入:
#!/usr/bin/env bash
set -e;
gmx --stdin < `cat <<EOF
node e "console.log('foo')"
EOF`
当我运行这个时,我收到此错误:
simple.sh: line 5: `cat <<EOF
node e "console.log('foo')"
EOF`: ambiguous redirect
如果我去掉反引号,
gmx --stdin < cat <<EOF
node e "console.log('foo')"
EOF
我收到此错误:
/simple.sh: line 5: cat: No such file or directory
有人知道如何修复吗?如果不清楚我想做什么 - 我只是想将字符串文字读入 gmx 进程的标准输入中。
我也尝试过这个:
gmx --stdin <<< node e "console.log('foo')"
但这似乎不起作用,我可能需要将节点命令放在引号中,这违背了我想要做的事情的目的。我希望在命令中包含 shell 变量 - HEREDOC 很好,因为我不需要转义 " 字符。
答案1
原来的:
<
需要文件或文件描述符,而您在那里有命令替换,它将用文本字符串替换任何反引号。
出于您的目的,您最好使用流程替代在bash
。像这样:
gmx --stdin < <(node e "console.log('foo')")
或者为了清楚起见,另一个例子:
wc -l < <(df)
编辑:
要传递表示命令的字符串文字,您可以使用:
gmx --stdin <<< "$(echo node -e $'"console.log(\'foo\')"' )"
允许$'...'
C 引用,这就是\'foo\'
部分的作用。
这是基本上相同的示例,但用管道代替(如果命令需要可搜索的输入)
$ touch with\ space
$ echo stat $'\'with space\''
stat 'with space'
$ echo stat $'\'with space\'' | sh
File: with space
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: 801h/2049d Inode: 1069455 Links: 2
Access: (0755/drwxr-xr-x) Uid: ( 1000/ xie) Gid: ( 1000/ xie)
Access: 2018-05-07 05:01:37.638553045 +0800
Modify: 2018-05-07 05:01:37.638553045 +0800
Change: 2018-05-07 05:01:37.638553045 +0800
Birth: -
此外,还有一种处理 via 引用的方法printf %q
,其help printf
描述为:
以可重复用作 shell 输入的方式引用参数
所以潜在的解决方案是
printf '%q' 'node -e "conlose.log('foo')"' | gmx --stdin
或者
gmx --stdin <<< "$( printf '%q' 'node -e "conlose.log('foo')"' )"
答案2
事实证明,我所需要做的就是这样做:
gmx --stdin <<EOF
node e "console.log('foo')"
EOF
node
它将把以字符串开头的行读入 gmx 命令的标准输入中。