主頁(yè) > 知識(shí)庫(kù) > 分享一個(gè)可以通過(guò)命令簡(jiǎn)寫執(zhí)行對(duì)應(yīng)命令的Shell腳本

分享一個(gè)可以通過(guò)命令簡(jiǎn)寫執(zhí)行對(duì)應(yīng)命令的Shell腳本

熱門標(biāo)簽:電話機(jī)器人對(duì)家居行業(yè)幫助大嗎 合肥電銷外呼系統(tǒng)供應(yīng)商 黑暗之魂3地圖標(biāo)注 蘭州電銷機(jī)器人加盟 沈陽(yáng)ai電銷智能機(jī)器人 電商外呼系統(tǒng)排名 AI智能電銷機(jī)器人壞處 如何申請(qǐng)400的電話呀 地圖標(biāo)注審核周期

本篇文章介紹一個(gè)可以通過(guò)命令簡(jiǎn)寫執(zhí)行對(duì)應(yīng)命令的 shell 腳本。

假設(shè)這個(gè) shell 腳本的名稱為 tinyshell.sh。

在 Linux 下進(jìn)行項(xiàng)目開發(fā),經(jīng)常會(huì)用到一些調(diào)試開發(fā)命令。

這些命令可能比較長(zhǎng),需要輸入多個(gè)字符。

例如,Android 系統(tǒng)抓取全部 log 并包含 log 時(shí)間的命令是 adb logcat -b all -v threadtime。

抓取 log 是調(diào)試開發(fā)非常常見的操作,這個(gè)命令又很長(zhǎng),輸入起來(lái)不方便。

為了簡(jiǎn)化輸入,可以配置一些命令簡(jiǎn)寫來(lái)對(duì)應(yīng)比較長(zhǎng)命令。

例如,配置 ala 對(duì)應(yīng) adb logcat -b all -v threadtime。

把 als 作為參數(shù)傳遞給當(dāng)前的 tinyshell.sh 腳本,會(huì)執(zhí)行該命令簡(jiǎn)寫對(duì)應(yīng)的命令。

這樣只需要輸入比較少的字符,就能執(zhí)行比較長(zhǎng)的命令。

實(shí)際上,這個(gè)功能類似于 bash 的 alias 別名,只是將這些別名統(tǒng)一放到該腳本來(lái)處理。

可以把 tinyshell.sh 腳本作為學(xué)習(xí) shell 腳本的參考例子,獨(dú)立維護(hù)更新,根據(jù)需要擴(kuò)充更多的功能。

配置命令簡(jiǎn)寫

如之前說(shuō)明,可以用 ala 表示 adb logcat -b all -v threadtime 這個(gè)命令。

這個(gè) ala 稱之為 “命令簡(jiǎn)寫”。

命令簡(jiǎn)寫使用一些簡(jiǎn)單的字符來(lái)表示特定的命令。

可以在命令簡(jiǎn)寫后面動(dòng)態(tài)提供命令的參數(shù)。

為了方便動(dòng)態(tài)添加、刪除、查詢命令簡(jiǎn)寫,可以把這些命令簡(jiǎn)寫保存在一個(gè)配置文件里面。

在執(zhí)行 tinyshell.sh 腳本時(shí),會(huì)讀取配置文件內(nèi)容,獲取到各個(gè)配置項(xiàng)的值。

配置項(xiàng)的基本格式是:命令簡(jiǎn)寫|命令內(nèi)容

每個(gè)配置項(xiàng)占據(jù)一行。每一行默認(rèn)以第一個(gè)豎線 ‘|' 隔開命令簡(jiǎn)寫和命令內(nèi)容。

一個(gè)參考的配置文件內(nèi)容如下所示:

ll|ls --color=auto -l
ala|adb logcat -b all -v threadtime
gl|git log
gp|git pull --stat --no-tags $(git remote) $(git rev-parse --abbrev-ref HEAD)

這里配置的命令內(nèi)容可以是系統(tǒng)支持的任意命令。

解析配置文件時(shí),需要用到之前文章介紹的 parsecfg.sh 腳本。

要獲取 parsecfg.sh 腳本的代碼,可以查看之前的文章。

后面會(huì)提供具體測(cè)試的例子,可供參考。

腳本代碼

列出 tinyshell.sh 腳本的具體代碼如下所示。

在這個(gè)代碼中,對(duì)大部分關(guān)鍵代碼都提供了詳細(xì)的注釋,方便閱讀。

