我正在使用Elixir的瓷器来调用shell脚本,在那里我有如下命令:
#!/usr/bin/env bash
aws s3 sync frontend/dist s3://$S3_BUCKET --delete
echo
现在,如果命令失败(因为存储桶错误),则会显示:
致命错误:调用时发生错误(InvalidBucketName) ListObjects操作:指定的存储桶无效。
但不会将这个致命的“致命错误”消息归还给瓷器。我怎样才能回复这个错误?
修改 瓷器代码:
Porcelain.shell(". #{Path.join(:code.priv_dir(:hub), "scripts/copy_site_to_s3.sh")}")
我知道可能的解决方案是使用exec
而不是shell
,但这更像是一个例子,我有一些稍微复杂但类似的shell脚本,面临同样的问题。
另一个脚本/示例(我正在测试失败):
调用:
result = Porcelain.shell(". #{Path.join(:code.priv_dir(:hub),
"scripts/git_clone_pull.sh")} #{github}"
)
IO.inspect result
脚本:
if cd frontend; then git reset --hard && git pull; else git clone $1 frontend; fi
它正确地失败了:
致命:身份验证失败 'https://github.com/x/frontend.git/'
但瓷器结果无法捕捉到信息:
%Porcelain.Result{err: nil, out: "", status: 128}
答案 0 :(得分:4)
如果您要查看Porcelain.{exec,shell}/3
options的文档,您会看到:
使用
:err
- 指定stderr传递回Elixir的方式 可能的值与:out
的值相同。此外,它接受原子:out
,表示将stderr
重定向到stdout
。Porcelain.Driver.Basic
时警告:,唯一支持的值是
nil
(stderr
将打印到终端)和{{1 }} 强>
重点是我的。在没有涉及:out
和任何其他3个 rd 方的情况下,可以在不那么繁琐的环境中轻松证明这一警告:
AWS
但我们仍有iex|1 ▶ Porcelain.shell("ls --gg", err: {:append, "error.log"})
#⇒ ls: unrecognized option '--gg'
# Try 'ls --help' for more information.
# %Porcelain.Result{err: {:append, "error.log"}, out: "", status: 2}
iex|2 ▶ ls "error.log"
# [ERROR] No such file or directory error.log
选项!
:out
Naya,幸运的是,iex|3 ▶ Porcelain.shell(">&2 echo 'error'", err: :out)
%Porcelain.Result{err: :out, out: "error\n", status: 0}
iex|4 ▶ Porcelain.shell("ls --gg", err: :out)
%Porcelain.Result{
err: :out,
out: "ls: unrecognized option '--gg'\nTry 'ls --help' for more information.\n",
status: 2
}
驱动程序可能会将Basic
重定向到:err
。也就是说,您有两种选择:
:out
参数,模式匹配到err: :out
并检查标准输出,或者:Porcelain.Driver.Goon
驱动程序并像profi一样处理您的when status > 0
信息流。