From 3b198b421212f3d04fa10426a66dc67a51434601 Mon Sep 17 00:00:00 2001
From: wandoubaba <wandoubaba517@gmail.com>
Date: Sat, 11 Nov 2023 13:23:35 +0800
Subject: [PATCH] new shell scripts

---
 .env.example       |   6 +-
 README.md          |  73 +++++++++++++++--
 composer           |  21 +++--
 config/process.php |  24 ++++--
 envexample         |  31 +++++++
 init               |  32 ++++++++
 php                |  22 +++++
 run                | 196 ---------------------------------------------
 server             |  48 +++++++++++
 9 files changed, 237 insertions(+), 216 deletions(-)
 create mode 100755 envexample
 create mode 100755 init
 create mode 100755 php
 delete mode 100755 run
 create mode 100755 server

diff --git a/.env.example b/.env.example
index a768e61..40a4645 100644
--- a/.env.example
+++ b/.env.example
@@ -7,9 +7,13 @@ SERVER_LISTEN = http://0.0.0.0:7878
 SERVER_COUNT = cpu_count()
 MAX_PACKAGE_SIZE = 1024*1024*5
 
+# monitor进程
+MONITOR_ENABLED = false
+
 # jsonrcp服务配置
+JSONRPC_ENABLED = true
 JSONRPC_SERVER_NAME = jsonrpc
-JSONRPC_SERVER_PORT = 8022
+JSONRPC_SERVER_LISTEN = JsonNL://0.0.0.0:8022
 JSONRPC_SERVER_COUNT = cpu_count()
 
 # REDIS配置
diff --git a/README.md b/README.md
index 7b50eb3..e4e85f0 100644
--- a/README.md
+++ b/README.md
@@ -9,11 +9,18 @@
 ## 使用方法
 
 ```sh
-# 启动
-./start
+# 初始化
+./init
 # composer
 ./composer install
-./conposer require xxxx
+./composer require xxxx
+# 服务控制
+./server start|restart|stop|status|reload|connections|logs
+# 自动生成.env.example文件
+./envexample
+# 执行其它php命令
+./php -m
+./php webman build:bin
 ```
 
 ## 一些有用的文件
@@ -21,11 +28,67 @@
 | 文件 | 作用 | 用法或说明 |
 |---|---|---|
 |composer|调起容器中的`composer`命令的shell脚本|用法与主机中的compose完全一致,`./composer $args...`|
-|run|调起容器中的`php start.php`命令的shell脚本,支持一系统参数,并支持-d模式|`./run help`可以查看用法|
-|docker-compose.yml|运行容器的编排文件|一般不需要理会这个文件,composer和start脚本都需要依赖这个文件|
+|server|服务控制脚本|`./server`可以查看用法|
+|docker-compose.yml|运行容器的编排文件||
 |docker.conf|定义运行服务的容器名称和使用的镜像版本|注意container_name不要与系统中其他服务的容器重名|
 |php.ini|映射到容器中的php.ini配置文件|容器中已经安装的扩展都有单独的配置文件,这里不会有体现|
 
 ## 服务端口
 
 在.env文件中可以定义服务端口,默认情况下docker容器是在host网络下启动的,当然,实际使用中也可以改成端口映射模式。
+
+## 已安装PHP扩展
+
+```sh
+php -m
+[PHP Modules]
+Core
+ctype
+curl
+date
+dom
+event
+exif
+fileinfo
+filter
+ftp
+gd
+hash
+iconv
+json
+libxml
+mbstring
+mysqli
+mysqlnd
+openssl
+pcntl
+pcre
+PDO
+pdo_mysql
+pdo_pgsql
+pdo_sqlite
+pgsql
+Phar
+posix
+readline
+redis
+Reflection
+session
+SimpleXML
+sockets
+sodium
+SPL
+sqlite3
+standard
+tokenizer
+xlswriter
+xml
+xmlreader
+xmlwriter
+Zend OPcache
+zip
+zlib
+
+[Zend Modules]
+Zend OPcache
+```
diff --git a/composer b/composer
index 19856cd..360511f 100755
--- a/composer
+++ b/composer
@@ -1,13 +1,22 @@
 #!/bin/bash
 
-# 读取docker.conf文件
-source docker.conf
+set -e
 
-# 设置系统环境变量
+source docker.conf
 export WORKERMAN_CONTAINER_NAME=$container_name
 export WORKERMAN_IMAGE_VERSION=$image_version
 
-# docker-compose.yml中的services下面的名字
-service_name="webman-jsonrpc"
+# 判断容器是否存在
+if [ ! "$(docker ps -a -q -f name=$WORKERMAN_CONTAINER_NAME)" ]; then
+    # 调用init脚本
+    ./init
+fi
 
