Linux shell| 学习记录

来自:linux程序设计中文第四版

变量

变量引用

shell中,变量不需要提前声明,默认所有变量均被看做为字符串来存储
引用变量名只需要在变量名添加 $符号

    variable=hello
    echo $variable 
    hello
    
    variable=”hello world ”  

注意:

  • 如果字符串里面包含空格,必须用引号括起来,另外等号两边不能有空格!
  • 双引号与单引号的差别,双引号会发生变量替换,单引号则不会替换
  • 被双引号包括起来的变量,变量替换不会被阻止的,所以被称为弱引用
  • 被单引号包括起来的变量,变量替换就会完全禁止,因此被称为全(强)引用
    ”$variable” 会被替换为变量表达式
    ‘$variable’  不会替换为变量表达式 

参数变量

  • $$ shell 本身的PID
  • $! shell 最后运行的后台Process 的PID
  • $? 最后运行命令的结束代码(返回值)
  • $- 使用set命令设定的Flag一览
  • $* 所有参数列表
  • $@ $*的一种变体
  • $# 添加到shell的参数个数
  • $0 shell 本身的文件名
  • $1-$n 添加到shell的各种参数值,$1是第一个参数。。。。。。。

read命令: 用来读取一个变量

read variable
Hello
echo $variable
Hello

变量运算符

条件&测试

test 、[]命令

eg:
    if test  -f  hello.c   (; then)
    then    
    …
    fi
或者
    if [ -f hello.c ]
    then 
    …
    fi 

test 命令比较主要分三种类型,字符串比较,数值比较,文件相关比较

  • 字符串比较
    • string1 = string2 如果两个字符串相同为真
    • string1 != string2 ….不同…..
    • -n string 如果字符串不为空则结果为真
    • -z string 如果字符串为null 则结果为真
  • 算术比较
    • expression1 –eq expression2 如果两个表达式相等则结果为真
    • expression1 –ne expression2 不等
    • expression1 –gt expression2 如果expression1 大于 expression2 为真
    • expression1 –ge expression2 大于等于
    • expression1 -lt expression2 小于
    • expression1 -le expression2 小于等于
    • ! expression 如果表达式为假则结果为真
  • 文件测试
    • -d file 文件是一个目录为真
    • -e file 文件存在则为真,历史上,-e选项不可移植,通常使用的是-f选项
    • -f file 文件是一个普通文件则为真
    • -g file 文件得set-group-id位被设置则结果为真
    • -r file 文件可读则结果为真
    • -s file 文件大小不为0 为真
    • -u file 文件的set-user-id 位被设置则结果为真
    • -w file 文件可写则为真
    • -x file 文件可执行则结果为真

控制结构

if语句

    if   condition
    then
        statements
    elif     condition1
        statements
    else
        statements
    fi
for 语句
for variable in  values
do 
    statements
done

有用的变量 $(commands) for 命令的参数表来自括在$()中的命令的输出结果

eg:
#!/bin/bash
for file in $(ls f*.sh); do
lpr $file
done 
exit 0

while语句

    while condition do
        statements
    done
eg:
    echo “please input passwd ”
    read trythis
    while [ “trythis !” = “passwd” ] ; do
        echo “sorry ,try again !!”
        read trythis 
    done
    exit 0

until 语句

与while相似,只是把条件测试反过来了,循环将反复执行直到条件为真,而不是在条件为真时反复执行。
    until condition
    do
        statements
    done
eg:
#!/bin/bash
until who | grep “$1” >/dev/null
do 
    sleep 60
done
#now ring the bell and announce the expected user.
echo –e ‘\a’
echo “****$1 has just logged in ****”
exit 0

case 语句

    case  variable  in
    pattern  [ | pattern ] …) statemetns ;;
    pattern  [ | pattern ] …) statemetns ;;
   esac
****************************************************            
    #!/bin/sh
    echo “Is it morning ? Please answer yes or no “
    read timeofday
    case “$tineofday” in 
    yes) echo “Good Morning”;;
    no)  echo  “Good Afternoon”;;
    y )  echo   “Good Morning “;;
    n   )  echo    “Good Afternoon” ;;
    *  )  echo “Sorry ,answer not recognized ” ;;
    esac 
****************************************************            
    #!/bin/sh
    echo “Is it morning ? Please answer yes or no “
    read timeofday
    case “$tineofday” in 
    yes|y|YES|Y) echo “Good Morning”;;
    no|n|NO|N)  echo  “Good Afternoon”;;
    *  )  echo “Sorry ,answer not recognized ” ;;
    esac 
            exit 0
****************************************************            
    #!/bin/sh
    echo “Is it morning ? Please answer yes or no “
    read timeofday
    case “$tineofday” in 
    yes|y|YES|Y) echo “Good Morning”
                    echo “up bright and early this morning”
                        ;;
    no|n|NO|N)  echo  “Good Afternoon”
                    ; ;
    *  )  echo “Sorry ,answer not recognized ”
          echo “Please answer yes or no ”
            exit 1      ; ;

    esac

命令列表

  • AND 列表
    从左边开始顺序执行每条命令,如果一条命令返回的是true,右边的下一条命令才能够执行。
         statement1 && statement2 && statements3 && …
    eg:
        #!/bin/bash
        touch file_one 
rm  -f file_two
if [ -f file_one ] && echo “hello” && [-f file_two ] && echo “there”
then 
    echo “in if”
else 
    echo “in else”
fi
exit 0
  • OR 列表
    statement1 || statement2 || statement3 || …
    从左边开始顺序执行,如果一调命令返回的是false,它右边的下一条命令才能够被执行,如此持续直到有一条命令返回true,或者所有的命令执行完毕。
eg:
#!/bin/bash
rm –f file_one 
if [ -f file_one ] || echo “hello” ||echo “there”
then 
    echo “in if”
else 
    echo “in else”
fi 
exit 0

语句块

如果想在某些只允许使用单个语句的地方使用多条语句,可以使用花括号来构造一个语句块。
    eg:
        get-confirm && {
                            grep –v “$cdcattnum” $tracks_file > $temp_file }

函数

    function_name () {
        statements 
    }
所有的函数定义需要放在函数调用之前
eg:
        #!/bin/bash
        foo() {
                echo “fuction foo is executing”
        }
        echo “script starting “
        foo
        echo “scripts ended”
        exit 0 

当一个函数被调用时,脚本程序的位置参数$*,$@,$#等会替换为函数的参数,可以用此方法来读取传递给函数的参数。
可以用local 关键字在shell函数中声明局部变量,此变量只在函数的作用范围内有效,如果一个局部变量和一个全局变量的名字相同,前者会覆盖后者。

eg:
    #!/bin/bash
    sample_text=”gloabel_variable” 
    foo() {
            local sample_text=”local variable “
            echo  “Funcition foo is executing “
            echo $sample_text
        }

    echo “script  starting “
    echo $sample_text
    foo
    echo     “script ended”
    echo $sample_text
    

    # !/bin/bash 
    yes_or_no() {
            echo “Is  your name $*  ? ”
            while true 
            do 
                echo –n “Enter yes or no :”
                read x 
                case “$x in
              y|yes ) return 0;;
                n|no) return 1 ;;
                * ] echo “Answer yes or no “
                esac 
            done 
            }

下面是主程序

        echo “Original parameters are $* ”
        if yes_or_no  “$1”
        then 
            echo “Hi $1,nice name “
        else 
            echo  “never mind”
        fi 
        exit 0

命令

break命令

用来跳出for,while或者until循环,可以为break提供一个数值参数来表示需要跳出的循环层数,但是会大大降低程序的可读性。

#!/bin/sh
rm –rf fred*
echo > fred1
echo >fred2
mkdir fred3
echo >fred4
for file in fred*
do 
    if [ -d “$file” ]; then 
        break;
    fi 
done 
echo first directory starting fred was $file
rm –rf fred*
exit 0

: 命令

冒号: 是一个空命令,偶尔被用于简化条件逻辑,相当于true的一个别名

    #!/bin/bash
    rm –f fred 
    if [-f fred ] ;then
    :
    else 
    echo file fred did not exist
fi
exit 0

continue 命令

类似C语言的continue,进入下一次循环继续进行

    #!/bin/bash
    rm –rf fred*
    echo > fred1
    echo >fred2
    mkdir   fred3
    echo > fred4
    for file in fred*
    do 
        if [ -d “$file” ] ; then
            echo “skipping directory $file”
            continue 
        fi

continue 可以带一个可选的参数用来表示希望继续执行的循环嵌套层数,也就是说你可以部分的跳出嵌套循环

eg :
        for x in 1 2 3
        do
        echo before $x
        continue 1 
        echo after $x
        done

.命令与source命令

点命令用于在当前shell中执行命令;
. ./sehll_scrips
与source ,命令相似,用于在当前shell 环境中执行脚本
source命令能够使子shell中的操作改变父shell中的环境变量,如果直接运行则不能改变父shell中的环境变量
载入环境变量

echo 命令

    echo –n “string to output ”
    echo –e  ‘\a’

eval命令 很有用????

允许对参数进行求值,

        foo =10
        x=foo
        y=’$’$X
        echo $y
                输出为$foo
        foo=10
        x=foo
        eval  y=’$’$x
        echo $y
                输出为10
        so,eval命令像一个额外的$,给出一个变量的值的值

exec命令

exec有两种不同的用法,典型用法是将当前shell替换为一个不同的程序

  • exec wall “Thanks for all the fiwsh”

脚本程序中会用wall替换当前的shell程序,exec命令后的代码都不会执行,因为执行这个脚本的shell已经不存在了
exec的各种方法是修改当前文件描述符
exec 3 <afile 这种用法很少见。

exit n命令

exit命令使用脚本程序以退出码结束运行
#!/bin/bash
[ -f .profile ] && exit 0 || exit 1

export 命令

此命令将作为它参数的变量导出到子shell中,并使之在子shell中有效。默认情况下, 在一个shell中被创建的变量在这个shell调用的下级shell中是不可用的,export 命令把自己的参数创建为一个环境变量,而这个环境变量可以被当前调用的其他脚本和程序看见。

expr命令

expr命令将它的参数当做一个表达式来求值,它的最常见的用法就是进行如下形式的简单数学运算:
x=‘expr $x =1’

printf命令

和 c语言中的使用方法相似,但是不支持浮点数,因为shell中所有的算术运算都是按照整数来进行计算的。

return命令

这个命令的作用是是函数返回,可以有一个数值参数作为函数的返回值。

set命令

set命令的作用是为shell设置参数变量
    eg:
        得到月份
        #!/bin/bash
        echo the date is $(date)
        set $(date)
        echo The month si $2
        exit 0

shift 命令

此命令将所有的参数变量左移一个位置,使$2变成$1,以此类推,原来$1的值将被丢弃,而$0的值将保持不变,如果shift命令时指定了一个数值参数,则表示所有的参数将左移一定的次数。
eg:
            #!/bin/bash
            while [ “$1” !=” “ ];do
                echo “$1”
                shift
            done
            exit 0 

trap命令

trap命令用于指定在接收到信号后将要采取的行动。
trap command signal
HUP(1) 挂起,通常因终端或用户退出而引发
INT(2) 中断。。。。。。。。。
more man 7 signal
eg:
#!/bin/bash
trap ‘rm –f /tmp/tmp_file_$$
date > /tmp/tmp_file_$$
echo “please interupt (CTRL-C) to interrupt
while
……………..懒得敲了 linux程序设计中文第四版,page51

unset 命令

其作用是从环境中删除变量或函数,不能删除shell本身定义的只读变量(如IFS)
#!/bin/bash 
foo =”Hello World”
echo $foo
unset foo
echo $foo

find和grep命令

find / -name test –print 
从根目录开始查找test的文件,输出文件的完整路径
find  / - mount –name test –print
这次不会搜索挂载的其他文件系统
还有好多,这里就不赘述了
grep命令使用正则表达式
    -I 忽略大小写
    -c 输出匹配行的数目,不输出匹配行
    -l 只列出包含匹配行的文件名,不输出真正的匹配行
    -v  对匹配模式取反,搜索不匹配行
    等等

export命令

    用于导出环境变量
    /etc/profile 
    /etc/bashrc
    $HOME/.bash_profile
    $HOME/.bashrc
    $HOME/.bash_logout
    原文作者:砦龑堃
    原文地址: https://www.jianshu.com/p/b80205f5bbab
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