免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2163 | 回复: 1
打印 上一主题 下一主题

[其他] 从 alias 到超级 alias [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-08-06 18:53 |只看该作者 |倒序浏览
本帖最后由 newzy 于 2014-08-06 19:07 编辑

[引入]
在linux环境下工作,alias可能为复杂难记的或长长的命令取个别名;alias 不能提供可变参数,就会经常写定大大小不的脚本简化这些操作。
比如常常会:
  mkdir -p foo/bar
  cd foo/bar
因为alias 不能在命令中间提供可变参数,于是就产生类似 mkcd.sh 的脚本:
  function mkcd (name) {
         mkdir -p $name;
         cd $name;
     }
是不是可以有一个类似 printf(fmt, ...) 的命令,fmt 于于列出要执行命令的序列串,用%1,%2,%3表示后面将要传入的参数呢?如:
  some_exec "mkdir %1; cd %1" foo/bar
     它会将 "mkdir %1; cd %1" 中的 %1 替换成 foo/bar,然后再执行之
这样就可以:
  alias mkcd=some_exec "mkdir %1; cd %1"'
以后再要创建 foo/bar 并进入这个目录时,就可以直接:
  mkcd foo/bar

如果需要到多个参数时,只要在alias 的格式串时用%1, %2, %3,... 依次表示第一,第二个参数就可以了。
假如我们有一个 make 命令:
  make [-j4] -DFOO_DEF=XXX -DBAR_DEF=YYY [CPU=MIPS|ARM]  foo_imagename
  本处假设 [-j4] [CPU=MIPS] 只能出现在make后,foo image前有某处,
就可以定义:
  alias mkfoo=some_exec "make %1 -DFOO_DEF=XXX -DBAR_DEF=YYY %2 foo_imagename"'
  alias mkbar=some_exec "make %1 -DFOO_DEF=XXX -DBAR_DEF=YYY %2 bar_imagename"'
保存到~/.bashrc里,这样我们可以用下面的命令了:
  mkfoo -j4
  mkfoo -j4 CPU=MIPS
  mkfoo CPU=MIPS
  mkbar -j4
  ...
这样的 alias + some_exec就能立大功了。它能让我们少记少重复好多事。

[进阶]
看下 alias mkfoo='some_exec "fmt"' 还是有些丑陋,是不是还可以这样:
  some_aliax fmt
就是直接用 some_alias 直接为一个格式串取别名,以上命令看起来像这样:
  some_alias "mkdir %1; cd %1"
  some_alias mkfoo=make %1 -DFOO_DEF=XXX -DBAR_DEF=YYY %2 foo_imagename'
  some_alias mkbar=make %1 -DFOO_DEF=XXX -DBAR_DEF=YYY %2 bar_imagename'

是不是有时候会忘记自定义命令的格式或参数,是不是可以直接在some_alias 里再定义下自定义的帮助信息,
如:
  some_alias 'mkdir %1; cd %1'  'mkcd [dirname]'
  some_alias mkfoo=make %1 -DFOO_DEF=XXX -DBAR_DEF=YYY %2 foo_imagename' 'mkfoo [-j4] [CPU=MIPS|ARM]"
  some_alias mkbar=make %1 -DFOO_DEF=XXX -DBAR_DEF=YYY %2 bar_imagename' 'mkfoo [-j4] [CPU=MIPS|ARM]"

保存到~/.bashrc里,这样我们就可以这样看到它们的帮助了:
  $mkdir
     mkdir [dirname]
  $mkdir -h
     mkdir [dirname]
    $mkfoo -h
     mkfoo [-j4] [CPU=MIPS|ARM]
  ...

[高级]
以上的 some_alias 默认是至少输入一个参数,如果没有参数就会显示帮助信息。
如果遇到参数个数至少几个的,如上面的 mkcd 至少要一个参数,而 mkfoo 最少确可以为零个参数,就是不输入任何参数也行。
直接在命令的最后用 -n [0-9] 指定参数个数吧,像这样:
  some_alias mkfoo=make %1 -DFOO_DEF=XXX -DBAR_DEF=YYY %2 foo_imagename'  'mkfoo [-j4] [CPU=MIPS|ARM]" -n 0
就可以不用输入参数了
  $mkfoo
如果指定的不是 -n 0, 而是 -n 2,那就是至少要两个参数了,参数不够就显示处自定义帮助。

是不是还可以指定verbose模式呢,这时回显原始执行的命令呢,这样的辅助可能会就更清析明了些。
如:
  some_alias "mkdir %1; cd %1" -v

这样执行过程:
   $mkcd foo/bar
  %CMD: mkdir -p foo/bar; cd foo/bar

用%CMD提示了原始命令,当然还会有个相当的 -s (suppress mode) 可以抑制输出命令提示。

[关于代码]
some_exec 和 some_alias 只是抛砖引玉,附录的code里用的是 xexec 和 xalias.
习惯把它保存存成 .xexec.sh,然后在 ~/.bashrc 里 source .xexec.sh, 然后再定义些可变参数的命令。
本人不是bash的高手,只是借以提高工作效率。在这里给大家交流下,希望这个超级 alias 也帮大家有帮助。

$ xexec
   Powered by newzyer@sina.com xexec v1.0.5
   Usage: xecec [[-u|--usage string] | [[-s|--suppress] | [-v|--verbose]] | [-e|escape the '#' and '^' to " and \'] | [-E|disable escape the '#' and '^' | [-n|--
$ xalias
   Powered by newzyer@sina.com xexec v1.0.5
   Usage: xalias [name] [%pattern] [help] [-s|-v|-n #]

  1. #
  2. # xexec.sh - Do args replecement and Execute the command in arg1
  3. #
  4. # modification history
  5. # --------------------
  6. # 01a, 2012-3-24   newzy create
  7. #

  8. # Function:
  9. # xexec arg1 arg2 arg3 ...
  10. #
  11. # This fucntion will execute the command in arg1. Before execute the
  12. # arg1, it tries to replace the keywords, such as %1 %2 %3 ... and or
  13. # @1 @2 @3 ..., with arg2 arg3 arg4 ... sequentially.
  14. #
  15. # E.g.: xexec "echo %2 %1" arg1 arg2
  16. #

  17. # xalias [name] [%pattern] [help] [-s|-v]
  18. _xalias_help_='"xalias [name] [%pattern] [help] [-s|-v|-n #]"'
  19. _xalias_exec_='"alias %1='\''xexec -e -u \"%3\" %4 %5 %6 %7 %8 %9 \"%2\"'\''"'
  20. alias xalias='xexec -s -u '"$_xalias_help_ $_xalias_exec_"''
  21. unset _xalias_help_
  22. unset _xalias_exec_

  23. function xexec() {
  24.     # parser parameters . . .
  25.     local copyright="Powered by [url=mailto:newzyer@sina.com]newzyer@sina.com[/url] xexec v1.0.5\n"
  26.     local usage="${copyright}Usage: xecec [[-u|--usage string] |"
  27.           usage="$usage [[-s|--suppress] | [-v|--verbose]] |"
  28.           usage="$usage [-e|escape the '#' and '^' to \" and \'] |"
  29.           usage="$usage [-E|disable escape the '#' and '^' |"
  30.           usage="$usage [-n|--minargs #] [%pattern] arg1 arg2 ..."
  31.     local minargs=1;
  32.     local escquot=0;
  33.     local verbose=1;
  34.     while [ -n $# ]; do
  35.       case "$1" in
  36.         -s) verbose=0; ;; # suppress mode
  37.         -v) verbose=1; ;; # verbose mode
  38.         -e) escquot=1; ;; # escape the '#' '^' to '\"' and '\''
  39.         -E) escquot=0; ;; # disable escape the '#' '^'
  40.         -u|--usage)
  41.             usage="${copyright}Usage: $2"; shift; ;;
  42.         -n|--minargs)
  43.             [ "$2" -ge "0" ] && minargs="$2"; shift; ;;
  44.         -*)
  45.             echo "%Error: Unsupported option: $1";
  46.             return; ;;
  47.         ""|\?|-h|--help|-*)
  48.             echo -e "${usage}\n";
  49.             return; ;;
  50.         *)  break; ;;
  51.       esac
  52.       shift
  53.     done

  54.     # no enough args, show usage
  55.     minargs=`expr $minargs + 1`
  56.     [ "$#" -lt "$minargs" ] && echo -e "${usage}\n" && return;
  57.     [[ "-h" == "$2" ]] && echo -e "${usage}\n" && return;

  58.     # Look the first paramter as request-executed command
  59.     local _cmd=$1; shift;
  60.     if [ ! -z "$_cmd" ]; then
  61.         # Replace args "%1, %2, ..." with input arguments
  62.         local argc argv arg; argc=0
  63.         for arg in "$@"; do
  64.             argv[$argc]=$arg; argc=`expr $argc + 1`;
  65.         done;
  66.         for ((i=0,j=1; i < 10; i++,j++)); do
  67.             # remove unused args
  68.         arg=${argv[$i]};

  69.         # escape the % to @< to avoid be replaced
  70.         [ ! -z "$arg" ] && arg=${arg//\%/\@<};

  71.         #echo "arg: ${arg}"
  72.         [ -z "$arg" ] && _cmd=${_cmd//"\%$j "/$arg};
  73.         [ -z "$arg" ] && _cmd=${_cmd//"\%$j "/$arg};

  74.         # replace args "%1 %2 ...
  75.         _cmd=${_cmd//\%$j/$arg};
  76.         _cmd=${_cmd//@$j/$arg};
  77.         done;

  78.         # escand the "#" and "^" to '"' and "'"
  79.         [ "$escquot" -gt 0 ] && _cmd=${_cmd//#/\"};
  80.         [ "$escquot" -gt 0 ] && _cmd=${_cmd//^/\'};

  81.         # restore the '@<' to '%'
  82.          _cmd=${_cmd//\@</\%};

  83.         # Execute command
  84.         [ "$verbose" -gt 0 ] && echo "%CMD: $_cmd"
  85.         eval $_cmd;
  86.     fi;
  87. }
复制代码

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
2 [报告]
发表于 2014-08-06 20:07 |只看该作者
首先shell支持函数的,你可以直接在shell脚本写函数,全功能哦~

比如你的第一个mkcd可以写作:

  1. function mkcd() {
  2.   mkdir $1
  3.   cd $1
  4. }
复制代码
后面的以此类推
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP