我正在开发Applescript,以使登录2因素身份验证域变得更加容易。长话短说,我想轮询当前会话的内容,并在出现用户名/密码/令牌代码时立即输入用户名/密码/令牌代码,而不是使用延迟和发送文本。幸运的是,iTerm v3。X有一堆很酷的AppleScript东西:https://www.iterm2.com/documentation-scripting.html
但是我在阅读终端会话的内容时遇到了很多麻烦。这是我到目前为止得到的:
on run
# Start or activate iTerm
tell application "iTerm"
activate
tell the first window
# Create a new tab, which will create a new session inside
set newTab to (create tab with default profile)
tell newTab
# Since we just created the tab, there should only be one session right now.
repeat with aSession in sessions
tell aSession
delay 3
#set myvar to (tty)
#set myvar to (text)
set myvar to (contents)
#do shell script "echo " & myvar & " >> ~/some_file.txt"
#write text (contents)
end tell
end repeat
end tell
end tell
end tell
return myvar
end run
如您所见,我已经尝试了几种不同的东西,根据文档,"内容"似乎是最有希望的解决方案,但是出现了疯狂的东西,如下所示:
session id "0986F3BD-D2AF-480F-B517-AB7A43B2A0C4" of tab 3 of window id "window-1" of application "iTerm"
这是什么东西?为什么我看不到我所期望的,它是这样的:
Last login: Fri Jun 10 18:18:22 on ttys001
me@MacBook-Pro:~|⇒
我连续工作了 3-5 次,但是一旦我再次编辑我的脚本,它就开始返回会话 ID 的东西。在这一点上,我认为Applescript或iTerm的Applescript API太不透明了。我敲定了一个实际上似乎效果很好的解决方法,这里适用于任何在我之后的人:
on grepCountsFor(searchString)
set terminalContents to my getContents()
log "terminal contents: " & terminalContents
set oneline to ""
set allRecords to paragraphs of terminalContents
repeat with aRecord in allRecords
if length of aRecord is greater than 0 then
set variable to aRecord
log "variable: " & variable
set oneline to oneline & variable
end if
end repeat
log "oneline: " & oneline
set command to "echo "" & oneline & "" | grep -o "" & searchString & "" | wc -l"
log "command: " & command
set counts to do shell script command
return counts as number
end grepCountsFor
on getContents()
#iTerm needs to be in the front for key presses to register.
my waitForWindow("iTerm")
# Mush buttons in the app
tell application "System Events"
keystroke "a" using command down
keystroke "c" using command down
set sessionContents to do shell script "pbpaste"
end tell
return sessionContents
end getContents
# Waits for a window to come into focus
on waitForWindow(appName)
# Poll until "appName" is the active window
set activeApp to "noApp"
repeat until activeApp is appName
set activeApp to (path to frontmost application as Unicode text)
# If the active app name does not contain the target,
# try to activate it again.
if appName is not in activeApp then
tell application appName
activate
end tell
else
# Done
exit repeat
end if
delay 0.1
end repeat
end waitForWindow