我写了一个小服务脚本,在Finder上的任意文件夹上打开iTerm终端窗口。
我希望它检查iTerm是否正在运行,以及是否要在新标签中打开终端会话而不是现有标签。
脚本是这样的:
on run {input, parameters}
set cdPath to "cd " & (quoted form of POSIX path of (input as string))
if application "iTerm" is running then
display notification "running"
tell application "iTerm"
set termWin to (current terminal)
tell termWin
launch session "Default"
tell the last session
write text cdPath
end tell
end tell
end tell
else
display notification "not running"
tell application "iTerm"
activate
set termWin2 to (current terminal)
tell termWin2
tell the last session
write text cdPath
end tell
end tell
end tell
end if
return input
end run
问题是,当我将脚本作为服务运行时,它总是表现得好像iTerm已经在运行(显示“运行”通知),即使iTerm已经关闭且非常明显没有运行。
但是,如果我将相同的脚本粘贴到脚本编辑器(将cdPath设置为文字,如set cdPath to "cd /etc"
)并直接执行它,它将正常工作,打开一个新的iTerm实例或重用现有的实例并创建一个新选项卡,并显示相应的通知。
如果我将脚本简化为仅显示通知(如下所示删除tell aplication
块:
on run {input, parameters}
set cdPath to "cd " & (quoted form of POSIX path of (input as string))
if application "iTerm" is running then
display notification "running and path is " & cd
else
display notification "not running and path is " & cdPath
end if
return input
end run
它会按预期运行(相应地显示“正在运行”或“未运行”。)
但是,如果我添加“告诉应用程序”部分,它将始终通过“运行”分支,无论如何。
例如:
on run {input, parameters}
set cdPath to "cd " & (quoted form of POSIX path of (input as string))
if application "iTerm" is running then
display notification "running"
else
display notification "not running"
tell application "iTerm"
activate
end tell
end if
return input
end run
将始终打开iTerm(即使tell application "iTerm"
在“未运行”分支上,但显示“正在运行”分支中的“正在运行”通知...仅仅存在“告诉”应用程序“将触发打开应用程序,然后运行服务。
有没有办法规避这个?为什么“tell application”块会打开app,即使它位于条件的另一个分支上?
答案 0 :(得分:1)
使用"正在运行"正在导致一个tell块的运行。使用系统事件获取正在运行的进程的名称,以检查应用程序是否正在运行。以下是您最终脚本示例的重写,可以按照您的意愿使用。
on run {input, parameters}
set cdPath to "cd " & (quoted form of POSIX path of (input as string))
tell application "System Events" to set theProcesses to name of every process whose visible is true
if theProcesses contains "iTerm" then
display notification "running"
else
display notification "not running"
tell application "iTerm"
activate
end tell
end if
return input
end run
如果你仍然无法使用它(在运行OS X 10.11.1的机器上运行,那么你也可以在运行脚本中包含任何tell块的地方添加技巧,所以它永远不会编译到运行时。这是原始脚本,证明了这一点:
on run {input, parameters}
set cdPath to "cd " & (quoted form of POSIX path of (input as string))
tell application "System Events" to set theProcesses to name of every process
if theProcesses contains "iTerm" then
display notification "running"
run script "tell application \"iTerm\"
set termWin to (current terminal)
tell termWin
launch session \"Default\"
tell the last session
write text cdPath
end tell
end tell
end tell"
else
display notification "not running"
run script "tell application \"iTerm\"
activate
set termWin2 to (current terminal)
tell termWin2
tell the last session
write text cdPath
end tell
end tell
end tell"
end if
return input
end run
答案 1 :(得分:0)
我想我找到了一个解释:
在ScriptEditor,Automator和Safari中的服务中尝试此代码:
display notification "" & running of application "TextEdit"
tell application "TextEdit" to activate
quit application "TextEdit"
display notification "" & running of application "TextEdit"
您将从AppleScript / Automator(=> false + true )和Safari(true + true)获得不同的结果。
尤其是来自第二次通知的AppleScript / Automator的 true 非常有说服力
...但是,如果你在“退出”行之后插入一分钟延迟,比如0.01,则运行将被测试为“假” - 如果脚本是从AppleScript / Automator中运行的。