本文为计算机教育中缺失的一课 The Missing Semester of Your CS Education 笔记
第一个 Shell 脚本:
新建一个文件 touch a.sh
。
文件内容:
#!/bin/bash echo "Hello World !"
更改文件权限 chmod +x a.sh
。
执行 ./a.sh
或 source a.sh
:
source
命令:执行当前文件中的命令。foo=bar
。
$foo
或 ${foo}
。
${#string}
。用括号来表示数组,数组元素用"空格"符号分割开:array_name=(value0 value1 value2 value3)
。
读取数组元素值:
${数组名[下标]}
。@
符号可以获取数组中的所有元素:${数组名[@]}
。获取数组长度:length=${#array_name[@]}
或 length=${#array_name[*]}
例——变量、字符串、数组:
#!/bin/bash var1="Hello" echo $var1 echo "double quote" "$var1" echo "single quote" '$var1' var2=("Monday" "Tuesday" "Wednesday") echo "lenth of array" ${#var2[@]} echo "lenth of first element" ${#var2[0]} # 输出 # Hello # double quote Hello # single quote $var1 # lenth of array 3 # lenth of first element 6
$0
:脚本名。$1
到 $9
:脚本的参数。 $1
是第一个参数,依此类推。$@
或 $*
:所有参数。
"$1" "$2" … "$n"
的形式输出所有参数。$*
以一个单字符串显示所有向脚本传递的参数。$#
:参数个数。$?
:前一个命令的返回值。0 表示没有错误,其他任何值表明有错误。$$
:当前脚本的进程识别码!!
:完整的上一条命令,包括参数。常见应用:当你因为权限不足执行命令失败时,可以使用 sudo !!
再尝试一次。$_
:上一条命令的最后一个参数。例——传递参数:
echo "-- \$* 演示 ---" for i in "$*"; do echo $i done echo "-- \$@ 演示 ---" for i in "$@"; do echo $i done echo "$0" echo "$#"
执行结果:
bogon:tmp wangxinyuan$ ./a.sh hhh w x y -- $* 演示 --- hhh w x y -- $@ 演示 --- hhh w x y ./a.sh 4 bogon:tmp wangxinyuan$ echo "$?" 0
算数运算符:
+
-
*
/
%
=
==
!=
。val=`expr $a + $b`
。*
前边必须加反斜杠 \
才能实现乘法运算。[$a == $b]
。关系运算符:
-eq
-ne
-gt
-lt
-ge
-le
。if [ $a -eq $b ]
。[[ ]]
而不是单方括号 [ ]
,这样会降低犯错的几率,尽管这样并不能兼容 sh。布尔运算符:
!
、或 -o
、与 -a
。if [ $a -lt 100 -a $b gt 15]
逻辑运算符:
&&
||
if [[ $a -lt 100 && $b -gt 100 ]]
字符串运算符:
=
、!=
、检查字符串长度是否为 0 -z
、检查字符串长度是否不为 0 -n
、检查字符串是否为空 $
。文件测试运算符:咕咕咕~
if else:
else
分支没有语句执行,就不要写这个 else
。if condition1 then command1 elif condition2 then command2 else commandN fi
for:
for var in item1 item2 ... itemN do command1 command2 ... commandN done
while:
while condition do command done
until、case esac、break、continue:咕咕咕~
function fun()
定义,也可以直接 fun()
定义,不带任何参数。return
返回;如果不加,将以最后一条命令运行结果作为返回值。return
后跟数值\(n(0~255)\)。$?
来获得。${n}
来获取参数。[ function ] funname [()] { action; [return int;] }
命令替换:$( CMD )
。
for file in $(ls)
,Shell 首先将调用 ls
,然后遍历得到的这些返回值。进程替换:<( CMD )
。
通配:
?
*
。例:对于文件 foo, foo1, foo2, foo10, bar:
rm foo?
删除 foo1 和 foo2。rm foo*
删除除 bar
外的所有文件。{ }
。shebang #!
:
#!/usr/local/bin/python
让内核知道去用 python 解释器而不是 Shell 命令来运行这段脚本。例——命令替换、通配:
#!/bin/bash echo "Starting program at $(date)" # 命令替换 echo "Running program $0 with $# arguments with pid $$" for file in "$@" do # 如果模式没有找到,则grep退出状态为 1 # 我们将标准输出流和标准错误流重定向到Null,因为我们并不关心这些信息 grep foobar "$file" > /dev/null 2> /dev/null if [[ $? -ne 0 ]] then echo "File $file does not have any foobar, adding one" echo "# foobar" >> "$file" fi done
执行结果:
bogon:tmp wangxinyuan$ touch text{1,2,3,4,5}.txt # 通配 bogon:tmp wangxinyuan$ echo "# foobar" > text3.txt bogon:tmp wangxinyuan$ ./a.sh text{1,2,3,4,5}.txt Starting program at 2022年 2月19日 星期六 15时20分19秒 CST Running program ./a.sh with 5 arguments with pid 19714 File text1.txt does not have any foobar, adding one File text2.txt does not have any foobar, adding one File text4.txt does not have any foobar, adding one File text5.txt does not have any foobar, adding one
cat
:连接文件并打印到标准输出设备上。chmod
:控制用户对文件的权限的命令。diff
:比较文件的差异。find
:在指定目录下查找文件。locate
:咕咕咕~mv
:为文件或目录改名、或将文件或目录移入其它位置。rm
:删除一个文件或者目录。tee
:读取标准输入的数据,并将其内容输出成文件。touch
:修改文件或者目录的时间属性,包括存取时间和更改时间。若文件不存在,系统会建立一个新的文件。cp
:复制文件或目录。read
:用于从标准输入读取数值。grep
:查找文件里符合条件的字符串。let
:计算表达式,let 表达式
。cd
:切换当前工作目录。mkdir
:创建目录。pwd
:显示工作目录。tree
:咕咕咕~ls
:显示指定工作目录下之内容.