COMP2041/9041 shell 速成之脚本

COMP2041/9041个人1V1高质量辅导、代做

对本文有疑问可联系个人邮箱[email protected]或加v:TutorFor100

有我学习更轻松

shell脚本速成

脚本变量

  • 变量没有类型,可以认为都是字符串

    比如 1 = “1”

  • 变量不需要初始化

  • 没有局部变量

  • $name 表示变量name的值

  • name=value 变量赋值,将value的值赋给name(注意,等号两边不能有空格)

例:读取当前时间

$ now=$(date)
$ echo $now
Sun 23 Jun 1912 02:31:00 GMT
$

单引号 : ‘’

单引号定义字符串所见即所得,即将单引号内的内容原样输出,或者描述为单引号里面看到的是什么就会输出什么。单引号是全引用,被单引号括起的内容不管是常量还是变量都不会发生替换。

例:

$ echo '*** !@#$%^&*(){}[]:;"<>?,./` ***'
*** !@#$%^&*(){}[]:;"<>?,./` ***
$ echo 'this is "normal"'
this is "normal"

双引号: “”

双引号引用的内容,所见非所得。如果内容中有命令、变量等,会先把变量、命令解析出结果,然后在输出最终内容。双引号是部分引用,被双引号括起的内容常量还是常量,变量则会发生替换,替换成变量内容。

$ answer=42
$ echo "The answer is $answer."
The answer is 42.
$ echo 'The answer is $answer.'
The answer is $answer.
$ echo "time's up"
time's up
$ echo "* *"
* *

<< : here documents

  • <
  • following lines until word specify multi-line string as command input
  • variables and commands expanded - same as double quotes
  • <<‘word’ variables and commands not expanded - same as single quotes
$ name=Andrew
$ tr a-z A-Z <<END-MARKER
Hello $name
How are you
Good bye
END-MARKER
HELLO ANDREW
HOW ARE YOU
GOOD BYE

数学运算

  • $((expression)) is evaluated as an arithmetic expression
    • expression is evaluated as C-like integer arithmetic
    • and is replaced with the result
    • the $ on variables can be omitted in expressions
  • shell arithmetic implementation slow compared to e.g. C
    • significant overhead converting to/from strings

例:

$ x=8
$ answer=$((x*x - 3*x + 2))
$ echo $answer
42

shell内置变量


  • $0 命令名称

  • $1 第一个命令行参数

  • $2 第二个命令行参数

  • $# 命令行参数个数

  • $* command-line arguments (don’t use)

  • $@ also command-line arguments (don’t use)

  • “$*” all the command-line arguments with word-splitting (don’t use)

  • “$@” all the command-line arguments without splitting (use)

  • $? exit status of the most recent command

  • $$ process ID of this


例:

# 读取第一个和第二个命令行参数
arg1=$1
arg2=$2

条件判断

1. if

基本语法:

if [ command ];then
   符合该条件执行的语句
elif [ command ];
then
   符合该条件执行的语句
else
   符合该条件执行的语句
fi
  • test命令

    • 用法: test expression

      当 test 判断 expression 成立时,退出状态为 0,否则为非 0 值

    • test 命令也可以简写为[],它的用法为:[ expression ]

    注意 [ ] 和expression之间的空格,这两个空格是必须的,否则会导致语法错误。[]的写法更加简洁,比 test 使用频率高

  • 判断符号

    • 字符串比较:=、!=
    • 数字比较: -eq 、 -ne 、 -lt
    • 文件是否存在/可执行/可读: -f 、 -x 、 -r
    • 布尔运算符 (and/or/not): -a 、 -o 、 !

更详细的test用法参考:http://c.biancheng.net/view/2742.html

例:

# does the variable msg have the value "Hello"?
test "$msg" = "Hello"

# does x contain a numeric value larger than y?
test "$x" -gt "$y"

# Error: expands to "test hello there = Hello"?
msg="hello there"
test $msg = Hello

# is the value of x in range 10..20?
test "$x" -ge 10 -a "$x" -le 20

# is the file xyz a readable directory?
test -r xyz -a -d xyz

# alternative syntax; requires closing ]
[ -r xyz -a -d xyz ]

