【问题标题】:youtube-upload runs from terminal but not cron callyoutube-upload 从终端运行,但不是 cron 调用
【发布时间】:2016-08-23 19:10:50
【问题描述】:

以下是我从 cron 调用的 up427.sh 脚本 在digitalocean server droplet上的ubuntu 12.06下。

脚本运行并使用 bash up427.sh 从该 droplet 上的终端上传到 youtube,但当从该 droplet 上的 crontab 完成 bash up427.sh 时则不会

它将错误 126 回显到我创建的名为 cx.txt 的错误输出文件中

我知道这意味着 126 命令调用无法执行 /dev/null 权限问题或命令不是可执行文件

记住它确实在我运行时运行

bash up427.sh

从 droplet 终端,它可以工作并上传到 youtube,因此当使用 bash 从终端运行脚本时,终端的 sh 命令和语法是正确的

我是根用户。

我的 crontab 是我以 root 身份使用 crontab -e 创建的通用 crontab,所以我相信它拥有所有特权。

以下是crontab对up427.sh的调用

SHELL=/bin/bash
HOME=/root/
#PATH=/sbin:/bin:/usr/sbin:/usr/bin:/root
MAILTO=”me@mail.com”
#PATH=/usr/local/share/youtube_upload:/root:/sbin:/bin:/usr/sbin:/usr/bin
#Uses client secrets at: /usr/local/share/youtube_upload/client_secrets.json
#Uses credentials fileat : /root/.youtube-upload-credentials.json



57 * * * *  bash /root/up427.sh; echo $?; echo$*; echo $$ > /root/up427dirfromcron.txt

(显然我将 57 调整到我希望它运行的任何分钟)

脚本从头开始执行 cd /root,这是所有这些文件和相关子目录所在的位置。

另外,我已经让 crontab 尝试了 home=/ 和 hpme=/root/ 并且没有任何区别

所有文件都由它们的特定子目录调用,以避免 cron 作业子目录 vageries(在我这样做之前发生)

我也尝试过使用和不使用所有 sh 标头。没有区别。

开始实际的逐字脚本文件 up427.sh(我在凌晨 3 点开始扯头发的日期)

SHELL=/bin/bash
HOME=/root
#PATH=/sbin:/bin:/usr/sbin:/usr/bin:/root
#MAILTO=”me@mail.com”
PATH=/usr/local/share/youtube_upload:/root:/sbin:/bin:/usr/sbin:/usr/bin


bash2run="youtube-upload --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials.json 
--title=mytitle --privacy=private /root/thefileiwanttouploadwhichisfineandworksfromcommandline.mp4 "


echo $bash2run  >/root/cx.txt


youtube-upload --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials.json 
--title=mytitle --privacy=private /root/thefileiwanttouploadwhichisfineandworksfromcommandline.mp4

echo $?  >>/root/cx.txt  (this echoes the error 126 when runby cron)

echo $*  >> /root/cx.txt  

echo $$  >> /root/cx.txt

echo "---------end of up427.sh-------------------"  >>/root/cx.txt

逐字sh文件up427.sh结束

同样,cx.txt 文件只是将错误排除在在 crontab 下运行 sh 文件,这样我就可以看到没有发生什么。

我尝试使用目录的所有渗透在此 sh 文件中调用 youtube-upload。从 cron 调用此 sh 时不起作用

/root/youtube-upload 下有一个子目录
我什至没有看到那里的程序很奇怪。

程序在引用的变量中记录了所有以下参数。

请注意,我有变量只是为了将其导出到 cx.txt 错误输出日志文件,但我实际上使用 bash 调用程序,如下一行所示。

我已经尝试过(在脚本中) bash“你上传--arguments” 没有引号。双引号。 sh 文件中的单引号等。

我在路径中包含了我能想到的所有内容。好像没什么区别。

程序来自

https://github.com/tokland/youtube-upload

我在这里查看了许多 crontab 答案,但没有一个适用并且让您从 cronjob 计划上传工作!

是的,程序确实被调用了。

cx.txt 中的错误表明了这一点。

我的目录结构是