這篇文章的后面也會(huì)對(duì)一些關(guān)鍵點(diǎn)進(jìn)行說(shuō)明,有助理解。

#!/bin/bash -i
# 使用 bash 的 -i 選項(xiàng),讓該腳本在交互模式下運(yùn)行.
# 實(shí)現(xiàn)一個(gè)小型的 shell. 支持內(nèi)置命令、命令簡(jiǎn)寫. 如果提供這兩種命令之外
# 的其他命令,會(huì)嘗試在 bash 中直接執(zhí)行所給命令,可以執(zhí)行系統(tǒng)支持的命令.
# 命令簡(jiǎn)寫指的是一些簡(jiǎn)單的字符,會(huì)對(duì)應(yīng)一串實(shí)際要執(zhí)行的命令.只要輸入命令
# 簡(jiǎn)寫就可以執(zhí)行對(duì)應(yīng)的命令,減少需要輸入的字符.命令簡(jiǎn)寫在配置文件中配置.

# 下面變量指定默認(rèn)解析的配置文件名.該文件配置了命令簡(jiǎn)寫、以及對(duì)應(yīng)的命令.
# 這個(gè) tinyshellcmds.txt 文件需要預(yù)先配置好,放到指定路徑的目錄底下.
# 直接修改這個(gè)配置文件,就可以動(dòng)態(tài)添加或刪除命令簡(jiǎn)寫.不需要修改腳本代碼.
SHORT_COMMANDS="${HOME}/.liconfig/tinyshellcmds.txt"

# PARSECFG_filepath 是 parsecfg.sh 腳本里面的變量. 如果這個(gè)變量為空,
# 說(shuō)明還沒(méi)有打開過(guò)配置文件,進(jìn)入下面的分支打開默認(rèn)的配置文件.
if [ -z "$PARSECFG_filepath" ]; then
  # 導(dǎo)入解析配置文件的腳本,以便調(diào)用該腳本的函數(shù)來(lái)解析配置文件.
  source parsecfg.sh
  # 調(diào)用 parsecfg.sh 里面的 open_config_file() 函數(shù)解析配置文件.
  # 如果配置文件不存在,會(huì)返回 1,經(jīng)過(guò)'!'操作符取反為 0,會(huì)退出執(zhí)行.
  if ! open_config_file "$SHORT_COMMANDS"; then
    exit 2
  fi
fi

# 下面變量指定 tiny shell 的提示字符串.
PROMPT="TinySh>>> "

# 下面使用 basename 命令來(lái)提取出腳本的文件名,去掉目錄路徑部分.
show_help()
{
printf "USAGE
  $(basename $0) [option] [shortcmd [argument1 ... [argumentn]]]
OPTIONS
  option: 可選的選項(xiàng)參數(shù). 支持的選項(xiàng)參數(shù)描述如下:
    -h: 打印這個(gè)幫助信息.
    -l: 打印配置文件本身的內(nèi)容,會(huì)列出配置的命令簡(jiǎn)寫和對(duì)應(yīng)的命令.
    -v: 以鍵值對(duì)的方式列出命令簡(jiǎn)寫和對(duì)應(yīng)的命令.
    -i: 在配置文件中查找指定內(nèi)容.后面跟著一個(gè)參數(shù),指定要查找的內(nèi)容.
    -e: 使用 vim 打開腳本的配置文件,以供編輯.
    -a: 新增或修改一個(gè)命令簡(jiǎn)寫和對(duì)應(yīng)的命令.后面跟著一個(gè)參數(shù),用
      單引號(hào)括起來(lái),以指定命令簡(jiǎn)寫和命令. 格式為: 命令簡(jiǎn)寫|命令.
      例如 -a 'p|git pull',如果p簡(jiǎn)寫不存在則新增它,否則修改它.
    -d: 從腳本配置文件中刪除一個(gè)命令簡(jiǎn)寫和對(duì)應(yīng)的命令.后面跟著一個(gè)
      參數(shù),指定要?jiǎng)h除的命令簡(jiǎn)寫.例如 -d s,會(huì)刪除命令簡(jiǎn)寫為 s 的行.
  shortcmd: 可選選項(xiàng).
    指定要直接執(zhí)行的命令簡(jiǎn)寫. 提供命令簡(jiǎn)寫參數(shù),不會(huì)進(jìn)入 tiny shell.
  argument1 ... argumentn: 可選選項(xiàng).
    指定該命令簡(jiǎn)寫的參數(shù). 命令簡(jiǎn)寫對(duì)應(yīng)一個(gè)命令,支持動(dòng)態(tài)提供參數(shù).
