我一直想学习AppleScript,所以我一直在尝试创建一个简单的脚本,当我从终端调用一个函数时,它将自动输入我的开发服务器并自动输入密码(I&# 39;我知道有更好的方法可以做到这一点,这只是一个练习。)
这是我的AppleScript:
tell application "Terminal"
activate
set SSH to "ssh git@server.local"
if (count of windows) is 0 then
do script SSH
else
do script SSH in window 1
end if
end tell
delay 2
tell application "System Events"
keystroke "somepassword"
keystroke return
end tell
当单击AppleScript编辑器中的“运行”按钮时,这非常有效,但是当尝试从终端(osascript ~/Desktop/ssh_dev.scpt
)调用它时,它不起作用。
ssh git@server.local出现在该行上,但未执行,而是中断为新行,这意味着"somepassword"
字符串出现在其下方。
在"somepassword"
字符串放入终端后,执行ssh命令并提示我输入密码。
任何帮助将不胜感激。
答案 0 :(得分:2)
duskwuff说:如果您的用例实际上是ssh登录,请使用公钥认证。
但是,更一般地说,您的工作方案与非工作方案之间的区别不在于它是从AppleScript编辑器还是从终端运行。它是从与ssh命令相同的窗口运行还是从不同的窗口运行。您可以通过删除if / else / endif使终端(总是打开一个窗口,至少在窗口中键入命令,从而永远不会有)从AppleScript编辑器中使该脚本在终端中工作计数为0)打开一个新的终端窗口,就像AppleScript编辑器一样:
tell application "Terminal"
activate
set SSH to "ssh git@server.local"
do script SSH
end tell
(** etc. **)
“在窗口1中执行脚本SSH”的问题是窗口1是脚本运行的终端。这意味着脚本必须在窗口1中完成,然后窗口1才能对给出的命令执行操作
但是当脚本完成时,密码已经被键入,并且ssh在请求密码数据之前不接受密码数据。当您通过慢速连接手动登录时,您可能已经看到类似的事情发生了。如果在ssh请求之前键入密码的开头,则ssh会忽略这些字符。
如果你愿意介绍这个过程,我可以想办法解决这个问题。如果您只是在命令的末尾添加一个&符号,它就会进入后台;这意味着终端现在正在接受输入。
osascript ~/Desktop/ssh_dev.scpt&
这有点笨拙,因为您也可以键入终端,并且可以在2秒延迟之前轻松输入,抢占AppleScript键入的文本。但它会奏效。
同样,如果您不依赖于使用osascript和文本文件,则可以将脚本保存为应用程序集以保持打开状态,然后将密码注入到空闲处理程序中。然而,这远远超出了您要求的条件。
另一个选择可能是调查“期望”(使用“男人期望”)。您应该能够在AppleScript中构建一个 expect 命令行,该命令行将成功地为ssh提供密码,但是为此目的,这个命令变得非常复杂。
答案 1 :(得分:0)
如果您已将终端作为“活动”窗口,则:
缺少tell process
,可能是问题
tell application "System Events" to tell process "Terminal"
keystroke "somepassword" as text
key code 36 -- return
end tell
这是一种方法。
此外,当您运行终端脚本时,您可以先说do script
,然后您要运行的所有脚本应为do script "blah" in window 1
或in front window
或另一个建议,虽然这是未经测试的......
tell application "Terminal"
activate
do script "ssh git@server.local"
do script "somepassword" in front window
end tell
那应该只运行“somepassword”脚本,如果你输入了那个并按下回车...(我认为)
回应: “我对这个解决方案的问题是,当它从终端运行时,它会打开一个新的终端窗口来运行命令(可以工作),但是我希望命令在当前的终端窗口中运行。有什么想法吗? “
try
do script "" in front window
on error
do script ""
end try
这将在前窗口中执行该脚本(如果存在)。如果没有,那么它将开启一个新的。