Shell 创建配置文件时抱怨文件权限

Shell complains about file permissions when creating a config file

我不确定是否应该在这里、Unix 论坛或其他完全不同的地方提问,但是,我们开始吧。

我正在使用 Packer to create a set of images (running Debian 8) for AWS and GCE, and during this process I want to install HAProxy 并为其设置一个配置文件。映像构建和包安装进行得很顺利,但是当我尝试创建配置文件或覆盖现有配置文件时遇到文件权限问题。

My Packer Shell Provisioner 以用户 admin 的身份运行一组脚本(据我所知,我无法使用 root 通过 SSH 进入此设置),其中我遇到问题的是这样的:

#!/bin/bash

# Install HAProxy
sudo apt-get update
sudo apt-get install -y haproxy

# Create backup of default config file
sudo mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak

# Write content over to new config file
OLDIFS=$IFS
IFS=''
sudo cat << EOF > /etc/haproxy/haproxy.cfg
# Content line 1
# Content line 2
# (...)
EOF
IFS=$OLDIFS

日志输出给我这个错误:/tmp/script_6508.sh: line 17: /etc/haproxy/haproxy.cfg: Permission denied

我也考虑过将预制配置文件移到新创建的映像中,但我不确定该怎么做。如果没有写入权限,那也行不通,对吗?

那么,有人知道我如何设置 Shell 脚本来解决这个问题吗?或者是否有其他可行的解决方案?

解决这个问题的方法很简单,123 的 给了我正确的答案:chown

通过改变这个

sudo mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak

至此

sudo chown admin /etc/haproxy/haproxy.cfg
sudo chmod 644 /etc/haproxy/haproxy.cfg
sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak

我现在拥有运行设置所需的权限和所有权。

编辑

其他用户提供了更好、更可行的解决方案,并回答了有关我的脚本的一些问题。

脚本的问题是行

sudo cat << EOF > /etc/haproxy/haproxy.cfg

/etc/haproxy/haproxy.cfg 的重定向发生在 sudo 被调用之前,因此需要该文件可以由 运行 正在运行脚本的任何用户创建和写入。

您更改该文件的权限和所有权的想法通过使该文件对用户 运行 脚本可写来解决这个问题,但实际上,您似乎正在执行脚本的每一行在任何情况下都是 root,所以为什么不把所有的 sudo 和 运行 整个都丢掉 root?

$ sudo myscript.sh   # executed by the 'admin' user

编辑:由于此脚本不是手动在目标机器上 运行,因此有两种解决方案:

  1. 使用 chmod 解决方案。
  2. 将配置文件写入一个临时文件并用sudo移动它。

第二种解决方案涉及更改线路

sudo cat << EOF > /etc/haproxy/haproxy.cfg

cat <<EOF >/tmp/haproxy.cfg.tmp

然后在 EOF 之后再往下

sudo cp /tmp/haproxy.cfg.tmp /etc/haproxy/haproxy.cfg
rm -f /tmp/haproxy.cfg.tmp

这可以说是 "cleaner" 而不是乱搞文件权限。

正如 Kusalananda 指出的那样,问题在于输出重定向发生在调用 sudo.

的 shell 中

在这种情况下,我通常使用这个简单的技巧:

TMPFILE=`tempfile`
cat << EOF > $TMPFILE
# Content line 1
# Content line 2
# (...)
EOF
sudo cp $TMPFILE /etc/haproxy/haproxy.cfg
rm $TMPFILE

我创建了一个临时文件并将内容放在那里(该步骤不需要 sudo)。然后使用 sudo,将临时文件复制到最终目的地。最后:删除临时文件。 (我使用副本使文件所有权属于根;此举将保留调用用户的 user/group。或者,可以使用 chmod/chown 来修复权限。)