web-dev-qa-db-ja.com

Bashコマンドはターミナルで実行されますが、Jenkins / Bashスクリプトでは実行されません

開発者が使用できるように、Jenkinsを使用してHTMLドキュメントをビルドし、ローカルのApache Webサーバーにデプロイしています。ターミナルでコマンドを実行すると、すべてが正しくインストールされます(サーバーが正しくセットアップされていることを証明します)。ただし、Jenkins内から同じコマンドを実行すると、それらは呼び出されますが、何も変更されません。 html.Zip(18行目)は削除されず、ファイルは/var/html/www/subdirに移動されません。また、curlリクエスト以外のエラーは報告されません。私は自分が間違っていることについて少し迷っています。

このスクリプト全体をSudoと呼ぶことに注意してください。私はこれが安全でないことを知っていますが、私は最初にスクリプトを動作させて、後でそれを変更しようとすることを考えました。 userがドキュメントのインストールの問題に遭遇しないようにするために、パスワードなしでSudoとしてコマンドを実行することを一時的に許可しました。繰り返しますが、これは安全ではないことを知っていますが、変数を排除しようとする精神のもと、これを追加しました。

Jenkinsはこのスクリプトを次のように呼び出します:Sudo ./documentation-publisher.sh

スクリプトのアクセス許可は、現時点で最も制限が少ない777です。スクリプトでls -lを呼び出すと、次のように報告されます:-rwxrwxrwx 1 devop developers 1144 Dec 3 10:29 documentation-publisher.sh

スクリプトでパスを明示的に設定することについて この投稿 からの提案を試しましたが、違いはありませんでした。使用される各コマンドへの明示的なパスも動作を変更しません。

#!/bin/sh -x

echo "Archiving generated HTML for transfer..."
cd Example/docs/html/
Zip -r html.Zip ./
scp -i ~/.ssh/id_rsa html.Zip [email protected]:/home/user 
ssh -i ~/.ssh/id_rsa [email protected] 

echo "Extracting generated HTML into www directory..."
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
unzip -o html.Zip -d ./subdir
rm -r /var/www/html/subdir
mkdir /var/www/html/subdir
cp -r ./subdir/* /var/www/html/subdir/

echo "Cleaning up after file transfer..."
rm -rf ./subdir 
rm ./html.Zip 

echo "Testing install..."
curl -f my.Host.example.com/subdir/index.html 
exit 

何が悪いのでしょうか?

4

My.Host.example.comにsshを挿入し、残りのスクリプトをそのホストで実行したいようです。この場合は、スクリプトの残りの部分をsshコマンドへの入力として渡す必要があります。現状では、sshはスクリプトのstdinから入力を受け取っている可能性があります。そのため、リモートシェルセッションを開き、ファイルの終わりを送信して、sshセッションを閉じて実行します。スクリプトの残りの部分。これらのコマンドをリモートで実行するには、sshコマンドへの入力として次のように渡す必要があります。

ssh -i ~/.ssh/id_rsa [email protected] <<EOF

echo "Extracting generated HTML into www directory..."
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
[...]
exit
EOF

次に、スクリプトにはエラーチェックがありません。一般に、スクリプト内の各コマンドを見て、失敗した場合はどうなるかを自問することをお勧めします。スクリプトの残りの部分を続行する必要がありますか、それとも「Railsから逃げて」ばかげたことをしますか?たとえば、scpコマンドが(何らかの理由で)失敗した場合、残りのスクリプトを実行しても意味がありません(/ var/www/htmlを消去して破壊的になる可能性があります)/subdirそしてそれを...おっと、何にも置き換えません)。次のように、個々のコマンドの終了ステータスごとにエラーチェックを実行できます。

scp -i ~/.ssh/id_rsa html.Zip [email protected]:/home/user || {
    echo "Failed to scp the html files to my.Host.example.com." >&2
    exit 1
}

...またはシェルの-eオプション(anyコマンドが失敗した場合にスクリプトを終了する)このオプションを使用すると、各コマンドを個別にエラーチェックする必要がなくなりますが、有益なエラーメッセージは表示されず、重要でないものが何らかの理由でエラーステータスを返した場合にスクリプトを終了することで問題を引き起こす可能性があります( BashFAQ#105 理由の例については-eは予期しない動作を引き起こす可能性があります)。また、このオプションを使用する場合は、必ずset -e両方をスクリプトの先頭に(または-xe(シバン行)、set -eリモートコンピュータに送信される最初のコマンドとして。

ところで、4行目のcdコマンドは、相対パスを使用しているため、特に失敗する可能性があります。これは、スクリプトが開始された作業ディレクトリに依存してcdを試行するディレクトリを意味します。これは必ずしもスクリプトがあるディレクトリではないことに注意してください。スクリプトを開始したプロセスから継承されているため、ほとんど何でもかまいません。 Jenkinsは、ユーザーとは異なる作業ディレクトリでスクリプトを開始しているため、すぐに失敗する可能性があります。まあ、実際には失敗せず、残りのすべてのコマンドを間違ったディレクトリで実行してください(ssh入力の問題のため、間違ったホストで)。

4
Gordon Davisson

ファイルをコピー、削除、または移動する場合は、絶対パスを使用するようにスクリプトを変更してください。現在、これらの行があります

rm ./html.Zip cp -r ./subdir/* /var/www/html/subdir/

変更 ./そのファイルまたはディレクトリへのフルパスへの部分。

2
lee