【问题标题】:How to invoke a unix script from java?如何从java调用unix脚本?
【发布时间】:2009-01-23 04:18:12
【问题描述】:

我想删除日志目录中的旧日志文件。 删除超过 6 个月的日志文件, 我写了这样的脚本

找到/dnbusr1/ghmil/BDELogs/import -type f -mtime +120 -exec rm -f {} \;

通过使用此脚本,我可以删除旧文件,但如何使用 java 调用此脚本?

【问题讨论】:

    标签: java unix exec


    【解决方案1】:

    【讨论】:

    • 如果您要使用它,您可能需要阅读以下内容:javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html
    • @Ben:我不同意那篇文章。从我从第 1 页读到的文章的作者不知道 Unix 进程是如何工作的。当然要等待一个过程,才能得到返回值! (这也不是 Unix 的自动等待方式;程序必须要求它。)
    • @Ben:第 2 和第 3 页更好,因为它讨论了处理程序需要/生成的任何输入和输出的需要。这些显然应该在等待之前设置(可能在单独的线程中)。
    • @Ben:总的来说,这篇文章对我来说似乎只涉及 Windows 编程。在第 4 页,许多 Unix 程序员都知道使用 shell 命令和重定向的陷阱,他们会/应该在需要 shell 功能时使用 ['sh', '-c', cmdstring]。
    • 请注意,我会说,对于使用 Java 的 Windows 程序员,那篇文章确实非常有用,应该推荐。因此,我的 cmets 认为它​​不适用于 Unix,不应被视为对这篇文章的普遍贬低。
    【解决方案2】:

    如果可移植性是一个问题,会阻止您使用 Runtime.exec() 运行,那么使用 File 和 FilenameFilter 在 Java 中编写此代码非常简单。

    编辑:这是删除目录树的静态方法...您可以很容易地添加过滤逻辑:

    static public int deleteDirectory(File dir, boolean slf) {
        File[]                              dc;                                     // directory contents
        String                              dp;                                     // directory path
        int                                 oc=0;                                   // object count
    
        if(dir.exists()) {
            dir=dir.getAbsoluteFile();
    
            if(!dir.canWrite()) {
                throw new IoEscape(IoEscape.NOTAUT,"Not authorized to delete directory '"+dir+"'.");
                }
    
            dp=dir.getPath();
            if(dp.equals("/") || dp.equals("\\") || (dp.length()==3 && dp.charAt(1)==':' && (dp.charAt(2)=='/' || dp.charAt(2)=='\\'))) {
                // Prevent deletion of the root directory just as a basic restriction
                throw new IoEscape(IoEscape.GENERAL,"Cannot delete root directory '"+dp+"' using IoUtil.deleteDirectory().");
                }
    
            if((dc=dir.listFiles())!=null) {
                for(int xa=0; xa<dc.length; xa++) {
                    if(dc[xa].isDirectory()) {
                        oc+=deleteDirectory(dc[xa]);
                        if(!dc[xa].delete()) { throw new IoEscape(IoEscape.GENERAL,"Unable to delete directory '"+dc[xa]+"' - it may not be empty, may be in use as a current directory, or may have restricted access."); }
                        }
                    else {
                        if(!dc[xa].delete()) { throw new IoEscape(IoEscape.GENERAL,"Unable to delete file '"+dc[xa]+"' - it may be currently in use by a program, or have restricted access."); }
                        }
                    oc++;
                    }
                }
    
            if(slf) {
                if(!dir.delete()) { throw new IoEscape(IoEscape.GENERAL,"Unable to delete directory '"+dir+"' - it may not be empty, may be in use as a current directory, or may have restricted access."); }
                oc++;
                }
            }
        return oc;
        }
    

    【讨论】:

      【解决方案3】:

      当你只想调用你描述的命令时调用:

      Runtime r = Runtime.getRuntime();
      Process process = r.exec("find /dnbusr1/ghmil/BDELogs/import -type f -mtime +120 -exec rm -f {} \\;"); //$NON-NLS-1$
      process.waitFor();
      

      如果您想调用多个命令,请使用 Chris Jester-Young 答案。 exec 方法还可以定义您要使用的文件。其他答案链接方法描述。

      【讨论】:

      • 就我个人而言,我非常讨厌 shell 元字符引用,只是使用 shell 脚本;当我不得不用其他语言调用 system/exec 时,我觉得有必要把我的眼睛挖出来。 :-P 因此,我通常更喜欢明确指定 argv 值的选项。 :-)
      【解决方案4】:

      在 Java 中使用系统调用是可能的,但通常不是一个好主意,因为您将失去代码的可移植性。您可以查看Ant 并使用类似purge task 的内容。

      【讨论】:

        【解决方案5】:

        添加到 Crashworks 的答案中,您在 cmdarray 中使用这些参数调用:

        new String[] {"find", "/dnbusr1/ghmil/BDELogs/import", "-type", "f",
            "-mtime", "+120", "-exec", "rm", "-f", "{}", ";"}
        

        如果您的find 支持-exec ... {} + 语法,请将末尾的";" 更改为"+"。它会让你的命令运行得更快(它会一次对一批文件调用rm,而不是对每个文件调用一次)。

        【讨论】:

          猜你喜欢
          • 2016-06-22
          • 1970-01-01
          • 2014-01-14
          • 2012-11-16
          • 2016-07-24
          • 1970-01-01
          • 2010-10-06
          • 1970-01-01
          • 2018-02-13
          相关资源
          最近更新 更多