[英]How to activate an ssh-account in Bash function in BATS test?
As part of a Bash script that is tested using the BATS, I noticed that my tests are not terminated when I run a function that activates an ssh-account.作为使用 BATS 测试的 Bash 脚本的一部分,我注意到当我运行激活 ssh 帐户的 function 时,我的测试并未终止。
The following function assumes a private and public ssh key pair exists in /home/<username>/.ssh/
.以下 function 假定 /home/<username>/.ssh/ 中存在私有和公共
/home/<username>/.ssh/
密钥对。 If I run it manually using source src/the_bash_script.sh && activate_ssh_account <my_git_username>
, it works and says Identity added: /home/name/.ssh/<my_git_email>
:如果我使用
source src/the_bash_script.sh && activate_ssh_account <my_git_username>
手动运行它,它可以工作并Identity added: /home/name/.ssh/<my_git_email>
:
#!/bin/bash
# Activates/enables the ssh for
activate_ssh_account() {
git_username=$1
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/"$git_username"
}
However, when it is ran from the test with:但是,当它从测试中运行时:
#!./test/libs/bats/bin/bats
load 'libs/bats-support/load'
load 'libs/bats-assert/load'
# https://github.com/bats-core/bats-file#Index-of-all-functions
load 'libs/bats-file/load'
# https://github.com/bats-core/bats-assert#usage
load 'assert_utils'
source src/the_bash_script.sh
@test "Check if ssh-account is activated after activating it." {
activate_ssh_account "some_git_username"
assert_equal "Something" "Something_else"
}
It hangs indefinitely.它无限期地挂起。
How can I activate an ssh-account without causing the BATS tests to hang indefinitely?如何在不导致 BATS 测试无限期挂起的情况下激活 ssh 帐户?
The test hangs indefinitely because BATS waits for ssh-agent
to terminate (which runs in the background once line eval "$(ssh-agent -s)"
is executed).测试无限期挂起,因为 BATS 等待
ssh-agent
终止(一旦执行eval "$(ssh-agent -s)"
行,它将在后台运行)。 To be more specific, BATS waits for file descriptor 3 to be closed (which is being held open by ssh-agent
).更具体地说,BATS 等待文件描述符 3关闭(由
ssh-agent
保持打开状态)。
Thus, this can be solved by either implementing the workaround mentioned in the documentation or by killing ssh-agent
.因此,这可以通过实施文档中提到的解决方法或杀死
ssh-agent
来解决。
Workaround from documentation:文档中的解决方法:
#!/bin/bash
# Activates/enables the ssh for
activate_ssh_account() {
git_username=$1
eval "$(ssh-agent -s 3>&-)"
ssh-add ~/.ssh/"$git_username"
}
This closes fd 3 for ssh-agent
and BATS will no longer hang.这将关闭
ssh-agent
fd 3,并且 BATS 将不再挂起。 Note that this leaves ssh-agent
running in the background, even after BATS exits.请注意,这会使
ssh-agent
在后台运行,即使在 BATS 退出后也是如此。 It is unclear from your question if that is desired or not.从您的问题中不清楚是否需要这样做。 If it's not, use the alternative below.
如果不是,请使用下面的替代方法。
Kill ssh-agent
:杀死
ssh-agent
:
Add a cleanup trap to activate_ssh_account
:向
activate_ssh_account
添加清理陷阱:
#!/bin/bash
# Activates/enables the ssh for
activate_ssh_account() {
trap "trap - RETURN; kill \$SSH_AGENT_PID" RETURN
git_username=$1
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/"$git_username"
}
The trap is executed when the function exits and kills ssh-agent
using the pid exported by eval "$(ssh-agent -s)"
(ie variable SSH_AGENT_PID
).当 function 退出并使用
eval "$(ssh-agent -s)"
导出的 pid(即变量SSH_AGENT_PID
)杀死ssh-agent
时,将执行陷阱。
If you don't want to use a trap for some reason, this will also work:如果您出于某种原因不想使用陷阱,这也可以:
#!/bin/bash
# Activates/enables the ssh for
activate_ssh_account() {
git_username=$1
eval "$(ssh-agent -s)"
result=0
ssh-add ~/.ssh/"$git_username" || result=$?
kill $SSH_AGENT_PID
return $result
}
Note that the ||
注意
||
construct is necessary because BATS will stop executing the function's code once a command fails (ie without ||
, kill
will not be executed if ssh-add
fails).构造是必要的,因为一旦命令失败,BATS 将停止执行函数的代码(即没有
||
,如果ssh-add
失败,将不会执行kill
)。
As a side note, to actually test if activate_ssh_account
succeeds or fails, you should use assert_success
instead of assert_equal
(unless there is more code that you omitted in your question).作为旁注,要实际测试
activate_ssh_account
是成功还是失败,您应该使用assert_success
而不是assert_equal
(除非您在问题中省略了更多代码)。
I never used BATS but by reading the doc I can say that there is a specific command for sharing common code.我从未使用过 BATS,但通过阅读文档,我可以说有一个用于共享公共代码的特定命令。 You may need to specify the full path though:
您可能需要指定完整路径:
load
: Share common codeload
: 共享通用代码You may want to share common code across multiple test files.
您可能希望跨多个测试文件共享通用代码。 Bats includes a convenient load command for sourcing a Bash source file relative to the location of the current test file.
Bats 包含一个方便的加载命令,用于获取相对于当前测试文件位置的 Bash 源文件。 For example, if you have a Bats test in
test/foo.bats
, the command例如,如果您在
test/foo.bats
中有一个 Bats 测试,则该命令
load test_helper
will source the script test/test_helper.bash in your test file.
将在您的测试文件中获取脚本 test/test_helper.bash。 This can be useful for sharing functions to set up your environment or load fixtures.
这对于共享功能以设置您的环境或加载固定装置很有用。
Try replacing尝试更换
source src/the_bash_script.sh
with和
load '/full/path/to/src/the_bash_script.sh'
Try adding the sourcing in @test
尝试在
@test
中添加采购
@test "Check if ssh-account is activated after activating it." {
source /full/path/to/src/the_bash_script.sh
activate_ssh_account "some_git_username"
assert_equal "Something" "Something_else"
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.