将 stderr 重定向到没有调试信息的变量

将 stderr 重定向到没有调试信息的变量

我想将此命令的标准错误保存到一个变量中。

printf "1\r" > /dev/cu.usbserial

stderr 是-bash: /dev/cu.usbserial: Permission denied。很好。

但是当我在 bash 脚本中运行此脚本时,变量前面会加上脚本名称和行号。我该如何阻止这种情况发生,并让它仅显示错误?我不想使用 sed 等来解析它。

var="$(printf "1\r" 2>&1 > /dev/cu.usbserial)"

$var就是现在:

/Users/elliott/Dropbox/scripts/switch1.sh: line 4: /dev/cu.usbserial: Permission denied

答案1

我不知道如何让解释脚本的 shell “忘记”它正在做这件事,或者从其错误消息中隐藏与脚本相关的诊断信息。然而,虽然这些上下文信息是通过 fork(进入子 shell)保留的,但它不会通过 exec(传递到新的shell 进程)。因此,以 fork/执行新的 shell 进程为代价,你可以这样做

var=$(sh -c 'printf "1\r" > /dev/cu.usbserial' 2>&1)

设置$var

sh: /dev/cu.usbserial: Permission denied

其特点sh -c有时会让人感到困惑(尤其是在使用时find … -exec sh -c "…" {} ";"),即附加命令行参数(在-c和新 shell 要运行的命令之后)将作为新 shell 的命令行参数, 从...开始$0  并被$0视为 shell/脚本名称,随后新 shell 会使用该名称作为错误消息的前缀。因此,

sh -c 'echo "Mellow rhymes with $2, but nothing rhymes with $1."; printf "1\r" > /dev/cu.usbserial' \
                                    red orange yellow

(为了便于阅读,将其分为两行)输出

Mellow rhymes with yellow, but nothing rhymes with orange.
red: /dev/cu.usbserial: Permission denied

因此,如果您愿意采取笨拙的黑客手段来让变量值以sh:或以外的其他值开头bash:,请使用

var=$(sh -c 'printf "1\r" > /dev/cu.usbserial' error 2>&1)

设置$var

error: /dev/cu.usbserial: Permission denied

(通过让 shell 认为其名称error)。

相关内容