linux脚本学习——从入门到入土1

linux脚本学习——从入门到入土1

linux脚本学习系列将以一系列实际脚本来讲解,在对脚本分析的过程中学习bash语言的使用。

文章目录

  • linux脚本学习——从入门到入土1
    • 方便的路径切换脚本
      • bind命令详解

方便的路径切换脚本

话不多说,直接上脚本:

#!/bin/bash
# do ". acd_func.sh"
# acd_func 1.0.5, 10-nov-2004
# petar marinov, http:/geocities.com/h2428, this is public domain

cd_func ()
{
  #声明函数的局部变量
  local x2 the_new_dir adir index 
  local -i cnt
  #如果参数1为“--”,则显示目录栈信息,并返回
  if [[ $1 ==  "--" ]]; then
    dirs -v
    return 0
  fi
  #如果参数1为空,则the_new_dir等于home路径。
  the_new_dir=$1
  [[ -z $1 ]] && the_new_dir=$HOME
  #判断the_new_dir的第一个字符是否为"-"
  if [[ ${the_new_dir:0:1} == '-' ]]; then
    #
    # Extract dir N from dirs
    #提取the_new_dir从1到最后的字符给index
    index=${the_new_dir:1}
    #如果只输入-,则index默认为1
    [[ -z $index ]] && index=1
    #提取目录栈中的第index个目录给adir
    adir=$(dirs +$index)
    #如果adir为空则返回
    [[ -z $adir ]] && return 1
    #否则the_new_dir为获得的目录
    the_new_dir=$adir
  fi

  #
  # '~' has to be substituted by ${HOME}
  #如果the_new_dir的首字符为~,则用目录栈中对应的the_new_dir后几个来替换
  [[ ${the_new_dir:0:1} == '~' ]] && the_new_dir="${HOME}${the_new_dir:1}"

  #
  # Now change to the new dir and add to the top of the stack
  #进入the_new_dir路径,并将the_new_dir复制到栈顶
  pushd "${the_new_dir}" > /dev/null
  [[ $? -ne 0 ]] && return 1
  the_new_dir=$(pwd)

  #
  # Trim down everything beyond 11th entry
  # 这里有个问题,实际中运行的只是剔除了第11个索引值
  popd -n +11 2>/dev/null 1>/dev/null

  #
  # Remove any other occurence of this dir, skipping the top of the stack
  for ((cnt=1; cnt <= 10; cnt++)); do
    x2=$(dirs +${cnt} 2>/dev/null)
    [[ $? -ne 0 ]] && return 0
    [[ ${x2:0:1} == '~' ]] && x2="${HOME}${x2:1}"
    if [[ "${x2}" == "${the_new_dir}" ]]; then
      popd -n +$cnt 2>/dev/null 1>/dev/null
      cnt=cnt-1
    fi
  done

  return 0
}

alias cd=cd_func

if [[ $BASH_VERSION > "2.05a" ]]; then
  # ctrl+w shows the menu
  bind -x "\"\C-w\":cd_func -- ;"
fi

这个脚本只有一个函数cd_func,这个函数实现了一系列好用的路径切换功能,然后用alias,别名功能讲cd_func取名为日常使用的cd,这样符合我们的日常使用习惯。
在脚本的最后判断如果当前bash的版本号大于2.05a时,就将cd_func --这个指令与Ctrl+w绑定起来。

bind命令详解

bind命令用于显示和设置命令行的键盘序列绑定功能。通过这一命令,可以提高命令行中操作效率。可以利用bind命令了解有哪些按键组合与其功能,也可以自行指定要用哪些按键组合.
选项介绍:

选项 用途
-d 显示按键配置内容
-f<按键配置文件> 载入指定的按键配置文件
-l 列出所有功能
-m<按键配置> 指定按键配置
-q<功能> 显示指定功能的按键
-v 列出目前的按键配置及其功能
-x <按键> 绑定按键与功能

下面我们使用bind -x来进行试验:

#绑定ctrl+l实现ls -l功能
bind -x ‘“\C-l”:ls -l’

接下来我们将详细分析cd_func函数。
首先看函数的前两行:

  local x2 the_new_dir adir index
  local -i cnt

local作用为在函数内定义局部变量,因此这两行作用是定义了一系列的局部变量。

  if [[ $1 ==  "--" ]]; then
    dirs -v
    return 0
  fi

这里有一个if语句,如果满足传入的第一个参数为"–",的话就执行dirs -v。
dirs作用为显示当前目录栈,目录栈是最近访问目录的列表。
其选项如下:

选项 作用
-c 清除目录栈
-l 显示完整的目录信息,而不是用~表示home目录
-p 以每个目录一行的方式显示路径
-v 在-p的基础上显示每个目录在目录栈中的索引
+N 显示从小到大排序,第N个索引的路径
-N 显示从大到小排序,第N个索引的路径

这个if语句的作用是如果传入的第一个参数为–,就显示当前的目录栈。

  the_new_dir=$1
  [[ -z $1 ]] && the_new_dir=$HOME

这里为判断$1是否为空,如果为空就将the_new_dir等于home路径.
在判断中-z表示空的意思。

  if [[ ${the_new_dir:0:1} == '-' ]]; then
    #
    # Extract dir N from dirs
    index=${the_new_dir:1}
    [[ -z $index ]] && index=1
    adir=$(dirs +$index)
    [[ -z $adir ]] && return 1
    the_new_dir=$adir
  fi

t h e n e w d i r : 0 : 1 的 作 用 为 提 取 t h e n e w d i r 中 第 一 个 字 符 ; {the_new_dir:0:1}的作用为提取the_new_dir中第一个字符; thenewdir:0:1thenewdir{the_new_dir:n}的作用为提取the_new_dir从n到最后的字符。

  [[ ${the_new_dir:0:1} == '~' ]] && the_new_dir="${HOME}${the_new_dir:1}"

在linux下~n表示目录栈中序号n的目录。

  pushd "${the_new_dir}" > /dev/null
  [[ $? -ne 0 ]] && return 1
  the_new_dir=$(pwd)

pushd指令将当前的路径复制到目录栈的栈顶,但原来索引位置还是保留原路径信息;
"> /dev/null"表示将pushd产生的打印信息不输出.

  for ((cnt=1; cnt <= 10; cnt++)); do
    x2=$(dirs +${cnt} 2>/dev/null)
    [[ $? -ne 0 ]] && return 0
    [[ ${x2:0:1} == '~' ]] && x2="${HOME}${x2:1}"
    if [[ "${x2}" == "${the_new_dir}" ]]; then
      popd -n +$cnt 2>/dev/null 1>/dev/null
      cnt=cnt-1
    fi
  done

将目录栈中与栈顶一样的路径删除。

OK,这样我们就搞明白了这个脚本的逻辑,并学到了新的bash命令。

你可能感兴趣的:(linux,学习,bash)