-docker compose run --rm "$service_name" composer "$@"
+# 判断容器是否在运行
+if [ ! "$(docker inspect -f {{.State.Running}} $WORKERMAN_CONTAINER_NAME)" = "true" ]; then
+    # 启动容器
+    docker start $WORKERMAN_CONTAINER_NAME
+fi
+
+# 进入容器并执行composer命令
+docker exec -it $WORKERMAN_CONTAINER_NAME bash -c "composer $*"
\ No newline at end of file
diff --git a/config/process.php b/config/process.php
index fa7e4ae..040ab64 100644
--- a/config/process.php
+++ b/config/process.php
@@ -15,9 +15,11 @@
 
 global $argv;
 
-return [
-    // File update detection and automatic reload
-    'monitor' => [
+$server_process = [];
+
+// 是否启用monitor
+if (env('MONITOR_ENABLED', true)) {
+    $server_process['monitor'] = [
         'handler' => process\Monitor::class,
         'reloadable' => false,
         'constructor' => [
@@ -39,10 +41,16 @@ return [
                 'enable_memory_monitor' => DIRECTORY_SEPARATOR === '/',
             ]
         ]
-    ],
-    env('JSONRPC_SERVER_NAME', 'jsonrpc') => [
+    ];
+}
+
+// 是否启用jsonrpc
+if (env('JSONRPC_ENABLED', true)) {
+    $server_process[env('JSONRPC_SERVER_NAME', 'jsonrpc')] = [
         'handler' => jsonrpc\Server::class,
-        'listen' => 'JsonNL://0.0.0.0:' . env('JSONRPC_SERVER_PORT', '8021'),
+        'listen' => env('JSONRPC_SERVER_LISTEN', 'JsonNL://0.0.0.0:8021'),
         'count' => eval("return " . env('JSONRPC_SERVER_COUNT', cpu_count() * 4) . ";"),
-    ],
-];
+    ];
+}
+
+return $server_process;
diff --git a/envexample b/envexample
new file mode 100755
index 0000000..fae2013
--- /dev/null
+++ b/envexample
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+# 自动生成.env文件对应的.env.example文件
+generate_env_example() {
+  # 清空原有的.env.example文件中的内容
+  > .env.example
+
+  # 逐行读取.env文件
+  while IFS= read -r line; do
+    # 去除首尾空格
+    line=$(echo "$line" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
+    # 如果是注释行或空白行,直接写入.env.example文件
+    if [[ $line == \#* || -z $line ]]; then
+      echo "$line" >> .env.example
+    # 如果是键值对行,判断键名是否包含指定字符串
+    elif [[ $line == *=* ]]; then
+      key=$(echo "$line" | cut -d= -f1)
+      value=$(echo "$line" | cut -d= -f2-)
+      # 如果键名包含指定字符串,将值清空写入.env.example文件
+      if [[ $key == *KEY || $key == *PASSWORD || $key == *SECRET || $key == *PASS || $key == *TOKEN || $key == *ID ]]; then
+        echo "$key=" >> .env.example
+      # 否则,清除首尾空格后原样写入.env.example文件
+      else
+        echo "$key=$value" >> .env.example
+      fi
+    fi
+  done < .env
+}
+
+# 每次run后都自动生成.env.example文件
+generate_env_example
\ No newline at end of file
diff --git a/init b/init
new file mode 100755
index 0000000..4810eb3
--- /dev/null
+++ b/init
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+set -e
+
+source docker.conf
+export WORKERMAN_CONTAINER_NAME=$container_name
+export WORKERMAN_IMAGE_VERSION=$image_version
+
+# 判断.env文件是否存在
+if [ ! -f .env ]; then
+    # 如果.env.example文件存在,则通过cp命令生成.env文件
+    if [ -f .env.example ]; then
+        cp .env.example .env
+        echo ".env file created from .env.example"
+    else
+        echo "Error: .env file does not exist and .env.example file also does not exist"
+        exit 1
+    fi
+fi
+
+# 判断容器是否存在
+if [ "$(docker ps -a -q -f name=$WORKERMAN_CONTAINER_NAME)" ]; then
+    echo "Container $WORKERMAN_CONTAINER_NAME already exists. Please delete it before installing. Or user $(tput bold)./server <action>$(tput sgr0) to control it."
+    exit 1
+fi
+
+# 启动容器
+docker compose up -d
+
+# 进入容器并执行composer install
+docker exec -it $WORKERMAN_CONTAINER_NAME bash -c "composer install"
+docker restart $WORKERMAN_CONTAINER_NAME
\ No newline at end of file
diff --git a/php b/php
new file mode 100755
index 0000000..8b90d68
--- /dev/null
+++ b/php
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+set -e
+
+source docker.conf
+export WORKERMAN_CONTAINER_NAME=$container_name
+export WORKERMAN_IMAGE_VERSION=$image_version
+
+# 判断容器是否存在
+if [ ! "$(docker ps -a -q -f name=$WORKERMAN_CONTAINER_NAME)" ]; then
+    # 调用init脚本
+    ./init
+fi
+
+# 判断容器是否在运行
+if [ ! "$(docker inspect -f {{.State.Running}} $WORKERMAN_CONTAINER_NAME)" = "true" ]; then
+    # 启动容器
+    docker start $WORKERMAN_CONTAINER_NAME
+fi
+
+# 进入容器并执行php命令
+docker exec -it $WORKERMAN_CONTAINER_NAME bash -c "php $*"
\ No newline at end of file
diff --git a/run b/run
deleted file mode 100755
index 3772cfd..0000000
--- a/run
+++ /dev/null
@@ -1,196 +0,0 @@
-#!/bin/bash
-
-# 读取docker.conf文件
-source docker.conf
-
-# 设置系统环境变量
-export WORKERMAN_CONTAINER_NAME=$container_name
-export WORKERMAN_IMAGE_VERSION=$image_version
-
-service_name="webman-jsonrpc"
-
-# 检查docker-compose.yml文件是否存在
-if [ ! -f "docker-compose.yml" ]; then
-    echo "Error: docker-compose.yml file not found"
-    exit 1
-fi
-
-# 自动生成.env文件对应的.env.example文件
-generate_env_example() {
-  # 清空原有的.env.example文件中的内容
-  > .env.example
-
-  # 逐行读取.env文件
-  while IFS= read -r line; do
-    # 去除首尾空格
-    line=$(echo "$line" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
-    # 如果是注释行或空白行,直接写入.env.example文件
-    if [[ $line == \#* || -z $line ]]; then
-      echo "$line" >> .env.example
-    # 如果是键值对行,判断键名是否包含指定字符串
-    elif [[ $line == *=* ]]; then
-      key=$(echo "$line" | cut -d= -f1)
-      value=$(echo "$line" | cut -d= -f2-)
-      # 如果键名包含指定字符串,将值清空写入.env.example文件
-      if [[ $key == *KEY || $key == *PASSWORD || $key == *SECRET || $key == *PASS || $key == *TOKEN || $key == *ID ]]; then
-        echo "$key=" >> .env.example
-      # 否则,清除首尾空格后原样写入.env.example文件
-      else
-        echo "$key=$value" >> .env.example
-      fi
-    fi
-  done < .env
-}
-# 每次run后都自动生成.env.example文件
-generate_env_example
-
-# 定义帮助函数
-show_help() {
-    echo "Usage: ./run [COMMAND] [OPTION]"
-    echo ""
-    echo "Commands:"
-    echo "  start         run once"
-    echo "  status        service status(daemon mode only)"
-    echo "  reload        reload files(daemon mode only)"
-    echo "  restart       restart service(daemon mode only)"
-    echo "  stop          stop service and container"
-    echo "  init          delete container and rebuild"
-    echo "  destroy       stop & remove the container"
-    echo "  help          show this help message"
-    echo "Options:"
-    echo "  -d            run in daemon mode.(start, restart, init)"
-}
-
-# 定义安装依赖的函数
-install_dependencies() {
-    # 执行一次composer install
-    docker compose run --rm "$service_name" composer install
-}
-
-# 判断容器是否存在并且正在运行
-is_container_running() {
-    if docker ps -a --format '{{.Names}}' | grep -q "$WORKERMAN_CONTAINER_NAME"; then
-        if docker ps --format '{{.Names}}' | grep -q "$WORKERMAN_CONTAINER_NAME"; then
-            return 0
-        else
-            return 1
-        fi
-    else
-        return 2
-    fi
-}
-
-# 判断是否需要在后台运行
-is_daemon_mode() {
-    for arg in "$@"; do
-        if [[ "$arg" == "-d" ]]; then
-            return 1
-        fi
-    done
-    return 0
-}
-
-# 解析命令行参数
-case "$1" in
-start)
-    # 判断容器是否存在并且正在运行
-    if is_container_running; then
-        echo "container $WORKERMAN_CONTAINER_NAME is already running"
-        exit 1
-    elif [[ $? -eq 1 ]]; then
-        # 存在但未运行,直接启动
-        if is_daemon_mode "$@"; then
-            docker start -a "$WORKERMAN_CONTAINER_NAME"
-        else
-            docker start "$WORKERMAN_CONTAINER_NAME"
-        fi
-    else
-        # 不存在,执行docker-compose up
-        if is_daemon_mode "$@"; then
-            docker compose up
-        else
-            docker compose up -d
-        fi
-    fi
-    ;;
-restart)
-    # 判断容器是否存在并且正在运行
-    if is_container_running; then
-        if is_daemon_mode "$@"; then
-            docker stop "$WORKERMAN_CONTAINER_NAME"
-            docker start -a "$WORKERMAN_CONTAINER_NAME"
-        else
-            docker restart "$WORKERMAN_CONTAINER_NAME"
-        fi
-    elif [[ $? -eq 1 ]]; then
-        # 存在但未运行,直接启动
-        if is_daemon_mode "$@"; then
-            docker start -a "$WORKERMAN_CONTAINER_NAME"
-        else
-            docker start "$WORKERMAN_CONTAINER_NAME"
-        fi
-    else
-        # 不存在,执行docker-compose up
-        if is_daemon_mode "$@"; then
-            docker compose up
-        else
-            docker compose up -d
-        fi
-    fi
-    ;;
-stop)
-    docker stop "$WORKERMAN_CONTAINER_NAME"
-    ;;
-reload)
-    # 判断容器是否存在并且正在运行
-    if is_container_running; then
-        # 执行start.php reload命令
-        docker exec -it "$WORKERMAN_CONTAINER_NAME" php start.php reload
-    else
-        echo "container $WORKERMAN_CONTAINER_NAME is not running"
-        exit 1
-    fi
-    ;;
-status)
-    # 判断容器是否存在并且正在运行
-    if is_container_running; then
-        # 执行start.php status命令
-        docker exec -it "$WORKERMAN_CONTAINER_NAME" php start.php status
-    else
-        echo "container $WORKERMAN_CONTAINER_NAME is not running"
-        exit 1
-    fi
-    ;;
-init)
-    read -p "Will delete current container. Are you sure? (y/n)" confirm
-    if [ "$confirm" != "y" ]; then
-        echo "Aborted."
-        exit 1
-    fi
-    docker rm -f "$WORKERMAN_CONTAINER_NAME"
-    # 执行docker-compose up
-    if is_daemon_mode "$@"; then
-        docker compose up
-    else
-        docker compose up -d
-    fi
-    ;;
-destroy)
-    read -p "Are you sure you want to destroy the container? (y/n)" confirm
-    if [ "$confirm" = "y" ]; then
-        docker rm -f "$WORKERMAN_CONTAINER_NAME"
-        echo "Container $WORKERMAN_CONTAINER_NAME has been destroyed."
-    else
-        echo "Aborted."
-        exit 1
-    fi
-    ;;
-help)
-    show_help
-    ;;
-*)
-    echo "Error: Invalid command"
-    show_help
-    exit 1
-    ;;
-esac
diff --git a/server b/server
new file mode 100755
index 0000000..7fc7133
--- /dev/null
+++ b/server
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+set -e
+
+if [ -z "$1" ]; then
+    echo "Usage: $0 [start|stop|logs|restart|status|reload|connections]"
+    exit 1
+fi
+
+source docker.conf
+export WORKERMAN_CONTAINER_NAME=$container_name
+export WORKERMAN_IMAGE_VERSION=$image_version
+
+if [ "$1" = "stop" ]; then
+    if [ "$(docker inspect -f {{.State.Running}} $WORKERMAN_CONTAINER_NAME 2>/dev/null)" = "true" ]; then
+        docker stop $WORKERMAN_CONTAINER_NAME
+    else
+        echo "Container $WORKERMAN_CONTAINER_NAME is not running."
+    fi
+else
+    # 判断容器是否存在
+    if [ ! "$(docker ps -a -q -f name=$WORKERMAN_CONTAINER_NAME)" ]; then
+        # 调用init脚本
+        ./init
+    fi
+    # 判断容器是否在运行
+    if [ ! "$(docker inspect -f {{.State.Running}} $WORKERMAN_CONTAINER_NAME 2>/dev/null)" = "true" ]; then
+        # 启动容器
+        docker start $WORKERMAN_CONTAINER_NAME
+    fi
+    if [ "$1" = "logs" ]; then
+        docker logs -f $WORKERMAN_CONTAINER_NAME
+    elif [ "$1" = "start" ]; then
+        :
+    elif [ "$1" = "restart" ]; then
+        docker restart $WORKERMAN_CONTAINER_NAME
+    elif [ "$1" = "status" ]; then
+        docker exec -it $WORKERMAN_CONTAINER_NAME bash -c "php start.php status"
+    elif [ "$1" = "reload" ]; then
+        docker exec -it $WORKERMAN_CONTAINER_NAME bash -c "php start.php reload"
+    elif [ "$1" = "connections" ]; then
+        docker exec -it $WORKERMAN_CONTAINER_NAME bash -c "php start.php connections"
+    else
+        echo "Invalid command"
+        echo "Usage: $0 [start|stop|logs|restart|status|reload|connections]"
+        exit 1
+    fi
+fi