zoukankan      html  css  js  c++  java
  • linux学习之linux百问,不断更新

    1、Shell脚本中用#表示注释,相当于C语言的//注释。但如果#位于第一行开头,并且是#!(称为Shebang)则例外,它表示该脚本使用 后面指定的解释器/bin/sh解释执行

    $ chmod +x script.sh
    $ ./script.sh

    2、两种执行Shell脚本的方法:

    $ ./script.sh
    $ sh ./script.sh

    3、 一行中可以输入由分号;隔开的多个命令

    $ cd ..;ls -l

    4、 只存在于当前Shell进程,用 set 命令可以显示当前Shell进程中定义的所有变量(包括本地变量和环境变量)和函数

    环境变量是任何进程都有的概念,而本地变量是Shell特有的概念。在Shell中,环境变量和本地变量的定义和用法相似。在Shell中定义或赋值一个变量:

    $ VARNAME=value

    注意等号两边都不能有空格,否则会被Shell解释成命令和命令行参数。

    一个变量定义后仅存在于当前Shell进程,它是本地变量,用export命令可以把本地变量导出为环境变量,定义和导出环境变量通常可以一步完成:

    $ export VARNAME=value

    也可以分两步完成:

    $ VARNAME=value
    $ export VARNAME

    unset命令可以删除已定义的环境变量或本地变量。

    $ unset VARNAME

    如果一个变量叫做VARNAME,用${VARNAME}可以表示它的值,在不引起歧义的情况下也可以用$VARNAME表示它的值。通过以下例子比较这两种表示法的不同:

    $ echo $SHELL
    $ echo $SHELLabc
    $ echo $SHELL abc
    $ echo ${SHELL}abc

    注意,在定义变量时不用$,取变量值时要用$。和C语言不同的是,Shell变量不需要明确定义类型,事实上Shell变量的值都是字符串,比如我们定义VAR=45,其实VAR的值是字符串45而非整数。Shell变量不需要先定义后使用,如果对一个没有定义的变量取值,则值为空字符串。

    5、Shell脚本中的单引号和双引号一样都是字符串的界定符(双引号下一节介绍),而不是字符的界定符。单引号用于保持引号内所有字符的字面值,即使引号内的\和回车也不例外,但是字符串中不能出现单引号。如果引号没有配对就输入回车,Shell会给出续行提示符,要求用户把引号配上对。例如:

    $ echo '$SHELL'
    $SHELL
    $ echo 'ABC\(回车)
    > DE'(再按一次回车结束命令)
    ABC\
    DE

    6、命令代换:`或 $()

    由反引号括起来的也是一条命令,Shell先执行该命令,然后将输出结果立刻代换到当前命令行中。例如定义一个变量存放date命令的输出:

    $ DATE=`date`
    $ echo $DATE

    命令代换也可以用$()表示:

    $ DATE=$(date)

    7、

    双引号用于保持引号内所有字符的字面值(回车也不例外),但以下情况除外:

    • $加变量名可以取变量的值

    • 反引号仍表示命令替换

    • \$表示$的字面值

    • \`表示`的字面值

    • \"表示"的字面值

    • \\表示\的字面值

    • 除以上情况之外,在其它字符前面的\无特殊含义,只表示字面值

    $ echo "$SHELL"
    /bin/bash
    $ echo "`date`"
    Sun Apr 20 11:22:06 CEST 2003
    $ echo "I'd say: \"Go for it\""
    I'd say: "Go for it"
    $ echo "\"(回车)
    >"(再按一次回车结束命令)
    "
    
    $ echo "\\"
    \

    8、启动bash会自动执行以下脚本:

    1. 首先执行/etc/profile,系统中每个用户登录时都要执行这个脚本,如果系统管理员希望某个设置对所有用户都生效,可以写在这个脚本里

    2. 然后依次查找当前用户主目录的~/.bash_profile~/.bash_login~/.profile三个文件,找到第一个存在并且可读的文件来执行,如果希望某个设置只对当前用户生效,可以写在这个脚本里,由于这个脚本在/etc/profile之后执行,/etc/profile设置的一些环境变量的值在这个脚本中可以修改,也就是说,当前用户的设置可以覆盖(Override)系统中全局的设置。~/.profile这个启动脚本是sh规定的,bash规定首先查找以~/.bash_开头的启动脚本,如果没有则执行~/.profile,是为了和sh保持一致。

    3. 顺便一提,在退出登录时会执行~/.bash_logout脚本(如果它存在的话)。

    9、条件测试test

    命令test[可以测试一个条件是否成立,如果测试结果为真,则该命令的Exit Status为0,如果测试结果为假,则命令的Exit Status为1(注意与C语言的逻辑表示正好相反)。例如测试两个数的大小关系:

    $ VAR=2
    $ test $VAR -gt 1
    $ echo $?
    0
    $ test $VAR -gt 3
    $ echo $?
    1
    $ [ $VAR -gt 3 ]
    $ echo $?
    1

    虽然看起来很奇怪,但左方括号[确实是一个命令的名字,传给命令的各参数之间应该用空格隔开,比如,$VAR-gt3][命令的四个参数,它们之间必须用空格隔开。命令test[的参数形式是相同的,只不过test命令不需要]参数。以[命令为例,常见的测试命令如下表所示:

    [ -d DIR ] 如果DIR存在并且是一个目录则为真
    [ -f FILE ] 如果FILE存在且是一个普通文件则为真
    [ -z STRING ] 如果STRING的长度为零则为真
    [ -n STRING ] 如果STRING的长度非零则为真
    [ STRING1 = STRING2 ] 如果两个字符串相同则为真
    [ STRING1 != STRING2 ] 如果字符串不相同则为真
    [ ARG1 OP ARG2 ] ARG1ARG2应该是整数或者取值为整数的变量,OP-eq(等于)-ne(不等于)-lt(小于)-le(小于等于)-gt(大于)-ge(大于等于)之中的一个

    和C语言类似,测试条件之间还可以做与、或、非逻辑运算:

    带与、或、非的测试命令

    [ ! EXPR ] EXPR可以是上表中的任意一种测试条件,!表示逻辑反
    [ EXPR1 -a EXPR2 ] EXPR1EXPR2可以是上表中的任意一种测试条件,-a表示逻辑与
    [ EXPR1 -o EXPR2 ] EXPR1EXPR2可以是上表中的任意一种测试条件,-o表示逻辑或

    例如:

    $ VAR=abc
    $ [ -d Desktop -a $VAR = 'abc' ]
    $ echo $?
    0

    注意,如果上例中的$VAR变量事先没有定义,则被Shell展开为空字符串,会造成测试条件的语法错误(展开为[ -d Desktop -a = 'abc' ]),作为一种好的Shell编程习惯,应该总是把变量取值放在双引号之中(展开为[ -d Desktop -a "" = 'abc' ]):

    $ unset VAR
    $ [ -d Desktop -a $VAR = 'abc' ]
    bash: [: too many arguments
    $ [ -d Desktop -a "$VAR" = 'abc' ]
    $ echo $?
    1

    10、 case/esac

    case命令可类比C语言的switch/case语句,esac表示case语句块的结束。C语言的case只能匹配整型或字符型常量表达式,而Shell脚本的case可以匹配字符串和Wildcard,每个匹配分支可以有若干条命令,末尾必须以;;结束,执行时找到第一个匹配的分支并执行相应的命令,然后直接跳到esac之后,不需要像C语言一样用break跳出。

    #! /bin/sh
    
    echo "Is it morning? Please answer yes or no."
    read YES_OR_NO
    case "$YES_OR_NO" in
    yes|y|Yes|YES)
      echo "Good Morning!";;
    [nN]*)
      echo "Good Afternoon!";;
    *)
      echo "Sorry, $YES_OR_NO not recognized. Enter yes or no."
      exit 1;;
    esac
    exit 0

    使用case语句的例子可以在系统服务的脚本目录/etc/init.d中找到。这个目录下的脚本大多具有这种形式(以/etc/apache2为例):

    case $1 in
    	start)
    		...
    	;;
    	stop)
    		...
    	;;
    	reload | force-reload)
    		...
    	;;
    	restart)
    	...
    	*)
    		log_success_msg "Usage: /etc/init.d/apache2 {start|stop|restart|reload|force-reload|start-htcacheclean|stop-htcacheclean}"
    		exit 1
    	;;
    esac

    启动apache2服务的命令是

    $ sudo /etc/init.d/apache2 start

    $1是一个特殊变量,在执行脚本时自动取值为第一个命令行参数,也就是start,所以进入start)分支执行相关的命令。同理,命令行参数指定为stopreloadrestart可以进入其它分支执行停止服务、重新加载配置文件或重新启动服务的相关命令。

    11、if fi

    和C语言类似,在Shell中用ifthenelifelsefi这几条命令实现分支控制。这种流程控制语句本质上也是由若干条Shell命令组成的,例如先前讲过的

    if [ -f ~/.bashrc ]; then
        . ~/.bashrc
    fi

    其实是三条命令,if [ -f ~/.bashrc ]是第一条,then . ~/.bashrc是第二条,fi是第三条。如果两条命令写在同一行则需要用;号隔开,一行只写一条命令就不需要写;号了,另外,then后面有换行,但这条命令没写完,Shell会自动续行,把下一行接在then后面当作一条命令处理。和[命令一样,要注意命令和各参数之间必须用空格隔开。if命令的参数组成一条子命令,如果该子命令的Exit Status为0(表示真),则执行then后面的子命令,如果Exit Status非0(表示假),则执行elifelse或者fi后面的子命令。if后面的子命令通常是测试命令,但也可以是其它命令。Shell脚本没有{}括号,所以用fi表示if语句块的结束。见下例:

    #! /bin/sh
    
    if [ -f /bin/bash ]
    then echo "/bin/bash is a file"
    else echo "/bin/bash is NOT a file"
    fi
    if :; then echo "always true"; fi

    :是一个特殊的命令,称为空命令,该命令不做任何事,但Exit Status总是真。此外,也可以执行/bin/true/bin/false得到真或假的Exit Status。再看一个例子:

    #! /bin/sh
    
    echo "Is it morning? Please answer yes or no."
    read YES_OR_NO
    if [ "$YES_OR_NO" = "yes" ]; then
      echo "Good morning!"
    elif [ "$YES_OR_NO" = "no" ]; then
      echo "Good afternoon!"
    else
      echo "Sorry, $YES_OR_NO not recognized. Enter yes or no."
      exit 1
    fi
    exit 0

    上例中的read命令的作用是等待用户输入一行字符串,将该字符串存到一个Shell变量中。

    此外,Shell还提供了&&和||语法,和C语言类似,具有Short-circuit特性,很多Shell脚本喜欢写成这样:

    test "$(whoami)" != 'root' && (echo you are using a non-privileged account; exit 1)

    &&相当于“if...then...”,而||相当于“if not...then...”。&&和||用于连接两个命令,而上面讲的-a-o仅用于在测试表达式中连接两个测试条件,要注意它们的区别,例如,

    test "$VAR" -gt 1 -a "$VAR" -lt 3

    和以下写法是等价的

    test "$VAR" -gt 1 && test "$VAR" -lt 3
  • 相关阅读:
    219. Contains Duplicate II
    189. Rotate Array
    169. Majority Element
    122. Best Time to Buy and Sell Stock II
    121. Best Time to Buy and Sell Stock
    119. Pascal's Triangle II
    118. Pascal's Triangle
    88. Merge Sorted Array
    53. Maximum Subarray
    CodeForces 359D Pair of Numbers (暴力)
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3078591.html
Copyright © 2011-2022 走看看