Bash

Bash

一、变量

环境变量:

  • 如何查看?env 或者printenv可以查看所有,printenv xxx或者echo $xxx可以查看特定变量
  • 常见环境变量

创建变量:

  • 等号两边不能有空格,如果变量有空格,必须放入引号中
  • 同一行可以定义多个变量,但是要有分号分割

特殊变量:

1
2
3
4
5
6
$# 传递给脚本的参数个数
$0 当前脚本文件名
$n 第n个参数,如$1表示第一个参数
$* 传递给脚本的所有参数
$$ 当前shell脚本ID
$? 上一条命令的返回值或者说退出状态

参考:http://c.biancheng.net/view/806.html

二、运算符

1
2
(()) 只能用于整数,不能用于浮点数的计算
a=$((8*9))

三、条件判断

1
2
3
4
5
6
7
if commands; then
commands
[elif commands; then
commands...]
[else
commands]
fi

或者写成以下格式:

1
2
3
4
5
6
7
8
9
if true
then
echo 'hello world'
fi

if false
then
echo 'it is false' # 本行不会执行
fi

常见条件判断符号:

  • ```bash -eq 等于 -ne 不等于 -le 小于等于 -ge 大于等于 -lt 小于 -gt 大于 -n xxx 若不为空 则返回true -z 若为空 则返回true

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
      
    * 表达式判断符号:https://wangchujiang.com/linux-command/c/test.html

    ### test命令

    `if`结构的判断条件,一般使用test命令,有三种形式

    ```bash
    # 写法一
    test expression

    # 写法二 中括号和表达式之间要有空格
    [ expression ]

    # 写法三 支持正则判断 中括号和表达式之间要有空格
    [[ expression ]]
    测试字符串:
    $string1 = $string2
    $string1 !\= $string2
    $string1 # 不为空
    -z $string1 # 长度为0
    -n $string1 # 长度不为0
    测试数字:
    -eq -ne -ge -gt -le -lt
    测试文件属性:
    -b -c -d -f -d -r

  • []test命令的简写形式

四、循环

while循环:

1
2
3
while condition; do
commands
done

或者

1
2
3
4
while condition
do
commands
done

五、分支语句

1
2
3
4
5
6
7
8
9
10
#!/bin/bash
temp="hello"
case $temp in
"he")
echo "111"
;;
"hello")
echo "222"
;;
esac

六、数组

1
2
3
4
5
array=(hello good nice)
for ele in ${array[@]} # 数组遍历
do
echo $ele
done

七、输入输出重定向

command > file 将输出重定向到 file。
command < file 将输入重定向到 file。
command >> file 将输出以追加的方式重定向到 file。
n > file 将文件描述符为 n 的文件重定向到 file。
n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m 将输出文件 m 和 n 合并。
n <& m 将输入文件 m 和 n 合并。
<< tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。
  • 文件描述符:0为标准输入,1为标准输出,2为标准错误输出

  • 例:ls a.txt b.txt > output.txt 2>&1,有a.txt但是没有b.txt,所以一部分在标准输出,一部分在标准错误输出。>1>的简写,因此上述命令可写为ls a.txt b.txt > output.txt 2>&1&存在的原因是为了指明后面的数字是文件描述符而不是文件名

  • >&&>意思相同

八、编写可靠Bash脚本

1
2
3
4
5
set -xeuo pipefail
-x 在执行每一个命令之前把经过变量展开之后的命令打印出来
-e 遇到一个命令失败(返回码非零)时,立即退出
-u 试图使用未定义的变量,就立即退出
-o pipefail 只要管道中的一个子命令失败,整个管道命令就失败

九、样例

9.1 H1ve平台的entrypoint

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#!/bin/sh
set -eo pipefail

# 这里:-指的是默认值
WORKERS=${WORKERS:-1}
WORKER_CLASS=${WORKER_CLASS:-gevent}
ACCESS_LOG=${ACCESS_LOG:--}
ERROR_LOG=${ERROR_LOG:--}
WORKER_TEMP_DIR=${WORKER_TEMP_DIR:-/dev/shm}

# 检查.ctfd_secret_key文件或者SECRET_KEY环境变量是否存在
if [ ! -f .ctfd_secret_key ] && [ -z "$SECRET_KEY" ]; then
if [ $WORKERS -gt 1 ]; then
echo "[ ERROR ] You are configured to use more than 1 worker."
echo "[ ERROR ] To do this, you must define the SECRET_KEY environment variable or create a .ctfd_secret_key file."
echo "[ ERROR ] Exiting..."
exit 1
fi
fi

# 检查数据库
if [ -n "$DATABASE_URL" ]; then
url=$(echo $DATABASE_URL | awk -F[@//] '{print $4}')
database=$(echo $url | awk -F[:] '{print $1}')
port=$(echo $url | awk -F[:] '{print $2}')
echo "Waiting for $database:$port to be ready"
while ! mysqladmin ping -h "$database" -P "$port" --silent; do
# Show some progress
echo -n '.'
sleep 1
done
echo "$database is ready"
# Give it another second.
sleep 1
fi

# 初始化数据库
python manage.py db upgrade

# 开启CTFd
echo "Starting CTFd"
exec gunicorn 'CTFd:create_app()' \
--bind '0.0.0.0:4000' \
--workers $WORKERS \
--worker-tmp-dir "$WORKER_TEMP_DIR" \
--worker-class "$WORKER_CLASS" \
--access-logfile "$ACCESS_LOG" \
--error-logfile "$ERROR_LOG"
# --workers 指明用于处理请求的工作进程的数量,默认为 1
# --worker-class 指明工作模式,默认为sync
# --worker-tmp-dir 一个临时目录,用于存放工作进程的心跳包文件

参考

https://wangdoc.com/bash/variable

https://zhuanlan.zhihu.com/p/264346586

http://c.biancheng.net/shell/

https://www.yiibai.com/bash/bash-scripting.html

https://quickref.cn/docs/bash.html

附:Windows平台脚本

如何在后台静默运行?

创建run.vbs

1
2
3
Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run "cmd /c your_script.bat", 0
Set objShell = Nothing

其中your_script.bat为自己的脚本文件


Bash
https://d4wnnn.github.io/2023/05/09/DevOps/Bash/
作者
D4wn
发布于
2023年5月9日
许可协议