(已解决) 关于函数 system 的两个问题
大佬们,新年好😄
关于函数 system 我有两个问题想求助,论坛里在年前有过一个关于 system 帖子,搭了一下顺风车,了解到了 system 可以执行 powershell 命令,这相当于用一个函数把一门编程语言给激活了。我看官方的函数文档也做了更新,补充了对 powershell -c 的简单说明。现在又旧事重提,只因疑惑尚存,望见谅。
举个简单的例子如下,A1:A3 是几个文本串,想通过 powershell 命令把文本串中的数字扩大 20 倍,此例没有其他意图,纯粹是为了学习,SPL 语句如下所示:
A | B | |
1 | a:1 b:2 c:3 | |
2 | d:11 e:12 f:13 | |
3 | g:14 h:15 i:16 | |
4 | =([A1:A3]*680).concat@ci() | 文本加单引号,用逗号隔开 |
5 | ="powershell -c"+A4+"| % {[regex]::replace($_,'\\d+',{(0+$args[0].value)*20})} | out-file 结果.txt -enc utf8" | powershell 数组作为参数传递 |
6 | =system(A5) |
A4 格把 A1:A3 的文本串添加单引号后用逗号连接,模拟 powershell 里的数组,作为参数传递给 A5。
A5 格中拼接成 powershell 的命令,其中的 out-file 把结果输出给 txt 文件。运行之后,可以在集算器的安装路径下的 bin 文件夹里看到这个输出文件 (因为没有指定输出路径),截图如下:
可以看到,数字都按要求扩大了 20 倍,输出的结果是 2040 行,因为把上述 3 个文本数组乘了 680 次。一切正常,运行的速度貌似也可以。
如果把上述 3 个文本数组乘 681 次,数组长度变成 2043,就会出现以下报错:
这个错误应该是文本长度受限了,我在 powershell 中做了同样的测试,能正常运行。所以,
问题 1:system() 里的文本长度是不是有限制?
(后注:命令行文本长度限制跟 SPL 无关,应该是微软的问题,powershell 长度限制 32766 字符,cmd 长度限制更短,可能是 8000 多字符,这个具体没有测试。)
接下来就是 system 执行后返回值的问题,也就是代码格中 A6 的返回值,如果正常,system 就返回 0,如果出错,就会返回 1(也有出现过 255)。powershell 命令并不是都会有返回值,比如对文件夹和文件的复制,移动,删除,增加等操作,不会有返回值。但也有一些命令是有返回值的,比如对文件夹文件目录路径的操作,或者一些计算等。比如,在 VBA 里调用 powershell 时可以通过 StdOut.ReadAll 或者 StdErr.ReadAll 读出返回信息,截图如下:
在 SPL 中,这部分返回值会出现在日志文件中,日志文件里的信息比较多,不仅仅是 powershell 的执行结果,如果要解析出这部分结果会比较费劲。要么在 powershell 命令中重定向输出至指定文件,然后再用 spl 语句把该文件读出结果,等使用完之后,再用 movefile 把这个文件删除,略显复杂。所以,
问题 2:SPL 在用 system 执行命令后,其返回值能否出现在代码格中?(已解决)
上述两个问题,恳请大佬们得闲时给予帮助,谢谢🙏 🙏
应该是 win10 的命令串长度有限制,不超过 2047,你也可以试试 VBA 是不是也报错
powershell 貌似是 32766 个字符限制,多一个都不行。
cmd 可能命令行长度限制的更短….
有办法解法这个长度限制吗?
没办法,spl 本身不控制,system 函数调用 java 的 Runtime.exec 完成的
grd 巨硬,到处都是坑,命令行长度不管他了,实在不行分批分段执行。
大佬帮忙看一下第 2 个问题,system 执行后代码格能返回结果吗?不仅仅是 0 或者 1。
大佬们,请问文中求助里的第 2 个问题可行吗?方便的时候可否回复一下?
增加了 2 个选项,还在开发
🙏 🙏 Much appreciated!!
system 函数中增加如下选项:
@ o: 返回 stdout 的结果;
@ a: 返回成 [exit,stdout,stderr] 的序列。
请前往下载贴中下载最新的 esproc-bin.jar 文件
666,谢谢 ddszm 大佬,谢谢 zaoya 大佬,谢谢老贼,谢谢 SPL!!!
大佬们,下午好🙏
我在 MAC 版集算器里使用 system 函数调用 sh -c 命令时,发现结果跟预期不符。
比如,用 ls ./*.xlsx 列出主目录下所有后缀是 xlsx 的文件,system 返回的结果是所有文件。
在命令行里返回的是过滤后的结果:
有些命令在 Mac 命令里能用,但使用 system 时没有返回结果,一直是执行状态。比如以下截图中的命令:
集算器里跑不出来结果,在 MAC bash 里是能出结果的。
是不是我哪里没用对?恳请大佬们有空时指导一下,谢谢🙏
用 system@o(“sh”:“-c”:“ls ./*.xlsx”)
谢谢大佬帮助,👍 👍 👍
测试成功,这么多引号,确实想不到。😄
system1 个参数时对应 Runtime.exec(String cmd),多个参数时对应 Runtime.exec(String[] cmdarray)
java 执行 exec(String cmd) 时会把 cmd 按空格拆开成串数组,”sh -c ls ./*.xlsx" 会拆成 4 个串的数组,然后调用 exec(String[] cmdarray),实际执行时第 4 个参数不起作用,猜测 sh -c 实际执行时只需要 1 个参数,所以只能自己拆成串数组