Shell学习

94 阅读2分钟

第一行表示用什么shell去执行

#!/bin/zsh

shell中常见的变量列表

  • $0 - 脚本名
  • $1 到 $9 - 脚本的参数。 $1 是第一个参数,依此类推。
  • $@ - 所有参数
  • $# - 参数个数
  • $? - 前一个命令的返回值
  • $$ - 当前脚本的进程识别码
  • !! - 完整的上一条命令,包括参数。常见应用:当你因为权限不足执行命令失败时,可以使用 sudo !!再尝试一次。
  • $_ - 上一条命令的最后一个参数。如果你正在使用的是交互式 shell,你可以通过按下 Esc 之后键入 . 来获取这个值。

关于文件描述符

  • 2>/dev/null 把错误输出到"黑洞"

  • >/dev/null 2>&1 默认情况也是1,也就是等同于1>/dev/null 2>&1。意思就是把标准输出重定向到"黑洞",还把错误输出2定向到标准输出1,也就是标准输出和错误输出都进了"黑洞"

  • 2>&1 >/dev/null 把错误输出2重定向到标准输出1,也就是屏幕,标准输出进入了黑洞,也就是标准输出进了黑洞,错误输出打印到屏幕

linux的文件描述符 0--标准输入(stdin) 1--标准输出(stdout) 2--标准错误(stderr)

一段shell脚本 便利我们提供的参数,使用grep搜索字符串foobar,如果没有找到,则将其作为注释追加到文件中
echo "Starting program at $(date)" # date会被替换成日期和时间

echo "Running program $0 with $# arguments with pid $$"

for file in "$@"; do
    grep foobar "$file" > /dev/null 2> /dev/null
    # 如果模式没有找到,则grep退出状态为 1
    # 我们将标准输出流和标准错误流重定向到Null,因为我们并不关心这些信息
    if [[ $? -ne 0 ]]; then
        echo "File $file does not have any foobar, adding one"
        echo "# foobar" >> "$file"
    fi
done

花括号{} -

当你有一系列的指令,其中包含一段公共子串时,可以用花括号来自动展开这些命令

####
convert image.{png,jpg}
# 会展开为
convert image.png image.jpg

cp /path/to/project/{foo,bar,baz}.sh /newpath
# 会展开为
cp /path/to/project/foo.sh /path/to/project/bar.sh /path/to/project/baz.sh /newpath

# 也可以结合通配使用
mv *{.py,.sh} folder
# 会移动所有 *.py 和 *.sh 文件

mkdir foo bar

# 下面命令会创建foo/a, foo/b, ... foo/h, bar/a, bar/b, ... bar/h这些文件
touch {foo,bar}/{a..h}
touch foo/x bar/y
# 比较文件夹 foo 和 bar 中包含文件的不同
diff <(ls foo) <(ls bar)
# 输出
# < x
# ---
# > y

shellcheck

帮助定位脚本中的错误