NOTE
  如果沒(méi)有提供任何參數(shù),默認(rèn)會(huì)進(jìn)入 tiny shell 解釋器. 在 tiny shell 中
  接收用戶輸入并執(zhí)行對(duì)應(yīng)的命令.直到讀取到EOF、或者執(zhí)行quit命令才會(huì)退出.
"
}

# tiny shell 的內(nèi)置命令數(shù)組. 這是一個(gè)關(guān)聯(lián)數(shù)組. 數(shù)組元素的
# 鍵名是內(nèi)置命令名. 數(shù)組元素的鍵值是響應(yīng)內(nèi)置命令的函數(shù)名.
declare -A BUILTIN_COMMAND=( \

  [help]="builtin_command_help" \

  [quit]="builtin_command_quit" \

  [debug]="builtin_command_debug" \

)

# bash 的 help 命令默認(rèn)會(huì)打印內(nèi)置命令列表. 這里仿照這個(gè)行為,
# 讓 help 內(nèi)置命令打印內(nèi)置命令列表、以及配置文件包含的命令簡(jiǎn)寫.
builtin_command_help()
{
printf "下面列出 Tiny Shell 支持的內(nèi)置命令列表和配置的命令簡(jiǎn)寫列表.
輸入內(nèi)置命令名或命令簡(jiǎn)寫,會(huì)執(zhí)行對(duì)應(yīng)的命令.
也可以輸入系統(tǒng)自身支持的命令,會(huì)在 bash 中執(zhí)行所給命令.

內(nèi)置命令列表:
  debug: 所給第一個(gè)參數(shù)指定打開、或關(guān)閉調(diào)試功能. 其參數(shù)說(shuō)明如下:
    on: 打開調(diào)試功能,會(huì)執(zhí)行 bash 的 set -x 命令
    off: 關(guān)閉調(diào)試功能,會(huì)執(zhí)行 bash 的 set +x 命令
  help: 打印當(dāng)前幫助信息.
  quit: 退出當(dāng)前 Tiny Shell.

命令簡(jiǎn)寫列表:
"
  # 調(diào)用 parsecfg.sh 的 handle_config_option -v 打印命令簡(jiǎn)寫列表
  handle_config_option -v
}

# quit 內(nèi)置命令. 執(zhí)行該命令會(huì)退出整個(gè)腳本,從而退出當(dāng)前 tiny shell.
builtin_command_quit()
{
  exit
}

