2013-07-12 164 views
0

我正在嘗試使用getopts創建一個腳本,它的工作方式爲wc。問題是當我一起使用兩個開關時卡住了。該腳本:Bash腳本作爲wc命令

while getopts l:w:c: choice 
do 
     case $choice in 
       l) wc -l $OPTARG;; 
       w) wc -w $OPTARG;; 
       c) wc -c $OPTARG;; 
       ?) echo wrong option. 
     esac 
done 

當我運行此腳本./script.sh -l file它的工作原理,但是當我使用./script -wl file它只是進入一個無限循環。任何人都可以請解釋發生了什麼以及如何解決它?

回答

3

你需要建立在case語句的選項,然後執行wc

# Set WC_OPTS to empty string 
WC_OPTS=(); 
while getopts lwc choice 
do 
    case $choice in 
      l) WC_OPTS+='-l';; 
      w) WC_OPTS+='-w';; 
      c) WC_OPTS+='-c';; 
      ?) echo wrong option. 
    esac 
done 
# Call wc with the options 
shift $((OPTIND-1)) 
wc "${WC_OPTS[@]}" "[email protected]" 
+1

我認爲這是最接近海報想要的。儘管使用'「$ @」'而不是'$ *'。 –

+0

@那個人你說錯了 – dougEfresh

+0

@ruakh我很好奇,你能舉個快速的例子嗎?我對bash數組不太熟悉。 – dougEfresh

4

你沒有正確地使用它。由於每getopts manual

如果一個字母后跟一個冒號,選項,預計將有一個 說法。

而在您的示例中,您沒有爲-w-l選項傳遞參數;

正確的用法是:

./script -w file1 -l file2 

這將正確地處理這兩個選項。

否則支持的選項,但沒有參數只是用它沒有冒號這樣的:

while getopts "hl:w:c:" choice 

這裏選擇h不會需要一個說法,但L,W,C將支持一個。

+1

他提到他想讓script.sh像wc一樣工作, 'wc -w file1 -l file2'與'wc -w - l file1 file 2' not'wc -w file1; wc -l file2' – dougEfresh

+0

@dougEfresh:是的,我讀過,但他的getops腳本仍然需要修復。 – anubhava

+0

的確如此。我其實首先問他爲什麼要這樣做。似乎有點奇怪,但我不是在這裏質疑,只是回答 – dougEfresh

1

添加到其他評論。 。 。的wc的版本,我已經得心應手,似乎處理這樣的選擇:

#!/bin/bash 

options=() 
files=() 

while (($# > 0)) ; do 
    if [[ "$1" = --help || "$1" = --version ]] ; then 
     wc "$1" # print help-message or version-message 
     exit 
    elif [[ "${1:0:1}" = - ]] ; then 
     while getopts cmlLw opt ; do 
      if [[ "$opt" = '?' ]] ; then 
       wc "$1" # print error-message 
       exit 
      fi 
      options+="$opt" 
     done 
     shift $((OPTIND-1)) 
     OPTIND=1 
    else 
     files+="$1" 
     shift 
    fi 
done 

wc "${options[@]}" "${files[@]}" 

(以上可以進一步細化,通過使用一個單獨的變量爲每五個可能的選項,以突出的事實,wc不關心其選項出現的順序,並且不關心給定選項是否出現多次。)

0
Got a workaround. 

#!/bin/bash 

if [ $# -lt 2 ] 
then 

    echo not a proper usage 
    exit 

fi 

file=$2 

while getopts wlc choice 

do 

    case $choice in 

     l) wc -l $file 
      ;; 
     w) wc -w $file 
      ;; 
     c) wc -c $file 
      ;; 
     ?) echo thats not a correct choice 

    esac 
done 

I think I got obsessed with OPTARG, thanks everyone for your kind help 
+0

太棒了,很高興你能夠正常工作。 – anubhava