标准的脚本结构
标准的 shell 脚本通常遵循一种基本的结构,这有助于组织代码并使其更易于理解和维护。以下是一个典型的 shell 脚本的基本结构:
bash
#!/bin/bash # 指定解释器路径,这一行告诉系统该脚本应该使用哪个 shell 来执行
# 脚本的元数据或描述
# 这是一个注释,用于描述脚本的目的、作者、版本等信息
# Author: Your Name
# Version: 1.0
# Description: This script does something useful
# 定义函数(可选)
function my_function() {
# 函数体
echo "This is my function."
}
# 脚本的主体部分
# 这里放置脚本的主要逻辑
# 可以先定义一些变量
my_variable="Hello, World!"
# 然后是命令和逻辑
echo "Starting the script..."
echo "The value of my_variable is: $my_variable"
# 调用之前定义的函数
my_function
# 如果有条件判断,可以这样写
if [ some_condition ]; then
echo "Condition is true."
else
echo "Condition is false."
fi
# 循环结构示例
for i in {1..5}
do
echo "Iteration $i"
done
# 脚本结束时的消息或清理操作(可选)
echo "Script execution finished."
# 退出脚本,可以返回一个退出状态码
exit 0 # 0 通常表示成功,非零值表示错误或异常在上面的示例中,注意以下几点:
#!/bin/bash是 shebang 行,它指定了用于执行脚本的 shell 解释器。对于 Bash 脚本,这通常是/bin/bash,但也可能是其他 shell 的路径,如/bin/sh、/usr/bin/env bash等。- 注释以
#开头,它们不会被执行,但可以提供有关脚本或其部分的信息。 - 函数定义使用
function关键字(尽管在 Bash 中这不是必需的)或简单地使用函数名后跟()。 - 脚本的主体部分包含了脚本的主要逻辑,包括变量定义、命令执行、条件判断和循环等。
- 在脚本的末尾,可以使用
exit命令来指定脚本的退出状态码。通常,exit 0表示成功,而非零值表示出现了某种错误或异常情况。 - 脚本应该具有良好的可读性和可维护性,这意味着代码应该清晰、简洁,并遵循良好的编程实践。
参考一个实际的开源的项目例子,mirrord 安装脚本如下:
bash
#!/bin/bash
# mirrord installer
# _ _
# _ __ ___ (_)_ __ _ __ ___ _ __ __| |
# | '_ ` _ \| | '__| '__/ _ \| '__/ _` |
# | | | | | | | | | | | (_) | | | (_| |
# |_| |_| |_|_|_| |_| \___/|_| \__,_|
#
# Usage:
# curl -fsSL https://github.com/metalbear-co/mirrord/raw/latest/scripts/install.sh | sh
set -e
file_issue_prompt() {
echo "If you wish us to support your platform, please file an issue"
echo "https://github.com/metalbear-co/mirrord/issues/new"
exit 1
}
get_latest_version() {
local res=$(curl --proxy socks5h://192.168.1.154:1080 -fsSL https://github.com/metalbear-co/mirrord/raw/latest/Cargo.toml | grep -m 1 version | cut -d' ' -f3 | tr -d '\"')
echo $res
}
copy() {
if [[ ":$PATH:" == *":$HOME/.local/bin:"* ]]; then
if [ ! -d "$HOME/.local/bin" ]; then
mkdir -p "$HOME/.local/bin"
fi
mv /tmp/mirrord "$HOME/.local/bin/mirrord"
else
# Try without sudo first, run with sudo only if mv failed without it.
mv /tmp/mirrord /usr/local/bin/mirrord || (
echo "Cannot write to installation target directory as current user, writing as root."
sudo mv /tmp/mirrord /usr/local/bin/mirrord
)
fi
}
# This function decides what version will be installed based on the following priority:
# 1. Environment variable `VERSION` is set.
# 2. Command line argument is passed.
# 3. Latest available on GitHub
function get_version() {
if [[ -z "$VERSION" ]]; then
if [[ -n "$1" ]]; then
VERSION="$1"
else
VERSION=$(get_latest_version)
fi
fi
echo $VERSION
}
function install() {
local version=$(get_version $1);
echo "Installing version $version"
if [[ "$OSTYPE" == "linux"* ]]; then
ARCH=$(uname -m);
OS="linux";
if [[ "$ARCH" != "x86_64" && "$ARCH" != "aarch64" ]]; then
echo "mirrord is only available for linux x86_64/aarch64 architecture"
file_issue_prompt
exit 1
fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
ARCH="universal";
OS="mac";
else
echo "mirrord isn't supported for your platform - $OSTYPE"
file_issue_prompt
exit 1
fi
# curl --proxy socks5h://192.168.1.154:1080 -o /tmp/mirrord -fsSL https://github.com/metalbear-co/mirrord/releases/download/$version/mirrord_$OS\_$ARCH
chmod +x /tmp/mirrord
copy
echo "mirrord installed! Have fun! For feedback and support, join our Discord server: https://discord.gg/metalbear, open an issue or discussion on our GitHub: https://github.com/metalbear-co/mirrord/ or send us an email at hi@metalbear.co"
}
install $1