读取一行时,从 AppleScript 启动 Python 脚本会产生 EOFError 简单示例验证示例运行

如何解决读取一行时,从 AppleScript 启动 Python 脚本会产生 EOFError 简单示例验证示例运行

我希望使用 AppleScript 来启动一个 Python 脚本,它的前几行是:

x = datetime.datetime.now()
varyear = str(x.year)
varday = str(x.day).zfill(2)
varmonth = str(x.month).zfill(2)
dateStamp = varyear + '-' + varday + '-' + varmonth

userDate = ""

userDate = input("Enter date of Bookmap replay data as YYYY-DD-MM: ")

if userDate != "":
    dateStamp=userDate

从终端(在 Mac 上)运行 Python 脚本时,我没有问题:系统提示我输入日期,如果我不提供日期,脚本将使用当前日期。

但是,当从 AppleScript 启动 Python 脚本时,我无法提供输入,因为会立即抛出 EOF 错误。

我的整个 AppleScript 包括

do shell script "source ~/.bash_profile; python3 /PythonScript.py"

并且仅用作启动 Python 脚本的一种方式。

作为一种变通方法,我创建了一个带有文本 ExecutePythonScript.sh 的 shell 脚本 (python3 /PythonScript.py),然后调整了我的 AppleScript 以启动 shell 脚本:

do shell script "/ExecutePythonScript.sh"

不幸的是,AppleScript 和 Python 之间的这一额外距离并没有帮助。

有没有办法允许通过终端输入,即使从 AppleScript 启动?

如果没有,有没有办法通过 AppleScript 请求输入并将该输入传递给 Python 脚本?

出于好奇,我在启动 Python 之前使用 AppleScript 来执行其他函数(通过 Hammerspoon)。因此,AppleScript 正在充当各种需要发生的事情的中央命令。

感谢您的帮助。

解决方法

我不确定从 AppleScript 运行您的 py 脚本时发生了什么。这很可能是环境问题。尝试阅读:https://developer.apple.com/library/archive/technotes/tn2065/_index.html

编辑:如果你尝试会发生什么:

do shell script "/full/path/to/python3 /full/path/to/pythonScript.py"

要回答您的另一个问题,您可以将数据从 AppleScript 传递到其他脚本。假设您将一个值读入变量 input,并且您想将其作为参数提供给脚本 pyScript.py,您可以这样做:

do shell script "pyScript.py " & input

[注意:字符串中需要空格。]

另一种方法是构建脚本执行字符串并运行它:

set shellScript to "pyScript.py " & input
do shell script "shellScript"
,

我对 Hammerspoon 并不熟悉,但这里有几个例子需要考虑。

简单示例

考虑以下简单的 .py 示例,该示例通过 AppleScript 提示输入并将该输入传递回 Python 脚本。

python-script.py

import datetime
from subprocess import Popen,PIPE

x = datetime.datetime.now()
varyear = str(x.year)
varday = str(x.day).zfill(2)
varmonth = str(x.month).zfill(2)
dateStamp = varyear + '-' + varday + '-' + varmonth

userDate = ""

userDatePrompt = """
  on getDateFromUser()
    tell application "System Events"
      activate
      set mssg to "Enter date of Bookmap replay data as YYYY-DD-MM:"
      set usrPrompt to display dialog mssg default answer "" buttons {"Cancel","Continue"} default button "Continue"
      return text returned of usrPrompt
    end tell
  end getDateFromUser

  return getDateFromUser()
"""

proc = Popen(['osascript','-'],stdin=PIPE,stdout=PIPE,stderr=PIPE,universal_newlines=True)
userDate,error = proc.communicate(userDatePrompt)

userDate = userDate.split("\n")[0]

if userDate != "":
    dateStamp = userDate

说明

  • 这利用 Python 的 Popen.communicate() 实质上产生了一个调用 AppleScript 对话框的新进程 - 提示用户输入日期。

  • 用于提示对话框的 AppleScript 被分配给 userDatePrompt 变量。

  • 在用户输入某个值(假定为日期)后,它会被传递回 Python 脚本并分配给 userData 变量。

  • 注意下面一行:

    userDate = userDate.split("\n")[0]
    

    我们首先split分配给userDate变量的字符串,使用换行符\n作为分隔符,然后访问数组中的第一项(即在索引{{1 }}),然后检查该值是否为空字符串 (0)。我们这样做是为了确保如果用户要么;点击取消按钮,或点击继续按钮而不输入值,我们使用您的默认日期值(即今天/现在)

注意:上述脚本的主要问题是我们不以任何方式验证用户输入。例如,他们可以;输入 "",然后单击 Continue 按钮,我们的脚本会很高兴地假定分配给 foo bar quux 变量的值是一个有效日期。最终导致我们的程序在我们开始使用该值时在某处崩溃。


验证示例

以下更全面的示例 userDate 额外验证用户输入的值是否是符合 .py 的有效日期。

python-script.py

YYYY-DD-MM

说明

  • 这基本上与前面的(简单)示例相同,但它提供了额外的验证,所有验证都通过 AppleScript 处理。
  • 根据前面的示例,我们提示用户通过 import datetime from subprocess import Popen,PIPE x = datetime.datetime.now() varyear = str(x.year) varday = str(x.day).zfill(2) varmonth = str(x.month).zfill(2) dateStamp = varyear + '-' + varday + '-' + varmonth userDate = "" userDatePrompt = """ on dateIsValid(givenDate) set statusCode to do shell script "date -j -f \\"%Y-%d-%m\\" " & quoted form of givenDate & " > /dev/null 2>&1; echo $?" if statusCode is equal to "0" then return true else return false end if end dateIsValid on getDateFromUser() tell application "System Events" activate set mssg to "Enter date of Bookmap replay data as YYYY-DD-MM:" set usrPrompt to display dialog mssg default answer "" buttons {"Use Default Date","Continue"} default button "Continue" cancel button "Use Default Date" return text returned of usrPrompt end tell end getDateFromUser repeat set dateReceived to my getDateFromUser() set isValidDate to dateIsValid(dateReceived) try if isValidDate then exit repeat else error end if on error tell application "System Events" activate display dialog quote & dateReceived & quote & " is not a valid date." & return & return & "Please try again." buttons {"OK"} default button 1 with icon caution end tell end try end repeat return dateReceived """ proc = Popen(['osascript',error = proc.communicate(userDatePrompt) userDate = userDate.split("\n")[0] if userDate != "": dateStamp = userDate 函数输入日期。这次 取消 按钮已更改为 使用默认日期 以更好地表明它的实际作用。
  • 随后,我们通过 getDateFromUser 函数验证用户输入。此函数利用 shells date 实用程序/命令来检查日期是否符合 dateIsValid
  • 通过 repeat 语句,我们基本上反复提示用户,直到提供有效日期为止 - 仅在遇到有效日期时退出。

运行

  • 通过 AppleScript:

    类似于您的示例,要通过 AppleScript 运行 YYYY-DD-MM,请使用以下 do shell script 命令

    python-script.py
  • 通过终端:

    或通过终端运行:

    do shell script "source ~/.bash_profile; python3 ~/Desktop/python-script.py"
    

注意:路径名; source ~/.bash_profile; python3 ~/Desktop/python-script.py ,在两个示例中都需要根据需要重新定义。还给出了我的回答中提供的示例,~/Desktop/python-script.py 部分并不是绝对必要的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-