/home/root/
then under that
drwxr-xr-x  7 root root     4096 Apr 24 16:04 google-api-php-client
drwxr-xr-x  3 root root     4096 Apr 24 17:40 .subversion
drwxr-xr-x  3 root root     4096 Apr 24 17:40 install
drwxr-xr-x  6 root root     4096 Apr 24 17:46 youtube-upload
-rw-r--r--  1 root root    17833 Apr 24 17:47 master.zip.1
drwxr-xr-x  6 root root     4096 Apr 24 17:47 youtube-upload-master
 -rw-r--r-- 1 root root   855 Apr 28 12:36 up427.sh

另外 /youtube-upload 的目录是

root@(none):~/youtube-upload# ls -l -t -r -a 
total 52
-rw-r--r--  1 root root  1247 Apr 24 17:46 setup.py
-rw-r--r--  1 root root  4920 Apr 24 17:46 README.md
-rw-r--r--  1 root root   725 Apr 24 17:46 .gitignore
drwxr-xr-x  2 root root  4096 Apr 24 17:46 examples
-rw-r--r--  1 root root   522 Apr 24 17:46 client_secrets.json
drwxr-xr-x  2 root root  4096 Apr 24 17:46 bin
drwxr-xr-x  6 root root  4096 Apr 24 17:46 .
drwxr-xr-x  3 root root  4096 Apr 24 17:46 youtube_upload
drwxr-xr-x  8 root root  4096 Apr 24 17:46 .git
drwx------ 11 root root 12288 Apr 28 01:28 ..

请提出建议

我不知道这是 github 项目文件范围或 cron 范围的错误还是一些愚蠢的错字

当我使用从终端运行它时

bash up427.sh

这是成功的输出

 root@(none):~# bash  up427man.sh
 Using client secrets: /usr/local/share/youtube_upload/client_secrets.json
 Using credentials file: /root/.youtube-upload-credentials.json
 Start upload: /root/thefileiwanttouploadwhichisfineandworksfromcommandline.mp4
 Video URL: https://www.youtube.com/watch?v=(theyoutubevideonumber)
 (randomcodespecifictoyoutubeasuthwhichiwontshowhere)

有些人要求以下内容

echo $SHELL
/bin/bash
root@(none):~# ps -p $$
 PID TTY          TIME CMD
20144 pts/1    00:00:00 bash
root@(none):~# which bash
/bin/bash

一些想法

我开始认为它可能无法解析 youtube-upload -arguments -arguments-arguments 的命令

我认为当 cron 调用时部件需要用引号引起来,但当 bash sh 文件从终端完成时则不需要。只是一个猜测。可能是完全错误的。现在尝试在零件周围使用多种不同的引号。

我对 sh 或 crontab 文件顶部的标题一无所知。喜欢 bin/bash 的东西,然后 misisng !等等

这很重要吗? crontab -e 编辑文件的顶部应该是什么

还有我的 up427.sh 文件?

奇怪的是,我一生都无法弄清楚我从 bash 或运行的命令行运行的程序的名称是什么

youtube-upload

因为这似乎是一个目录名称,而我实际上找不到该名称但它运行的程序!会不会是某个环境变量在键入时会调用另一个程序?

当我开始向它添加目录前言时,例如 /root/youtube-上传

我得到诸如“程序'youtube-upload'是一个目录”之类的东西

然而调用是

youtube-upload --title=blahblah -- decription=blahblah

正如它在 git 页面上显示的那样!

以最纯粹的工作形式从命令行运行 在表格中

bash up427.sh

up427.sh 是

youtube-upload --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials.json --title='titleonyoutube' --privacy=private /root/filetobeuploaded.mp4

这没有在 cronjob 下运行时将 txt 发送到文件以向我显示输出的所有废话。

希望对你有帮助。

运行时有效

bash up427.sh

从终端命令行

但是从 crontab 文件调用时返回错误 127

更新

尝试在从 crontab 调用的脚本中使用 EVAL 语句后

这是一个新脚本,其中包含对 youtube-upload 程序的调用的多种变体,包括许多引号变体等,以查看是否可行。调用的每个变体都在 Youtube 名称上命名为不同的上传名称,因此我可以看到哪个已上传到 youtube。

和以前一样,从 cron 调用时没有任何效果

