V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
duanguyuan
V2EX  ›  程序员

请教 Java Runtime.exec("sh -x xx.sh")无效的问题

  •  
  •   duanguyuan · 2020-05-28 22:38:26 +08:00 · 2549 次点击
    这是一个创建于 1638 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我们经常会用如下代码在 Java 里调用系统命令:

    Process proc =Runtime.getRuntime().exec("sh xxx.sh");
    

    但是,今天为了在调试模式下运行脚本,加了 -x 参数,发现没有效果,得到的脚本的输出流与没有 -x 参数一样。直接在shell里执行sh -x xxx.sh,是能出现调试效果的。 但在 jvm 里面,就无效了。另外测试了-n-v参数,-n有效,-v无效。 请问这是什么原因呢?

    参考资料:

    [dmtsai@study ~]$ sh [-nvx] scripts.sh
    选项与参数:
    -n  :不要执行 script,仅查询语法的问题;
    -v  :再执行 sccript 前,先将 scripts 的内容输出到屏幕上;
    -x  :将使用到的 script 内容显示到屏幕上,这是很有用的参数!
    
    范例一:测试 dir_perm.sh 有无语法的问题?
    [dmtsai@study ~]$ sh -n dir_perm.sh 
    # 若语法没有问题,则不会显示任何信息!
    
    范例二:将 show_animal.sh 的执行过程全部列出来~
    [dmtsai@study ~]$ sh -x show_animal.sh 
    + PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/root/bin
    + export PATH
    + for animal in dog cat elephant
    + echo 'There are dogs.... '
    There are dogs....
    + for animal in dog cat elephant
    + echo 'There are cats.... '
    There are cats....
    + for animal in dog cat elephant
    + echo 'There are elephants.... '
    There are elephants....
    
    第 1 条附言  ·  2020-05-29 15:42:49 +08:00
    感谢 4 、5 、6 、8 楼大佬提供的思路,的确,sh -x 输出的调试信息是标准错误输出!
    问题已解决,代码太长,我贴在回复里面
    谢谢大家!
    我发现在 V 站问问题,比什么 CSDN 、博客园、segmentfault 都高效啊!! 宝藏网站!
    9 条回复    2020-05-29 15:52:51 +08:00
    Hieast
        1
    Hieast  
       2020-05-29 00:43:45 +08:00
    没写过 Java,单就问题来看建议查一下文档看 Runtime.getRuntime().exec 这种方式运行时标准输出跟当前进程是否一致。可以尝试 Process proc =Runtime.getRuntime().exec("sh -x xxx.sh > x.log"); 把标准输出重定向到文件,看文件里有没有输入。
    oneisall8955
        2
    oneisall8955  
       2020-05-29 00:54:29 +08:00 via Android
    用数组来装命令和参数试试?
    binux
        3
    binux  
       2020-05-29 01:08:18 +08:00
    sh 不是同一个 sh
    momocraft
        4
    momocraft  
       2020-05-29 01:31:11 +08:00
    sh -x 的调试信息的输出是 stderr
    fmumu
        5
    fmumu  
       2020-05-29 09:14:00 +08:00 via Android
    把 process 的错误输出拿出来看看,exec 有几个重载方法都看看
    whoami9894
        6
    whoami9894  
       2020-05-29 10:00:18 +08:00
    ```
    root@e:/tmp# cat 1.sh
    echo 123
    root@e:/tmp# sh 1.sh
    123
    root@e:/tmp# sh -x 1.sh
    + echo 123
    123
    root@e:/tmp# sh -x 1.sh > 1
    + echo 123
    root@e:/tmp# cat 1
    123
    root@e:/tmp# sh -x 1.sh > 1 2>&1
    root@e:/tmp# cat 1
    + echo 123
    123
    ```
    Infernalzero
        7
    Infernalzero  
       2020-05-29 10:08:51 +08:00
    用 ProcessBuilder,把 sh 和 xxx.sh 作为两个参数传入即可
    或者还是 RunTime 的话改成"/bin/bash", "-c", "xxx.sh"
    huaouo
        8
    huaouo  
       2020-05-29 12:37:17 +08:00 via iPhone
    ProcessBuilder redirectOutput(ProcessBuilder.Redirect.INHERIT)
    redirectError(ProcessBuilder.Redirect.INHERIT)
    试试?
    duanguyuan
        9
    duanguyuan  
    OP
       2020-05-29 15:52:51 +08:00
    问题解决啦!谢谢大家。
    我在 github 上找到一段比较完整的代码:
    https://github.com/chenerzhu/quartz-console/blob/master/src/main/java/com/chenerzhu/quartz/executor/impl/ShellExecutor.java
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1457 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 23:57 · PVG 07:57 · LAX 15:57 · JFK 18:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.