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
编辑:由于此脚本不是手动在目标机器上 运行,因此有两种解决方案:
- 使用
chmod
解决方案。
- 将配置文件写入一个临时文件并用
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
来修复权限。)
我不确定是否应该在这里、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
编辑:由于此脚本不是手动在目标机器上 运行,因此有两种解决方案:
- 使用
chmod
解决方案。 - 将配置文件写入一个临时文件并用
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
.
在这种情况下,我通常使用这个简单的技巧:
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
来修复权限。)