Phonegap CLI を使用してハイブリッド Android アプリのビルドを自動化するために、Ubuntu 14.04 サーバーをセットアップ中です。関連するすべてのスクリプトを作成した後、かなり奇妙な問題に遭遇しました。サーバーに SSH で接続すると、対話型シェル セッションでスクリプトを実行し、すべての Phonegap コマンドを正常に実行できます。ただし、他の (訪問者が生成した) イベントによってトリガーされる自動化されたスクリプトで同じコマンドを実行しようとすると、すべて失敗します。問題を特定するために、以下に概説する簡単な実験に絞り込みました。
ステップ 1 - 起動スクリプトを作成pgtest
します。/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 の場所を認識していることを確認しています。
- ノード+ NPMの安定版(4.1.1)を使用するためにNVMを起動しています
- バッチファイルが実際に実行されていることを確認したいので、
ls /home
その出力をファイルにパイプし/tmp/ls
ます。 - node、git、phonegap が実際に利用可能であることを確認したいので、出力をフォルダー内
which node|git|phonegap
のファイルにパイプし/tmp
ます。 phonegap -v
物事を複雑にすることはほとんど意味がないので、現在のバージョン番号を報告するために、最も単純な Phonegap コマンドを発行しています。これを行うときに発生する可能性のあるエラーは、ファイルにパイプされています/tmp/pgpe
。
ステップ 2 -pgtest
最後に
ln -s /etc/init.d/pgtest /etc/rc2.d/S04PGTestが実行されていることを確認します
説明- サーバー上の他のすべてが起動する機会があった後にのみ、このスクリプトを実行したい
これらすべてが整った状態で、サーバーで再起動し、/tmp
フォルダーの内容を調べました。私の発見
ls
/home
-存在する正しいフォルダのフォルダ リスト。node
、Node、Git、およびPhonegapの場所を指しgit
ますpgp
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
フォルダをクリアして/etc/init.d/pgtest
インタラクティブ シェル セッションで a を発行すると、次の結果が得られます。
/tmp/ls
/home
前と同じようにフォルダ リストが存在し、取り込まれます/tmp/node
、/tmp/git
/tmp/pgp
現在および正しい/tmp/pgpv
reports5.3.6
- 現在の Phonegap のバージョン番号/tmp/pgpe
EMPTYです。つまり、エラーは報告されません
明らかに、インタラクティブな bash シェル環境には、自動化されたスクリプトを実行したときに存在しないものがあります。この場合は起動時に発生しますが、他の方法で自動化されたスクリプトを介してプロセスをトリガーすると発生します。
このすべてで、私は問題の原因を突き止めることに近づいています. しかし、これらのシステムがどのように機能するかについての私の知識は、私をがっかりさせています。インタラクティブなシェル環境と、自動化されたスクリプトが遭遇する環境との違いは何ですか? で報告されたエラーをどのように解釈すればよい/tmp/pgpe
ですか? それらを修正するにはどうすればよいですか?
ここで私を正しい軌道に乗せることができる人には、非常に感謝しています。
@Eduardo の提案に照らして編集します。2 つの環境セット (interactive と init.d) を取得しました。DIFF (interactive vs init.d) を実行した結果は、この fiddleにあります。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_comments: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]="リリース" [5]="x86_64-pc-linux-gnu") BASH_VERSION='4.3.11(1)-リリース' DIRSTACK=() EUID=0 GROUPS=() -HOME=/root HOSTNAME=example.com HOSTTYPE=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: ..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: .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 OPTIND=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 +PREVLEVEL=N PS4='+ ' -PWD=/etc/init.d +PWD=/ +RUNLEVEL=2 SHELL=/bin/bash SHELLOPTS=ブレースエキスパンド:ハッシュ:インタラクティブコメント -SSHLVL=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 -TERM=xterm +SHLVL=1 +TERM=linux UID=0 -USER=root -XDG_RUNTIME_DIR=/run/user/1000 -XDG_SESSION_ID=5 +UPSTART_EVENTS=ランレベル +UPSTART_INSTANCE= +UPSTART_JOB=rc _= n +前回=N +ランレベル=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
。