仕事メモとか

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

カテゴリ: bash

bashの自己ファイルを消したらどうなるか

はい、ちょっと話題になったので自分でも作ってみました。

test01.sh
#!/bin/sh
echo "start"
sleep 1
rm $0
sleep 1
echo "end"

test02.sh
#!/bin/sh
echo "start"
sleep 1
truncate -s0 "$0"
sleep 1
echo "end"
rm自分バージョンと、trancate自分バージョン。
rmでは自己ファイルを消しますが、バックでまだ残ってるので進みます。
一方、trancateでファイルを0にする感じです。

結果はこちら

[tmp]$ sh test01.sh
start
end

[tmp]$ sh test02.sh
start
[tmp]$
これは教えてもらった事ですが、rm自体はリンクを消すだけだから(よって早い)実態としては残ってる。trancateコマンドはファイルを直接触りに行くから消えると。

参考:
https://www.atmarkit.co.jp/ait/articles/1712/01/news017.html
このエントリーをはてなブックマークに追加


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

このエントリーをはてなブックマークに追加

↑このページのトップヘ