乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Shell:語法規(guī)范

       新進小設(shè)計 2022-06-20 發(fā)布于北京

      背景

      博客:https://www.cnblogs.com/Rohn

      使用哪一種Shell

      可執(zhí)行文件必須以 #!/bin/bash 和最小數(shù)量的標志開始。請使用 set 來設(shè)置shell的選項,使得用 <script_name>調(diào)用你的腳本時不會破壞其功能。

      推薦使用:

      #!/usr/bin/env bash
      

      env一般固定在/usr/bin目錄下,而其余解釋器的安裝位置就相對不那么固定。

      限制所有的可執(zhí)行Shell腳本為bash使得我們安裝在所有計算機中的shell語言保持一致性。

      無論你是為什么而編碼,對此唯一例外的是當你被迫時可以不這么做的。其中一個例子是Solaris SVR4包,編寫任何腳本都需要用純Bourne shell

      [root@test ~]# echo $SHELL
      /bin/bash
      

      什么時候使用Shell

      使用Shell需要遵守的一些準則:

      • 如果你主要是在調(diào)用其他的工具并且做一些相對很小數(shù)據(jù)量的操作,那么使用Shell來完成任務(wù)是一種可接受的選擇。
      • 如果你在乎性能,那么請選擇其他工具,而不是使用Shell。
      • 如果你發(fā)現(xiàn)你需要使用數(shù)據(jù)而不是變量賦值(如 ${PHPESTATUS} ),那么你應(yīng)該使用Python腳本。
      • 如果你將要編寫的腳本會超過100行,那么你可能應(yīng)該使用Python來編寫,而不是Shell。

      請記住,當腳本行數(shù)增加,盡早使用另外一種語言重寫你的腳本,以避免之后花更多的時間來重寫。

      注釋

      博客:https://www.cnblogs.com/Rohn

      Bash只支持單行注釋,使用#開頭的都被當作注釋語句。

      頂層注釋

      每個文件必須包含一個頂層注釋,對其內(nèi)容進行簡要概述。版權(quán)聲明和作者信息是可選的。
      例如:

      #!/usr/bin/env bash
      # Author: Rohn
      # Version: 1.0
      # Created Time: 2020/06/06
      # Perform hot backups of MySQL databases.
      
      • 第1行,指明解釋器,使用bash

      #!叫做"Shebang"或者"Sha-bang"(Unix術(shù)語中,#號通常稱為sharp,hash或mesh;而!則常常稱為bang),指明了執(zhí)行這個腳本文件的解釋程序。當然,如果使用bash test.sh這樣的命令來執(zhí)行腳本,那么#!這一行將會被忽略掉。

      • 第2-5行,分別為作者、版本號、創(chuàng)建時間、功能說明。

      功能注釋

      任何不是既明顯又短的函數(shù)都必須被注釋。任何庫函數(shù)無論其長短和復雜性都必須被注釋。

      其他人通過閱讀注釋(和幫助信息,如果有的話)就能夠?qū)W會如何使用你的程序或庫函數(shù),而不需要閱讀代碼。

      所有的函數(shù)注釋應(yīng)該包含:

      • 函數(shù)的描述
      • 全局變量的使用和修改
      • 使用的參數(shù)說明
      • 返回值,而不是上一條命令運行后默認的退出狀態(tài)

      例如:

      #!/usr/bin/env bash
      # Author: Rohn
      # Version: 1.0
      # Created Time: 2020/06/06
      # Perform hot backups of Oracle databases.
      
      export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin'
      
      #######################################
      # Cleanup files from the backup dir
      # Globals:
      #   BACKUP_DIR
      #   ORACLE_SID
      # Arguments:
      #   None
      # Returns:
      #   None
      #######################################
      cleanup() {
        ...
      }
      

      TODO注釋

      TODOs應(yīng)該包含全部大寫的字符串TODO,接著是括號中你的用戶名。冒號是可選的。最好在TODO條目之后加上bug或者ticket的序號。

      例如:

      # TODO(mrmonkey): Handle the unlikely edge cases (bug ####)
      

      格式

      博客:https://www.cnblogs.com/Rohn

      縮進

      縮進兩個空格,沒有制表符。例如:

      if [ a > 1 ];then
        echo '${a} > 1'
      fi
      

      行的長度和長字符串

      行的最大長度為80個字符。例如:

      # DO use 'here document's
      cat <<END;
      I am an exceptionally long
      string.
      END
      
      # Embedded newlines are ok too
      long_string="I am an exceptionally
        long string."
      

      管道

      如果一行容不下整個管道操作,那么請將整個管道操作分割成每行一個管段。

      應(yīng)該將整個管道操作分割成每行一個管段,管道操作的下一部分應(yīng)該將管道符放在新行并且縮進2個空格。這適用于使用管道符|的合并命令鏈以及使用||&&的邏輯運算鏈。

      例如:

      # All fits on one line
      command1 | command2
      
      # Long commands
      command1   | command2   | command3   | command4
      

      循環(huán)

      if-else語句

      if; then放在同一行,;后空一格,else單獨一行,fi單獨一行,并與if垂直對齊。即:

      if condition; then
        statement(s)
      else
        statement(s)
      fi
      

      for-do和while-do語句

      while/for; do放在同一行,donewhile/for垂直對齊,即:

      # while structure
      while condition; do
        statement(s)
      done
      
      # for structure
      for condition; do
        statement(s)
      done
      

      例如:

      for dir in ${dirs_to_cleanup}; do
        if [[ -d "${dir}/${ORACLE_SID}" ]]; then
          log_date "Cleaning up old files in ${dir}/${ORACLE_SID}"
          rm "${dir}/${ORACLE_SID}/"*
          if [[ "$?" -ne 0 ]]; then
            error_message
          fi
        else
          mkdir -p "${dir}/${ORACLE_SID}"
          if [[ "$?" -ne 0 ]]; then
            error_message
          fi
        fi
      done
      

      case語句

      • 通過2個空格縮進可選項。
      • 在同一行可選項的模式右圓括號之后和結(jié)束符 ;;之前各需要一個空格。
      • 長可選項或者多命令可選項應(yīng)該被拆分成多行,模式、操作和結(jié)束符;;在不同的行。

      匹配表達式比caseesac 縮進一級。多行操作要再縮進一級。一般情況下,不需要引用匹配表達式。模式表達式前面不應(yīng)該出現(xiàn)左括號。避免使用;&;;&符號。即:

      # case structure
      case in expression in
        pattern1)
          statement1
          ;;
        pattern2)
          statement2
          ;;
        ...
        *)
          statementn
          ;;
      esac
      

      例如:

      case "${expression}" in
        a)
          variable="..."
          some_command "${variable}" "${other_expr}" ...
          ;;
        absolute)
          actions="relative"
          another_command "${actions}" "${other_expr}" ...
          ;;
        *)
          error "Unexpected expression '${expression}'"
          ;;
      esac
      

      只要整個表達式可讀,簡單的命令可以跟模式和;; 寫在同一行。這通常適用于單字母選項的處理。當單行容不下操作時,請將模式單獨放一行,然后是操作,最后結(jié)束符;; 也單獨一行。當操作在同一行時,模式的右括號之后和結(jié)束符;;之前請使用一個空格分隔。

      verbose='false'
      aflag=''
      bflag=''
      files=''
      while getopts 'abf:v' flag; do
        case "${flag}" in
          a) aflag='true' ;;
          b) bflag='true' ;;
          f) files="${OPTARG}" ;;
          v) verbose='true' ;;
          *) error "Unexpected option ${flag}" ;;
        esac
      done
      

      變量擴展

      按優(yōu)先級順序:保持跟你所發(fā)現(xiàn)的一致;引用你的變量;推薦用${var}而不是$var

      例如

      # Section of recommended cases.
      
      # Preferred style for 'special' variables:
      echo "Positional: $1" "$5" "$3"
      echo "Specials: !=$!, -=$-, _=$_. ?=$?, #=$# *=$* @=$@ \$=$$ ..."
      
      # Braces necessary:
      echo "many parameters: ${10}"
      
      # Braces avoiding confusion:
      # Output is "a0b0c0"
      set -- a b c
      echo "${1}0${2}0${3}0"
      
      # Preferred style for other variables:
      echo "PATH=${PATH}, PWD=${PWD}, mine=${some_var}"
      while read f; do
        echo "file=${f}"
      done < <(ls -l /tmp)
      
      # Section of discouraged cases
      
      # Unquoted vars, unbraced vars, brace-quoted single letter
      # shell specials.
      echo a=$avar "b=$bvar" "PID=${$}" "${1}"
      
      # Confusing use: this is expanded as "${1}0${2}0${3}0",
      # not "${10}${20}${30}
      set -- a b c
      echo "$10$20$30"
      

      特性

      博客:https://www.cnblogs.com/Rohn

      命令替換

      使用 $(command)而不是反引號。

      嵌套的反引號要求用反斜杠轉(zhuǎn)義內(nèi)部的反引號。而$(command) 形式嵌套時不需要改變,而且更易于閱讀。

      例如:

      # This is preferred:
      var="$(command "$(command1)")"
      
      # This is not:
      var="`command \`command1\``"
      

      文件名的通配符擴展

      當進行文件名的通配符擴展時,請使用明確的路徑。

      因為文件名可能以-開頭,所以使用擴展通配符./**來得安全得多。

      # Here's the contents of the directory:
      # -f  -r  somedir  somefile
      
      # This deletes almost everything in the directory by force
      psa@bilby$ rm -v *
      removed directory: `somedir'
      removed `somefile'
      
      # As opposed to:
      psa@bilby$ rm -v ./*
      removed `./-f'
      removed `./-r'
      rm: cannot remove `./somedir': Is a directory
      removed `./somefile'
      

      命名約定

      博客:https://www.cnblogs.com/Rohn

      函數(shù)名

      使用小寫字母,并用下劃線分隔單詞。使用雙冒號 :: 分隔庫。函數(shù)名之后必須有圓括號。關(guān)鍵詞 function 是可選的,但必須在一個項目中保持一致。

      如果你正在寫單個函數(shù),請用小寫字母來命名,并用下劃線分隔單詞。如果你正在寫一個包,使用雙冒號 :: 來分隔包名。大括號必須和函數(shù)名位于同一行(就像在Google的其他語言一樣),并且函數(shù)名和圓括號之間沒有空格。

      # Single function
      my_func() {
        ...
      }
      
      # Part of a package
      mypackage::my_func() {
        ...
      }
      

      當函數(shù)名后存在 () 時,關(guān)鍵詞 function 是多余的。但是其促進了函數(shù)的快速辨識。

      變量名

      使用小寫字母,循環(huán)的變量名應(yīng)該和循環(huán)的任何變量同樣命名。例如:

      for zone in ${zones}; do
        something_with "${zone}"
      done
      

      常量和環(huán)境變量名

      全部使用大寫字母,用下劃線分隔,聲明在文件的頂部。例如:

      # Constant
      readonly PATH_TO_FILES='/some/path'
      
      # Both constant and environment
      declare -xr ORACLE_SID='PROD'
      

      源文件名

      使用小寫字母,如果需要的話使用下劃線分隔單詞。例如: maketemplate 或者 make_template ,而不是 make-template

      只讀變量

      使用小寫字母,使用 readonly 或者 declare -r 來確保變量只讀。

      因為全局變量在Shell中廣泛使用,所以在使用它們的過程中捕獲錯誤是很重要的。當你聲明了一個變量,希望其只讀,那么請明確指出。

      zip_version="$(dpkg --status zip | grep Version: | cut -d ' ' -f 2)"
      if [[ -z "${zip_version}" ]]; then
        error_message
      else
        readonly zip_version
      fi
      

      使用本地變量

      使用小寫字母,使用 local 聲明特定功能的變量。聲明和賦值應(yīng)該在不同行。

      使用 local 來聲明局部變量以確保其只在函數(shù)內(nèi)部和子函數(shù)中可見。這避免了污染全局命名空間和不經(jīng)意間設(shè)置可能具有函數(shù)之外重要性的變量。

      當賦值的值由命令替換提供時,聲明和賦值必須分開。因為內(nèi)建的 local 不會從命令替換中傳遞退出碼。

      my_func2() {
        local name="$1"
      
        # Separate lines for declaration and assignment:
        local my_var
        my_var="$(my_func)" || return
      
        # DO NOT do this: $? contains the exit code of 'local', not my_func
        local my_var="$(my_func)"
        [[ $? -eq 0 ]] || return
      
        ...
      }
      

      調(diào)用命令

      博客:https://www.cnblogs.com/Rohn

      檢查返回值

      對于非管道命令,使用$?或直接通過一個if語句來檢查以保持其簡潔。例如:

      if ! mv "${file_list}" "${dest_dir}/" ; then
        echo "Unable to move ${file_list} to ${dest_dir}" >&2
        exit "${E_BAD_MOVE}"
      fi
      
      # Or
      mv "${file_list}" "${dest_dir}/"
      if [[ "$?" -ne 0 ]]; then
        echo "Unable to move ${file_list} to ${dest_dir}" >&2
        exit "${E_BAD_MOVE}"
      fi
      

      Bash也有 PIPESTATUS 變量,允許檢查從管道所有部分返回的代碼。如果僅僅需要檢查整個管道是成功還是失敗,以下的方法是可以接受的:

      tar -cf - ./* | ( cd "${dir}" && tar -xf - )
      if [[ "${PIPESTATUS[0]}" -ne 0 || "${PIPESTATUS[1]}" -ne 0 ]]; then
        echo "Unable to tar files to ${dir}" >&2
      fi
      

      可是,只要你運行任何其他命令, PIPESTATUS 將會被覆蓋。如果你需要基于管道中發(fā)生的錯誤執(zhí)行不同的操作,那么你需要在運行命令后立即將 PIPESTATUS 賦值給另一個變量(別忘了 [ 是一個會將 PIPESTATUS 擦除的命令)。

      tar -cf - ./* | ( cd "${DIR}" && tar -xf - )
      return_codes=(${PIPESTATUS[*]})
      if [[ "${return_codes[0]}" -ne 0 ]]; then
        do_something
      fi
      if [[ "${return_codes[1]}" -ne 0 ]]; then
        do_something_else
      fi
      

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多