---
title: 源码包准备
description: "1. 请在源服务器（x86）任意位置创建一个.sh脚本文件（例如pack_nginx_sources.sh），脚本内容详见pack_nginx_sources.sh链接。"
url: https://www.hikunpeng.com/document/detail/zh/kunpengdevps/portingadvisor/demo/nginxbestpractice_21_0003.html
sourcePath: /source/zh/kunpengdevps/portingadvisor/demo/nginxbestpractice_21_0003.html
indexId: 1e4a8d63b2fd3efd54db0ede6c1e0d228badb96e49d7acd87c4467217a6f397b74
---
# 源码包准备

#### 操作步骤

1. 请在源服务器（x86）任意位置创建一个.sh脚本文件（例如pack_nginx_sources.sh），脚本内容详见pack_nginx_sources.sh链接。
2. 执行该脚本以完成打包过程。打包后的tar包位于“/home”目录下。

```
bash
/home
/pack_nginx_sources.sh
/usr/local/nginx
```


  显示如下内容，则表示打包成功。

  1 2 3 4 5 6 7 8 9 10 11 12 13 Copying /usr/local/nginx to /home/nginx_mig_tmp ... Getting installation configure command paths... configure arguments: --prefix=/usr/local/nginx --with-http_ssl_module --with-http_gzip_static_module --with-http_stub_status_module Getting startup config file... root 2864 32744 0 01:49 pts/1 00:00:00 bash pack_nginx_sources.sh /usr/local/nginx root 2881 2864 0 01:49 pts/1 00:00:00 grep nginx Scanning included sources in config file... [conf file]: /home/nginx_mig_tmp/nginx/conf/fastcgi.conf [conf file]: /home/nginx_mig_tmp/nginx/conf/nginx.conf Packing tar... Nginx related components are packaged into nginx_migration.tar. Note: Please manually check and remove unrelated files/dirs if needed. Please manually upload it to the node server and extract it using the command: tar xvf nginx_migration.tar -C /custom_path

  /home：脚本存放路径，请根据实际规划进行修改。 /usr/local/nginx：源Nginx安装目录的绝对路径，请根据实际路径进行修改。 若Nginx指定配置文件启动（即指定-c选项），且安装路径下不存在二进制文件，则需要根据提示信息手动输入Nginx二进制路径，用于打包与二进制相关的配置文件。

3. 打包完成后请手动删除生成的“/home/nginx_mig_tmp”目录。
4. 使用SSH远程登录工具，将压缩包文件上传至目标节点服务器（agent01）的自定义路径，以“/home”目录为例。
5. 进入保存压缩包文件的自定义目录，解压源成分压缩包。

```
cd /home
tar xvf nginx_migration.tar
```


  解压后的文件路径为源成分所在路径，本次实践中为“/home/nginx_mig_tmp”。


#### pack_nginx_sources.sh

