ZSH:如果输出包含换行符和其他特殊字符,如何将程序的输出回显到临时文件?

ZSH:如果输出包含换行符和其他特殊字符,如何将程序的输出回显到临时文件?

我正在尝试编写一个 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 > fileecho $($1) > file

尝试将应用程序的输出作为 zsh 参数传递,或者将应用程序的名称作为 zsh 参数传递,然后 zsh 脚本执行应用程序的名称。

无法弄清楚如何在不遇到“命令未找到:node main.js”或“命令未找到:#”或类似错误的情况下正常工作。

答案1

你可以做到:

#! /bin/zsh -
TMPPREFIX=${TMPDIR:-/tmp}/atom.
(){ide --file=$1} =(print -r -- "$@")

并将其调用为:

that-script "$(cmd)"

需要引号,否则 shell 会分割$cmdon 个$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功能,所以我认为这样就可以了。

有关的:

相关内容