所以 eval 没有帮助。

但是,当使用新的 eval 和旧的 echo 语句时,当从终端调用相同的脚本时,与之前一样上传了许多变体

这些是从终端调用脚本时上传的调用的变体。

如你所见

四个使用 eval 工作

还有四个使用 echo 的旧方法工作

2avartest2 HD

2commbashworksvartest2 HD

avartest2 HD

commbashworksvartest2 HD

2avartest2eval HD

2commbashworksvartest2eval HD

avartest2eval HD

commbashworksvartest2eval HD

再一次,它们仅在从终端运行脚本时才起作用,而在从 cron 运行时不起作用!

ARRGGHHHHH 双三重奏!

这是一个新脚本,其中有许多 (8) 个使用 eval 的实例和相同的旧 8 个使用 echo 的实例,但也不起作用

(我不知道如何将整个内容粘贴为一个巨大的代码块,因此它没有缩进,因为我无法手动缩进所有这些行。但坦率地说,无论如何它更容易阅读。)

    commbashworks="youtube-upload --title=commbashworksvartest2eval --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials.json --privacy=private /root/uptest.mp4"

评估 $commbashworks

回声

a='youtube-upload --title=avartest2eval --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials.json - -privacy=private /root/uptest.mp4'

评估$a

回声

b="/root/youtube-upload --title=bvartest2eval --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials .json --privacy=private /root/uptest.mp4"

评估 $b

回声

c='/root/youtube-upload --title=cvartest2eval --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials .json --privacy=private /root/uptest.mp4'

评估 $c

回声

d="../root/youtube-upload --title=dvartest2eval --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload -credentials.json --privacy=private /root/uptest.mp4"

评估$d

回声

e='../root/youtube-upload --title=evartest2eval --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload -credentials.json --privacy=private /root/uptest.mp4'

评估 $e

回声

#

commbashworks="youtube-upload --title=2commbashworksvartest2eval --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials.json - -privacy=private uptest.mp4"

评估 $commbashworks

回声

a='youtube-upload --title=2avartest2eval --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials.json - -privacy=private uptest.mp4'

评估$a

回声

b="/root/youtube-upload --title=2bvartest2eval --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials .json --privacy=private uptest.mp4"

评估 $b

回声

c='/root/youtube-upload --title=2cvartest2eval --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials .json --privacy=private uptest.mp4'

评估 $c

回声

d="../root/youtube-upload --title=2dvartest2eval --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload -credentials.json --privacy=private uptest.mp4"

评估$d

回声

e='../root/youtube-upload --title=2evartest2eval --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload -credentials.json --privacy=private /uptest.mp4'

评估 $e

回声

#

commbashworks="youtube-upload --title=commbashworksvartest2 --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials.json - -privacy=private /root/uptest.mp4"

不要替换这个

回声 $($commbashworks)

回声

a='youtube-upload --title=avartest2 --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials.json - -privacy=private /root/uptest.mp4'

回声 $($a)

回声

b="/root/youtube-upload --title=bvartest2 --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials .json --privacy=private /root/uptest.mp4"

回声 $($b)

回声

c='/root/youtube-upload --title=cvartest2 --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials .json --privacy=private /root/uptest.mp4'

回声 $($c)

回声

d="../root/youtube-upload --title=dvartest2 --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload -credentials.json --privacy=private /root/uptest.mp4"

回声 $($d)

回声

e='../root/youtube-upload --title=evartest2 --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload -credentials.json --privacy=private /root/uptest.mp4'

回声 $($e)

回声

#

commbashworks="youtube-upload --title=2commbashworksvartest2 --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials.json - -privacy=private uptest.mp4"

回声 $($commbashworks)

回声

a='youtube-upload --title=2avartest2 --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials.json - -privacy=private uptest.mp4'

回声 $($a)

回声

b="/root/youtube-upload --title=2bvartest2 --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials .json --privacy=private uptest.mp4"

回声 $($b)

回声

c='/root/youtube-upload --title=2cvartest2 --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials .json --privacy=private uptest.mp4'

回声 $($c)

回声

d="../root/youtube-upload --title=2dvartest2 --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload -credentials.json --privacy=private uptest.mp4"