```
#!/bin/bash

# 检查命令行参数，确保提供了源Nginx安装目录的绝对路径
if [ $# -ne 1 ]; then
     echo "Usage: $0 <source_nginx_install_dir>"
     exit 1
fi

source_nginx_dir="$1"
source_nginx_binary="$source_nginx_dir/sbin/nginx"
temp_dir="/home/nginx_mig_tmp"
source_nginx_tmp="$temp_dir/$(basename "$source_nginx_dir")"
migration_tar="nginx_migration.tar"

if [ ! -d "$source_nginx_dir" ]; then
     echo "The parameter entered is not a valid directory."
     echo "Usage: $0 <source_nginx_install_dir>"
     exit 1
fi

if [ ! -d "$source_nginx_dir/sbin" ]; then
    echo "The source Nginx installation path does not contain the sbin directory."
    echo "Usage: $0 <source_nginx_install_dir>"
    echo "Notice: This script only supports the source Nginx binary stored in \"<source_nginx_install_dir>/sbin\"."
    exit 1
fi

if [ ! -f "$source_nginx_binary" ]; then
    echo "The source Nginx binary file is not in $source_nginx_dir/sbin."
    echo "Usage: $0 <source_nginx_install_dir>"
    echo "Notice: This script only supports the source Nginx binary stored in \"<source_nginx_install_dir>/sbin\"."
    exit 1
fi

# 步骤一：创建临时目录并复制Nginx安装目录
target_nginx_dir="$(dirname "$source_nginx_tmp")"
mkdir -p "$target_nginx_dir"
echo "Copying $source_nginx_dir to $target_nginx_dir ..."
if ! cp -rp "$source_nginx_dir" "$target_nginx_dir"; then
     echo "Failed to copy the Nginx installation directory"
     exit 1
fi
# 创建指定目录打包包外的成分
source_related_dir="$source_nginx_tmp/sbin/source_related"
mkdir -p "$source_related_dir"
mkdir -p "$source_related_dir/external_confs"
external_confs_record="$source_related_dir/external_confs/external_conf_record.txt"
touch "${external_confs_record}"
chmod 600 "${external_confs_record}"

# 步骤二：获取编译选项指定的依赖文件并复制
echo -e "\e[1;32m Getting installation configure command paths...\e[0m"
keywords="sbin-path|conf-path|error-log-path|http-log-path|http-client-body-temp-path|http-fastcgi-temp-path|http-proxy-temp-path|http-scgi-temp-path|http-uwsgi-temp-path|pid-path|lock-path"
cd "$source_nginx_dir"
strings "$source_nginx_binary" | grep "configure arguments"
strings "$source_nginx_binary" | grep "configure arguments" | grep -Eo "($keywords)=[^[:space:]]+" | awk -F '=' '{print $2}' | while read -r path; do
     # 如果依赖文件已在包内，则跳过复制步骤
     if [[ "$path" == "$source_nginx_dir"* ]]; then
         echo "Skip copying $path because it is in the source Nginx directory."
         continue
     fi

     source_path="$path"

     # 获取相对路径的真实路径
     if [[ "$path" == ../* ]]; then
         source_path=$(realpath --relative-base="$source_nginx_dir" -m "$path")
     fi

     # 如果是nginx的conf和log文件，拷贝所在目录
     if [[ "$source_path" =~ \.conf$ ]] || [[ "$source_path" =~ \.log$ ]]; then
         source_path=$(dirname "$source_path")
     fi

     target_dir="$source_related_dir/$(dirname "$source_path")"
     if [ ! -d "$target_dir" ]; then
         mkdir -p "$target_dir"
     fi
     echo "Copying $source_path to $target_dir ..."
     if ! cp -rp "$source_path" "$target_dir"; then
         echo "Failed to copy file/directory: $source_path"
     fi
 done

# 步骤三：获取启动配置文件并复制
echo " "
echo -e "\e[1;32m Getting startup config file...\e[0m"
ps -ef | grep nginx
nginx_process_info=$(ps -ef | grep nginx)
if grep -q " -c " <<< "$nginx_process_info" || [ -f "$source_nginx_binary" ]; then
    keywords=""
else
  echo -e "\e[1;93m Please refer to the process information of 'ps -ef | grep nginx' above, check whether the source nginx to be migrated is started with a specified configuration file. \e[0m"
  echo -e "\e[1;93m e.g., nginx: master process {path to the nginx binary to be migrated} -c {configuration file path} \e[0m"
  echo -e "\e[1;93m If it is not started based on the specified configuration file, press Enter to skip this step. Otherwise, enter the Nginx binary file path. \e[0m"
  echo "Enter Nginx binary path: "
  read -r nginx_binary_path
  keywords="$nginx_binary_path"
fi
ps -ef | grep nginx | grep -oE "nginx: master process $keywords \-c ([^ ]+)" | while read -r line; do
     CONF_FILE=$(echo "$line" | grep -oE 'c ([^ ]+)' | cut -d ' ' -f2)
     echo "[Startup config file]: $CONF_FILE"
     if [ ! -f "$CONF_FILE" ]; then
         continue
     fi
     conf_dir=$(dirname "$CONF_FILE")
     # 包内的跳过
     if [[ "$conf_dir" == "$source_nginx_dir"* ]]; then
         continue
     fi

     echo "$CONF_FILE" >> "$external_confs_record"

     target_dir=$(dirname "$source_related_dir$conf_dir")
     if [ ! -d "$target_dir" ]; then
         mkdir -p "$target_dir"
     fi
     echo "Copying $conf_dir to $target_dir ..."
     if ! cp -rp "$conf_dir" "$target_dir"; then
         echo "Failed to copy confs dir: $conf_dir"
     fi
 done

# 步骤四：扫描配置文件中引用的外部文件/目录并复制
echo " "
echo -e "\e[1;32m Scanning included sources in config file...\e[0m"
conf_file_list=()
while IFS= read -r -d '' file; do
     conf_file_list+=("$file")
done < <(find "$source_nginx_tmp" -type f -name "*.conf" -print0)

# 入参：[line][relative_base_path]
function handle_included() {
     line="$1"
     relative_base_path="$2"
     path=$(echo "$line" | awk '{print $2}' | sed 's/[";]//g')

     if [[ "$path" == /* ]]; then
         source_path="$path"
         target_path="$source_related_dir$source_path"
     elif [[ "$path" == ../* ]]; then
         source_path=$(realpath --relative-base="$relative_base_path" -m "$path")
         target_path="$source_related_dir$source_path"
     else
         return
     fi

     if [[ "${path##*/}" == \** ]]; then
         source_path=$(dirname "$source_path")
         target_path=$(dirname "$target_path")
     fi

     target_dir=$(dirname "$target_path")
     mkdir -p "$target_dir"
     echo "Copying $source_path to $target_dir ..."
     if ! cp -rp "$source_path" "$target_dir"; then
         echo "Failed to copy file/directory: $path"
     fi
}

for file in "${conf_file_list[@]}"; do
     echo "[conf file]: $file"
     file_dir=$(dirname "$file")
     if [ ! -f "$file" ]; then
         continue
     fi
     # 获取源conf的dir
     if echo "$file" | grep -q "source_related"; then
         source_conf_dir=$(echo "$file_dir" | awk -F 'source_related' '{print $2}')
     else
         source_conf_dir="$source_nginx_dir/conf"
     fi
     # 相对于conf路径
     keywords="include|ssl_certificate|ssl_certificate_key|ssl_dhparam"
     cd "$source_conf_dir"
     grep -wE "^[[:space:]]*($keywords)" "$file" | while read -r line; do
         handle_included "$line" "$source_conf_dir"
     done
     # 相对安装路径
     keywords="error_log|access_log|root|alias|client_body_temp_path|fastcgi_temp_path|proxy_temp_path|proxy_cache_path|scgi_temp_path|uwsgi_temp_path"
     cd "$source_nginx_dir"
     grep -wE "^[[:space:]]*($keywords)" "$file" | while read -r line; do
         handle_included "$line" "$source_nginx_dir"
     done
 done

# 步骤五：清理source_related内，步骤三扫描配置文件时，二次拷贝的源Nginx安装目录
echo " "
cd "$(dirname "$temp_dir")"
source_related_nginx="$source_related_dir$source_nginx_dir"
if [ -d "$source_related_nginx" ]; then
     echo "[remove]: $source_related_nginx"
     rm -rf "${source_related_nginx}"
fi

# 步骤六：打包源成分目录
echo " "
echo -e "\e[1;32m Packing tar...\e[0m"
tar cvf "$migration_tar" "$(basename "$temp_dir")" >/dev/null
if [[ "$?" -ne "${SUCCESS}" ]]; then
     echo "Failed to create tar."
     exit 1
fi

echo "Nginx related components are packaged into $migration_tar."
echo "Note: Please manually check and remove unrelated files/dirs if needed."
echo "Please manually upload it to the node server and extract it using the command: tar xvf $migration_tar -C /custom_path"
```
