セロリには多くのプロセスがあるので、サーバーでセロリを再起動したいと思います。すべてのプロセスIDを照会して終了するために、次のスクリプトを作成しました。
#
# stop celery process
#
PID=`ps -ef|grep -w ${CELERY_PROGRAM_NAME}|grep -v grep|cut -c 9-15`
if [ -z "${PID}" ]; then
echo "Process aready down..."
else
array=(${PID//\n/})
for var in "${array[@]}"
do
single_pid=`echo ${var} | awk 'gsub(/^ *| *$/,"")' `
if [[ ${single_pid} -gt 1 ]]; then
kill -15 "${single_pid}"
else
echo "Process ${PROGRAM_NAME} not found"
fi
done
fi
ログでpidが配列に変換されておらず、次のステップが正しく分割されていないことがわかりました。 GitHub Actionsでリモートでこのスクリプトを実行します。以下はGitHub Actionsのログ出力です。
======CMD======
cd /opt/apps/pydolphin
. /opt/apps/pydolphin/restart.sh
======END======
err: +/opt/apps/pydolphin/restart.sh:16> PROGRAM_NAME=schedulespider.py
err: +/opt/apps/pydolphin/restart.sh:17> CELERY_PROGRAM_NAME=celery
err: +/opt/apps/pydolphin/restart.sh:18> PYTHON_BIN_PATH=/usr/bin/python3
err: +/opt/apps/pydolphin/restart.sh:23> PID=+/opt/apps/pydolphin/restart.sh:23> ps -ef
err: +/opt/apps/pydolphin/restart.sh:23> PID=+/opt/apps/pydolphin/restart.sh:23> grep -w celery
err: +/opt/apps/pydolphin/restart.sh:23> PID=+/opt/apps/pydolphin/restart.sh:23> grep -v grep
err: +/opt/apps/pydolphin/restart.sh:23> PID=+/opt/apps/pydolphin/restart.sh:23> cut -c 9-15
err: +/opt/apps/pydolphin/restart.sh:23> PID=' 9777
err: 9778
err: 9779
err: 9865
err: 9867
err: 9868 '
err: +/opt/apps/pydolphin/restart.sh:24> [ -z ' 9777
err: 9778
err: 9779
err: 9865
err: 9867
err: 9868 ' ']'
err: +/opt/apps/pydolphin/restart.sh:27> array=( ' 9777
err: 9778
err: 9779
err: 9865
err: 9867
err: 9868 ' )
err: +/opt/apps/pydolphin/restart.sh:28> var= 9777
err: 9778
err: 9779
err: 9865
err: 9867
err: 9868
err: +/opt/apps/pydolphin/restart.sh:30> single_pid=+/opt/apps/pydolphin/restart.sh:30> echo ' 9777
err: 9778
err: 9779
err: 9865
err: 9867
2021/07/19 06:00:52 Process exited with status 1
err: 9868 '
err: +/opt/apps/pydolphin/restart.sh:30> single_pid=+/opt/apps/pydolphin/restart.sh:30> awk 'gsub(/^ *| *$/,"")'
err: +/opt/apps/pydolphin/restart.sh:30> single_pid='9777
err: 9778
err: 9779
err: 9865
err: 9867
err: 9868'
err: +/opt/apps/pydolphin/restart.sh:31> [[ '9777
err: 9778
err: 9779
err: 9865
err: 9867
err: 9868' -gt 1/opt/apps/pydolphin/restart.sh:31: bad math expression: operator expected at `9778\n9779\n...'
err: ]]
スクリプトを読みましたが、何が間違っているのかわかりませんでした。スクリプトを機能させるにはどうすればよいですか?
ベストアンサー1
単にを使用する代わりに独自の「終了ループ」を作成することを決定した場合は、少なくとも次pkill
のpgrep
出力を分割し、分割は代わりに可能な先行/末尾のスペースによって妨げられないPIDのリストを取得するために使用しますps
。
array=($(pgrep -- "${CELERY_PROGRAM_NAME}"))
pgrep
または、出力を直接繰り返します。
for single_pid in $(pgrep -- "${CELERY_PROGRAM_NAME}"); do ...
pgrep
1行に1つずつPIDリストを作成します。デフォルトの bash IFS は連続した空白に分割されます。改行を含むたとえば、配列にマップします。
$ pgrep ssh
1194
3688
22642
22754
$ array=($(pgrep ssh))
$ declare -p array
declare -a array=([0]="1194" [1]="3688" [2]="22642" [3]="22754")
または使用できますreadarray -t array < <(pgrep ssh)
。
要素がないとループは実行されないため、文字列が空であることをテストする必要はありません。
実装が機能しない理由は1${PID//\n/}
からリテラルn
文字が削除されます。数値のみを含むと仮定すると、何もできません。PID
PID
array=(${PID//\n/})
しなければならないsingle_pid
PIDを取得するために追加の処理を必要としないように、別々のPID配列が作成され、先行スペースと末尾のスペースが削除されます。
エラー出力によると、明らかにそうではないという事実は、次の2つの理由の1つを示唆しています。
シェルのIFS値を修正しました。
使用中のシェルは、引用符のない変数拡張をトークン化しません。
zsh
、出力形式は、デフォルトのxtrace
動作としてファイルを使用していることを示します。つまり、コマンドの置き換え時にIFS分割を実行しても、上記のコードはそのシェルで動作し続けます。から改行に分割するには、zsh
次を使用することをお勧めします。array=(${(f)"$(pgrep -- $CELERY_PROGRAM_NAME)"})
ただし、これは現在の値への依存関係を
bash
排除します。readarray
$IFS
1実際に改行文字を削除するには、以下を使用できます。${PID//$'\n'/}