読者です 読者をやめる 読者になる 読者になる

座敷牢日誌

都落ちした元SEがソフトウェアやネット関連のことを書いています

bashで * が意図しないワイルドカード展開される場合の対処

C言語ソースコードの1行の文字数を80までにする必要があって, チェックツールなどが用意されているわけではなかったので, bashでチェックしようとしてハマったこと.

#!/usr/bin/env bash
row=1
while read line; do
    chars=$(($(echo $line | wc -c) - 1))
    if [ $chars -gt 80 ]; then
        printf "filename %s, row %d, characters %d\n" "$1" $row $chars
    fi
    row=$(($row + 1))
done < <(iconv -f UTF-8 -t CP932 $1)

こんな感じのスクリプトを用意して, 80文字を超える行があったら, そのファイル名と行番号と文字数を出力しようとしていたが, 文字数が80文字を大きく超過した行が大量に出てきた.

なんでかなあと思ったら, *ワイルドカードとして展開されていた. line 変数の中身が /* だとすると, / 直下のアイテムが列挙されているということ.

#!/usr/bin/env bash
while read line; do echo $line; done <<EOF
/*
EOF

このようなスクリプトを実行すると, 次のように出力されてしまう.

/bin /boot /dev /etc /home /lib /lib64 /lost+found /mnt /opt /proc /root /run
/sbin /srv /sys /tmp /usr /var

回避するには, $line をダブルクォートでくくってやればよい.

#!/usr/bin/env bash
while read line; do echo "$line"; done <<EOF
/*
EOF

これで, /* と出力されるようになるから, ここから文字数の評価もできるようになる. ちなみにシングルクォートでくくると, $line と出力されるようになる.

シェルのクォーティングの有無による挙動の違いってすぐに忘れてしまう.

広告を非表示にする