# debug 內(nèi)置命令. 所給第一個(gè)參數(shù)指定打開、或關(guān)閉調(diào)試功能.
# debug on: 打開調(diào)試功能,會(huì)執(zhí)行 bash 的 set -x 命令
# debug off: 關(guān)閉調(diào)試功能,會(huì)執(zhí)行 bash 的 set +x 命令
builtin_command_debug()
{
  if [ $# -ne 1 ]; then
    echo "Usage: debug on/off"
    return 1
  fi

  if [ "$1" == "on" ]; then
    set -x
  elif [ "$1" == "off" ]; then
    set +x
  else
    echo -e "Unknown argument: $1\nUsage: debug on/off"
  fi
  return
}

# 處理 tiny shell 內(nèi)置命令.對(duì)于內(nèi)置命令,會(huì)調(diào)用對(duì)應(yīng)函數(shù)進(jìn)行處理.
# 該函數(shù)的返回值表示所給命令名是否內(nèi)置命令.
# 返回 0, 表示是內(nèi)置命令. 返回 1, 表示不是內(nèi)置命令.
execute_builtin_command()
{
  # 在傳遞過(guò)來(lái)的參數(shù)中,第一個(gè)參數(shù)是命令名,剩余的參數(shù)是該命令的參數(shù).
  local cmdname="$1"
  # 從 BUILTIN_COMMAND 數(shù)組中獲取所給命令對(duì)應(yīng)的處理函數(shù).
  # 如果所給命令不是內(nèi)置命令,會(huì)獲取為空.
  local cmdfunc="${BUILTIN_COMMAND["${cmdname}"]}"

  if [ -n "${cmdfunc}" ]; then
    # 將位置參數(shù)左移一位,移除命令名,剩下的就是該命令的參數(shù).
    shift 1
    ${cmdfunc} "$@"
    # 無(wú)論執(zhí)行內(nèi)置命令是否報(bào)錯(cuò),都會(huì)返回 0,表示該命令是內(nèi)置命令.
    return 0
  else
    return 1
  fi
}

# 處理 tiny shell 的命令簡(jiǎn)寫.在所解析的配置文件中包含了支持的命令簡(jiǎn)寫.
# 該函數(shù)的返回值表示所給命令名是否命令簡(jiǎn)寫.
# 返回 0, 表示是命令簡(jiǎn)寫. 返回 1, 表示不是命令簡(jiǎn)寫.
execute_short_command()
{
  # 判斷所給的參數(shù)是否對(duì)應(yīng)配置文件中的某個(gè)鍵名.如果是,將取出鍵值.
  local key="$1"
  # 從配置文件中獲取所給命令簡(jiǎn)寫對(duì)應(yīng)要執(zhí)行的命令
  local cmd_value=$(get_value_by_key "${key}")
  if test -n "${cmd_value}"; then
    # 將位置參數(shù)左移一位,移除命令簡(jiǎn)寫,剩下的就是命令的參數(shù).
    shift 1
    # 下面要用 "$*" 來(lái)把所有參數(shù)組合成一個(gè)參數(shù),再跟命令內(nèi)容一起傳入
    # bach -c,確保 bash -c 把命令內(nèi)容和所有參數(shù)都當(dāng)成要執(zhí)行的命令
    bash -c "$cmd_value $*"
    # 打印命令簡(jiǎn)寫,以及該簡(jiǎn)寫對(duì)應(yīng)的命令,以便查看具體執(zhí)行了什么命令.
    # 先執(zhí)行命令,再打印命令內(nèi)容. 由于有些命令的輸出很多,先打印命令
    # 內(nèi)容的話,需要拉動(dòng)終端滾動(dòng)條,才能找到打印的命令內(nèi)容,不便于查看.
    echo -e "\e[33m命令簡(jiǎn)寫: ${key}. 命令: ${cmd_value} $*\e[0m"
    return 0
  else
    # 如果獲取到的鍵值為空,表示所給鍵名不是有效的命令簡(jiǎn)寫,返回 1
    return 1
  fi
}

# 處理所給的內(nèi)容.這個(gè)內(nèi)容可能是內(nèi)置命令,命令簡(jiǎn)寫,或者命令本身.
handle_input_command()
{
  # 所給參數(shù)是要執(zhí)行的命令名、以及命令參數(shù). 如果命令名是配置的
  # 命令簡(jiǎn)寫,會(huì)把該命令簡(jiǎn)寫替換成對(duì)應(yīng)的命令,再進(jìn)行對(duì)應(yīng)的命令.
  local inputcmd="$@"

  # if 語(yǔ)句可以直接判斷命令返回值是否為 0,并不是只能搭配 [ 命令使用.
  # 注意: 由于有的 tiny shell 內(nèi)置命令接收參數(shù),下面的 ${cmd_line}
  # 不能用雙引號(hào)括起來(lái),否則多個(gè)參數(shù)會(huì)被當(dāng)成一個(gè)參數(shù).
  if execute_builtin_command ${inputcmd}; then
    # 先調(diào)用 execute_builtin_command 函數(shù)處理內(nèi)置命令.如果所給
    # 命令是內(nèi)置命令,則調(diào)用對(duì)應(yīng)的函數(shù)進(jìn)行處理,且不再往下執(zhí)行.
    return 0
  elif execute_short_command ${inputcmd}; then
    # 調(diào)用 execute_short_command 函數(shù)處理命令簡(jiǎn)寫.
    return 0
  else
    # 對(duì)于 tiny shell 不能執(zhí)行的命令,嘗試用 bash -c 在 bash 中執(zhí)行.
    bash -c "${inputcmd}"
    # 當(dāng) return 命令不加具體狀態(tài)碼時(shí),它會(huì)返回上一條執(zhí)行命令的狀態(tài)碼.
    return
  fi
}

# SIGINT 信號(hào)的處理函數(shù).目前不做特殊處理,只是想在輸入CTRL-C后,不會(huì)終止
# 當(dāng)前 tiny shell. 輸入 CTRL-C 還是可以終止 tiny shell 啟動(dòng)的子 shell.
sigint_handler()
{
  # 當(dāng)輸入 CTRL-C 后,終端只顯示"^C",但是不會(huì)自動(dòng)換行,需要輸入回車才會(huì)
  # 換行,并重新輸出提示字符串. 而在交互式Bash中,輸入"^C"后,就會(huì)自動(dòng)回
  # 車,并輸出提示字符串.這里模仿這個(gè)行為,先輸出一個(gè)回車,再輸出提示符.
  printf "\n${PROMPT}"
}

# 啟動(dòng) tiny shell 解釋器. 從標(biāo)準(zhǔn)輸入不停讀取、并執(zhí)行所給命令.直到
# 使用 CTRL-D 輸入 EOF 為止, 或者輸入 quit 命令退出當(dāng)前解釋器.
start_tinyshell()
{
  # 執(zhí)行 python 命令,默認(rèn)會(huì)打印 python 版本號(hào)和一句幫助提示.
  # 這里仿照這個(gè)行為,打印 tiny shel 版本號(hào)和一句幫助提示.
  echo -e "Tiny shell 1.0.0\nType 'help' for more information."

  # 捕獲SIGINT信號(hào),以便輸入 CTRL-C 后,不會(huì)退出當(dāng)前的 tiny shell.
  # 注意: 由于子shell會(huì)繼承父shell所忽略的信號(hào),所以不能將 SIGINT 信號(hào)
  # 設(shè)成忽略,而是要指定一個(gè)處理函數(shù). 當(dāng)前 shell 所捕獲的信號(hào)不會(huì)被
  # 子 shell 繼承. 所以子 shell 還是可以被 CTRL-C 終止. 即,指定信號(hào)處理
  # 函數(shù)后,當(dāng)前 tiny shell 不會(huì)被CTRL-C終止.但是當(dāng)前 tiny shell 執(zhí)行的
  # 命令會(huì)運(yùn)行在子 shell 下,可以用 CTRL-C 終止運(yùn)行在子 shell 下的命令.
  # 查看 man bash 對(duì)子 shell 的信號(hào)繼承關(guān)系說(shuō)明如下:
  # traps caught by the shell are reset to the values inherited from
  # the shell's parent, and traps ignored by the shell are ignored
  trap "sigint_handler" SIGINT

  # 如果不使用 -e 選項(xiàng),輸入上光標(biāo)鍵, read 會(huì)讀取到 "^[[A";輸入下光標(biāo)鍵,
  # read 會(huì)讀取到 "^[[B".而使用 -e 選項(xiàng)后,輸入上下光標(biāo)鍵,不會(huì)讀取到亂碼,
  # 但是在子shell中,也不會(huì)返回歷史命令.因?yàn)閟hell腳本是在非交互模式下執(zhí)行.
  # 可以使用 bash 的 -i 選項(xiàng)讓腳本在交互模式下運(yùn)行,例如: "#/bin/bash -i"
  while read -ep "${PROMPT}" input; do
    # 傳遞參數(shù)給函數(shù)時(shí),參數(shù)要用雙引號(hào)括起來(lái),避免參數(shù)帶有空格時(shí),會(huì)拆分
    # 成多個(gè)參數(shù). 當(dāng)輸入CTRL-C時(shí), tiny shell 捕獲了這個(gè)信號(hào),不會(huì)退出
    # 當(dāng)前的 tiny shell.但是read命令會(huì)被中斷,此時(shí)讀取到的 input 為空.
    # 不需要對(duì)空行做處理,所以下面先判斷 input 變量值是否為空.
    if [ -n "${input}" ]; then
      handle_input_command "${input}"
      # 執(zhí)行 history -s 命令把所給的參數(shù)添加到當(dāng)前歷史記錄中.后續(xù)
      # 通過(guò)上下光標(biāo)鍵獲取歷史命令,就可以獲取到新添加的命令.這個(gè)只
      # 影響當(dāng)前 tiny shell 的歷史記錄,不會(huì)寫入外部shell的歷史記錄.
      history -s "${input}"
    fi
  done

  # 輸出一個(gè)換行.當(dāng)用戶輸入CTRL-D結(jié)束執(zhí)行后,需要換行顯示原先的終端提示符.
  echo
}

# 循環(huán)調(diào)用 getopts 命令處理選項(xiàng)參數(shù).
while getopts "hlvi:ea:d:" opt; do
  # 調(diào)用parsecfg.sh腳本處理選項(xiàng)的函數(shù)來(lái)處理 "lvi:ea:d:" 這幾個(gè)選項(xiàng).
  # 如果處理成功,就直接繼續(xù)讀取下一個(gè)選項(xiàng),不再往下處理.
  # handle_config_option()函數(shù)要求傳入的選項(xiàng)以'-'開頭,而getopts命令
  # 返回的選項(xiàng)不帶有'-',所以下面在 ${opt} 前面加上一個(gè) '-'.
  handle_config_option "-${opt}" "${OPTARG}"
  if [ $? -ne 127 ]; then
    continue
  fi

  case "$opt" in
    h) show_help ;;
    ?) echo "出錯(cuò): 異常選項(xiàng),請(qǐng)使用 -h 選項(xiàng)查看腳本的幫助說(shuō)明." ;;
  esac
