2017-07-03 23 views
2

我正在使用此腳本生成系統中帶有手冊頁的可用命令列表。用time運行這個程序在我的電腦上顯示平均約49秒。優化用手冊頁列出可用命令的腳本

#!/usr/local/bin/bash 

for x in $(for f in $(compgen -c); do which $f; done | sort -u); do 
    dir=$(dirname $x) 
    cmd=$(basename $x) 
    if [[ ! $(man --path "$cmd" 2>&1) =~ 'No manual entry' ]]; then 
     printf '%b\n' "${dir}:\n${cmd}" 
    fi 
done | awk '!x[$0]++' 

有沒有辦法來優化這對於更快的結果?

這是我當前輸出的一個小樣本。目標是按目錄對命令進行分組。這將在稍後被輸入到一個數組中。

/bin: # directories generated by $dir 
[  # commands generated by $cmd (compgen output) 
cat 
chmod 
cp 
csh 
date 

回答

0

要在這裏完全忽視內置插件。無論如何,which就是這樣做的。腳本未經過徹底測試。在Cygwin

#!/bin/bash 
shopt -s nullglob # need this for "empty" checks below 
MANPATH=${MANPATH:-/usr/share/man:/usr/local/share/man} 
IFS=: # chunk up PATH and MANPATH, both colon-deliminated 

# just look at the directory! 
has_man_p() { 
    local needle=$1 manp manpp result=() 
    for manp in $MANPATH; do 
     # man? should match man0..man9 and a bunch of single-char things 
     # do we need 'man?*' for longer suffixes here? 
     for manpp in "$manp"/man?; do 
      # assumption made for filename formats. section not checked. 
      result=("$manpp/$needle".*) 
      if ((${#result[@]} > 0)); then 
       return 0 
      fi 
     done 
    done 
    return 1 
} 

unset seen 
declare -A seen # for deduplication 
for p in $PATH; do 
    printf '%b:\n' "$p" # print the path first 
    for exe in "$p"/*; do 
     cmd=${exe##*/} # the sloppy basename 
     if [[ ! -x $exe || ${seen[$cmd]} == 1 ]]; then 
      continue 
     fi 
     seen["$cmd"]=1 
     if has_man_p "$cmd"; then 
      printf '%b\n' "$cmd" 
     fi 
    done 
done 

時間帶有截斷路徑(滿一個與Windows有原始版本太多失誤):

$ export PATH=/usr/local/bin:/usr/bin 
$ time (sh ./opti.sh &>/dev/null) 

real 0m3.577s 
user 0m0.843s 
sys  0m2.671s 

$ time (sh ./orig.sh &>/dev/null) 

real 2m10.662s 
user 0m20.138s 
sys  1m5.728s 

(買者兩個版本:在Cygwin的/usr/bin最東西自帶a .exe extension)