提问人:Madara's Ghost 提问时间:8/24/2015 最后编辑:CommunityMadara's Ghost 更新时间:8/25/2015 访问量:228
如何确保使用正确的用户或权限创建文件?
How to make sure file is created with the correct user or permissions?
问:
商业模式有点复杂,所以如果解释不是 100% 清楚,请见谅:
Uploader 接口 () 定义了上传文件(包含在字节数组中)的不同方式,例如,它获取内容和字符串,并将其上传到给定键下的 Amazon S3。String upload(String path, byte[] fileContents)
AmazonUploader
path
我有一个名为 QA 的类,它将给定的文件数组按原样写入本地磁盘。LocalUploader
Uploader 用于两种不同的情况:
- Web 界面,由用户运行
web
- 命令行界面,由用户通过用户 登录 运行。
ssh
root
命令行界面与 Web 界面不同,但它们都捆绑了 Uploader。此外,命令行可执行文件是最后运行的 bash 脚本。java -jar ....
这个想法是将文件保存到已知位置,然后通过简单的静态 http 服务器提供它们。
简而言之,问题:由于两个进程都写入同一位置,因此当命令行界面写入文件时,Web 界面不再可写入该文件(无法访问 ,显然,反之亦然没有问题)。web
root
现在,我坚持使用 Java 6 进行上传,所以没有文件包。nio
工作流程简述:
这是我尝试过的:
- 使用 的 .如果我在写入文件之前执行此操作,它将失败(返回),如果我在之后执行此操作,它将返回 true 但不设置标志。
java.io.File
.setWritable()
false
writable
- 用于以其他用户身份运行 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/
这整件事闻起来像是一些微不足道的问题,甚至一开始就不应该存在,但我被难住了。将不胜感激任何帮助。
答:
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
评论
bash
init.sh
su
sudo
chmod
String cmd[] = { "chmod", "644", file.getAbsolutePath() };
Runtime.getRuntime().exec(cmd)
init.sh
bash
su
sudo