无法从CRON(凭证)运行AWS CLI


27

尝试运行简单的AWS CLI备份脚本。它在包含文件中的各行之间循环,将这些路径备份到S3,然后将输出转储到日志文件中。当我直接运行此命令时,它运行没有任何错误。当我通过CRON运行它时,我的输出日志中出现“无法找到凭据”错误。

shell脚本:

AWS_CONFIG_FILE="~/.aws/config"

while read p; do
 /usr/local/bin/aws s3 cp $p s3://PATH/TO/BUCKET --recursive >> /PATH/TO/LOG 2>&1
done </PATH/TO/INCLUDE/include.txt

我仅在看到错误后才将该行添加到配置文件中,认为这可能会解决问题(即使我很确定默认情况下这就是AWS的外观)。

Shell脚本以root身份运行。我可以在指定位置看到AWS配置文件。这一切对我来说都很不错(就像我说的那样,它在CRON之外运行良好)。


2
尝试使用绝对路径~/.aws/config
ceejayoz 2014年

绝对首先尝试(使用/root/.aws/config),但在其他一些线程中看到它之后又跳回〜/。两种方式都存在相同的错误。
binaryorganic 2014年

2
不是直接的答案,而是关于使用API​​密钥的评论:更好的做法(并且容易得多)是将角色分配给实例,并围绕这些角色创建策略,然后完全不需要指定密钥,或者让他们在实例上以纯文本方式躺在周围。不幸的是,这只能在实例创建时指定。顺便说一句,要复制日志文件(和备份等),请查看s3cmd工具,该工具提供类似于rsync的功能。
nico

Answers:


20

如果在直接运行而不是从cron运行时可以运行,则环境可能有所不同。您可以通过以下方式交互式地保存环境

set | sort > env.interactive

并在脚本中执行相同的操作

set | sort > /tmp/env.cron

然后diff /tmp/env.cron env.interactive看看重要的是。诸如此类PATH的事情是最有可能的罪魁祸首。


4
谢谢!能够自行解决问题的步骤基本上是无价的。在PATH变量中肯定有几个差异,在这种情况下,我有点认为是HOME的差异导致了问题。至于我的特定问题,我最终只是从用户的cron文件而不是/ etc / crontab运行该文件,这最终解决了所有问题。再次感谢!
binaryorganic 2014年

对。通常在脚本中添加正确的PATH变量(echo $PATH会告诉它应该是什么)即可解决该问题。
Fr0zenFyr

33

从crontab运行作业时,$HOME环境变量为/

亚马逊客户端寻找

~/.aws/config

要么

~/.aws/credentials

如果$HOME= /,则客户端将找不到这些文件

要使其正常工作,请更新您的脚本,以使其导出实际的主目录,以用于 $HOME

export HOME=/root

然后将配置或凭据文件放入

/root/.aws/

这很有帮助,还有来自stackoverflow.com/a/26480929/354709的以下修复程序,其中包括为aws命令添加绝对路径-因为在root用户中未正确设置$ PATH。
Dan Smart

2
这应该是公认的答案。
Madbreaks'Mar

6

我可以通过以下方法解决此问题:

export AWS_CONFIG_FILE="/root/.aws/config"
export AWS_ACCESS_KEY_ID=XXXX
export AWS_SECRET_ACCESS_KEY=YYYY

1
但是,这样做的主要目的aws configure是使您不必将凭据放在脚本中。请参阅@chicks发布的答案以正确解决此问题。
Madbreaks

1
不要存放AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY脚本值。第一行应该已经提供了这些值。
AWippler '18


1

aws cli工具的二进制文件安装在下/usr/local/bin/aws

我的错误是cron用户/usr/local/bin/aws在运行时无法访问;它只能访问/usr/bin/

我所做的是/usr/bin使用以下命令在aws中创建一个链接。

root@gateway:~# ln -s /usr/local/bin/aws /usr/bin/aws

我还在脚本中添加了一些更改;这是一个示例函数:

starter () {
    echo "
    ==================================================

    Starting Instance

    ==================================================
    "

    /usr/bin/aws ec2 start-instances --instance-ids $instance --region us-east-1

    sleep 30

    echo "Assigning IP Address "

    /usr/bin/aws ec2 associate-address --instance-id $instance  --region us-east-1 --public-ip XX.XX.XX.XX

}

和cron条目:

30 5 * * * sh /usr/local/cron/magentocron.sh

这种方法对我有用。


曼苏尔,您的答案格式已完全损坏。
Aldekein

使用完整路径/usr/bin/aws是解决方案的关键。
Ramratan Gupta

1

.bashrc用户默认文件中的这一行将阻止非交互式外壳程序获得完整的用户环境(包括PATH变量):

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

注释掉该行以允许$HOME/.bashrc从非交互式上下文执行。

我还必须向source我的shell脚本中添加一个显式命令以正确设置环境:

#!/bin/bash
source $HOME/.bashrc

有关其他信息,请参见此答案


1

我们都知道环境路径变量$ PATH具有二进制文件的位置。Crontab的$ PATH可能没有位置awscli。

您可以做的是,找到awscli二进制文件的路径。

# which aws
/usr/local/bin/aws

并在脚本的开头(在shebang之后)添加以下行,从而在crontab的$ PATH中添加路径。

PATH=$PATH:/usr/local/bin/

这对我有用!!!


你的回答对我有用。挠头一个小时。谢谢,好友
Hussain7

0

我知道这不是完美的解决方案,但对我有用:

export HOME=/home/user
export AWS_CONFIG_FILE="/home/user/.aws/config"
export AWS_ACCESS_KEY_ID=XXX
export AWS_SECRET_ACCESS_KEY=XXX


0

我遇到了同样的问题,但是从cron条目(2>@1)中删除了stderr重定向后,我aws: command not found在日志中看到了。

这是因为AWS cli已安装在用户的主文件夹中,并且我已经在用户的目录中添加了一行.bash_profile以将AWS cli路径添加到$PATH。奇怪的是,这实际上是AWS cli安装文档告诉您的安装方式。但是.bash_profile执行用户的crontab时不会使用该用户的(至少无论如何在我的环境中)。

因此,我为解决此问题所做的一切就是确保我的crontab脚本的路径中也包含aws cli。因此,在我的剧本下,我现在有了PATH=~/.local/bin:$PATH


0

对我来说,这就是窍门:

#!/bin/bash

HOME=/home/ubuntu
AWS_CONFIG_FILE="/home/ubuntu/.aws/config"

aws ec2 describe-instances #or whatever command you need to use.

当前EC2实例中的默认用户是ubuntu,而根文件夹是该用户的主文件夹。那也是aws cli存在的地方。


0

并不是最好的,但是我必须在AWS客户端命令之前直接在shell / bash脚本中提供配置。喜欢:

#!/bin/bash

export AWS_ACCESS_KEY_ID=<ZZZ>
export AWS_SECRET_ACCESS_KEY=<AAA>
export AWS_DEFAULT_REGION=<BBB>
aws s3 cp ....
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.