Home shellscript
Post
Cancel

shellscript

Totorial

Tutorialspoint

Blog

Tips

  • $0

    1
    
    The variable $0 is the basename of the program as it was called.
    
  • $1 .. $9

    1
    
    $1 .. $9 are the first 9 additional parameters the script was called with.
    
  • $@

    1
    
    The variable $@ is all parameters $1 .. whatever.
    
  • $*

1
  The variable $*, is similar, but does not preserve any whitespace, and quoting, so "File with spaces" becomes "File" "with" "spaces".
  • $#

    1
    
    $# is the number of parameters the script was called with.
    
  • $?

    1
    
    This contains the exit value of the last run command.
    
  • $$

    1
    2
    
    The $$ variable is the PID (Process IDentifier) of the currently running shell.
    This can be useful for creating temporary files, such as /tmp/my-script.$$ which is useful if many instances of the script could be run at the same time, and they all need their own temporary files.
    
  • $!

1
2
  The $! variable is the PID of the last run background process.
  This is useful to keep track of the process as it gets on with its job.
  • IFS
1
2
  This is the Internal Field Separator.
  The default value is SPACE TAB NEWLINE, but if you are changing it, it's easier to take a copy.
1
2
3
4
5
6
7
  #!/bin/sh
  old_IFS="$IFS"
  IFS=:
  echo "Please input some data separated by colons ..."
  read x y z
  IFS=$old_IFS
  echo "x is $x y is $y z is $z"
  • -en

    1
    2
    3
    4
    5
    6
    7
    
    Passing the "-en" to echo tells it not to add a linebreak (for bash and csh).
    For Dash, Bourne and other compliant shells, you use a "\c" at the end of the line, instead.
    Ksh understands both forms
      
    (note: see /echo.html for a note on different implementations - particularly Dash/Bourne vs Bash)
       
    As with other use of the backticks, `whoami` runs in a subshell, so any cd commands, or setting any other variables, within the backticks, will not affect the currently-running shell.
    
    1
    2
    3
    4
    5
    6
    7
    
    #!/bin/sh
    echo -en "What is your name [ `whoami` ] "
    read myname
    if [ -z "$myname" ]; then
      myname=`whoami`
    fi
    echo "Your name is : $myname"
    
  • :=

    1
    
    Set the variable to the default if it is undefined:
    
    1
    
    echo "Your name is : ${myname:=John Doe}"
    
  • :-

    1
    
    By using curly braces and the special ":-" usage, you can specify a default value to use if the variable is unset
    
    1
    2
    3
    
    echo -en "What is your name [ `whoami` ] "
    read myname
    echo "Your name is : ${myname:-`whoami`}"
    
  • set -e

    1
    
    它使得脚本只要发生错误,就终止执行。
    
  • set -x

    1
    
    用来在运行结果之前,先输出执行的产生该结果的那一行命令。
    
  • set -u

    1
    
    遇到不存在的变量就会报错,并停止执行。
    
  • set -o pipefail

    1
    2
    
    set -e有一个例外情况,就是不适用于管道命令。
    set -o pipefail用来解决这种情况,只要一个子命令失败,整个管道命令就失败,脚本就会终止执行。
    
  • getopts

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    
    while getopts "hvsfbrxntlk:a:e:" OPTION
    do
         case $OPTION in
             h)
                 usage
                 exit 1
                 ;;
             v)
                 VERBOSE=yes
                 ;;
             s)
                 BUILD_DEVICE=no
                 BUILD_SIMULATOR=yes
                 BUILD_STATIC_FRAMEWORK=no
                 ;;
             f)
                 BUILD_DEVICE=yes
                 BUILD_SIMULATOR=yes
                 BUILD_STATIC_FRAMEWORK=yes
                 ;;
             r)  CONFIGURATION="Release"
                 DISABLEDEBUG=yes
                 ;;
             n)
                 NONETWORK=yes
                 ;;
             l)
                 SKIPLIBVLCCOMPILATION=yes
                 ;;
             k)
                 SDK=$OPTARG
                 ;;
             a)
                 BUILD_DEVICE=yes
                 BUILD_SIMULATOR=yes
                 BUILD_STATIC_FRAMEWORK=yes
                 FARCH=$OPTARG
                 ;;
             b)
                 BITCODE=no
                 ;;
             t)
                 TVOS=yes
                 IOS=no
                 BITCODE=yes
                 SDK_VERSION=`xcrun --sdk appletvos --show-sdk-version`
                 SDK_MIN=10.2
                 OSVERSIONMINCFLAG=tvos
                 OSVERSIONMINLDFLAG=tvos
                 ;;
             x)
                 MACOS=yes
                 IOS=no
                 BITCODE=no
                 SDK_VERSION=`xcrun --sdk macosx --show-sdk-version`
                 SDK_MIN=10.11
                 OSVERSIONMINCFLAG=macosx
                 OSVERSIONMINLDFLAG=macosx
                 BUILD_DEVICE=yes
                 BUILD_DYNAMIC_FRAMEWORK=yes
                 BUILD_STATIC_FRAMEWORK=no
                 ;;
             e)
                 VLCROOT=$OPTARG
                 ;;
             ?)
                 usage
                 exit 1
                 ;;
         esac
    done
    
  • getopt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    try:
        opts, args = getopt.getopt(argv[1:], "hm:i:n:", ["h=", "m=", "i=", "n="])
    except getopt.GetoptError as e:
        print(str(e))
        print(usage)
        sys.exit(2)
      
    for opt, arg in opts:
        if opt in ('-h', "--h"):
            print(usage)
            sys.exit()
        elif opt in ('-m', '--m'):
            if arg not in ('i2h', 'h2i'):
                print('the mode you input not recorgnized, mode should be "ih2"|"h2i"')
                sys.exit(2)
            else:
                mode = arg 
        elif opt in ('-i', '--i'):
            prefix = '0x'
            input = arg
            if arg.startswith(prefix):
                input = arg[len(prefix):]
        elif opt in ('-n', '--n'):
            nbits = int(arg)
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    
    #!/bin/bash
    # Set some default values:
    ALPHA=unset
    BETA=unset
    CHARLIE=unset
    DELTA=unset
      
    usage()
    {
      echo "Usage: alphabet [ -a | --alpha ] [ -b | --beta ]
                            [ -c | --charlie CHARLIE ] 
                            [ -d | --delta   DELTA   ] filename(s)"
      exit 2
    }
      
    # [getopt ref](https://www.tutorialspoint.com/unix_commands/getopt.htm)
    PARSED_ARGUMENTS=$(getopt -a -n alphabet -o abc:d: --long alpha,bravo,charlie:,delta: -- "$@")
    VALID_ARGUMENTS=$?
    if [ "$VALID_ARGUMENTS" != "0" ]; then
      usage
    fi
      
    echo "PARSED_ARGUMENTS is $PARSED_ARGUMENTS"
    eval set -- "$PARSED_ARGUMENTS"
    while :
    do
      case "$1" in
        -a | --alpha)   ALPHA=1      ; shift   ;;
        -b | --beta)    BETA=1       ; shift   ;;
        -c | --charlie) CHARLIE="$2" ; shift 2 ;;
        -d | --delta)   DELTA="$2"   ; shift 2 ;;
        # -- means the end of the arguments; drop this, and break out of the while loop
        --) shift; break ;;
        # If invalid options were passed, then getopt should have reported an error,
        # which we checked as VALID_ARGUMENTS when getopt was called...
        *) echo "Unexpected option: $1 - this should not happen."
           usage ;;
      esac
    done
      
    echo "ALPHA   : $ALPHA"
    echo "BETA    : $BETA "
    echo "CHARLIE : $CHARLIE"
    echo "DELTA   : $DELTA"
    echo "Parameters remaining are: $@"
    
    1
    2
    3
    4
    5
    6
    
    we have passed the -a option to getopt to enable the "alternative" mode, whereby a single hyphen is also accepted(so "-alpha" is the same as "--alpha")
      
    Then the "-n alphabet" option tells getopt that the program is actually known to the user as "alphabet". Without this, getopt would spit out error messages with "getopt" as the program name, like this this:
      
    ./alphabet -x
    getopt: unrecognized option '-x'
    
    1
    
    If getopt accepted all of the input, it will return a status code of zero (0) to indicate success. Otherwise, it will return a non-zero status code. This is passed to the calling shell in the special $? variable. We save this as VALID_ARGUMENTS - you could just check $? directly, but it's nice to save it in a variable in case some extra command gets inserted between the getopt and the test.
    
    1
    
    every time we call shift it pushes one (or more) off the stack. See shift for more information on how that works.
    
    1
    
    The special case -- is passed to us after all the parameters have been parsed; here we shift to get the "--" off the stack, then break out of the while loop.
    
    1
    
    ./alphabet.sh -a -b -c charlie -d river lorem ipsum
    
    1
    2
    3
    4
    5
    6
    
    PARSED_ARGUMENTS is  -a -b -c 'charlie' -d 'river' -- 'lorem' 'ipsum'
    ALPHA   : 1
    BRAVO   : 1 
    CHARLIE : charlie
    DELTA   : river
    Parameters remaining are: lorem ipsum
    
    1
    
    ./alphabet.sh --alpha --bravo --charlie charlie --delta river lorem ipsum
    
    1
    2
    3
    4
    5
    6
    
    PARSED_ARGUMENTS is  --alpha --bravo --charlie 'charlie' --delta 'river' -- 'lorem' 'ipsum'
    ALPHA   : 1
    BRAVO   : 1 
    CHARLIE : charlie
    DELTA   : river
    Parameters remaining are: lorem ipsum
    
    1
    
    $ ./alphabet.sh -a --bravo -c=Charlie -delta River lorem ipsum
    
    1
    2
    3
    4
    5
    6
    
    PARSED_ARGUMENTS is  -a --bravo --charlie 'Charlie' --delta 'River' -- 'lorem' 'ipsum'
    ALPHA   : 1
    BRAVO   : 1 
    CHARLIE : Charlie
    DELTA   : River
    Parameters remaining are: lorem ipsum
    
  • pushd and popd

  • 重定向

    1
    2
    3
    4
    5
    
    在shell脚本中,默认情况下,总是有三个文件处于打开状态,标准输入(键盘输入)、标准输出(输出到屏幕)、标准错误(也是输出到屏幕),它们分别对应的文件描述符是0,1,2 。
      
    >  默认为标准输出重定向,与 1> 相同
    2>&1  意思是把 标准错误输出 重定向到 标准输出.
    &>file  意思是把标准输出 和 标准错误输出 都重定向到文件file中
    
  • /dev/null

    1
    
    /dev/null是一个文件,这个文件比较特殊,所有传给它的东西它都丢弃掉
    
  • cut

    1
    2
    
    cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段写至标准输出。
    如果不指定 File 参数,cut 命令将读取标准输入。必须指定 -b、-c 或 -f 标志之一。
    
    1
    2
    3
    4
    5
    6
    
    -b :以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志。
    -c :以字符为单位进行分割。
    -d :自定义分隔符,默认为制表符。
    -f :与-d一起使用,指定显示哪个区域。
    -n :取消分割多字节字符。仅和 -b 标志一起使用。如果字符的最后一个字节落在由 -b 标志的 List 参数指示的
    范围之内,该字符将被写出;否则,该字符将被排除
    
    1
    2
    3
    
    gotmajor=`echo $gotver|cut -d. -f1`
    gotminor=`echo $gotver|cut -d. -f2`
    gotmicro=`echo $gotver|cut -d. -f3`
    

    References

1
2
OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/AFNetworking/AFNetworking.framework/Headers"

This post is licensed under CC BY 4.0 by the author.