如何向变量添加通配符以传递给 "do shell script?"
How can I add a wildcard to a variable to pass to "do shell script?"
我在远程服务器上有一个名为 A00122-StupidLongNameThatIHaveToKeep
的目录。
我有一个 AppleScript,只使用项目编号将文件复制到服务器。在复制之前,我想验证路径是否有效。为此,我想我可以通过 SSH 发送命令来验证项目是否存在并使用 find
获取全名
set projectNumber to A00122
set projectPath to do shell script "ssh " & uName & "@server.com '( find /Volumes/HardDrive/ -type d -maxdepth 1 -name '" & projectNumber & "*' )'"
预期的 shell 命令是:
`ssh username@server.com '( find /Volumes/HardDrive/ -type d -maxdepth 1 -name 'A00122*'`
哪个应该return
/Volumes/HardDrive/A00122-StupidLongNameThatIHaveToKeep
但我得到的是:
no matches found: A00122*
如何向我的变量添加通配符并将其传递给 do shell script
?
这里有两个基本的复杂问题:首先,您构建 find
命令的片段将经过三个不同的解析层——首先是 AppleScript,然后是本地 shell,最后由远程 shell -- 每一层将解析、应用、 和删除 一层引号 and/or 转义。其次,引号不嵌套;看起来您正在尝试使用单引号和括号的组合来通过 shell 解析的两个级别来获得未扩展的通配符,但它只是行不通。
让我们通过这三个层次来了解哪里出了问题。从 AppleScript 命令开始:
set projectPath to do shell script "ssh " & uName & "@server.com '( find /Volumes/HardDrive/ -type d -maxdepth 1 -name '" & projectNumber & "*' )'"
AppleScript 解析并删除双引号(连同插入变量),给出如下内容:
ssh fred@server.com '( find /Volumes/HardDrive/ -type d -maxdepth 1 -name 'A00122*' )'
^----------------------------------------------------^ ^--^
这基本上就是您所说的您想要的,但它不会按照您的意愿行事,因为(正如我所说)引号不会嵌套。当 shell 解析它时,它将把我加下划线的部分视为单引号,而它们之间的部分——我认为你打算放在两层引号内——完全不加引号!现在,A00122*
不在引号中这一事实在这一点上并不重要(除非你在本地计算机上有一些 really 奇怪命名的文件),但问题是 所有 这些引号将在命令发送到远程 shell 之前被删除。那么远程shell收到的是:
( find /Volumes/HardDrive/ -type d -maxdepth 1 -name A00122* )
由于 A00122*
此时不在引号中,远程 shell 将尝试将其扩展为匹配文件列表,这(显然)失败了,错误消息表明远程 shell 是 zsh,它抱怨不匹配的通配符(默认情况下)。另外,请注意括号在这里没有任何用处;我认为它们可能是为了让引号嵌套,但这不起作用。
因此,建议 1:删除括号和 "inner" 单引号并为通配符添加一个转义符(必须加倍才能通过 AppleScript):
set projectPath to do shell script "ssh " & uName & "@server.com 'find /Volumes/HardDrive/ -type d -maxdepth 1 -name " & projectNumber & "\*'"
建议 2:如果您只进行深度 1 搜索,为什么不让 shell 扩展通配符并 echo
结果:
set projectPath to do shell script "ssh " & uName & "@server.com 'echo " & projectNumber & "*'"
...然后检查结果是否以 "A00122-" 开头(注意破折号在这里很重要,因为除了 zsh 之外的 shells 可能会 return "A00122*").
我在远程服务器上有一个名为 A00122-StupidLongNameThatIHaveToKeep
的目录。
我有一个 AppleScript,只使用项目编号将文件复制到服务器。在复制之前,我想验证路径是否有效。为此,我想我可以通过 SSH 发送命令来验证项目是否存在并使用 find
set projectNumber to A00122
set projectPath to do shell script "ssh " & uName & "@server.com '( find /Volumes/HardDrive/ -type d -maxdepth 1 -name '" & projectNumber & "*' )'"
预期的 shell 命令是:
`ssh username@server.com '( find /Volumes/HardDrive/ -type d -maxdepth 1 -name 'A00122*'`
哪个应该return
/Volumes/HardDrive/A00122-StupidLongNameThatIHaveToKeep
但我得到的是:
no matches found: A00122*
如何向我的变量添加通配符并将其传递给 do shell script
?
这里有两个基本的复杂问题:首先,您构建 find
命令的片段将经过三个不同的解析层——首先是 AppleScript,然后是本地 shell,最后由远程 shell -- 每一层将解析、应用、 和删除 一层引号 and/or 转义。其次,引号不嵌套;看起来您正在尝试使用单引号和括号的组合来通过 shell 解析的两个级别来获得未扩展的通配符,但它只是行不通。
让我们通过这三个层次来了解哪里出了问题。从 AppleScript 命令开始:
set projectPath to do shell script "ssh " & uName & "@server.com '( find /Volumes/HardDrive/ -type d -maxdepth 1 -name '" & projectNumber & "*' )'"
AppleScript 解析并删除双引号(连同插入变量),给出如下内容:
ssh fred@server.com '( find /Volumes/HardDrive/ -type d -maxdepth 1 -name 'A00122*' )'
^----------------------------------------------------^ ^--^
这基本上就是您所说的您想要的,但它不会按照您的意愿行事,因为(正如我所说)引号不会嵌套。当 shell 解析它时,它将把我加下划线的部分视为单引号,而它们之间的部分——我认为你打算放在两层引号内——完全不加引号!现在,A00122*
不在引号中这一事实在这一点上并不重要(除非你在本地计算机上有一些 really 奇怪命名的文件),但问题是 所有 这些引号将在命令发送到远程 shell 之前被删除。那么远程shell收到的是:
( find /Volumes/HardDrive/ -type d -maxdepth 1 -name A00122* )
由于 A00122*
此时不在引号中,远程 shell 将尝试将其扩展为匹配文件列表,这(显然)失败了,错误消息表明远程 shell 是 zsh,它抱怨不匹配的通配符(默认情况下)。另外,请注意括号在这里没有任何用处;我认为它们可能是为了让引号嵌套,但这不起作用。
因此,建议 1:删除括号和 "inner" 单引号并为通配符添加一个转义符(必须加倍才能通过 AppleScript):
set projectPath to do shell script "ssh " & uName & "@server.com 'find /Volumes/HardDrive/ -type d -maxdepth 1 -name " & projectNumber & "\*'"
建议 2:如果您只进行深度 1 搜索,为什么不让 shell 扩展通配符并 echo
结果:
set projectPath to do shell script "ssh " & uName & "@server.com 'echo " & projectNumber & "*'"
...然后检查结果是否以 "A00122-" 开头(注意破折号在这里很重要,因为除了 zsh 之外的 shells 可能会 return "A00122*").