背景
我对 Linux 非常陌生,所以如果这不是主题,或者我使用了错误的术语,请提前道歉,ETC。
我正在编写一个 shell 脚本,通过从 node.js 项目调用 Powershell 在 Ubuntu/WSL 上执行。我传递一个包含命令的字符串wsl
以及我尝试运行到 PowerShell 模块的 shell 脚本的路径,如下所示
新的 PowerShell("wsl ./lpass.sh")
问题
shell脚本能够完美运行,但是,我有一行代码需要运行时将输入传递到命令提示符。这行代码向服务器发送登录请求,然后服务器做出响应,提示用户输入密码。当我仅用这一行调用脚本时,我已经能够使这一行代码正常工作,在出现提示时将用户输入传递给命令。这就是lpass.sh
当我让命令以我想要的方式工作时文件的样子。
#!/bin/sh
echo 'Password' | LPASS_DISABLE_PINENTRY=1 lpass login --force [email protected]
通过以这种方式配置文件,我只需从 PowerShell 命令行调用脚本即可登录到我想要的 LastPass 帐户。使用管道,我的密码将被传递并在提升时作为命令提示符的输入输入。然而,显然,我想做的不仅仅是通过 LastPass 的 CLI 登录帐户。
我希望能够做的是,登录 LastPass 帐户,然后在登录后通过 LastPass CLI 执行更多操作。我希望该lpass.sh
文件包含更多命令和代码,而不仅仅是一行,例如所以...
#!/bin/sh
echo 'Test' | LPASS_DISABLE_PINENTRY=1 lpass login --force [email protected]
lpass show -G -x --json poopy | jq '.' > poopy.json
问题是,如果我运行如上所示的文件,命令提示符不会在管道之前接受我的输入,因此不会将我登录到 LastPass 帐户。之后的命令似乎工作正常,但我不确定结果,因为如果不登录 LastPass,我无法执行该命令。
问题
如何编写 shell 脚本,以便我的第一行在echo "password" | lpass login
管道之前接受输入,但其中也包含多行代码?是否有某处或某些内容描述了命令提示符如何与脚本的其余部分交互/shell 脚本如何执行?我找到了一些有关 shell 脚本的文档这里和其他一些地方,但是我正在努力寻找我遇到的确切问题。或者更好的是,我真正感兴趣的是,命令提示符如何通过脚本与 shell 进行交互,以及 shell 如何执行/运行/调试导致命令无法在更多行代码中正常运行的脚本在它之后。
答案1
将 lasspass 主密码嵌入到随机脚本中通常是一个糟糕的主意,这些脚本可能会错误地提交到 github 或作为法律发现过程的一部分发送到其他地方,或者被某些 bloatenschlaag 浏览器中运行的 JavaScript 捕获。考虑到这一点...
根据lpass(1)
手册页,密码可以在标准输入上接受:
如果 pinentry 程序不可用,或者 LPASS_DISABLE_PINENTRY 环境变量设置为 1,将从标准输入读取密码,并在标准错误上显示提示。
这在实践中似乎有点挑剔,尽管最终我能够得到类似的东西
printf 'Hunter2' |
LPASS_DISABLE_PINENTRY=1 lpass login [email protected]
从命令行工作。您可能想要检查退出状态字(被壳咬碎到$?
变量中)以查看命令是否确实有效,并在非零退出时使脚本失败。
另一种选择是设置LPASS_ASKPASS
哪个程序应该将密码生成到标准输出,但这或多或少与上面的相同。
lpass
可能会让一个小守护进程默认运行;这可能会使事情变得复杂。您可以通过导出 到运行LPASS_AGENT_DISABLE=1
该命令的环境来禁用它。或者,使用查看是否应输入密码:lpass
lpass status
$ lpass status
Not logged in.
$ echo $?
1
其他密码程序可能会读取,/dev/tty
在这种情况下,您通常需要expect
与程序交互之类的东西,因为在这种情况下将不会使用标准输入。相关程序可能会或可能不会记录这一事实。
无论如何,完整的 Lastpass shell 脚本可能如下所示,仅在必要时登录。它可以进行更多的错误检查,例如捕获登录或状态命令的结果,并在出现问题时显示信息,而不是默认隐藏它。
#!/bin/sh
lpasslogin() {
printf 'Hunter2' |
LPASS_DISABLE_PINENTRY=1 lpass login --force [email protected] >/dev/null 2>&1
}
lpassup() {
lpass status >/dev/null || lpasslogin
status=$?
if [ $status -ne 0 ]; then
printf >&2 "lpass login failed\n"
exit $status
fi
}
lpassup
# account creation for testing
printf "Username: test\nPassword: Hunter2" |
lpass add test --non-interactive
# and now testing (`jq` might not be doing much here?)
#lpass show -G -x --json test | jq . > test.json