Script

1. 风格

  • 使用Bash作为Shell脚本语言
  • 应被用于小功能, 最好在百行内
  • 使用.sh作为扩展名
  • 缩进为两个空格

1.1. 文件头

  • #!/bin/bash#!/user/bin/env bash开头
#!/user/bin/env bash
#
# @brief  Write your file description.
# @note   xxx
# @author  xxx

1.2. 文件名&函数名&变量名

  • 文件名: 使用小写字母, 下划线分隔
  • 函数名: 使用小写字母, 下划线分隔, 后跟圆括号
  • 变量名: 使用小写字母, 下划线分隔
# Single Func
my_func() {
  ...
}

# Part of a package
mypackage::my_func() {
  ...
}

# Var
for zone in ${zones}; do
  something_with "${zone}"
done

1.3. 其他变量

  • 常量和环境变量名: 全部大写, 下划线分隔, 声明在文件顶部
  • 只读变量: readonly修饰
  • 局部变量: local修饰, 只在函数内和子函数中可见; 声明和赋值需在不同行
zip_version="$(dpkg --status zip | grep Version: | cut -d ' ' -f 2)"
if [[ -z "${zip_version}" ]]; then
  error_message
else
  readonly zip_version
fi

my_func2() {
  local name="$1"

  # Separate lines for declaration and assignment:
  local my_var
  my_var="$(my_func)" || return

  # DO NOT do this: $? contains the exit code of 'local', not my_func
  local my_var="$(my_func)"
  [[ $? -eq 0 ]] || return

  ...
}

1.4. 主函数 main

  • 仅长脚本或非线性流时使用
  • 放在最下面

1.5. 内建命令

# Prefer this:
addition=$((${X} + ${Y}))
substitution="${string/#foo/bar}"

# Instead of this:
addition="$(expr ${X} + ${Y})"
substitution="$(echo "${string}" | sed -e 's/^foo/bar/')"

2. 教程

2.1. 样例

$ vim test.sh创建脚本

#!/bin/bash
echo "Hello World!"

运行脚本

chmod +x ./test.sh
./test.sh

2.2. 返回值

  • 每个命令都有一个返回值, 成功为0, 失败为1~255之间的整数
  • exit 提前终止脚本, 并把返回值交给shell; 当不带参数时, 返回上一个命令的返回值
  • return 提前终止函数
  • 程序结束后, shell将返回值赋给环境变量$?, 用来检测脚本执行成功与否

2.3. 变量

# 创建变量, 无空格
my_link="https://www.yuque.com/gendloop"
readonly my_link
my_link="abc" # bash: my_link: readonly variable

# 删除变量
# unset <var>
user="gendloop"
unset user

# 字符串变量
my_str1="Hello"
my_str2=${my_str1}" World"
echo \"$my_str1\" \"$my_str2\" # "Hello" "Hello World"

# 整数变量

# 局部变量(函数内)
local local_var
local_var="local value"

# 环境变量
export GLOBAL_VAR="global value"
$HOME      当前用户主目录
$PATH      查找命令的目录
$PWD      当前工作目录
$RANDOM    0~32767 间的整数
$UID    当前用户的ID
$PS1    主要系统输入提示符
$PS2    次要系统输入提示符

# 位置参数
$0      脚本名称
$1...$9    第1~9个参数列表
${10}...${N} 每10~N个参数列表
$* $@     除了$0外的所有位置参数
$FUNCNAME   函数名(仅函数内有值)

2.4. 大括号拓展

# {start..end..increment}
echo beg{i,a,u}n # begin began begun
echo {0..9} # 0 1 2 3 4 5 6 7 8 9
echo {00..09..3} # 00 03 06 09

2.5. 命令置换

# 用一组``或$()包裹命令
strs=($(echo beg{i,a,u}n))
echo ${strs[@]}

itvs=(`echo {0..9..3}`)
echo ${itvs[*]}

now=$(date +%T)
echo $now

2.6. 算数扩展

# 算数表达式必须在$(())中
x=1
y=2
echo $(( x+y ))
echo $(( x++ + ++y ))
echo $(( x+y ))

2.7. 双引号的使用

# 当变量中包含空格时, 注意加上双引号
fruits=" Apple  Pear    Peach"
echo $fruits # 会被分成单独的词
echo "$fruits"

2.8. 数组

// todo: https://www.runoob.com/linux/linux-shell-variable.html

// todo: https://github.com/denysdovhan/bash-handbook/blob/master/translations/zh-CN/README.md#%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F

3. References

  1. https://google.github.io/styleguide/shellguide.html
  2. https://zh-google-styleguide.readthedocs.io/en/latest/google-shell-styleguide/contents.html
  3. https://www.runoob.com/linux/linux-shell.html
  4. https://github.com/denysdovhan/bash-handbook/blob/master/translations/zh-CN/README.md
  5. https://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_02.html#sect_03_02_04
  6. https://github.com/alebcay/awesome-shell?tab=readme-ov-file#guides
  7. https://github.com/Idnan/bash-guide
  8. https://github.com/jlevy/the-art-of-command-line/blob/master/README-zh.md
Copyright © gendloop 2024 all right reserved,powered by Gitbook该文件修订时间: 2026-04-03 03:43:16

results matching ""

    No results matching ""