如何通过Java代码在Linux上运行超级用户命令?

时间:2014-02-13 09:21:52

标签: java linux exec elevated-privileges

我的应用有多个用户和一个超级用户。我试图通过Java代码在Linux中编写和存储文件但我得到权限被拒绝错误。我使用了以下代码:

Process process = Runtime.getRuntime().exec("/usr/bin/tiff2pdf -o /tmp/tiff_dir/temp.pdf /tmp/tiff_dir/image.tiff");
int returnCode = process.waitFor();

我收到以下错误:

java.io.FileNotFoundException: image.tiff (Permission denied)

根据我的分析,似乎因为用户没有root权限,我收到此错误。解决方案是什么?

3 个答案:

答案 0 :(得分:1)

你不应该像超级用户一样运行这样的命令,因为它会带来安全风险(即如果有人控制了你的java程序,那么他们就拥有了王国的钥匙)。相反,您应该以较低的权限运行。

问题似乎是访问image.tiff而不是tiff2pdf。检查image.tiff的所有者和权限。

答案 1 :(得分:1)

首先,这两行不会产生java.io.FileNotFoundException: image.tiff (Permission denied)

Process process = Runtime.getRuntime().exec("/usr/bin/tiff2pdf -o temp.pdf image.tiff");
int returnCode = process.waitFor();

如果由于某种原因,命令失败,它将返回一个非零返回码,将在进程的标准错误上产生一些输出(这就是约定)。您可以从process.getErrorStream()获得标准错误(可能值得一看标准输出,以防万一)。如果在那里找不到文件的问题,它就不会抛出这样的FileNotFoundException,因为Java无法理解命令的预期输出。

编辑,跟随您的评论:

  

它仅从这一点抛出,returnCode的值为1.一旦我手动更改了root用户的文件权限,一切正常。

那是不可能的。如果您的应用程序在这两行中的任何一行引发异常,它将退出正常的控制流:您将无法读取returnCode

其次,您应该使用exec中的每个参数运行String[]命令,而不是将其全部放在一行中,如果文件名例如有空格,这应该可以防止引用问题。

我还建议在命令中使用绝对路径,以确保您在预期的目录中工作。 (*编辑:*现在您正在使用绝对路径,请确保您的用户具有/tmp/tiff_dir的rwx权限。)

为了更直接地回答您的问题,出于安全原因,您当然可以使用sudo运行Runtime.exec(new String[] {"/usr/bin/sudo", ... the rest of your command ... },但这是个坏主意。您还需要更改sudoers文件以允许它没有密码,或者找到传递密码的方法,on the command line(绝对有安全风险!)或将其传递给输入以某种方式手动流。)

答案 2 :(得分:0)

试试这个:

File file = new File("/opt/image.tiff");
Runtime runtime = Runtime.getRuntime();
runtime.exec(new String[] { "/bin/chmod", "777",file.getPath()});

这将对文件执行完全权限。