2021SC@SDUSC
install-package.sh从名字来看是安装各种包的。其代码如下:
#!/bin/bash
script_dir="$(dirname "$0")"
target="$1"
output_dir="$2"
option_no_update="${no_update:+1}"
source "${script_dir}"/bootstrap.sh
require 'styles'
require 'resolver'
if [[ -z "$target" ]] || [[ -z "$output_dir" ]]; then
echo "Usage: $(basename "$0") :<configuration>|<package-name> <output-directory>"
exit 1
fi
set -e
[[ -d "${output_dir}" ]] || mkdir -p "${output_dir}"
files_updated=0
install_package() {
local user_name="$(resolve_user_name "$1")"
local package_name="$(resolve_package_name "$1")"
local package_dir="${root_dir:-.}/package/${user_name}/${package_name}"
local package="$(resolve_package "$1")"
local branch="$(resolve_branch "$1")"
local branch_label="${branch:+@${branch}}"
local recipe="$(resolve_recipe "$1")"
local recipe_options=($(resolve_recipe_options "$1"))
fetch_or_update_package
if [[ -n "${recipe}" ]]; then
require 'recipe'
install_recipe "${package_dir}/${recipe}.recipe.yaml"
elif [[ -f "${package_dir}/recipe.yaml" ]]; then
require 'recipe'
install_recipe "${package_dir}/recipe.yaml"
else
install_files_from_package "${package_dir}"
fi
}
fetch_or_update_package() {
if ! [[ -d "${package_dir}" ]]; then
echo $(info 'Downloading package:') $(highlight "${package}") $(print_option "${branch_label}")
local fetch_options=()
if [[ -n "${branch}" ]]; then
fetch_options+=(--branch "${branch}")
fi
"${script_dir}"/fetch-package.sh "${package}" "${package_dir}" "${fetch_options[@]}"
else
if [[ -z "${option_no_update}" ]]; then
echo $(info 'Updating package:') $(highlight "${package}")
else
echo $(info 'Found package:') $(highlight "${package}")
fi
"${script_dir}"/update-package.sh "${package_dir}" "${branch}"
fi
}
install_files_from_package() {
local package_dir="$1"
local IFS=$'\r\n'
local data_files=(
$(
cd "${package_dir}"
ls *.yaml 2> /dev/null \
| grep -v -e '\.custom\.yaml$' -e '\.recipe\.yaml$' -e '^recipe\.yaml$'
ls *.txt 2> /dev/null
ls *.gram 2> /dev/null
ls opencc/*.* 2> /dev/null \
| grep -e '\.json$' -e '\.ocd$' -e '\.txt$'
)
)
install_files "${data_files[@]}"
}
install_files() {
if [[ "$#" -eq 0 ]]; then
return
fi
local source_path
local target_path
for file in "$@"; do
source_path="${package_dir}/${file}"
target_path="${output_dir}/${file}"
if ! [ -e "${target_path}" ]; then
create_containing_directory "${target_path}"
echo $(info 'Installing:') $(print_item "${file}")
elif ! diff -q "${source_path}" "${target_path}" &> /dev/null; then
echo $(info 'Updating:') $(print_item "${file}")
else
continue
fi
cp "${source_path}" "${target_path}"
((++files_updated))
done
}
create_containing_directory() {
local target_dir="$(dirname "$1")"
if ! [ -d "${target_dir}" ]; then
echo $(info 'Creating directory:') $(print_item "${target_dir}")
mkdir -p "${target_dir}"
fi
}
load_package_list_from_target "${target}"
for package in "${package_list[@]}"; do
install_package "${package}"
done
if [[ "${files_updated}" -eq 0 ]]; then
echo $(print_result 'No files updated.')
else
echo $(print_result "Updated ~ ${files_updated} files " \
"from ${#package_list[@]} packages in") "'${output_dir}'"
fi
第一行给脚本目录赋值为 dirname加脚本名称。target赋值为第一个参数。输出的目录为第二个参数。然后是没见过的echo中出现了冒号加一。网上没找到相关资料。然后去shell上自己试:
这样赋的值是不管update是多少,最后都只跟冒号后的数有关。也就是说这里option_no_update被直接赋值为1了。
然后创建一个文件。调用require函数(详见bootstrap.sh,用来引导模块的函数,在其中会创建与该名称相关的.sh文件),将styles和resolver作为参数导入。
然后判断target和output_dir的值是否为零,为零报一个输出然后异常状态退出。
set -e 当脚本执行出现意料之外的情况时,立即退出,避免错误被忽略,导致最终结果不正确。
接下来判断output_dir是否已经为一个目录文件名,是的话,将file_dated的值赋为零;如果不是,则创建一个父目录。
进入install_package函数,前面是几个本地变量的赋值。然后引入fetch_or_update_package函数。如果recipe的值不为零,建一个recipe模板,调用本函数,参数为recipe "${package_dir}/${recipe}.recipe.yaml"。如果${package_dir}/recipe.yaml为一个普通文件。引入recipe模板,调用本函数,参数为recipe "${package_dir}/recipe.yaml"。否则调用install_files_from_package,参数为${package_dir};
fetch_or_update_package函数主要是用来选择接受或者更新包的。
进入install_files_from_package函数。前面同样是赋值。将路径锁定到package_dir下。将.yaml所有文件的错误输出定向到/dev/null文件中,即&1。后面是grep的相关匹配模式。.txt,.gram,opencc/.都重定向到&1中。
引入install_files函数,参数为data_files数组的所有元素。
install_files主要用来安装文件,create_containing_directory则是用来创建目录将所有文件放入。