2012-04-08 47 views
11

bashスクリプト関数の中で、スクリプトのコマンドライン引数と別の引数リストを操作する必要があります。だから関数に2つの引数リストを渡そうとしていますが、問題は複数の単語の引数が分割されることです。マルチワード項目を尊重しながら、質問がある、要素を反復処理する方法を、彼らは関数に全体として渡されなければならない二つのリストがあるので、スクリプトを呼び出す複数ワードの引数をbash関数に渡す

function params() 
{ 
    for PARAM in $1; do 
     echo "$PARAM" 
    done 

    echo . 

    for ITEM in $2; do 
     echo "$ITEM" 
    done 
} 

PARAMS="[email protected]" 
ITEMS="x y 'z t'" 
params "$PARAMS" "$ITEMS" 

は私に

myscript.sh a b 'c d' 
a 
b 
c 
d 
. 
x 
y 
'z 
t' 

を与えます一重引用符で囲まれた 'cd'と 'z t'?

私が使用している回避策(下記参照)はBASH_ARGVを使用しているので、関数に単一のリストを渡す必要があります。しかし、私は何が起こっているのか、上記の作業をするために必要なことをより深く理解したいと思います。スクリプトを呼び出す

function params() 
{ 
    for PARAM in "${BASH_ARGV[@]}"; do 
     echo "$PARAM" 
    done 

    echo . 

    for ITEM in "[email protected]"; do 
     echo "$ITEM" 
    done 
} 

params x y 'z t' 

は、私はそれを必要とする方法はどれ...私に

myscript.sh a b 'c d' 
c d 
b 
a 
. 
x 
y 
z t 

を与える(逆転された最初のリストを除いて、それは私が推測許容だろう)

答えて

7
function params() 
{ 
    arg=("[email protected]") 

    for ((i=1;i<=$1;i++)) ;do 
     echo "${arg[i]}" 
    done 

    echo . 

    for ((;i<=$#-$1+2;i++)) ;do 
     echo "${arg[i]}" 
    done 
} 

items=(w x 'z t') 
params $# "[email protected]" "${items[@]}" 

args a b 'c d'でスクリプトを呼び出すと、出力は次のようになります。

a 
b 
c d 
. 
x 
y 
z t 
+0

私は、アイテムを個々に関数に渡しています。引用符を尊重しながらbashが文字列を項目に分割する唯一の場所は、コマンドラインを解釈するときです。 – haelix

+0

配列要素を '$ {items [@]}' '(二重引用符で囲む)として渡す性質は、各要素を$ {items [0]}" "$ {items [1] } $ {items [2]} ...など... '$ {items [@]}'として渡すと、空白を含む要素で単語分割が行われます。 –

1

上記のPeter.Oの答えはうまくいきます。これはその例です。

複数の単語の引数をとり、実行中のプロセスのリストを検索し、引数の1つと一致するものを削除する関数またはスクリプトが必要でした。次のスクリプトはそれを行います。関数kill_processes_that_match_argumentsは1つのforループしか必要としません。なぜなら、私の必要性は、関数へのすべての引数のセットを反復することだけだったからです。動作するようにテストされています。

#!/bin/bash 

function kill_processes_that_match_arguments() 
{ 
    arg=("[email protected]") 
    unset PIDS_TO_BE_KILLED 

    for ((i=0;i<$#;i++)) 
    do 
     unset MORE_PIDS_TO_KILL 
     MORE_PIDS_TO_KILL=$(ps gaux | grep "${arg[i]}" | grep -v 'grep' | awk '{ print $2 }') 
     if [[ $MORE_PIDS_TO_KILL ]]; then 
      PIDS_TO_BE_KILLED="$MORE_PIDS_TO_KILL $PIDS_TO_BE_KILLED" 
     fi 
    done 

    if [[ $PIDS_TO_BE_KILLED ]]; then 
     kill -SIGKILL $PIDS_TO_BE_KILLED 
     echo 'Killed processes:' $PIDS_TO_BE_KILLED 
    else 
     echo 'No processes were killed.' 
    fi 
} 

KILL_THESE_PROCESSES=('a.single.word.argument' 'a multi-word argument' '/some/other/argument' 'yet another') 
kill_processes_that_match_arguments "${KILL_THESE_PROCESSES[@]}" 
関連する問題