#函数是功能是以自定义的方式把命令行的选项和参数拆分成数组。引号中的内容在计算位置时会当作一个整体。 #parse.option <default> <retain> "$@" #default 默认选项,如果为空请用 - 占位 #retain 保留最后几位做为参数 #"$@" 这个变量表示参数列表 # 如:parse.option '-de -f' 2 "$@"
function parse.option(){ local defalut="$1" local option="" local retain="$2" local args="" shift 2; local arr=( "$@" ) local length=${#arr[@]} for i in "${!arr[@]}"; do [ -n "`echo ${arr[$i]} | grep -P 's*w+s+s*'`" ] && arr[$i]=""${arr[$i]}"" done [ $length -eq "$retain" ] && args=${arr[@]:$length - $retain} [ $length -gt "$retain" ] && { option=${arr[@]:0:$length - $retain}; args=${arr[@]:$length - $retain}; } [ -z "$option" -a "$defalut" != '-' ] && option="$defalut" echo "([0]='$option' [1]='$args')" }
我想扩展一个 ln 命令,因为它不够方便,非要写绝对路径。我想让相对路径也创建。
function ln(){
declare -A all=`parse '-isv' 2 "$@"` set -- ${all[1]} local target=$1 [ ${target:0:1} != '/' ] && target="`pwd`/$target" sudo /usr/bin/ln ${all[0]} $target $2
}
这里用到了 parse.option "$*" 2 '-is' 也就是说,前面都是选项,只有最后两位是参数,默认选项是 -is 选项我不管,我只处理路径参数
如果目标路径不是以 / 开头,那就在路径前面加上当前路径,组成绝对路径。这样既扩展了 ln 的功能,同时也没有把选项写死。
下面还有一些常用函数。
function start(){ case "$1" in 'php') sudo php-fpm;; 'nginx') sudo nginx;; 'redis') redis-server;; :*) local item="${@#:}" [ "$@" == ":all" ] && item="$(docker ps -q -f status=exited)" [ -n "$item" ] && docker start $item ;; '') start docker;; 'web') start php && start nginx;; *) sudo service $1 start;; esac } function stop(){ case "$1" in 'php') sudo pkill -9 php-fpm;; 'nginx') sudo nginx -s stop;; 'web') stop php && stop nginx;; 'redis') redis-cli shutdown;; -*) sudo pkill -9 ${1#-};; :*) local item="${@#:}" [ "$@" == ":all" ] && item="$(docker ps -q)" [ -n "$item" ] && docker stop $item ;; *) sudo service $1 stop;; esac } #批量将文件链接到 bin 目录,如果参数是一个目录,则链接目录中的所有文件 function tobin(){ [ $# == 1 -a -d "$1" ] && { cd $1; set -- `ls $1`; } for item in "$@"; do [ ${item:0:1} != '/' ] && item="`pwd`/$item" [ -f "$item" ] && sudo ln -fs $item /usr/local/bin && echo "$item" done } function tosbin(){ [ $# == 1 -a -d "$1" ] && { cd $1; set -- `ls $1`; } for item in "$@"; do [ ${item:0:1} != '/' ] && item="`pwd`/$item" [ -f "$item" ] && sudo ln -fs $item /usr/local/sbin && echo "$item" done } #打开文件或目录 #可以打开 docker 容器中的文件,如: open :container /tmp/test.txt 注:参数要冒号开头 #会把容器中的文件复制到 /tmp/<container>/ 目录中,如果复制为成功,则在该目录新建。 #可以再结合一个 push :container /tmp/test.txt 就会找到 /tmp/<container>/test.txt 并复制到容器中 #如果没有参数,表示打开当前目录 #由于我是用的 WSL 打开当前目录的命令 explorer.exe . 请换成 xdg-open 命令 function open(){ option="$1" case "$option" in '-source') code /etc/apt/sources.list;; '-profile') code /etc/profile;; '-bashrc') code /etc/bash.bashrc;; :*) local con="${option#:}" local file="/tmp/$con`basename $2`" mkfdir $file docker cp $con:$2 $file 2>/dev/null open $file ;; '') explorer.exe .;; #xdg-open $PWD;; *) mime=`file --mime-type $option | awk '{print $2}'` #如果是符号链接 if [ $mime == 'inode/symlink' ];then option=`readlink -e $option` mime=`file --mime-type $option | awk '{print $2}'` fi if [ -n "`echo $mime | grep -E '^(text/|inode/x-empty|application/json)'`" ];then #用编辑器打开 code $option elif [ "$mime" = 'inode/directory' ];then cd $option && explorer.exe . #xdg-open $option elif [ "$mime" != 'cannot' ];then #默认方式打开 color red "文件类型:$mime" explorer.exe $option #xdg-open $option else color red "新建: $option" [ ! -w . ] && sudo touch $option code $option fi ;; esac } #可以推送 git #可以结合上面 open 可以再把文件推送到容器 function push(){ option="$1" case "$option" in :*) local conter="${option#:}"; docker cp /tmp/$conter/`basename $2` $conter:$2 || { echo "上传失败"; return 1; };; '') push .;; *) git add $@ && git commit -m '日常更新' && git push;; esac } #文件重命令 #第二个参数只是单纯表示新名字,如:rename /home/old.txt new.txt function rename(){ sudo mv $1 `dirname $1`/$2 } #类似于 whereis 命令,但列出内容更详细 function where(){ local name="$1" [ -n "`which $name`" ] && { color red "当前命令:"; which $name; } [ -n "`type -a $name 2>/dev/null`" ] && { color red "命令列表:"; type -a $name; } [ "`whereis $name`" != "$name:" ] && { color red "目录列表:"; whereis $name; } || color red "$name 不存在" } #综合了 apt install 和 dpkg -i 安装软件 #如果不带任何参数,则进入查找安装过程 #如:install 回车,输入 mysql,会列出包名,输入要安装的包名或输入 exit 退出 function install(){ if [ $# == 0 ];then [ -z `which sudo` ] && apt install -y sudo local software="" until [ "$software" == 'exit' ] do echo -en "