仕事メモとか

仕事中に調べた情報とか知ったことをメモしています。
unixコマンド, vim, oracle, putty, postgresql, bash, EXCEL, python, SQL全般 など。
最近は tableau, movabletype とかも触ったりしています。
雑な読書感想とかはこちら

カテゴリ: bash


bashの地味な罠「IFS」で落とし穴にはまった

はい、未だにbashを触ってるわけなんですが、他の人が作ったり修正したもので
後から予想外の挙動になったりしたりします。

結論から書くと、今回はIFSでセパレータを指定していたため、スペースで分けてる部分がおかしい挙動になっていました。

●元プログラム
DATA="1 2 3"
for dat in $DATA ; do
echo "$dat"
done

1
2
3


これ、datがfor文で1,2,3と回るわけなんですが、
他の部分でIFSを指定した人がいて、想定した挙動になっていませんでした。

●変更後
IFS=,
DATA="1 2 3"
for dat in $DATA ; do
echo "$dat"
done

1 2 3

for文は「1 2 3」という1つの文字列として扱ってしまいます。
IFSがこのプログラム上のセパレータをカンマだけに指定してしまっているためです。

通常、bashだとスペース、タブ、改行などがセパレータとして許容されているのですが、
IFS=,とした場合、カンマだけになるようです。

参考:
https://www.server-memo.net/shellscript/ifs.html


パイプラインでエラーになった時にスクリプトを止めるpipefail指定

bashの最初の方に、set -e して、スクリプト内にエラーがあったら止める、としているのですが、
なんか止まらないで変な挙動をしているものを発見。

調べたら、パイプ処理でこけてるのに、その後も頑張っちゃっていました。

設定)
set -eu

-e=エラーになったらこける
-u=パラメータ展開中に未設定の場合こける

ということで、パイプでエラーのときもコケル設定を追加

set -o pipefail


ちなみにどんなものがセットできるのか調べるときは、コマンドライン上で

set -o
と実行すると、一覧が出てきます。
なんだか色々設定できるものがある。


参考:
https://blog.ueda.tech/?p=5953
http://www.atmarkit.co.jp/ait/articles/1805/10/news023.html
https://qiita.com/progrhyme/items/6e522d83de3c94aadec9


bash上でのexitコマンドについて

exitコマンドを使うと、スクリプトを終了させることが出来ます。
まあそれはそうなんですが、変数を入れると戻り値を指定できます。

exit [n]

n自体は、0~255までの数字を入れることが出来、
これを終了コードとして渡すことが出来ます。
指定しない場合は終了コード無しで終了します。

終了コードを受け取った側がどう処理するかに寄りますが、
どの数字を入れたとしても終了するし、どの数字がエラーで、どの数字が正常なのか、というのは
受け取った側が判断することなので、そこを決めておかないと、

exit 0
とかやったところで、これが正常終了なのかどうなのか決まっていません。


ちなみに、このnの場所に文字など数字以外を入れると、
このコマンド自体がエラーになります。


参考:
http://itdoc.hitachi.co.jp/manuals/3020/30203S3530/JPAS0289.HTM

bashで実行中に途中でプログラムを止めたい場合 readコマンド

スクリプトを作っていると、割と途中で一旦停止したい、
ということが発生します。

そんなときに、readコマンド


read -p pause

こうすることで、一旦入力待ちにすることで停止し、
何か入力すると先に進みます。


参考:
http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230866/?rt=nocnt

bashの変数で文字数を取得する

変数の文字数で色々判断できる場合があるのですが、
これ変数展開だけで簡単にできました。

${#DAT}

これで文字数取得できるため、以下のようなこともできます。

if [ ${#DAT} = 10 ]; then
# 変数文字数が10桁の場合は変数内容を表示
echo "$DAT"
else
# 変数文字数が10桁以外の場合はエラー
echo "error"
fi

これは地味に便利。



参考:
https://qiita.com/t_nakayama0714/items/80b4c94de43643f4be51

↑このページのトップヘ