我在 Windows 上,并且有远程 Linux 服务器。我对它们都没有管理员权限。我有以下步骤/命令
cp C:/ ... /file.war C:/temp/update/file.war
sftp server
write password
cd /tmp
put file.war
exit
ssh server
write password
chmod 755 /tmp/file.war
pbrun -u server_user bash
cd /tomcat_location/webap
rm -r file
rm file.war
cp /tmp/file.war file.war
ps -ax | grep tomcat
kill -9 tomcat_pid
cd /tomcat_location/commands
./startup.sh
如果我在本地完成所有这些操作,我可以轻松地为其编写 shell/bash 脚本。但我在两台不同的计算机上。密码始终相同。pbrun 是使用我自己的密码切换用户的命令。
有没有简单的方法可以将其转换为单个脚本?它会要求输入密码并自动执行所有步骤。或者至少是重新启动 tomcat 的部分(sftp、chmod、删除和 copig 部分)?我无法安装任何新软件。我的本地电脑上安装了 java 8 和 perl。
我尝试使用 perl exec 进行了一些操作,但我不知道如何保持其 cmd 的状态。如果结果尽可能接近原始命令,那就太好了。
答案1
首先,弄清楚哪些命令可以自己执行某些操作,哪些命令需要子命令作为输入。例如,sftp
属于后一类——“sftp server”以下到“exit”的所有内容都是不是单独的顶级命令,而只是输入到标准输入'sftp' 进程。
因此,在您的脚本中,实际上只有 3 个命令需要执行:cp
、sftp
和ssh
。其他所有内容都是要输入到其标准输入 (stdin) 的文本。
在 Bash 脚本中,最常使用“heredoc”
<<EOF
将多行文本传递到程序的标准输入(尽管也可以使用其他方法)。在 Perl 脚本中,你可以使用它
open()
来启动一个进程 – 查找"-|"
和"|-"
特殊 MODE 值在perldoc-f 打开(“将文件句柄打开到命令中”部分)。在 Java 中,通过快速谷歌搜索,当您通过 Runtime.exec() 启动一个进程时,生成的 Process 对象具有令人困惑的名称
.getOutputStream()
,允许您写入其 stdin。
(即使在通过 ssh 运行的命令中,技术上也存在其他同一层——当您通过 pbrun 启动 bash 时,它还会通过 stdin 接收进一步的命令,因此您也可以<<
在那里使用另一个,但这可能没有必要。我仍然会尝试“从内而外”地自动化这一过程,即首先打开普布伦部分放入正在服务器上运行的脚本中。)
这密码提示sftp 和 ssh 都是例外,因为它专门处理交互式键盘输入即使stdin 来自其他来源。为了避免密码提示,理想情况下,你应该设置一种不涉及密码的身份验证方法,即公钥auth – 所有 SSH 客户端和服务器都支持此功能,并且不需要任何一方具有任何管理员权限(除非有人故意禁用它)。查找ssh-keygen
和authorized_keys
。
(通常我还会建议使用 OpenSSH 的内置“连接多路复用”功能,即-o ControlPath=...
相关选项,但您使用的是 Windows,我不确定该功能是否在 Windows 版本的 OpenSSH 上可用。但是,如果它确实有效,那么它还允许您启动单个“后台”连接,输入一次密码,然后通过该连接运行 SFTP 和 shell。)
还有另一种方法可以解决这个问题。你的目标不是“运行 sftp 命令”——你的目标是使用 SFTP 协议上传文件,而且您不需要 sftp 命令。您可以直接使用 Perl 或 Java 的 SSH/SFTP 客户端模块 - 然后您就可以像开发应用程序本身一样开发部署工具。
(对于 Java,沙石似乎很受欢迎,而学士有点过时了。Perl 有 Net::SSH2,在 Windows 上安装起来可能比较困难。)它们中的大多数甚至允许您通过同一个 SSH 连接同时使用 SFTP 和 shell 命令。