#!/bin/bash if ! type "include" > /dev/null 2>&1; then include() { . "$(cd "$(dirname "$1")" && pwd)/${2}"; }; fi include "${BASH_SOURCE[0]}" ./global.bash if ! pragma_once ${BASH_SOURCE[0]}; then return 0; source ./global.bash fi default_visit_dir_callback() { local path="$1" if [ -L "$path" ]; then target=$(readlink "$path") echo "$path : 符号链接 -> $target" elif [ -d "$path" ]; then echo "$path : 目录" elif [ -f "$path" ]; then echo "$path : 普通文件" else echo "$path : 其它类型" fi } visit_dir() { local dir_path="$1" local callback="${2:-default_visit_dir_callback}" while IFS= read -r -d '' path <&3; do "$callback" "$path" done 3< <(find "$dir_path" -mindepth 1 -print0) } g_last_dir="" g_symlink_log="" g_symlink_buf="" g_file_list_buf="" collect_non_symlink() { local path="$1" local work_dir=$(pwd) if [ "$(stat -c %h "$path")" -gt 1 ]; then local r_t="${path#"$work_dir"/}" g_file_list_buf+="$r_t"$'\n' return 0 elif [ -L "$path" ]; then local target=$(readlink "$path") get_relative_path "$work_dir" "$path" local r_t=$_ret_ if [[ "$target" == /* ]]; then # echo "target abs: $target" g_file_list_buf+="$r_t"$'\n' return 0 fi local p=$(realpath "$(dirname "$path")/$target") if [[ "$p" != "$work_dir"* ]]; then g_file_list_buf+="$r_t"$'\n' return 0 fi local dir=$(dirname $r_t) local name=$(basename $r_t) get_relative_path "$work_dir/$dir/" "$p" local r_s=$_ret_ if [[ "$g_last_dir" != "$dir" ]]; then g_last_dir="$dir" g_symlink_buf+=" Set-Location \"\$target_dir/$dir\" "$'\n' fi g_symlink_buf+=" New-Item -ItemType SymbolicLink -Path '$name' -Target '$r_s'"$'\n' return 0 elif [ -d "$path" ]; then : elif [ -f "$path" ]; then local r_t="${path#"$work_dir"/}" g_file_list_buf+="$r_t"$'\n' return 0 else : fi } replace_template_to_var() { local -n output_var=$1 # 传名引用,结果写这里 local name="$2" local script_dir script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" local filepath="$script_dir/power_shell.template.ps1" if [[ ! -f "$filepath" ]]; then echo "File not found: $filepath" >&2 return 1 fi local content content=$(<"$filepath") content="${content//\'\[\[name\]\]\'/\'$name\'}" output_var="$content" } tar_non_symlink_and_log_symlink() { local dir_to_package="$1" local name name=$(basename "$dir_to_package") local work_dir work_dir=$(dirname "$dir_to_package") local tar_file="./$name.tar.gz" cd "$work_dir" || { echo "Failed to cd $work_dir"; return 1; } g_symlink_log="./${name}_rebuild_rlink.ps1" > "$g_symlink_log" g_last_dir="" g_symlink_buf="" g_file_list_buf="" local data replace_template_to_var data "$name" "" g_symlink_buf+="$data"$'\n' exec_record_fast_fail "visit_dir \"$dir_to_package\" collect_non_symlink" g_symlink_buf+=$'\nRead-Host -Prompt "Press any key to exit"' echo "$g_symlink_buf" > "$g_symlink_log" # 动态获取线程数 local thread_num=1 if command -v nproc >/dev/null 2>&1; then thread_num=$(nproc) elif [[ "$(uname)" == "Darwin" ]]; then thread_num=$(sysctl -n hw.ncpu) fi # 用标准输入传递文件列表给 tar start_time=$(date +%s%3N) # printf '%s\n' "$g_file_list_buf" | tar cf - -T - | pigz -p "$thread_num" > "$tar_file" printf '%s\n' "$g_file_list_buf" | tar cf - --dereference -T - | pigz -p "$thread_num" > "$tar_file" end_time=$(date +%s%3N) elapsed_sec=$(awk "BEGIN {printf \"%.3f\", $((end_time - start_time))/1000}") echo "Packaged file: $tar_file Elapsed time: $elapsed_sec seconds" } #tar_non_symlink_and_log_symlink "/ae/test_link/test" #tar_non_symlink_and_log_symlink "/ae/wyc_build/win_rk356x" # visit_dir "/ae/test_link/test" # windows 设置大小写敏感 # https://cloud.tencent.com/developer/article/2362943 return 0