ウェアラブルスピーカー
肩に乗せるスピーカーがほしいと思っているのだけれど、
いま売っているのは全部重く感じて、買ってない。
もう少し軽いのがあれば、と思っていたら
すごく軽いのが発表された。
重さは約88g!
他のは300gくらいだから、すごく軽い。
良い。
発売されたら試してみよう。
発売日は、2018年11月17日とのこと。
ソニーのConcept Nがほしかったけど、
商品化されないのかな。
シェルで関数のトレース表示(3)
トレース表示用の関数をつくることにした。
sample1.sh
#!/usr/bin/ksh function f1 { echo f1 } function f2 { echo f2 f1 }
sample2.sh
. ./sample1.sh function f3 { echo f3 f2 } f3
トレースオプションつきで実行
$ ksh -x sample2.sh + . ./sample1.sh + f3 f3 f2 f1 $
関数の中はトレースされない
修正する
- トレース表示用の
__trace__
関数をつくる - スクリプトファイルから関数名をとる
- とってきた関数に
typeset -ft
を設定する
※関数はfunction
で定義している前提
sample2.sh
$ . ./sample1.sh function f3 { echo f3 f2 } __trace__() { set - if [ ! -z "$(echo ${1:-} | sed 's/[^x]//g')" -a -r ${2:-$0} ] then r='^ *function +' for f in $(awk "/$r/"'{sub(r,"");print}' r="$r" ${2:-$0}); do typeset -ft $f; done fi set -${1:-} } __trace__ $- f3
HP-UXでは__trace__()
内のset
は不要
トレースオプションつきで実行
$ ksh -x sample2.sh + . ./sample1.sh + __trace__ hxB + f3 + echo f3 f3 + f2 f2 f1 $
関数(f3)の中もトレースされる
※HP-UXではksh
ではなくsh
でも良い
インクルードした関数のトレースも表示
f3
実行の前に__trace__ $- ./sample1.sh
を入れると、
インクルードした関数のトレースも表示される
$ ksh -x sample2.sh + . ./sample1.sh + __trace__ hxB + __trace__ hxB ./sample1.sh + f3 + echo f3 f3 + f2 + echo f2 f2 + f1 + echo f1 f1 $
関数(f2, f1)の中もトレースされる
-x
をつけないとトレースは表示されない
$ ksh sample2.sh f3 f2 f1 $
Ubuntoのksh
だと、関数をfunction
とname()
で定義した場合で
トレースの表示あり/なしが違うみたい。
関数の呼び出しもとで-x
をつけたとき、
function
で定義した関数のトレースは表示されないname()
で定義した関数のトレースは表示される
シェルで関数のトレース表示(2)
Ubuntoのtypeset -fx 関数名
でトレース表示されない件はよくわからなかった。
set -x
で関数もトレース表示されるから、
Ubuntoではset -x
かsh -x
で実行することにしよう。
Hp-UXは関数内にset -x
がないとトレース表示されないから
いままでは、読み込むファイルの先頭でvar=$-
と、設定を変数に入れて
各関数でset -$var
と設定していた。
これでsh -x file
と実行すると、関数内でset -x
が実行されて
トレース表示される。
でも全部の関数にset -$var
を入れるもの、あまりきれいじゃない気がする。
HP-UXのtypeset -ft
は関数ごとに設定できるから良いんだけど、
カレントの環境しか設定できないから、
sh -x file
みたいにファイルを実行した場合はトレース表示されない。
スクリプトファイルの中に全部の関数をtypeset -ft
する関数をつくって
mainの処理を実行する前にその関数を呼べば良いのかもしれないけど、いまいち。
DEBUGをtrapしてもできるかもしれないけど、
トレース表示だけのための処理を書くのも、うまくない気がする。
難しい。
Pythonで関数のグラフをかく
Pythonで2次関数のグラフをかく。
matplotlib
とnumpy
をインストールする
pip install matplotlib pip install numpy
コードをかく
import matplotlib.pyplot as plt import numpy as np # 0から3.1まで、0.1ずつのデータをつくる(等差数列) x = np.arange(0, 3.1, 0.1) # グラフにする数式 y = 2 * x ** 2 # グラフの大きさ デフォルトは(8, 6) 800x600ピクセル plt.figure(figsize=(5, 5), dpi=100) # グラフのタイトル plt.title(r'$y = 2x ^ 2$') # x軸のラベル名 plt.xlabel(r'$x$') # y軸のラベル名とラベル名の傾き plt.ylabel(r'$y$', rotation=0) # x軸の0~3までの間に4つ目盛りをつける plt.xticks(np.linspace(0, 3, 4, endpoint=True)) # y軸の0~18までの間に4つ目盛りをつける plt.yticks(np.linspace(0, 18, 19, endpoint=True)) # グラフの線の色や幅 plt.plot(x, y, color="blue", linewidth=2, linestyle="-") # y軸の1と10に補助線を引く plt.hlines([1, 10], min(x), max(x), linestyles="dashed") # x軸の1と2と2.5に補助線を引く plt.vlines([1, 2, 2.5], min(y), max(y), linestyles="dotted") # (2, 8)に点をかく plt.scatter(2, 8) # (2.1, 8.1)にテキストをかく plt.text(2.1, 8.1, 'text') plt.show()
実行する
- 実行するとグラフが表示される
- Save the figureのボタンをクリックすると画像を保存できる
標準出力と標準エラー出力を別の変数に入れる(2)
つづき
プロセス置換のつかえないsh
で、stdoutとstderrを別々の変数に入れる方法はあるのだろうか。
サンプル コマンド
command() { echo "[-- stdout1 --]" echo "[-- stdout2 --]" echo "[-- stderr1 --]" >&2 echo "[-- stderr2 --]" >&2 return 3 }
1. evalを使う
bashの時と同じようにevalと使う
unset out stdout stderr ret eval "stderr=\"$({ stdout=$(command);ret=$?;echo "\""; typeset -p stdout; typeset -p ret; } 2>&1);" echo $ret echo -e "stdout=$stdout\nstderr=$stderr"
結果
3 stdout=[-- stdout1 --] [-- stdout2 --] stderr=[-- stderr1 --] [-- stderr2 --]
stderrの代入でクォートしないとエラーになってしまうので、=の前に\"
を入れた。
ただ、閉じる\"
を最後の)
の後ろに書くと、typeset (declare)のダブルクォーテーションが2重になってしまう。
なので、途中にecho
を入れて"
を出力してみた。
結果、エラーにはならないけど、stderrの最後に改行が入ってしまう。
2. 区切り文字を追加する
標準出力と標準エラー出力を同じ変数に入れる。
変数に入れるときに分けるための文字列を追加する。
そして、入れたあとにsedで別々の変数に分ける。
unset out stdout stderr out=$({ echo "#####$(command)"; } 2>&1) echo $? stdout=$(echo "$out" | sed -nre '/#####/,$s/^(#####|)//p') stderr=$(echo "$out" | sed -nre '/#####/,$!p') echo -e "stdout=$stdout\nstderr=$stderr"
結果
0 stdout=[-- stdout1 --] [-- stdout2 --] stderr=[-- stderr1 --] [-- stderr2 --]
別々の変数に入れることはできたけど、 設定する文字列も考えないといけないし、あんまりよくない気がする。
戻り値をとるときはこんな感じ。
out=$({ a=$(command);b=$?;echo "#####$a";return $b; } 2>&1) echo $? 0
最初のevalを使う方法のダブルクォーテーションがなぞ。
これが解決できれば良いのだけれど、ぜんぜんわからない。
この件についてはkshがいいですね。
シェルでコマンドの標準出力と標準エラー出力を別の変数に入れる
コマンドの標準出力と標準エラー出力を別々の変数に格納する
サンプルのコマンド
function command { echo "[-- stdout --]" echo "[-- stderr --]" >&2 return 3 }
1. 標準エラー出力をファイルに書く
ファイルに書いてあとから読む方法は、
わかりやすいし、コマンドの戻り値もとれる
tmpfile=$(mktemp --tmpdir=.) stdout=$(command 2>$tmpfile) echo $? stderr=$(cat $tmpfile) rm $tmpfile echo stdout=$stdout stderr=$stderr
結果
3 stdout=[-- stdout --] stderr=[-- stderr --]
でも、ファイルをつくりたくない。
2. eval、コマンド置換、プロセス置換を使う
こんな感じにコマンド置換やプロセス置換をしてeval
に渡す
stdout= stderr= eval "$((command) 2> >(stderr=$(cat);typeset -p stderr) > >(stdout=$(cat);typeset -p stdout))" echo $? echo stdout=$stdout stderr=$stderr
結果
0 stdout=[-- stdout --] stderr=[-- stderr --]
eval
でdeclare -- stdout="xx
とdeclare -- stderr="xx"
が実行されることで変数に設定される
※typeset -p name
は declare -- name=value"
を出力する
戻り値はとれない。 別の変数に設定すればとれる。
stdout= stderr= eval "$((command) 2> >(stderr=$(cat);typeset -p stderr) > >(stdout=$(cat);typeset -p stdout);ret=$?;typeset -p ret)" echo stdout=$stdout stderr=$stderr ret=$ret
結果
stdout=[-- stdout --] stderr=[-- stderr --] ret=3
戻り値が別の変数になってしまうのが残念。
3. kshを使う
kshだとシンプルにできる
stdout= stderr= stderr=${ { stdout=$(command); } 2>&1; } echo $? echo stdout=$stdout stderr=$stderr
結果
3 stdout=[-- stdout --] stderr=[-- stderr --]
戻り値もとれるし、良い。