我使用“reprepro”从本地存储库获取最新的 Debian 软件包,手动操作效果很好。
现在我需要通过 cron 作业自动执行此过程,但 reprepro 密码是提示符。
是否有可能通过 bash 脚本发送密码?在 reprepro 手册页中找不到任何内容。
答案1
我需要同样的东西,正在寻找解决方案。除了运行gpg-agent
,它将只要求输入一次密码(例如在启动期间)并将其缓存以供下次使用,我什么也没找到。
问题是如何与交互式脚本进行交互,这些脚本要求从 stdin 获取用户输入。预计(apt-get install expect
)正好解决了这个问题。
这是我编写并保存在 /usr/local/bin/reprepro_expect 中的脚本:
#!/usr/bin/expect -f
set timeout 2
set passphrase "mysupersecretpassword"
spawn reprepro -b [lindex $argv 0] [lindex $argv 1] [lindex $argv 2] [lindex $argv 3]
expect {
"*passphrase:*" {
send -- "$passphrase\r"
}
}
expect {
"*passphrase:*" {
send -- "$passphrase\r"
}
}
interact
您可以像这样运行它:
reprepro_expect [path_to_repository] [command] [distribution] [package_name]
例如:
添加新包:
reprepro_expect /var/www/myrepo includedeb wheezy mypackage_0.1-1_all.deb
删除包
reprepro_expect /var/www/myrepo remove wheezy mypackage
安全性:由于您的私钥密码存储在脚本中,我建议将chown
其提供给用户,并在其下使用并将其设置为 500。为什么不将密码作为另一个参数传递?因为它将存储在 ~/.bash_history 中,并在运行时chmod
显示。ps axu
答案2
正如其他答案中提到的,expect
可以解决这个问题。我最终得到了类似这样的结果,保存reprepro.exp
并使其可执行chmod 755 reprepro.exp
#!/usr/bin/expect -f
set timeout 5
set passphrase "$env(SIGNING_PASSWORD)"
# Call reprepro with variable length arguments, so that this script
# takes the same arguments as the original program
spawn reprepro {*}$argv
expect {
timeout {send_error "\nFailed to get password prompt\n";
exit 1}
"Please enter passphrase*" {send -- "$passphrase\r";
send_user " *** entering passphrase ***";
exp_continue}
}
# Get the pid, spawnid, oserr and exitcode from the spawned reprepro command
set returnvalues [wait]
# Extract the reprepro exit code
set exitcode [lindex $returnvalues 3]
# Exit with the exitcode from reprepro (0 on success)
exit $exitcode
只有一个expect
语句意味着如果密码错误,它也会起作用(即不会崩溃)。然后 gpg 将要求输入密码三次,而 reprepro 将返回非 0 的退出代码。
您可以在 .bashrc 中导出环境变量SIGNING_PASSWORD
,或者在脚本中用真实密码替换它,或者执行其他操作。使用您需要的适当安全级别。
答案3
我的工作代码。我将另一个 bashscript 中的脚本回显到一个文件中,然后打开它。
#!/usr/bin/expect -f
set timeout 5
spawn reprepro -v -b $SCRIPT_DIR/repository/ubuntu includedeb $UBUNTUVERSION $DEBFILE
expect {
timeout {send_error \"\\nFailed to get password prompt\\n\";
exit 1}
\"Pass*\" {send -- \"$KEYPASSWD\\r\";
send_user \" *** entering passphrase ***\";
exp_continue}
}
# Get the pid, spawnid, oserr and exitcode from the spawned reprepro command
set returnvalues [wait]
# Extract the reprepro exit code
set exitcode [lindex $returnvalues 3]
# Exit with the exitcode from reprepro (0 on success)
exit $exitcode
不要忘记运行命令update-alternatives --set pinentry /usr/bin/pinentry-tty >/dev/null || gpg-connect-agent reloadagent /bye >/dev/null
,所以 reprepro 不想打开图形用户输入!
答案4
此答案适用于 ansible 用户。
我遇到了同样的问题,我创建了一个虚拟文件,对其进行了加密,然后gpg-agent
按照 mkudlacek 的建议使用它来缓存密码,但使用了 ansible expect 模块。我使用了以下任务:
- name: create test.txt, created a dummy file
file:
path: /test.txt
state: touch
mode: u=rw,g=rw,o=rw #!!! just for testing purposes
- name: encrypt file
expect:
command: gpg --pinentry-mode loopback --sign /test.txt
responses: 'Enter passphrase:': '{{ your_pw }}'
timeout: 60
您现在可以通过单独的任务添加 Reprepro 包并删除 test.txt 文件。