回声 $($d)

回声

e='../root/youtube-upload --title=2evartest2 --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload -credentials.json --privacy=private /uptest.mp4'

回声 $($e)

回声

#

找到更新解决方案!

更正它没有用。它删除了文件。

【问题讨论】:

  • 57 * * * * /bin/bash /root/up427.sh; /bin/echo $?; /bin/echo$*; /bin/echo $$ > /root/up427dirfromcron.txt ?您也可以将完整路径添加到 shell 脚本中的所有内容......只是为了排除任何路径问题

标签: bash shell youtube-api cron-task


【解决方案1】:

我的第一个猜测是您的默认 shell 不是 Bash,并且当脚本在 cron 下执行时,它会在不同的 shell 下运行。我猜测这是因为您遇到了从 CLI 到 CRON 的一些差异的原因是:

  1. 我注意到,当交互式运行时,您通过 bash up427.sh 指定 bash;和
  2. 您没有在脚本顶部指定 shell。

为了帮助我们解决问题:

  • 您可以将您的 crontab 条目添加到您的帖子中吗?
  • 您能告诉我们您在终端运行echo $SHELL 时看到了什么吗?

更新

根据您的更新,看起来不匹配的外壳可能不是根本原因。鉴于不断变化的错误代码(从 126 到 127),必须涉及更多内容。要完全排除不匹配的shell,您是否可以从目标服务器的终端尝试以下操作(以运行crontab的同一用户身份登录终端)并报告输出:

$ echo $SHELL
$ ps -p $$
$ which bash

更新 #2
我建议使用eval。为此,您需要将完整的命令构建为将传递给eval 的字符串。这将被用来代替echo $bash2run >/root/cx.txt。这个想法的一个基本例子是:

my_args='-al'
eval "ls ${my_args}"

如果你从这个基本的例子开始,我想你会得到它的工作。

关于evalexecsource 的使用的小型但内容丰富的讨论,我建议您阅读bash shell: 'exec', 'eval', 'source' - looking for help to understand 上的此线程

此外,我建议通过添加-x 标志以调试模式运行脚本,如下所示:

bash -x up427.sh

【讨论】:

  • echo #SHELL 返回一个空白行,我在顶部附近添加了实际的 crontab -e。我现在从 cron 运行时收到错误 127 而不是错误 126,因此它无法找到命令 youtube-upload 。我不知道我改变了什么。呃
  • echo $SHELL /bin/bash root@(none):~# ps -p $$ PID TTY TIME CMD 20144 pts/1 00:00:00 bash root@(none):~#哪个 bash /bin/bash
  • 好的,我将深入了解您的脚本。同时,您能否确认脚本从终端正确运行?您关于错误代码更改的 cmets 很奇怪,尤其是没有更改。
  • 是的,我刚刚确认了从终端运行“bash up427.sh”的脚本,其他所有内容都被注释掉了(以便于理解)
  • youtube-upload --client-secrets=/usr/local/share/youtube_upload/client_secrets.json --credentials-file=/root/.youtube-upload-credentials.json(这里换行但是不在 nano 编辑器的脚本文件中)--title='titleonyoutube' --privacy=private /root/filetobeuploaded.mp4
【解决方案2】:

找到更新解决方案! 好吧,解决方案实际上删除了一些随机文件,因此我将其删除,直到找出原因为止。

我留下了之前的重要笔记

任何时候你都使用 CRON 我不能足够强调完全指定所有 sh 文件、参数中的文件以及任何你想通过管道输出的文件的完整路径的重要性,例如 >> /mydirectorywhereiwantit/ crontab 文件和 sh 文件脚本文件中的完整 output.txt。

据我所知,cron 会在 bashing 时查找文件并将文件写入它碰巧所在的任何目录,如果该目录与您通常从终端。在 CRONTAB 和被调用的 SH 脚本文件和参数中完全指定所有文件的所有路径!

感谢约翰·马克·米切尔 (John Mark Mitchell) 提供了这么多可能的解决方案。

【讨论】:

    猜你喜欢
    • 2021-03-19
    • 2018-07-09
    • 2011-07-22
    • 1970-01-01
    • 2019-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多