# 检查参数个数是不是2
if [ $# != 2 ] ; then
echo "Something"
exit 1
fi

文件目录判断:
[ -a FILE ] 如果 FILE 存在则为真。
[ -d FILE ] 如果 FILE 存在且是一个目录则返回为真。
[ -e FILE ] 如果 指定的文件或目录存在时返回为真。
[ -f FILE ] 如果 FILE 存在且是一个普通文件则返回为真。
[ -r FILE ] 如果 FILE 存在且是可读的则返回为真。
[ -w FILE ] 如果 FILE 存在且是可写的则返回为真。(一个目录为了它的内容被访问必然是可执行的)
[ -x FILE ] 如果 FILE 存在且是可执行的则返回为真。

2. case

基本语法:

case word in
pattern1)
commands1
;;
pattern2)
commands2
;;
patternn)
commandsn
esac

例:

# Checking number of command line args
case $# in
0) echo "You forgot to supply the argument" ;;
1) filename=$1 ;;
*) echo "You supplied too many arguments" ;;
esac

# Classifying a file via its name
case "$file" in
*.c) echo "$file looks like a C source-code file" ;;
*.h) echo "$file looks like a C header file" ;;
*.o) echo "$file looks like a an object file" ;;
...
?) echo "$file's name is too short to classify" ;;
*) echo "I have no idea what $file is" ;;
esac

循环

1. while循环:

基本语法:

while command
do
body-commands
done
  • the execution path depends on the exit status of command
  • command is executed and if its exit status is 0,
    • the body-commands are executed
    • and then command is executed and if its exit status is 0
    • the body-commands are executed
    • and …
  • if the exit status of command~ is not 0, execution of the loop stops

例:

# Print the integers 1..n with no argument checking
last=$1
number=1
while test $number -le "$last"
do
echo $number
number=$((number + 1))
done

2. for 循环

基本语法:

for var in word1 word2 word3
do
body-commands
...
done
  • the loop executes once for each word with var set to the word
  • break & continue statements can be in used inside for & while loops
    with the same effect as C/Python
  • keywords such for, if, *while, … are only recognised at the start of a command, e.g.:
$ echo when if else for
when if else for

例:

echo 'Using $*:'
for a in $*
do
echo "$a"
done
echo 'Using "$*":'
for a in "$*"
do
echo "$a"
done
# This is the way to loop over command-line arguments
echo 'Using "$@":'
for a in "$@"
do
echo "$a"
done

使用退出状态实现条件执行

  • 如果命令之间以 “;” 分割或者另起新行,所有命令都会执行, e.g:

    cmd1 ; cmd2 ; … ; cmdn

  • 当命令由 && 分割时

    cmd1 && cmd2 && … && cmdn

    如果有一个命令的退出状态不是0,执行停止

    只有cmdn的退出状态是0时,cmdn+1才会执行

  • 当命令由 || 分割时

    cmd1 || cmd2 || … || cmdn

    如果有一个命令的退出状态是0,执行停止

    只有cmdn的退出状态不是0时,cmdn+1才会执行

  • {} can be used to group commands

  • () also can be used to group commands - but executes them in a subshell

    • changes to variables and current working directory have no effect outside the subshell
  • exit status of group or pipeline of commands is exit status of last command

例:

# run a.out if it exists and is executablr
test -x a.out && ./a.out

# if directory tmp doesn't exist create it
test -d tmp || mkdir tmp

# if directory tmp doesn't exist create it
{test -d tmp || mkdir tmp;} && chmod 755 tmp

# but simpler is
mkdir -p tmp && chmod 755 tmp

# exit status
if cut -d: -f1 /etc/passwd|grep '^admin$'

{ }和( )的比较:

$ cd /usr/share
$ x=123
$ ( cd /tmp; x=abc; )
$ echo $x
123
$ pwd
/usr/share

$ { cd /tmp; x=abc; }
$ echo $x
abc
$ pwd
/tmp

由此可以发现:

  • changes to variables and current working directory have no effect outside a subshell
  • pipelines also executed in subshell, but variables and directory not usually changed in a pipeline

你可能感兴趣的:(linux,开发语言,unix)