2017-03-19 3 views
0

私は非常に最近bashを学びました。私はスクリプトの引数を読み込もうとしています。だから私は./test -so doc1引数を解析するためのコードにエラーがあります

./tests2: line 13: syntax error near unexpected token `newline' 
./tests2: line 13: ` done' 

を実行したときに、私は次のエラーを取得する

#!/bin/bash 
for ((i=1; i<=$#; i++)); do 
    if [[ ${!i:0:1} == "-" ]] && ! [[ ${!i:1} =~ [^a-zA-Z]+ ]]; then 
    for ((j=1; j<=$(($(expr length ${!i})-1)); j++)); do 
     if [[ ${!i:j:1} == "s" ]]; then 
     k=$((i+1)) 
     if [ -e ${!k} ]; then 
      echo $(realpath ${!k}) 
     fi 
     elif [[ ${!i:j:1} == "o" ]]; then 
     echo "Running script without output!" 
     fi 
    done 
    fi 
done 

することができます私はこれを書いたが、私はエラーを取得(とVimがピンク色で第四行の最後の二重のかっこをhighlitedました)誰でも私のスクリプトの何が間違っているのか理解できますか?

+1

通常、インデックスを使用している場合は、何か問題があります。それはあなたが実際にマッチさせようとしていることは何ですか?おそらくもっと簡単で、はるかに慣用的な解決法があります。 – chepner

+0

私はインデックスが何であるか分かりません。しかし、私は与えられたすべてのパラメータをチェックし、 "rm -rf ..."のように複数の文字が含まれているかどうかを確認しようとしていただけです。 –

+0

また、 'bash'マニュアルページの' getopts'コマンド。 – chepner

答えて

3

実際には、bash自体のバグに遭遇したようです。

バッシュは、ループのための演算内$((arithmetic expansion))内部で使用する場合$(command substitution)を処理するために失敗します。それは、余分な))とだけの問題ではありません

$ for ((; ; $(($(echo 1))))); do echo "running"; break; done 
bash: syntax error near unexpected token `newline' 

:bashがうまく入れ子にすることを処理します。

$ for ((; ; $((1)))); do echo "running"; break; done 
running 

そして、推奨されていないバックティックではうまく動作します。$(..)

$ for ((; ; $((`echo 1`)))); do echo "running"; break; done 
running 

それは一般的に((arithmetic commands))内も大丈夫です、それが影響を受けているループのためだけ算術です:

$ while (($(($(echo 1))))); do echo "running"; break; done 
running 

そうです、おめでとう、bashのバグのように見えます!私はこれが既知の問題かどうかはわかりませんが、今のところあなたは他の投稿の1つに示唆されているように書き換えることができます。あるいは、好ましくはgetoptsを使用してください。

+0

これに関するいくつかのテストをしてくれてありがとう、ありがとう、それはバグでした!あなたは自分の投稿を '潜在的なバグin forループ(bash)'に改名すべきだと思いますか? –

+0

もちろんforループの算術展開は、forループがすでに算術コンテキストであるため通常不要です。したがって、簡単な回避策があります。 – rici

+0

ああ!私はまだそれらの二重括弧が意味するものを得ていなかった。私は、これらの二重括弧が役に立たないところに追加し、それがなければ完全に機能したことを理解しています: 'for(j = 1; j <= $(expr length $ {!i}) - 1; j ++));ありがとう@rici! –

0

問題は内側のforループにネストされた((...))です。コードを次のように変更することができます:

#!/bin/bash 
for ((i=1; i<=$#; i++)); do 
    if [[ ${!i:0:1} == "-" ]] && ! [[ ${!i:1} =~ [^a-zA-Z]+ ]]; then 
    lim=$(($(expr length ${!i})-1)) 
    for ((j=1; j<=$lim; j++)); do 
     if [[ ${!i:j:1} == "s" ]]; then 
     k=$((i+1)) 
     if [[ -e ${!k} ]]; then 
      echo $(realpath ${!k}) 
     fi 
     elif [[ ${!i:j:1} == "o" ]]; then 
     echo "Running script without output!" 
     fi 
    done 
    fi 
done 
+0

他の二重括弧の中に二重括弧を入れることはできませんか? –

+1

そうですね。私はまだ私の研究をしていない。 – codeforester

関連する問題