done

# $# 大于0,說(shuō)明提供了命令參數(shù). $# 等于OPTIND減去1,說(shuō)明傳入的參數(shù)都
# 是以 '-' 開頭的選項(xiàng)參數(shù). 此時(shí),直接結(jié)束執(zhí)行,不需要再往下處理.
# 下面的 -a 表示兩個(gè)表達(dá)式都為真時(shí)才為真.表達(dá)式之間不要加小括號(hào).
# Shell里面的小括號(hào)有特殊含義,跟C語(yǔ)言的小括號(hào)有些區(qū)別,加上會(huì)有問(wèn)題.
if [ $# -gt 0 -a $# -eq $((OPTIND-1)) ]; then
  exit 0
fi

if [ $# -eq 0 ]; then
  # 當(dāng)不帶任何參數(shù)時(shí),默認(rèn)啟用 tiny shell.
  start_tinyshell
else
  # 左移所給的命令參數(shù),去掉已處理過(guò)的選項(xiàng)參數(shù),只剩下非選項(xiàng)參數(shù).
  shift $((OPTIND-1))
  # 執(zhí)行腳本時(shí),如果提供了非選項(xiàng)參數(shù),那么第一個(gè)參數(shù)認(rèn)為是命令簡(jiǎn)寫,
  # 需要執(zhí)行該命令簡(jiǎn)寫對(duì)應(yīng)的命令. 第一個(gè)參數(shù)之后的所有參數(shù)認(rèn)為是
  # 命令的參數(shù). 即,可以在命令簡(jiǎn)寫之后提供參數(shù)來(lái)動(dòng)態(tài)指定一些操作.
  execute_short_command "$@"
fi

exit

代碼關(guān)鍵點(diǎn)說(shuō)明

使用 trap 命令捕獲信號(hào)

在 bash 中,可以使用 trap 命令捕獲信號(hào),并指定信號(hào)處理函數(shù)。

捕獲信號(hào)后,可以避免收到某個(gè)信號(hào)終止腳本執(zhí)行。

當(dāng)前 tinyshell.sh 腳本使用 trap 命令捕獲 SIGINT 信號(hào)。

也就是 CTRL-C 鍵所發(fā)送的信號(hào),避免按 CTRL-C 鍵會(huì)退出當(dāng)前 tiny shell。

要注意的是,不能設(shè)置成忽略 SIGINT 信號(hào)。

在 bash 中,父 shell 所忽略的信號(hào),也會(huì)被子 shell 所忽略。

除了內(nèi)置命令之外,當(dāng)前 tiny shell 所執(zhí)行的命令運(yùn)行在子 shell 下。

如果設(shè)置成忽略 SIGINT 信號(hào),那么子 shell 也會(huì)忽略這個(gè)信號(hào)。

那么就不能用 CTRL-C 來(lái)終止子 shell 命令的執(zhí)行。

例如,Android 系統(tǒng)的 adb logcat 命令會(huì)不停打印 log,需要按 CTRL-C 來(lái)終止。

此時(shí),在 tiny shell 里面按 CTRL-C 就不能終止 adb logcat 的執(zhí)行。

父 shell 所捕獲的信號(hào),子 shell 不會(huì)繼承父 shell 所捕獲的信號(hào)。

子 shell 會(huì)繼承父 shell 的父進(jìn)程的信號(hào)狀態(tài)。

父 shell 的父進(jìn)程一般是外部 bash shell 進(jìn)程。

而 bash shell 進(jìn)程默認(rèn)捕獲SIGINT并終止前臺(tái)進(jìn)程。

即,雖然當(dāng)前 tiny shell 捕獲了 SIGINT 信號(hào),但是子 shell 并沒(méi)有捕獲該信號(hào)。

可以在 tiny shell 使用 CTRL-C 來(lái)終止子 shell 命令的執(zhí)行。

使用 history -s 命令添加歷史記錄

在 tiny shell 執(zhí)行命令后,默認(rèn)不能用上下光標(biāo)鍵查找到 tiny shell 自身執(zhí)行的歷史命令。

為了可以查找到 tiny shell 自身執(zhí)行的歷史命令,使用 history -s 命令添加命令到當(dāng)前 shell 的歷史記錄。

這個(gè)命令只會(huì)影響當(dāng)前 shell 的歷史記錄。

退出當(dāng)前 shell 后,在外部 shell 還是看不到 tiny shell 所執(zhí)行的命令。

由于這個(gè) tiny shell 主要是為了執(zhí)行命令簡(jiǎn)寫。

這些命令簡(jiǎn)寫只有 tiny shell 自身支持,不需要添加到 bash shell 的歷史記錄。

如果想要命令歷史信息添加到外部 shell 的歷史記錄,可以在退出 tinyshell.sh 腳本之前,執(zhí)行 history -w ~/.bash_history 命令把歷史記錄寫入到 bash 自身的歷史記錄文件。

測(cè)試?yán)?br />

把 tinyshell.sh 腳本放到 PATH 變量指定的可尋址目錄下。

查看 tinyshell.sh 腳本代碼,可知要解析的配置文件名是 tinyshellcmds.txt。

把前面貼出的命令簡(jiǎn)寫配置信息寫入 tinyshellcmds.txt 文件。

把這個(gè)文件放到 HOME 目錄的 .liconfig 目錄下。

之后,就可以開始執(zhí)行 tinyshell.sh 腳本。

當(dāng)前的 tinyshell.sh 腳本可以執(zhí)行內(nèi)置命令、命令簡(jiǎn)寫對(duì)應(yīng)的命令、系統(tǒng)自身支持的命令。

當(dāng)不提供任何命令參數(shù)時(shí),會(huì)進(jìn)入 tiny shell。

在 tiny shell 中,會(huì)不停接收用戶輸入并執(zhí)行對(duì)應(yīng)命令。

直到讀取到 EOF 、或者執(zhí)行 quit 命令才會(huì)退出 tiny shell。

處理選項(xiàng)參數(shù)和直接處理命令簡(jiǎn)寫的例子

下面是不進(jìn)入 tiny shell,只處理選項(xiàng)參數(shù)和命令簡(jiǎn)寫的例子:

$ tinyshell.sh -v
key='gl'    value='git log'
key='gp'    value='git pull --stat --no-tags $(git remote) $(git rev-parse --abbrev-ref HEAD)'
key='ll'    value='ls --color=auto -l'
key='ala'    value='adb logcat -b all -v threadtime'
$ tinyshell.sh ll
-rwxrwxr-x 1 xxx xxx 964 11月 14 17:37 tinyshell.sh
命令簡(jiǎn)寫: ll. 命令: ls --color=auto -l

這里先執(zhí)行 tinyshell.sh -v 命令,用鍵值對(duì)的形式列出支持的命令簡(jiǎn)寫。

此時(shí),只處理所給的選項(xiàng)參數(shù),不會(huì)進(jìn)入 tiny shell 里面。

tinyshell.sh ll 命令,提供了一個(gè) ll 參數(shù)(兩個(gè)小寫字母 l)。

這個(gè)參數(shù)會(huì)被當(dāng)成命令簡(jiǎn)寫,然后執(zhí)行該命令簡(jiǎn)寫對(duì)應(yīng)的命令。

執(zhí)行結(jié)束后,不會(huì)進(jìn)入 tiny shell 里面。

基于剛才列出的命令簡(jiǎn)寫,可知 ll 對(duì)應(yīng) ls --color=auto -l 命令。

實(shí)際執(zhí)行的也是這個(gè)命令。

進(jìn)入 tiny shell 循環(huán)處理命令的例子

當(dāng)不提供任何命令參數(shù)時(shí),會(huì)進(jìn)入 tiny shell 里面,循環(huán)處理命令。

具體例子如下所示:

$ tinyshell.sh
Tiny shell 1.0.0
Type 'help' for more information.
TinySh>>> help
下面列出 Tiny Shell 支持的內(nèi)置命令列表和配置的命令簡(jiǎn)寫列表.
輸入內(nèi)置命令名或命令簡(jiǎn)寫,會(huì)執(zhí)行對(duì)應(yīng)的命令.
也可以輸入系統(tǒng)自身支持的命令,會(huì)在 bash 中執(zhí)行所給命令.

內(nèi)置命令列表:
  debug: 所給第一個(gè)參數(shù)指定打開、或關(guān)閉調(diào)試功能. 其參數(shù)說(shuō)明如下:
    on: 打開調(diào)試功能,會(huì)執(zhí)行 bash 的 set -x 命令
    off: 關(guān)閉調(diào)試功能,會(huì)執(zhí)行 bash 的 set +x 命令
  help: 打印當(dāng)前幫助信息.
  quit: 退出當(dāng)前 Tiny Shell.

命令簡(jiǎn)寫列表:
key='gl'    value='git log'
key='gp'    value='git pull --stat --no-tags $(git remote) $(git rev-parse --abbrev-ref HEAD)'
key='ll'    value='ls --color=auto -l'
key='ala'    value='adb logcat -b all -v threadtime'
TinySh>>> date
2019年 12月 31日 星期二 17:46:41 CST
TinySh>>> ll -C
tinyshell.sh
命令簡(jiǎn)寫: ll. 命令: ls --color=auto -l -C

當(dāng)執(zhí)行 tinyshell.sh 命令會(huì)進(jìn)入 tiny shell 時(shí),會(huì)打印一個(gè) “TinySh>>>” 提示符。

在 tiny shell 中執(zhí)行 help 命令可以查看支持的內(nèi)置命令和命令簡(jiǎn)寫。

在 tiny shell 中執(zhí)行 date 命令打印當(dāng)前的日期和時(shí)間。

當(dāng)前的 tiny shell 自身不支持 date 命令。

這里執(zhí)行了系統(tǒng)自身的 date 命令。

最后執(zhí)行 ll -C 命令。

這里的 ll 是命令簡(jiǎn)寫。后面的 -C 是對(duì)應(yīng)命令的參數(shù)。

具體執(zhí)行的命令是 ls --color=auto -l -C。

ls 命令的 -C 選項(xiàng)會(huì)多列顯示文件名,覆蓋了 -l 選項(xiàng)的效果。

由于 -l 選項(xiàng)的效果被覆蓋,輸出結(jié)果沒(méi)有打印文件的詳細(xì)信息,只列出文件名。

可以看到,在命令簡(jiǎn)寫之后,可以再提供其他的命令參數(shù)。

即,可以只配置比較長(zhǎng)的命令前綴部分,一些簡(jiǎn)單的參數(shù)可以動(dòng)態(tài)提供。

不需要在配置文件中添加很多內(nèi)容相似、只有細(xì)微差異的配置項(xiàng)。

以上就是分享一個(gè)可以通過(guò)命令簡(jiǎn)寫執(zhí)行對(duì)應(yīng)命令的Shell腳本的詳細(xì)內(nèi)容,更多關(guān)于命令簡(jiǎn)寫執(zhí)行對(duì)應(yīng)命令的Shell腳本的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

您可能感興趣的文章:
  • 監(jiān)控MySQL主從狀態(tài)的shell腳本
  • shell腳本使用兩個(gè)橫杠接收外部參數(shù)的方法
  • 使用Shell腳本如何啟動(dòng)/停止Java的jar程序
  • Shell中使用grep、sed正則提取和替換字符串
  • Shell eval通過(guò)變量獲取環(huán)境變量的方法實(shí)現(xiàn)
  • shell腳本實(shí)戰(zhàn)-while循環(huán)語(yǔ)句
  • shell腳本--sed的用法詳解
  • linux shell中 if else以及大于、小于、等于邏輯表達(dá)式介紹
  • Linux中執(zhí)行shell腳本的4種方法總結(jié)
  • 一個(gè)不錯(cuò)的shell 腳本教程 入門級(jí)
  • Shell字符串比較相等、不相等方法小結(jié)
  • python中執(zhí)行shell命令的幾個(gè)方法小結(jié)

標(biāo)簽:淮南 隴南 河北 通遼 黔南 常州 黔南 河池

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《分享一個(gè)可以通過(guò)命令簡(jiǎn)寫執(zhí)行對(duì)應(yīng)命令的Shell腳本》,本文關(guān)鍵詞  分享,一個(gè),可以通過(guò),命令,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《分享一個(gè)可以通過(guò)命令簡(jiǎn)寫執(zhí)行對(duì)應(yīng)命令的Shell腳本》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于分享一個(gè)可以通過(guò)命令簡(jiǎn)寫執(zhí)行對(duì)應(yīng)命令的Shell腳本的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章