applescript 将文本传递给 python 脚本---stdout 的位被截断
applescript pass text to python script---bits of stdout get truncated
我正在尝试使用 applescript 将字符串传递给 python 脚本(我的最终用途是处理来自 icloud 的笔记)。然而,出于某种原因,当我尝试使用 print 语句进行测试时,它会产生奇怪的结果。
这是 applescript:
set s to "here is a
long string
with
line breaks"
do shell script "python t3.py " & quoted form of s
这里是 t3.py:
import sys
print("about to print whole argument list")
print(sys.argv)
print("printed whole argument list")
当我调用调用 python 脚本的 applescript 时,打印出一些非常奇怪的东西:
printed whole argument listng string\n\nwith\n\nline breaks']
但是,如果我注释掉 python 脚本的最后一行,它会打印:['t3.py', 'here is a \n\nlong string\n\nwith\n\nline breaks']
这是最接近正确的(它只会删除预期打印中的第一个)。
我的第一个假设是,这是 Python 端的某种流缓冲,所以我在每个打印调用中添加了 flush=True
。输出无变化。
这到底是怎么回事?我正在使用 python 3.6.4.
您 运行 遇到文本换行符编码不一致的麻烦。不同的 OSes 以不同的方式表示文本中的行尾:unix(和 unix 衍生产品,如 macOS)使用换行符(有时写为 \n
); DOS(和衍生行Windows)使用换行符后跟回车符return(\n\r
);和老式 Mac OS(在 OS X 之前)只使用马车 return (\r
).
AppleScript 可以追溯到 OS Mac OS 之前的 X 天,并且仍然使用回车符 return。它 有时 在与 OS 的其余部分交谈时翻译 to/from unix 约定,但并非总是如此。这里发生的是,您的 python 脚本正在生成带有换行符的输出,AppleScript 的 do shell script
命令正在捕获其输出并转换为回车符 return 约定,并且它永远不会转换回来。当它被发送到终端时,回车 returns 使它返回到第 1 列,但不会返回到下一行,因此每个 "line" 输出都打印在最后一个输出之上。
如何解决这个问题(或者它是否需要修复)取决于更大的上下文,即您实际要对输出执行的操作。在许多情况下(包括仅 运行 它在命令行上),您可以通过 tr '\r' '\n\
管道输出以将输出中的回车符 return 转换回换行符:
$ osascript t3.applescript
printed whole argument listg string\n\nwith\n\nline breaks']
$ osascript t3.applescript | tr '\r' '\n'
about to print whole argument list
['t3.py', 'here is a\n\nlong string\n\nwith\n\nline breaks']
printed whole argument list
编辑:至于如何让 AppleScript 生成带有 unix 样式定界符的结果...我没有看到简单的方法,但是您可以使用文本替换功能 从 CR 转换低频:
on replaceText(find, replace, subject)
set prevTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to find
set subject to text items of subject
set text item delimiters of AppleScript to replace
set subject to subject as text
set text item delimiters of AppleScript to prevTIDs
return subject
end replaceText
set s to "here is a
long string
with
line breaks"
set CRstring to do shell script "python t3.py " & quoted form of s
set LFstring to replaceText("\r", "\n", CRstring)
你也可以做一个特殊用途的函数:
on CR2LF(subject)
set prevTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to "\r"
set subject to text items of subject
set text item delimiters of AppleScript to "\n"
set subject to subject as text
set text item delimiters of AppleScript to prevTIDs
return subject
end CR2LF
我正在尝试使用 applescript 将字符串传递给 python 脚本(我的最终用途是处理来自 icloud 的笔记)。然而,出于某种原因,当我尝试使用 print 语句进行测试时,它会产生奇怪的结果。
这是 applescript:
set s to "here is a
long string
with
line breaks"
do shell script "python t3.py " & quoted form of s
这里是 t3.py:
import sys
print("about to print whole argument list")
print(sys.argv)
print("printed whole argument list")
当我调用调用 python 脚本的 applescript 时,打印出一些非常奇怪的东西:
printed whole argument listng string\n\nwith\n\nline breaks']
但是,如果我注释掉 python 脚本的最后一行,它会打印:['t3.py', 'here is a \n\nlong string\n\nwith\n\nline breaks']
这是最接近正确的(它只会删除预期打印中的第一个)。
我的第一个假设是,这是 Python 端的某种流缓冲,所以我在每个打印调用中添加了 flush=True
。输出无变化。
这到底是怎么回事?我正在使用 python 3.6.4.
您 运行 遇到文本换行符编码不一致的麻烦。不同的 OSes 以不同的方式表示文本中的行尾:unix(和 unix 衍生产品,如 macOS)使用换行符(有时写为 \n
); DOS(和衍生行Windows)使用换行符后跟回车符return(\n\r
);和老式 Mac OS(在 OS X 之前)只使用马车 return (\r
).
AppleScript 可以追溯到 OS Mac OS 之前的 X 天,并且仍然使用回车符 return。它 有时 在与 OS 的其余部分交谈时翻译 to/from unix 约定,但并非总是如此。这里发生的是,您的 python 脚本正在生成带有换行符的输出,AppleScript 的 do shell script
命令正在捕获其输出并转换为回车符 return 约定,并且它永远不会转换回来。当它被发送到终端时,回车 returns 使它返回到第 1 列,但不会返回到下一行,因此每个 "line" 输出都打印在最后一个输出之上。
如何解决这个问题(或者它是否需要修复)取决于更大的上下文,即您实际要对输出执行的操作。在许多情况下(包括仅 运行 它在命令行上),您可以通过 tr '\r' '\n\
管道输出以将输出中的回车符 return 转换回换行符:
$ osascript t3.applescript
printed whole argument listg string\n\nwith\n\nline breaks']
$ osascript t3.applescript | tr '\r' '\n'
about to print whole argument list
['t3.py', 'here is a\n\nlong string\n\nwith\n\nline breaks']
printed whole argument list
编辑:至于如何让 AppleScript 生成带有 unix 样式定界符的结果...我没有看到简单的方法,但是您可以使用文本替换功能
on replaceText(find, replace, subject)
set prevTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to find
set subject to text items of subject
set text item delimiters of AppleScript to replace
set subject to subject as text
set text item delimiters of AppleScript to prevTIDs
return subject
end replaceText
set s to "here is a
long string
with
line breaks"
set CRstring to do shell script "python t3.py " & quoted form of s
set LFstring to replaceText("\r", "\n", CRstring)
你也可以做一个特殊用途的函数:
on CR2LF(subject)
set prevTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to "\r"
set subject to text items of subject
set text item delimiters of AppleScript to "\n"
set subject to subject as text
set text item delimiters of AppleScript to prevTIDs
return subject
end CR2LF