我正在尝试编写一个 ZSH 脚本,以便可以运行任意脚本(例如 JavaScript 应用程序)并在另一个应用程序(我的 IDE)中将脚本的输出作为文件打开。在这里,我的想法是调用它./myscript.sh $(node main.js)
。myscript.sh
现在的内容:
#!/bin/zsh
TEMPFILE=$(mktemp /tmp/atom.XXXX)
echo $1 > $TEMPFILE
ide --file=$TEMPFILE
我在线路上遇到了麻烦echo
。应用程序的输出是标记,因此其中包含各种空格、反引号、(单|双)引号、字母数字字符、符号和换行符。
我了解这些问题与应用程序输出中的反引号和引号种类有关。一些虚拟输出:
# Weightlifting Workout A
Bodyweight: 165
| Lift | ||| 1RM (lb) |
|---| ---:|---:|---:| :-- |
|**Squats**|100x5<br>*0.61xBW*|90x6<br>*0.55xBW*|80x8<br>*0.48xBW*|112.5 |
|**Deadlift**|250x2<br>*1.52xBW*|||257.1 |
我想解决办法是我需要在 周围包裹一些东西$1
,但不确定是什么。 JavaScript 输出中的换行符与echo
.
我尝试过./myscript.sh $(node main.js)
, ./myscript.sh "node main.js"
,的组合./myscript.sh "$(node main.js)"
与echo $1 > file
、echo $($1) > file
等
尝试将应用程序的输出作为 zsh 参数传递,或者将应用程序的名称作为 zsh 参数传递,然后 zsh 脚本执行应用程序的名称。
无法弄清楚如何在不遇到“命令未找到:node main.js”或“命令未找到:#”或类似错误的情况下正常工作。
答案1
你可以做到:
#! /bin/zsh -
TMPPREFIX=${TMPDIR:-/tmp}/atom.
(){ide --file=$1} =(print -r -- "$@")
并将其调用为:
that-script "$(cmd)"
需要引号,否则 shell 会分割$cmd
on 个$IFS
字符的输出。这仅适用于 NL、SPC、TAB 和 NUL(默认值$IFS
),引用字符、反引号等都不是问题。
但这比直接做更多的是打字:
ide --file =(cmd)
或者如果它必须ide --file=file
代替ide --file file
:
(){ide --file=$1} =(cmd)
=(cmd)
是 zsh 特定的进程替换形式,它使用临时文件而不是管道(for <(...)
)。(){code} args
是一个匿名函数。
$1
请注意,要输出后跟换行符的内容,语法为:
printf '%s\n' "$1" # POSIX
print -r -- "$1" # ksh/zsh
echo -E - $1 # zsh only
如果包含反斜杠或类似于, , ... 的内容,则Notecho $1
无法正常工作,参见$1
-n
-
-Enenne
为什么 printf 比 echo 更好?了解详情。
答案2
您的脚本已修改:
#!/bin/sh
TEMPFILE=$(mktemp /tmp/atom.XXXX)
cat >"$TEMPFILE"
ide --file="$TEMPFILE"
你可以用它作为
node main.js | ./myscript.sh
这会将命令的输出传递node
到脚本的标准输入。然后,该脚本只需将其标准输入重定向到临时文件。
或者,
#!/bin/sh
TEMPFILE=$(mktemp /tmp/atom.XXXX)
printf '%s\n' "$1" >"$TEMPFILE"
ide --file="$TEMPFILE"
并将脚本用作
./myscript "$( node main.js )"
(注意双引号和 的使用printf
)
我知道我在上面的示例中切换到了/bin/sh
,但您似乎没有使用任何特别高级的zsh
功能,所以我认为这样就可以了。
有关的: