`gcloud compute copy-files`: 拷贝文件时出现权限被拒绝的错误。

35

我在将文件复制到我的Google Compute Engine上遇到了困难。 我正在使用Google Compute Engine上的Ubuntu服务器。

我正在从我的OS X终端执行此操作,并且已经使用gcloud进行了授权。

local:$ gcloud compute copy-files /Users/Bryan/Documents/Websites/gce/index.php example-instance:/var/www/html --zone us-central1-a
Warning: Permanently added '<IP>' (RSA) to the list of known hosts.
scp: /var/www/html/index.php: Permission denied
ERROR: (gcloud.compute.copy-files) [/usr/bin/scp] exited with return code [1].

您能否使用 gcloud compute ssh <instance-name> 命令从本地 OS X 计算机连接到实例的 SSH? - Faizan
@Faizan 是的,我使用了 gcloud compute --project "<PROJECT>" ssh --zone "us-central1-a" "<compute-name>" - bryan
在你的命令前面加上 sudo 能让它工作吗? - BrockLee
3
目标目录的权限似乎存在问题,我的建议是将文件先复制到其他地方(例如/tmp),然后在通过SSH连接到实例后再将它们复制到/var/www/html。请注意,这个过程是为了解决问题并确保文件能够复制成功。 - Faizan
7个回答

84

在实例名称之前插入root@

local:$ gcloud compute copy-files /Users/Bryan/Documents/Websites/gce/index.php root@example-instance:/var/www/html --zone us-central1-a

我可以通过ssh登录到VM实例,并且我使用前缀root@,但是在gcloud compute copy-files上仍然收到相同的错误消息。您有进一步的建议可以帮助我解决这个问题吗? - Drux
4
有更多的证据了。我无法使用root用户身份登录到VM实例中。也许最好将这些文件通过scp复制到一个中间位置,如/tmp,而不是尝试启用此功能。 - Drux
1
@Drux,@Dave——由于这个问题涉及到Google Compute Engine,您不能直接作为“root”SSH到VM,这是出于设计考虑,以保持您的VM更加安全。请参见我的答案以了解在这种情况下该怎么做。 - Misha Brukman
我要注意的是,在 <instance-name> 前加上 <instance-user>@ 的前缀是因为如果没有前缀,gcloud compute copy-files 默认使用 <local-workstation-user>@<instance-name>,即在本地工作站上调用 gcloud 的本地用户的用户名。 - Matthew
这应该在谷歌的文档中有说明,但那里写得非常不清楚。 - Ben Wilson
显示剩余3条评论

22
这不起作用的原因是您的用户名没有GCE VM实例的权限,因此无法写入/var/www/html/
请注意,由于此问题涉及Google Compute Engine VM,您无法直接使用root SSH到VM,也无法直接复制文件作为root,原因相同:gcloud compute scp使用scp依赖于ssh进行身份验证。
可能的解决方案:
  1. (also suggested by Faizan in the comments) this solution will require two steps every time

    1. use gcloud compute scp --recurse to transfer files/directories where your user can write to, e.g., /tmp or /home/$USER

    2. login to the GCE VM via gcloud compute ssh or via the SSH button on the console and copy using sudo to get proper permissions:

      # note: sample command; adjust paths appropriately
      sudo cp -r $HOME/html/* /var/www/html
      
  2. this solution is one step with some prior prep work:

    1. one-time setup: give your username write access to /var/www/html directly; this can be done in several ways; here's one approach:

      # make the HTML directory owned by current user, recursively`
      sudo chown -R $USER /var/www/html
      
    2. now you can run the copy in one step:

      gcloud compute scp --recurse \
          --zone us-central1-a \
          /Users/Bryan/Documents/Websites/gce/index.php \
          example-instance:/var/www/html
      

1
sudo chown -R [我的用户名] /var/www/html使用第三方SFTP工具对我有效。 - John Phelps

4

我曾经也遇到过同样的问题,但是其他答案中提供的方法并没有使它正常工作。最终,我成功的原因是根据官方文档中所述,在复制文件时显式地发送我的 "user"。重要的部分是括号中的 "USER@"。

gcloud compute scp [[USER@]INSTANCE:]SRC [[[USER@]INSTANCE:]SRC …] [[USER@]INSTANCE:]DEST

在我的情况下,我最初可以通过输入以下内容来传输文件:
gcloud compute scp instance_name:~/file_to_copy /local_dir

但是在我遇到权限被拒绝后,我通过输入以下内容使其正常工作:

gcloud compute scp my_user_name@instance_name:~/file_to_copy /local_dir

在我的情况下,用户名是我登录Google Cloud时使用的用户名。


1
这是唯一对我有效的解决方案(在实例之前加上user@)。谢谢。 - Glenster

3

我使用一个bash脚本将文件从我的本地机器复制到远程GCE机器上的可写目录,然后通过ssh移动这些文件。

SRC="/cygdrive/d/mysourcedir"
TEMP="~/incoming"
DEST="/var/my-disk1/my/target/dir"

您还需要设置 GCE_USER 和 GCE_INSTANCE。
echo "=== Pushing data from $SRC to $DEST in two simple steps"
echo "=== 1) Copy to a writable temp directoy in user home"
gcloud compute copy-files "$SRC"/*.* "${GCE_USER}@${GCE_INSTANCE}:$TEMP"
echo "=== 2) Move with 'sudo' to destination"
gcloud compute ssh ${GCE_USER}@${GCE_INSTANCE} --command "sudo mv $TEMP/*.* $DEST" 

在我的情况下,我不想将目标目录的所有权改变,因为这会导致其他脚本出现问题...

2

2

这个确切问题的更新解决方案(2020)

为了阐述,我们需要将此问题分为两个部分。 "copy-files" 指令已经被官方弃用,我们应该使用 "scp",但是旧和新选项都只限于某些特定文件夹。

由于我们可以访问到/tmp 文件夹,这意味着我们可以使用首选的"scp"命令轻松移动我们的分发文件,作为分阶段的步骤。

更重要的是,我们还可以通过 SSH 远程执行脚本或命令,这意味着有限的访问权限不再是问题。

示例时间

第一部分是将 dist 文件夹及其所有内容递归地复制到 tmp 文件夹中,并且 gloud 确实提供了访问权限:

gcloud compute scp --recurse dist user_name@instance:/tmp

第二部分利用了我们可以通过 SSH 远程运行命令的事实:

gcloud compute ssh user_name@instance --command "sudo bash golive"

(或者您可能需要执行任何其他命令)

更重要的是,这也意味着我们可以使用 sudo 和 "cp" 复制函数将分发文件直接复制到最终目标:

gcloud compute ssh user_name@instance --command "sudo cp -rlf /tmp/dist/* /var/www/html/"

这完全消除了通过 ssh 终端首先设置权限的必要性。


-3

这是将文件从远程机器复制到您的机器。请确保您已设置ssh,因为这将使用默认的ssh密钥。 对我有用的是:

gcloud compute scp 'username'@'instance_name':~/source_dir  /destination_dir --recurse

这是通用的语法,如果您想将文件从您的本机复制到远程机器,可以使用此命令。 --recurse : 用于复制包含其他文件的目录
语法:gcloud compute scp 'SOURCE' 'DESTINATION' 注意:不要以 root 身份运行。

欢迎来到Stack Overflow。在回答一个旧问题或已有被接受的答案的问题之前,请先查看已经提供的答案,并思考如何为现有信息添加内容。在这种情况下,您提供的信息仅仅是命令行使用输出。更重要的是,@Nekroz已经提供了这些信息,并详细说明了发布内容的实质性原因。 - chb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接