shellcheck 警告 SC2129「個別のリダイレクトの代わりに { cmd1; cmd2; } >> ファイルの使用を検討してください。」とはどういう意味ですか?

shellcheck 警告 SC2129「個別のリダイレクトの代わりに { cmd1; cmd2; } >> ファイルの使用を検討してください。」とはどういう意味ですか?

shellcheck理解できない警告があります:

In /mnt/e/bin/iconic line 540:
            printf "FALSE|" >> "$IconsRaw"           # Select field number 1
            ^-- SC2129: Consider using { cmd1; cmd2; } >> file instead of individual redirects.

私たちの多くがここにいることに気づきましたシェルチェックbash スクリプト / シェル コマンドを修正するため、この質問がトピックに沿ったものであることを願っています。


bash スクリプトの関連セクションを投稿したコメントによると:

    if [[ "$X" == "?" || "$Y" == "?" ]] ; then
        : # Bad X or Y offset usually "Link to Name.ext~" (backup name)
    else
        let i++
        printf "FALSE|" >> "$IconsRaw"           # Select field number 1
        printf "%s|" "$i" >> "$IconsRaw"         # 2
        printf "%s|" "${File##*/}" >> "$IconsRaw"
        printf "%s|" "$Linkless" >> "$IconsRaw"  # 4
        printf "%s|" "$Date" >> "$IconsRaw"      # 5
        printf "%s|" "$X" >> "$IconsRaw"         # 6
        echo   "$Y" >> "$IconsRaw"               # 7
    fi

解決

shellcheck承認された回答とコメントのおかげで、コード内のエラーをキャッチするだけでなく、パフォーマンスの改善も提案していることが分かりました。この場合、ファイル名は、と$IconsRawのそれぞれで何度も開かれ、閉じられていました。printfecho

より効率的な bash コード:

    # X,Y screen coordinates invalid on backup files ending with "~"
    ! [[ "$X" == "?" || "$Y" == "?" ]] && { let i++; echo \
        "FALSE|$i|${File##*/}|$Linkless|$Date|$X|$Y" >> "$IconsRaw"; }

答え1

スクリプトには のインスタンスが複数あると想定しています>> "$IconsRaw"。そのメッセージは、出力を 1 回だけリダイレクトし、コマンドをサブシェルにグループ化することを提案しています。おそらく、ファイルを複数回開いたり閉じたりするオーバーヘッドを回避するためです。

したがって、これの代わりに:

    printf "FALSE|" >> "$IconsRaw"           # Select field number 1
    printf "%s|" "$i" >> "$IconsRaw"         # 2
    printf "%s|" "${File##*/}" >> "$IconsRaw"
    printf "%s|" "$Linkless" >> "$IconsRaw"  # 4
    printf "%s|" "$Date" >> "$IconsRaw"      # 5
    printf "%s|" "$X" >> "$IconsRaw"         # 6
    echo   "$Y" >> "$IconsRaw"               # 7

これ:

{
    printf "FALSE|"            # Select field number 1
    printf "%s|" "$i"          # 2
    printf "%s|" "${File##*/}" 
    printf "%s|" "$Linkless"   # 4
    printf "%s|" "$Date"       # 5
    printf "%s|" "$X"          # 6
    printf "%s\n" "$Y"         # 7
} >> "$IconsRaw"

しかし、これもまた不必要な繰り返しでありprintf、次のようにする方が効率的です。

printf '%s|%s|%s|%s|%s|%s|%s\n' \
      'FALSE' "$i" "${File##*/}" "$Linkless" \
      "$Date" "$X" "$Y" >> "$IconsRaw"

関連情報