【发布时间】:2016-02-03 09:24:03
【问题描述】:
我正在设置 Ubuntu 14.04 服务器以使用 Phonegap CLI 自动构建混合 Android 应用程序。编写完所有相关脚本后,我遇到了一个相当奇怪的问题——当我通过 SSH 连接到我的服务器时,我可以运行脚本并在我的交互式 shell 会话中成功运行所有 Phonegap 命令。但是,每次尝试在由其他一些访问者生成的事件触发的自动化脚本中运行这些相同的命令都会失败。为了确定问题,我将其简化为一个简单的实验,如下所述。
第 1 步 - 编写启动脚本,pgtest in /etc/init.d
#! /bin/bash
source ~/.nvm/nvm.sh;
nvm use stable;
cd /home;
ls >> /tmp/ls;
which node >> /tmp/node;
which git >> /tmp/git;
which phonegap >> /tmp/pgp;
phonegap -v >> /tmp/pgpv 2>/tmp/pgpe;
解释
- 我使用 NVM 来管理 Node,所以我确保系统知道在哪里可以找到 nvm.sh
- 我正在启动 NVM 以使用 Node + NPM 的稳定 (4.1.1.) 版本
- 我想确保我的批处理文件实际上正在执行,所以我执行
ls /home并将其输出通过管道传输到/tmp/ls文件。 - 我想确保 node、git 和 phonegap 确实可用,因此我将
which node|git|phonegap的输出通过管道传输到/tmp文件夹中的文件。 - 一点都不复杂,所以我发出最简单的 Phonegap 命令,
phonegap -v来报告当前版本号。执行此操作时可能发生的任何错误都将通过管道传输到文件/tmp/pgpe。
第 2 步 - 确保最后运行 pgtest
ln -s /etc/init.d/pgtest /etc/rc2.d/S04PGTest
解释 - 我只希望这个脚本在我的服务器上的所有其他东西有机会启动后运行
完成所有这些后,我通过服务器重新启动并检查了/tmp 文件夹的内容。我的发现
-
ls-/home文件夹的文件夹列表存在且正确。 -
node、git和pgp指向 Node、Git 和 Phonegap 的位置 -
pgpv,应该包含Phonegap版本号,是EMPTY -
pgpe存在且不为空
这意味着 系统 在尝试执行 phonegap -v 时遇到错误。以下是pgpe的内容。
path.js:8
throw new TypeError('路径必须是字符串。已接收' +
^
TypeError:路径必须是字符串。收到未定义
在 assertPath (path.js:8:11)
在 Object.posix.join (path.js:477:5)
在对象处。
(/root/.nvm/versions/node/v4.1.1/lib/node_modules/phonegap/node_modules/phonegap-build/lib/common/config/global.js:17:28)
在 Module._compile (module.js:434:26)
在 Object.Module._extensions..js (module.js:452:10)
在 Module.load (module.js:355:32)
在 Function.Module._load (module.js:310:12)
在 Module.require (module.js:365:17)
在需要时(module.js:384:17)
在对象。 (/root/.nvm/versions/node/v4.1.1/lib/node_modules/phonegap/node_modules/phonegap-build/lib/common/config.js:9:13)
现在奇怪的是。如果我清除 /tmp 文件夹并在交互式 shell 会话中发出 /etc/init.d/pgtest 我会得到以下结果
-
/tmp/ls与以前一样出现并填充有/home文件夹列表 -
/tmp/node,/tmp/git/tmp/pgp存在且正确 -
/tmp/pgpvreports5.3.6- 当前Phonegap版本号 -
/tmp/pgpe是 EMPTY ,即没有错误报告
显然,交互式 bash shell 环境有一些在我运行自动化脚本时不存在的东西 - 在这种情况下是在启动时,但当我以任何其他方式通过自动化脚本触发进程时也会发生这种情况。
通过所有这些,我越来越接近确定问题的原因。然而,我对这些系统如何工作的了解让我失望了。交互式 shell 环境与我的自动化脚本遇到的环境有什么区别?我该如何解释/tmp/pgpe 中报告的错误?我该怎么做才能修复它们?
我将非常感谢任何能够让我走上正轨的人。
根据@Eduardo 的建议进行编辑。我抓住了两组环境(交互式和 init.d)。可以在this fiddle 中找到执行 DIFF(交互式与 init.d)的结果。下面显示了一个不太容易访问的 DIFF 结果转储
--- /home/env.inter 2015-11-11 08:30:40.314172560 +0000 +++ /home/env.auto 2015-11-11 08:32:55.240906000 +0000 @@ -1,48 +1,38 @@ bash=/bin/bash BASHOPTS=cmdhist:complete_fullquote:extquote:force_fignore:hostcomplete:interactive_cmets:login_shell:progcomp:promptvars:sourcepath BASH_ALIASES=() -BASH_ARGC=() -BASH_ARGV=() +BASH_ARGC=([0]="1") +BASH_ARGV=([0]="开始") BASH_CMDS=() BASH_LINENO=([0]="0") -BASH_SOURCE=([0]="/etc/init.d/pgtest") +BASH_SOURCE=([0]="/etc/rc2.d/S04pgtest") BASH_VERSINFO=([0]="4" 1="3" [2]="11" [3]="1" [4]="release" [5]="x86_64-pc-linux-gnu ") BASH_VERSION='4.3.11(1)-发布' DIRSTACK=() EUID=0 组=() -HOME=/根 主机名=example.com 主机类型=x86_64 IFS=$'\t\n' -LANG=en_US.UTF-8 -LESSCLOSE='/usr/bin/lesspipe %s %s' -LESSOPEN='| /usr/bin/lesspipe %s' -LOGNAME=root -LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01: cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37; 44:ex=01;32:.tar=01;31:.tgz=01;31:.arj=01;31:.taz=01;31: .lzh=01;31:.lzma=01;31:.tlz=01;31:.txz=01;31:.zip=01; 31:.z=01;31:.Z=01;31:.dz=01;31:.gz=01;31:.lz =01;31:.xz=01;31:.bz2=01;31:.bz=01;31:.tbz=01;31: .tbz2=01;31:.tz=01;31:.deb=01;31:.rpm=01;31:.jar=01;31:.war=01;31:.ear=01;31:.sar=01;31:.rar=01;31:.ace=01; 31:.zoo=01;31:.cpio=01;31:.7z=01;31:.rz=01;31:.jpg= 01;35:.jpeg=01;35:.gif=01;35:.bmp=01;35:.pbm=01;35: .pgm=01;35:.ppm=01;35:.tga=01;35:.xbm=01;35:.xpm=01;35:.tif=01;35:.tiff=01;35:.png=01;35:.svg=01;35:.svgz=01;35 :.mng=01;35:.pcx=01;35:.mov=01;35:.mpg=01;35:.mpeg= 01;35:.m2v=01;35:.mkv=01;35:.webm=01;35:.ogm=01;35:.mp4=01;35:.m4v=01;35:.mp4v=01;35 :.vob=01;35:.qt=01;35:.nuv=01;35:.wmv=01;35:.asf= 01;35:.rm=01;35:.rmvb=01;35:.flc=01;35:.avi=01;35:。 fli=01;35:.flv=01;35:.gl=01;35:.dl=01;35:.xcf=01;35: em>.xwd=01;35:.yuv=01;35:.cgm=01;35:.emf=01;35:.axv=01;35 :.anx=01;35:.ogv=01;35:.ogx=01;35:.aac=00;36:.au=00 ;36:.flac=00;36:.mid=00;36:.midi=00;36:.mka=00;36:。 mp3=00;36:.mpc=00;36:.ogg=00;36:.ra=00;36:.wav=00;36:.axa=00;36:.oga=00;36:.spx=00;36:.xspf=00;36:' MACHTYPE=x86_64-pc-linux-gnu -MAIL=/var/mail/root -NVM_DIR=/root/.nvm -NVM_IOJS_ORG_MIRROR=https://iojs.org/dist -NVM_NODEJS_ORG_MIRROR=https://nodejs.org/dist -NVM_RC_VERSION= OPTERR=1 选择=1 OSTYPE=linux-gnu -PATH=/opt/android/platform-tools:/opt/android/tools:/opt/android:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin :/bin:/usr/games:/usr/local/games +PATH=/sbin:/usr/sbin:/bin:/usr/bin PIPESTATUS=([0]="0") -PPID=4801 +PPID=911 +前级=N PS4='+' -PWD=/etc/init.d +密码=/ +RUNLEVEL=2 SHELL=/bin/bash SHELLOPTS=braceexpand:hashall:interactive-cmets -SHLVL=3 -SSH_CLIENT='nn.nn.nn.nn nnnn nnnn' -SSH_CONNECTION='nn.nn.nn.nn nnnn nn.nn.nn.nn nnnn' -SSH_TTY=/dev/pts/0 -期限=xterm +SHLVL=1 +期限=Linux UID=0 -用户=根 -XDG_RUNTIME_DIR=/运行/用户/1000 -XDG_SESSION_ID=5 +UPSTART_EVENTS=运行级别 +UPSTART_INSTANCE= +UPSTART_JOB=rc _=n +上一个=N +runlevel=2
我在这里更改的唯一内容 - 屏蔽了主机名和 SSH 客户端 IP 地址。
我很确定在发布这个问题之前我已经在自己的实验中尝试过这个,但是按照下面@Eduardo 的建议,我尝试坚持
EXPORT PATH=/opt/android/platform-tools:/opt/android/tools:/opt/android:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
在脚本的顶部 - 就在 source ~/.nvm... 行的下方。重启后结果还是一样:空的/tmp/pgpv 和/tmp/pgpe 中报告的相同错误。
【问题讨论】:
-
man bash。一个交互式 bash shell 附带profiles 或rcs 来源,具体取决于它是否是登录 shell。 -
这可能是问题所在:pgpv 2> 因为它包含空格和更大的符号。
-
@4ae1e1 您的评论可能有用,但对我没有用。正如我所提到的,我已经达到了我对 bash 的理解的极限。那个 man bash 条目是什么意思,它与我观察到的有什么关系?
-
@LajosArpad。嗯......我是否在我的问题中暗示我的脚本没有运行并且我需要帮助?
pgpv>与手头的问题无关。 -
您认为
~在系统启动时运行的init.d脚本会解析到什么?哪个用户具有适合您想要执行的操作的 phonegap 配置?你在设置phonegap/node/etc吗?普通用户的shell初始化文件中的相关设置? (安装可能会自动为您设置它们。)
标签: bash cordova automation phonegap-cli