如何确保使用正确的用户或权限创建文件?

How to make sure file is created with the correct user or permissions?

提问人:Madara's Ghost 提问时间:8/24/2015 最后编辑:CommunityMadara's Ghost 更新时间:8/25/2015 访问量:228

问:

商业模式有点复杂,所以如果解释不是 100% 清楚,请见谅:

Uploader 接口 () 定义了上传文件(包含在字节数组中)的不同方式,例如,它获取内容和字符串,并将其上传到给定键下的 Amazon S3。String upload(String path, byte[] fileContents)AmazonUploaderpath

我有一个名为 QA 的类,它将给定的文件数组按原样写入本地磁盘。LocalUploader

Uploader 用于两种不同的情况:

  1. Web 界面,由用户运行web
  2. 命令行界面,由用户通过用户 登录 运行。sshroot

命令行界面与 Web 界面不同,但它们都捆绑了 Uploader。此外,命令行可执行文件是最后运行的 bash 脚本。java -jar ....

这个想法是将文件保存到已知位置,然后通过简单的静态 http 服务器提供它们。

简而言之,问题:由于两个进程都写入同一位置,因此当命令行界面写入文件时,Web 界面不再可写入该文件(无法访问 ,显然,反之亦然没有问题)。webroot

现在,我坚持使用 Java 6 进行上传,所以没有文件包。nio

工作流程简述:

Workflow

这是我尝试过的:

  • 使用 的 .如果我在写入文件之前执行此操作,它将失败(返回),如果我在之后执行此操作,它将返回 true 但不设置标志。java.io.File.setWritable()falsewritable
  • 用于以其他用户身份运行 jar。但这会扰乱参数插入su
  • 使用,很快就被 Java 忽略了。可能是因为这是一个不同的过程。umask
  • 将组 ID 标志用于 linux 权限 - 被 Java 立即忽略。可能是因为这是一个不同的过程。

我没有尝试的:

  • 使用 ACL - 我们不能弄乱底层分区。
  • 将文件作为输出返回,并让 bash 写入文件 - 并非所有命令都需要写入文件,此外,可能需要也可能不需要写入多个文件。这不是我想放在 bash 脚本中的逻辑,这是上传者的工作。

注意事项:

  • 我在 Uploader 上使用 Java 6。没有花哨的东西。
  • 我正在使用 Spring 3.2 作为 Uploader。无法启动。
  • 可能可以在 Uploader 中使用实用程序库。
  • 我正在将 Java 8 用于命令行可执行文件

一些相关代码:

上传.java

@Override
public String upload(String path, byte[] fileContents) {
    final File file = new File(path);
    try {
        FileUtils.writeByteArrayToFile(file, fileContents);
    } catch (IOException e) {
        throw new RuntimeException("Error writing file to path " + path, e);
    }
    return "";
}

init.sh

#!/bin/bash

CONFIGDIR=${spring.config.location}
CONFIGFILE=$CONFIGDIR/${app.name}.conf
# Loading a settings from CONFIGFILE
[ -f $CONFIGFILE ] && source $CONFIGFILE

# Setting JAVA_BIN
if [ -z "$JAVACMD" ] ; then
  if [ -n "$JAVA_HOME"  ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
      # IBM's JDK on AIX uses strange locations for the executables
      JAVACMD="$JAVA_HOME/jre/sh/java"
    else
      JAVACMD="$JAVA_HOME/bin/java"
    fi
  else
    JAVACMD="`which java`"
  fi
fi

# Starting the application
$JAVACMD $JAVA_OPTS -jar ${app.home}/bin/${build.finalName}.jar  "$@" --spring.config.location=$CONFIGDIR/

这整件事闻起来像是一些微不足道的问题,甚至一开始就不应该存在,但我被难住了。将不胜感激任何帮助。

Java Bash 文件 Maven

评论

0赞 chepner 8/24/2015
中的参数名称不能包含句点。在执行之前是否由其他工具进行预处理?(我问是因为使用 ,或者最好是 ,可能是正确的答案。jar 文件应以用户“web”身份运行,与在 Web 应用中运行相同,而不是以 root 身份运行。bashinit.shsusudo
0赞 Madara's Ghost 8/24/2015
是的,您看到的是 maven 从 pom.xml 替换的参数。已部署的版本具有配置目录的环境特定路径。
0赞 SomeJavaGuy 8/24/2015
我为类似的问题所做的是使用这样的命令。.之后按照运行时执行它使文件可写和可读。chmodString cmd[] = { "chmod", "644", file.getAbsolutePath() };Runtime.getRuntime().exec(cmd)
0赞 Madara's Ghost 8/24/2015
@chepner我不同意你的编辑并回滚。这与 maven 关系不大,与文件关系很大。
2赞 chepner 8/24/2015
它至少在某种程度上与 Maven 相关,如所示是无效代码。使用 / Maven 运行它的正确方法可能涉及 Maven。init.shbashsusudo

答:

1赞 Lars Gendner 8/25/2015 #1

你试过使用sudo吗?

sudo -u web $JAVACMD $JAVA_OPTS -jar ${app.home}/bin/${build.finalName}.jar  "$@" --spring.config.location=$CONFIGDIR/

这应该有效,因为命令行界面是由以 root 身份登录的用户调用的(这不建议,但我认为它是给定的)。

评论

0赞 Madara's Ghost 8/25/2015
这是给定的。我会试一试,然后回复你。谢谢:)
0赞 Lars Gendner 8/25/2015
不客气;-)也许你必须对命令行参数传递进行一些摆弄,我无法预测行为,因为我没有你的环境(请随时发布发生的事情)。如果 init.sh 不是以 root 身份运行,您可能需要在 中设置适当的 sudo-permissions。sudoers