我有这个代码巴什脚本:
r2g(){
echo "executable is: $0" # "/bin/bash"
(
set -e;
r2g_internal "$@" \
2> >( while read line; do echo "r2g error: $line"; done ) \
1> >( while read line; do echo "r2g: $line"; done )
)
exit_code="$?"
if [[ "$exit_code" != "0" ]]; then
echo "something experienced an error, to see log, run: r2g_view_log";
return 1;
fi
}
发生的情况是,r2g_internal
运行后,sh 由某个进程启动,它显然试图为 bash 环境提供资源,我从 sh 中得到了他奇怪的语法错误:
r2g error: sh: r2g: line 2: syntax error near unexpected token `>'
r2g error: sh: r2g: line 2: ` r2g_internal "$@" 2> >( while read line; do echo "r2g error: $line"; done ) > >( while read line; do echo "r2g: $line"; done ) );'
r2g error: sh: error importing function definition for `r2g'
我制作了一个视频来演示这个问题: https://www.uselooom.com/share/82f23ebfe6754412a20be057957e45f4
以及后续视频: https://www.uselooom.com/share/0465c2857cc244879b52b7bdb516243e
运行时npm install
,某些sh
进程必须由 .. 启动npm
。有时,当我运行 git 命令时git
,似乎也会启动一个sh
进程,并且在这种情况下,终端中会显示相同类型的语法错误。
我不明白为什么通过 bash 启动的 sh 进程会尝试从父 shell/env 获取一些 bash 代码?
该视频使问题更加清晰(我希望)。
如果我打电话unset -f r2g
,问题就会立即消失。所以我猜/bin/sh
正在调用我的 r2g 函数,但我不知道如何或为什么。
这是 r2g 和 r2g_internal 的源代码: https://gist.github.com/ORESoftware/0fa7e3d6b75a65b17b6b126a7bec3397
答案1
这可能无法解决您的问题,只需花点时间做一些笔记,评论太长了:
如果您不需要这样做,请不要这样做结构您的代码作为一行,我引用:
r2g_internal "$@" 2> >( while read line; do echo "r2g error: $line"; done ) 1> >( while read line; do echo "r2g: $line"; done )
对于其他人来说,甚至对你来说,我怀疑它都是难以阅读的。
我将从头开始:
我没有看到舍邦喜欢:
#!/bin/bash
或者
#!/bin/sh
等等。
如果您不需要 Bash,但此 shell 脚本似乎需要它,请使用POSIX
sh
出于便携性目的。由于
exit_code
仅使用一次,因此您可以避免它。您无需始终引用数字。在这种情况下
"$?"
。避免 Bash 特定的
[[ .. ]]
,并使用经典的测试命令。在这种情况下:if [ $? -ne 0 ]
您不需要在行尾添加分号,您可以使用如下结构:
if [ $? -ne 0 ] then echo "something experienced an error, to see log, run: r2g_view_log" return 1 fi
使用
-r
开关与read
.阅读有关此主题的更多信息这里。我还做了一些调整,请检查一下。
我不确定这是否是故意的,但我想不是故意的;
return 1
从我看来,你用过的地方应该是exit 1
。这舍邦可以包含
set -e
如下内容:#!/bin/bash -e
根据上面重写:
#!/bin/bash -e
r2g()
{
echo "executable name is: $0"
r2g_internal "$@" 2> >( while read -r line; do echo "r2g error: $line"; done ) >( while read -r line; do echo "r2g: $line"; done )
if [ $? -ne 0 ]
then
echo "something experienced an error, to see log, run: r2g_view_log"
exit 1
fi
}
答案2
无意冒犯,但您是否尝试过阅读并理解错误消息:
意外标记 ` 附近出现语法错误>'
它明确告诉您的代码包含明显的错误:2> >(
。 '>' 是将标准输出直接写入文件。您正在尝试将 r2g_internal 的输出定向到从标准输入读取的脚本。您必须使用 '|'而不是'>'。
还有一个错误 - 您可以将 stdout 和 stderr 定向到单独的文件,但不能轻松地将它们定向到单独的脚本。您必须先将它们写入文件,然后单独处理它们。
r2g_internal "$@" 1> stdout.txt 2> stderr.txt
cat stderr.txt | ( while read line; do echo "r2g error: $line"; done )
cat stdout.txt | ( while read line; do echo "r2g: $line"; done )