Quantcast
Channel: Bashタグが付けられた新着記事 - Qiita
Viewing all 2750 articles
Browse latest View live

その昔作ったbashで歴代将軍を補完するスクリプトと補助コマンド

$
0
0

この記事はクソアプリ2 Advent Calendar 2019の16日目が空いていたので昔作ったクソアプリの紹介をするものです。

その昔こんな話題がありました。

なぜたった15人しかいない徳川将軍は覚えられないのですか? - Togetter

プログラマ視点では、「シェルで補完できないから」というのが一つの意見としてあります(暴論)。

bashの補完スクリプトの作成

ということで徳川幕府の将軍を補完できるスクリプトを書きました。2013年のことです。

当時の問題点

シェルの補完という行為は、基本的にあるコマンドに対して行うものです。しかしこの時点では存在しないコマンド"shogun"に対する補完として実装していました。
また、対応したのは徳川幕府だけで、鎌倉幕府には対応していませんでした。

鎌倉幕府対応版

2年後の2015年、鎌倉幕府への対応を行いました。

shogunコマンドの実装

さらに、shogunコマンドの実体をgoで実装しました。
これで存在しないコマンドに対する補完ではなくなり、無事問題点を解決できました。

ライセンスの設定

ライセンスを明記していなかったので、GNU All Permissinve Licenseを設定しました。リンク先にもありますが、これはGNUが小さなプログラムやファイルに対して推奨しているライセンスであり、GPLとの互換性もあります。

残る問題点

室町幕府に対応していません。
PRがあれば対応したいと思います。


鬼滅の刃の幾何学模様シェル芸

$
0
0

鬼滅の刃の幾何学模様シェル芸とは?

こういう画像を出すシェル芸です。
炭治郎
x.png
禰豆子
x.png
善逸
x.png
やっていきましょう。
前提条件はimagemagickがインストールされていることです。

炭治郎

作りたい画像

x.png

コマンドができるまで

ステップ0. 作りたい画像を観察する

画像をよく見て、性質を捉え、作る方法を考えます。
68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3134333939362f30646130313164342d626239612d306264632d343432652d3565323261396131373533642e706e67 (1).png
実際はこの段階では完成した画像は無いわけなので、炭治郎をよく見てください。
そうすると
a.png
赤く囲んだ部分を単位として、大きなキャンバスにしきつめることでこの画像になりそうですね。

ステップ1. タイルを作る

黒と緑が互い違いになったタイルを作りましょう。
コマンド

$ convert <(echo P3 2 2 1 0 0 0 0 1 0 0 1 0 0 0 0)-scale 10000% /images/0.png

出力画像
0.png
200x200のタイルができました。
echo P3 2 2 1 0 0 0 0 1 0 0 1 0 0 0 0は、無圧縮PPMフォーマットで、
横2ピクセルx縦2ピクセルの、黒と緑の画像を出力します。
最初のP3 2 2 1はPNMのヘッダです。P3が無圧縮のRGB(PPM)画像であることを示します。
続く2 2 1は画像のサイズが2x2であり、画素値が最大1(0または1の2値)であることを示します。
残りの0 0 0 0 1 0 0 1 0 0 0 0はデータ部分で、3つの数値が1ピクセルのRGB値になっています。
3つごとに区切ると0 0 0→黒, 0 1 0→緑,0 1 0→緑,0 0 0→黒で、
それぞれ左上、右上、左下、右下のピクセルの色になります。
convert <(echo P3 2 2 1 0 0 0 0 1 0 0 1 0 0 0 0)で、2x2画像をconvertに入力します。
コマンドの続きは-scale 10000%となっています。これはは100倍拡大です。

ステップ2. タイルを繰り返す

できたタイルを単位として、大きなキャンバスに繰り返し貼り付けて敷き詰めます。
コマンド

$ convert <(echo P3 2 2 1 0 0 0 0 1 0 0 1 0 0 0 0)-scale 10000% -write mpr:a +delete -size 1000x1000 tile:mpr:a /images/x.png

出力画像
x.png
完成ですね。
前ステップのコマンドの続きは -write mpr:a +deleteとなっています。
これでタイルをmpr:aに格納して、いったんイメージシーケンスを空にしています。
その続きは-size 1000x1000 tile:mpr:aとなっています。
これで1000x1000のサイズに、mpr:aのタイルを敷き詰めたものができます。

完成したコマンド

$ convert <(echo P3 2 2 1 0 0 0 0 1 0 0 1 0 0 0 0)-scale 10000% -write mpr:a +delete -size 1000x1000 tile:mpr:a /images/x.png

別解1

$ convert <(echo P3 2 2 1 0 0 0 0 1 0 0 1 0 0 0 0)-scale 10000% -define distort:viewport=1000x1000 -virtual-pixel tile -distort srt 0 /images/x.png

-virtual-pixel tileを使う方法。
mprに格納して、いったんイメージシーケンスをクリアする、
っていうのをやらないで済む。

別解2

$ convert <(echo P3 2 2 1 0 0 0 0 1 0 0 1 0 0 0 0)-scale 10000% miff:-|convert -size 1000x1000 tile:- /images/x.png

miff(magick image file format)で出力してパイプすることで、
mpr格納とイメージシーケンスクリアをしなくて済むし、
別解1より実行も早い(理由はよくわからない)。
シェル芸らしさ(?)も高い感じがする。

禰豆子

作りたい画像

x.png

コマンドができるまで

ステップ0. 作りたい画像を観察する

今回もタイルの繰り返しで画像を作れるでしょうか?
b.png
赤で囲った部分をタイルとして繰り返すことで作れそうですね。
さらに赤い部分は
c.png
黄色で囲った部分を上下左右に反転して結合すると作れそうですね。

ステップ1. 黄色囲み部分を作る

黄色で囲った部分を作りましょう。

コマンド

$ convert -size 86x50 xc:pink -stroke black -fill none -draw'polyline 0,0 0,49 28,0 85,0 0,49 57,49 85,0 85,49' /images/0.png

出力画像
0.png
-size 86x50 xc:pinkで86x50のピンク色のキャンバスを作っています。
86x50は、だいたいcos30°:sin30°になるようにしています。
-stroke blackで、図形を描く時の輪郭線を黒にしています。
-fill noneで、図形を描くときの塗りつぶしを無しにしています。
-draw 'polyline …'で、polyline以降の座標で表された点を結ぶ折れ線(多角形)を描きます。

ステップ2. 赤囲み部分を作る

赤で囲んだ部分を作りましょう。
コマンド

$ convert -size 86x50 xc:pink -stroke black -fill none -draw'polyline 0,0 0,49 28,0 85,0 0,49 57,49 85,0 85,49'\( +clone -flop\) +append \( +clone -flip\)-append /images/1.png

出力画像
1.png
\( +clone -flop \) +appendは、前ステップの黄色囲み部分のコピーを左右反転して、横に結合しています。
\( +clone -flip \) -appendは、さらにそのコピーを上下反転して、縦に結合しています。

ステップ3. タイルを繰り返す

あとは炭治郎と同じです。

$ convert -size 86x50 xc:pink -stroke black -fill none -draw'polyline 0,0 0,49 28,0 85,0 0,49 57,49 85,0 85,49'\( +clone -flop\) +append \( +clone -flip\)-append-write mpr:a +delete -size 800x800 tile:mpr:a /images/x.png

x.png
完成ですね。

完成したコマンド

$ convert -size 86x50 xc:pink -stroke black -fill none -draw'polyline 0,0 0,49 28,0 85,0 0,49 57,49 85,0 85,49'\( +clone -flop\) +append \( +clone -flip\)-append-write mpr:a +delete -size 800x800 tile:mpr:a /images/x.png

別解1

$ convert -size 86x50 xc:pink -stroke black -fill none -draw'polyline 0,0 0,49 28,0 85,0 0,49 57,49 85,0 85,49'-define distort:viewport=800x800 -virtual-pixel mirror -distort srt 0 /images/x.png

-virtual-pixel mirrorを使う方法。
黄色囲み部分からいきなり完成形にいける。

別解2

$ convert -size 86x50 xc:pink -stroke black -fill none -draw'polyline 0,0 0,49 28,0 85,0 0,49 57,49 85,0 85,49'\( +clone -flop\) +append \( +clone -flip\)-append miff:-|convert -size 800x800 tile:- /images/x.pn

miffを使う方法。やはり別解1より実行が早い。

線の太さが気になる人へ

「なんか線の太さが一定じゃないのが気になる」という人向けのコマンド
線太さ2の場合のコマンド

$ convert -size 86x50 xc:pink -stroke black -strokewidth 2 -fill none -draw'polyline -0.5,-0.5 -0.5,49.5 28,-0.5 85.5,-0.5 -0.5,49.5 57,49.5 85.5,-0.5 85.5,49.5'\( +clone -flop\) +append \( +clone -flip\)-append miff:-|convert -size 800x800 tile:- /images/y.png

出力画像
y.png
線太さ1の場合のコマンド

$ convert -size 86x50 xc:pink -stroke black -strokewidth 1 -fill none -draw'polyline -0.5,-0.5 -0.5,49.5 28,-0.5 85.5,-0.5 -0.5,49.5 57,49.5 85.5,-0.5 85.5,49.5'\( +clone -flop\) +append \( +clone -flip\)-append miff:-|convert -size 800x800 tile:- /images/z.png

出力画像
z.png
今回詳しく説明はしませんが
「ピクセルは点ではない」
「画像の左上隅の頂点は、ピクセル座標の(0,0)ではなく(-0.5,-0.5)である」
っていう話が関係しています。

善逸

作りたい画像

x.png

コマンドができるまで

ステップ0. 作りたい画像を観察する

白三角が規則的に並んでる画像と、黄色から赤のグラデーション画像をうまいこと結合するとこれができそうですね。
白三角が規則的に並んでる画像は、
a.png
青で囲んだ部分を繰り返せばできそうですね。
さらに青で囲んだ部分は、
b.png
赤で囲んだ部分を、幅の半分だけ横にずらして(はみ出した部分は反対側から出てくるイメージ)、縦に結合すればできそうですね。

ステップ1. グラデーションを作る

コマンド

$ convert -size 1000x1000 gradient:yellow-orangered /images/0.png

出力画像
0.png
gradient:yellow-orangeredで、黄色からオレンジレッドのグラデーションを作っています。

ステップ2. 赤囲み部分を作る

コマンド

$ convert -size 66x58 xc:black -fill white -draw'polyline 33,0 13,34 53,34' /images/0.png

出力画像
1.png
-draw 'polyline …'で多角形(三角形)を描いています。

ステップ3. 青囲み部分を作る

コマンド

$ convert -size 66x58 xc:black -fill white -draw'polyline 33,0 13,34 53,34'\( +clone -roll +33+0 \)-append /images/2.png

出力画像
2.png
前ステップのコマンドに続けて\( +clone -roll +33+0 \)することで、
赤囲み部分の幅の半分(33ピクセル)だけ横にずらしたものを作って、
-appendで縦に結合しています。

ステップ4. タイルを繰り返す

$ convert -size 66x58 xc:black -fill white -draw'polyline 33,0 13,34 53,34'\( +clone -roll +33+0 \)-append-write mpr:a +delete -size 1000x1000 tile:mpr:a /images/3.pn

出力画像
3.png
前ステップのコマンドに続けて-write mpr:a +deleteすることでmpr:aに格納して、イメージシーケンスをクリア、-size 1000x1000 tile:mpr:aすることで、1000x1000のサイズで、mpr:aをタイルとして繰り返しています。

ステップ5. 結合する

ステップ1のグラデーションとステップ4の白三角繰り返し画像をうまいこと結合します。
コマンド

$ convert -size 66x58 xc:black -fill white -draw'polyline 33,0 13,34 53,34'\( +clone -roll +33+0 \)-append-write mpr:a +delete -size 1000x1000 tile:mpr:a \(-size 1000x1000 gradient:yellow-orangered \)-compose lighten -composite /images/x.png

出力画像
x.png
完成ですね。
-compose lightenで結合の方法を指定して、-compositeで結合しています。
lightenは二つの画像のピクセル値の明るい方を使う結合方法ですね(たぶん)。
なので、黒と他の色なら、他の色の方が使われ、白と他の色なら白の方が使われます。

完成したコマンド

$ convert -size 66x58 xc:black -fill white -draw'polyline 33,0 13,34 53,34'\( +clone -roll +33+0 \)-append-write mpr:a +delete -size 1000x1000 tile:mpr:a \(-size 1000x1000 gradient:yellow-orangered \)-compose lighten -composite /images/x.png

別解1

$ convert -size 66x58 xc:black -fill white -draw'polyline 33,0 13,34 53,34'\( +clone -roll +33+0 \)-append-define distort:viewport=1000x1000 -virtual-pixel tile -distort srt 0 \(-size 1000x1000 gradient:yellow-orangered \)-compose lighten -composite /images/x.png

-virtual-pixel tileを使って繰り返す方法。

別解2

$ convert -size 66x58 xc:black -fill white -draw'polyline 33,0 13,34 53,34'\( +clone -roll +33+0 \)-append miff:-|convert -size 1000x1000 tile:- <(convert -size 1000x1000 gradient:yellow-orangered miff:-)-compose lighten -composite /images/x.png

miffを使う方法。白三角繰り返し画像をパイプで渡して、グラデーション画像を<でリダイレクトしています。
<(convert -size 1000x1000 gradient:yellow-orangered miff:-):-)の部分がかわいいですね。

冨岡さん

今回詳しく説明しませんけど、冨岡さんも一応やりました。
コマンド

$ convert -size 344x150 xc:yellow -stroke blac出力画像k -fill none -draw'polyline 0,0 0,100 86,150 86,50 0,0'-draw'polyline 0,25 0,100 63,137 63,62 0,25'-draw'polyline 172,0 86,50 86,150 172,100 172,0'-draw'polyline 172,25 107,62 107,137 172,100 172,25'-fill orange -draw'polyline 0,50 0,100 43,125 43,75 0,50'-draw'polyline 172,50 129,75 129,125 172,100 172,50'-fill mediumseagreen -draw'polyline 172,0 172,100 258,150 258,50 172,0'-draw'polyline 344,0 258,50 258,150 344,100 344,0'-fill darkgreen -draw'polyline 0,0 86,50 172,0'-draw'polyline 86,150 172,100 258,150'\( +clone -roll +86+0 \)-append\( +clone -roll +172+0 \)-append miff:-|convert -size 1000x1000 tile:- /images/x.png

出力画像
a.png
もっと工夫して短く書けそうな感じはしますが、今回はここまで。

まとめ

鬼滅の刃に出てくる幾何学模様は、imagemagickで簡単に描ける!(やつもあるし難しいのやつもある)

所感

書いているうちにmiffの使い方を知ったので、当初考えていたよりもちょっとテクニカルな感じになりましたね。

shellの基礎構文

$
0
0

この記事は、CAM Advent Calendar 18日目の記事です
前回は @kkenyaさんによる、Chrome拡張機能で楽をしたいでした。
記事一覧はこちらから↓
https://qiita.com/advent-calendar/2019/cam-inc

概要

shellに関して今までなんとなく使ってきましたが、基礎的な内容もよく知らないな〜と思ったので今回の記事にしました!
数あるshellの中でも今回はbashを採用します。
内容は初歩の初歩なのでshellを当たり前のように使っている方には何も面白くないかもしれませんので悪しからず。
記事に関しても初投稿になるので、typoや間違ってる事があればご指摘お願い致します。

変数の基本

自分の主観になりますが、shellは今まで触ってきた言語の中でも特徴が強く感じました。
カーネルとのインターフェースを担っているという性質上しかたないのかもしれませんが↓のように変数の宣言時にスペースを含めるとエラーとなってしまったり、宣言する時は変数名だけでなのですが使用する際には$を付けなければいけなかったり (一部の言語では変数に常に$をつけなければならない言語もありますが...) これが一番驚いたのですが型が文字列型しかないそうです。

# ↓変数宣言時にスペースを含めるとと駄目
a = 123
-bash: a: command not found # エラーになってしまう# 変数を使う時は宣言した変数名の前に$をつけて使うa=123
echo$a
123 # 123が出力される# 変数は文字列の型しか存在しないa=1
b=1
c=$a+$becho$c
1+1 # 変数が展開した状態の文字列が代入される

変数展開について

shellは様々な書き方により変数展開のが変わるという性質をもっています。
例えばこのような曖昧な変数名を使おうとすると変数abとみなされてしまうので期待した表示ができなくなります。

a=1
b=2
echo$ab# 何も表示されない

そこで、前後の文字に影響を受けないようにするには{}でくくると変数名が明確になります。

a=1
b=2
echo${a}${b}
12  # 期待した通りに表示される

{}この記法で文字列の一部を抜き出すという使い方もできます。

a=123
echo${a:1:2}
23

クォートによる変数展開

shellではクォートの違いにより動作が変わるという特徴を持っています。
その違いによりどのような動作をするのか確認してみました。

a=date
echo'$a'$a# 変数が展開されずにそのまま $a が表示されるecho"$a"date# 変数が展開され date が文字列として表示されるecho`$a`
2019年 12月15日 月曜日 15時07分38秒 JST # 変数が展開されクォート内をコマンドとして実行される

ついでに、クォートの組み合わせで動作が変化するものもあるか検証してみました。

a=date
echo'"$a"'"$a"# 展開されずecho'`$a`'`$a`# 同上echo"'$a'"'date'#  ''は無効になり中の変数が展開されるecho"`$a`"
2019年 12月15日 月曜日 15時15分38秒 JST # ""の中でも``は有効echo`'$a'`-bash: $a: command not found # $aがコマンドとして認識されるのでエラーとなるecho`"$a"` 
2019年 12月15日 月曜日 15時15分38秒 JST # ``と動作は変わらない

↑の組み合わせで "``" が機能するので 「文字列+コマンド」 の組み合わせで色々できそうな気がしますね。

配列について

配列の扱いもやはり特殊ですね。

a=(1 2 3)# スペースで区切るecho$a
1 # 最初の要素が表示されるecho${a[0]}
1 # 指定したインデックスの要素を取り出すecho${a[@]} 
1 2 3 # 全ての要素を表示するecho${#a[@]}
3 # 要素数を表示する

a[0]=10 # 代入時にはカーリー・ブレイスは必要ないecho${a[@]} 
10 2 3

a+=(4 5)# 追加代入するecho${a[@]} 
10 2 3 4 5

制御構文

基本shellの制御構文は

if[条件式 ]then
 処理
fi

このようにifthenを行を分けて書く必要がありますが、可読性が落ちるので

if[条件式 ];then
 処理
fi

と書く場合が多いです。そして条件文の[ですが実はこれ構文の一部ではなくコマンドらしいです。
ですので[ 1 = 1 ]このようにスペースをしっかり取らないとエラーになってしまいます。
[コマンドが何をしているのか実際に使ってみます。

[ 1 = 1 ]# 何も戻ってこない...

特に何か起こる訳ではないのですが$?という特殊変数を使うことである程度何が起こっているのか分かるようになります。
($?はシェルが最後に実行したコマンドの終了状態を保持している)

[ 1 = 1 ]echo$?
0 # 成功したら0が保持されている[ 0 = 1 ]echo$?
1 # 失敗したときは1?

実は各種UNIX一般コマンドはコマンドの成否を戻り値という形で返しています。

  • 0が成功
  • 0以外が失敗

[がコマンドifがコマンドの終了状態で判断しているという事は、別に[ 条件式 ]のような形に拘る必要は無い訳です。
必要に応じてgrepfindなので条件判断ができるということですね。

# 分かりやすくする為に出力を""で括ってますtouch test
if ls | grep test;then# grepの成功可否で判断できる!echo OK 
else
 echo NO
fi"test""OK"if ls | grep test2;then
 echo OK 
else
 echo NO
fi"NO"

最後に

よく分からないまま使っていたshellの記述に関して、実際にどういった動きをしているのかを確かめるプラス、
自分の備忘録として今回の記事を書きましたが、やはりshellは結構特殊な動作をするなーと改めて認識しました。
今後、業務の中でもshellを取り扱ったりshell scriptを書いたりすることが多くなるのでもっとshellについて詳しく学ぶべきだと再認識しました。

次は@camYoshimuraさんです。お楽しみに!

参考資料

今回の記事を書く上で参考にさせて頂きました。ありがとう御座います。
https://qiita.com/katsukii/items/383b241209fe96eae6e7
https://shellscript.sunone.me/if_and_test.html#if-%E6%96%87%E3%81%A8%E3%81%AF
https://qiita.com/a_yasui/items/ec4f75b300410af8958d

hub コマンドが補完されなくなった件について

「: =: unexpected operator」とか「: =~: binary operator expected」とか

$
0
0

各アプリのCI/CD環境をJenkinsで構築中、1日の業務の1/3をロストさせたこの問題をメモしておくことに苦笑

失敗

次の内容をジョブに「シェルの実行」などのシェルスクリプトに設定しているとタイトルのエラーが出てしまう。
ちなみに#!bin/shにオプションを付けてないため異常終了ではなく正常終了する。

詳細: Jenkinsのシェルの実行について

#!/bin/sh# TEST = "++++"
TEST ="++ERRORS++"echo"$TEST"if["$TEST"=~ ERRORS ];then
  exit 1
fi

echo"done!!"exit 0

成功

スペースを消し、変数サイドのダブルクォーテーションを外してif [[ ~ ]]スタイルに調整するとタイトルのエラーは出なくなり、ちゃんと異常終了してくれる。

#!/bin/sh# TEST="++++"TEST="++ERRORS++"echo"$TEST"if[[$TEST=~ ERRORS ]];then
  exit 1
fi

echo"done!!"exit 0

WSL から open でウェブサーフィン

$
0
0

以前、こんな記事WSL から openを書きました。
そしたら、今日上がったdotfiles Advent Calendar 2019 の 18 日目の記事WSLにもそこそこ使えるopenが欲しい!で、色々と改善する方法を教えてもらえたので早速取り入れたいと思います。

改善点は以下のとおりです。
1. ググった結果をopen
2. URLをopen
3. 複数入力に対応

注意

powershell.exe start

Import-Module : The specified module 'C:\tools\poshgit\dahlbyk-posh-git-4184928\src\posh-git.psd1' was not loaded because no valid module file was found in any module directory.
At C:\Users\username\OneDrive\写真\ドキュメント\WindowsPowerShell\Microsoft.PowerShell_profile.ps1:2 char:1
+ Import-Module 'C:\tools\poshgit\dahlbyk-posh-git-4184928\src\posh-git ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceUnavailable: (C:\tools\poshgi...c\posh-git.psd1:String) [Import-Module], FileNot FoundException
    + FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand

と怒られたので使っていません。

実装

if[[$(uname-r)=~ Microsoft ]];then
    local Chrome='/mnt/c/Program\ Files\ \(x86\)/Google/Chrome/Application/chrome.exe'function open(){if[$# -eq 0 ];then
            echo"ERROR: get no input argument."echo"Please specify file-paths, URLs, googling-words"echo"open [file/path]"return 1
        fi
        for arg;do
            if[-e"${arg}"];then
                readlink-f${arg} | xargs wslpath -m | xargs cmd.exe /c start
            elif[[${arg}=~ http ]];then
                echo"${arg}" | xargs -I{} bash -c"${Chrome} '{}'"else
                echo"${arg}" | sed's/ /+/g' | xargs -I{} bash -c"${Chrome} 'https://www.google.com/search?q={}'"fi
        done}fi

実行例

open "hello world" https://www.google.co.jp https://qiita.com "wsl open" ~/Downloads

実行結果

  • chrome(インターネット・ブラウザ)
    • hello world の検索結果 (google.com)
    • google.com
    • qiita.com
    • wsl open の検索結果 (google.com)
  • explore(ファイル・ブラウザ)
    • ダウンロード(シンボリックリンクを事前に設定している必要があります)

zsh の safix alias を使えば、pptやpdfも開けます。参考:WSL から open

以前との違い

以前詳細に記事を書いたので、以前と変えていない箇所については説明しません。参考:WSL から open

no input error

if[$# -eq 0 ];then
    echo"ERROR: get no input argument."echo"Please specify file-paths, URLs, googling-words"echo"open [file-paths/URLs/googling-words]"return 1
fi
  • 入力がない場合はエラーを返す

複数の入力に対応

for arg;do
    if[-e"${arg}"];then
        readlink-f${arg} | xargs wslpath -m | xargs cmd.exe /c start
    fi
done

Chrome で開く

local Chrome='/mnt/c/Program\ Files\ \(x86\)/Google/Chrome/Application/chrome.exe'for arg;do
    if[[${arg}=~ http ]];then
        echo"${arg}" | xargs -I{} bash -c"${Chrome} '{}'"else
        echo"${arg}" | sed's/ /+/g' | xargs -I{} bash -c"${Chrome} 'https://www.google.com/search?q={}'"fi
done

おわりに

  • Chrome='/mnt/c/Program\ Files\ \(x86\)/Google/Chrome/Application/chrome.exe'はブラウザであれば変えても多分大丈夫
  • powershell.exe startを使ったほうがいい理由と使えない理由が知りたい
  • wsl 内からフォルダを開こうとすると、怒られた(開けるけど)
'\\wsl$\Ubuntu-18.04\home\wsl_username'
CMD.EXE was started with the above path as the current directory.
UNC paths are not supported.  Defaulting to Windows directory.

zshにエイリアスを設定→chrome起動

$
0
0

シェルをbashからzshに乗り換えたので、zshにエイリアスを設定することにしました。
ターミナルのコマンドからGoogleChromeなどのアプリケーションを開けるようにします。

zshとは

zshはbashの上位互換と言われており、自称「最強のシェル」だそうです。「ズィーシェル」と読んでます。基本的に使い方はbashとほとんど同じみたいなので、2019年の秋にリリースされたmacOS Catalinaからデフォルトのシェルがbashからzshに変わったというのを聞いて、zshに引っ越ししました。

エイリアスとは

コマンドを別名で登録する機能のことです。コマンドのショートカットを作ることができます。

設定

ホームディレクトリ下にある、.zshrcをテキストエディタで編集します。テキストエディタにはemacsを使っています。

terminal
% emacs ~/.zshrc

.zshrcを開いたら、以下のように、入力してエイリアスを設定します。

.zshrc
aliaschrm='open /Applications/Google\ Chrome.app'

openのコマンドでアプリケーションを開くようになっています。
編集が終わったら、ターミナルに戻り、.zshrcの変更を反映させます。

terminal
% source ~/.zshrc

これで設定は完了です。

terminal
% chrm

chrmのコマンドだけで無事ターミナルからGoogleChromeが起動できました。

アプリのパス確認

アプリケーションの起動をするなら、パスを設定する必要があるのですが、macならFinderアプリケーションにあるアイコンをそのままターミナルにドラッグ&ドロップすれば、簡単にパスを確認できます。

よく使うLINEjupyter notebookのエイリアスも設定してみました。また、chromeのコマンドをopen -nとすることで、新しいウィンドウで開くようにしました。

.zshrc
#chromealiaschrm='open -n /Applications/Google\ Chrome.app'#LINEaliasline='open /Applications/LINE.app'#JupyterNotebookaliasjn='jupyter notebook'

おわりに

他にもエイリアスやショートカットキーを設定して、作業の効率化をしていこうと思います。

参考資料

zshにエイリアスとかいう奴入れたら人生の時間がn秒増えて神

AWKコマンドで正規表現にマッチした行だけを抽出

$
0
0

AWKマスターへの道のり アドベントカレンダーの4日目
https://qiita.com/advent-calendar/2019/awker

環境

$ awk-V
GNU Awk 5.0.1, API: 2.0 (GNU MPFR 4.0.2, GNU MP 6.1.2)

やりたいこと

特定の正規表現にマッチした行を抽出する。

コード

// 行全体で行う場合
$ cat target.tsv | awk-F'\t''/<正規表現>/'

// 特定のカラム()で行う場合
$ cat target.tsv | awk-F'\t''$1=/<正規表現>/'

// ← で囲った部分が正規表現として評価されます。
基本的な正規表現はもちろん使えますが、気になる方は正規表現で使える文字列を参考にしてみてください。

※awkコマンドでは、パターンのみを書いてアクションを書かない場合には、tureの時にprint $0が実行されます。

最後に

awkコマンド何でもできるなぁー。

私もなんでもできるようになりたいなぁー。。。


最短最速でターミナルカスタマイズをする。

$
0
0

はじめに

初めまして!DMM WEBCAMPでメンターをしている@y-hirako0928です。

この記事では、日々プログラムを書いていく中で頻繁に使うターミナルを使いやすく、カッコよくしていく方法を紹介していく記事です。

ターミナルといえば、黒い背景に白い文字。実行された結果も全部白文字。

正直、ダサくないですか?
もっとかっこいいターミナル、欲しくない?

この質問にYES!と思った人は、ぜひぜひターミナルを自分の思いのままにカスタマイズしていきましょう!

この記事に書かれていること:
Macのターミナルに使えるカスタマイズ知識
カスタマイズ未経験者向けの簡単な解説
最低限のカスタマイズの例
さらに進んだカスタマイズをする場合に便利な記事一覧

この記事に書かれていないこと:
・windowsのコマンドプロンプトやPowerShellのカスタマイズ
・シェルについての詳しい解説
・zshプラグインなど、外部ツールやインストールが必要なツールを用いたカスタマイズについて

1. iTerm2を導入しよう

iTerm2とは、ターミナルと同じコマンドラインツールです。
この記事では、ターミナルのカスタマイズよりもiTerm2を導入し、カスタマイズすることをオススメしています。

iTerm2

スクリーンショット 2019-12-19 2.55.05.png

iTermは

ターミナルを素早く&カッコよく開く設定をつけることができる!
画面収録 2019-12-18 1.32.16.mov.gif

私は、controlを2回連続で入力するとしたからニュッ!とiTerm2のコマンドラインが表示されるように設定しています。設定を変更すれば上部、右側、左側からニュッ!と表示できるように設定することもできます。

ね?かっこいいでしょ?
かっこいい以外にも、ブラウザでサイトをみながらちょっとしたコマンドを実行したい時にも便利に使えます。

また、iTerm2は設定できる項目が多く、ユーザーの好みに合わせてより細かなカスタマイズができます。

iTerm2のインストールに特別な設定は必要ありませんので、外部アプリをダウンロードする手順を素直にこなしていけば問題なくダウンロードできます。サイトのDownloadをクリックし、アプリを起動してみましょう。

もし、細かい手順を知りたい方はこちらの記事を参考にすると良いかもしれません。

初心者向け iTerm2のインストール方法 - Qiita

ニュッ! と飛び出るターミナルの設定方法

1. iTerm2 > preferences...をクリックして設定を開きます

スクリーンショット 2019-12-19 3.14.29.png

2. ホットキー用の設定を作ります

メニューからProfileを選び、+をクリックして新しいプロファイルを作成。舐めをわかりやすいようにHotkey windowを作ります。
こうすることで、windowHotkey windowの二つを同時に使うことができます。
スクリーンショット 2019-12-19 3.17.31.png

3. keyメニューを開きます

keyメニューに移り、A hotkey opens a dedicated window with this profileの項目にチェックを入れ、configure Hotkey WindowをクリックしてHotkeyの設定画面を開きます。
スクリーンショット 2019-12-19 3.23.27.png

4. ホットキーを開くためのアクションを自由に設定します。

個人的にオススメは、^Controlキーのダブルタップでニュッ!と開く設定です。もし同じ設定にするならば、Double-tap keyの項目にチェックを入れ、^Controlを選択すると良いでしょう。
スクリーンショット 2019-12-19 3.28.27.png

5. どの場所から開くかを設定します。

メニューからwindowを選択し、Settings for New Windowsの項目を編集します。
スクリーンショット 2019-12-19 13.46.16.png

下からニュッ!と出す設定にしたければ、Styleの項目の中からFull-Width Bottom of Screenを選択します。その他にも、フルスクリーンで開く設定や、ニュッ!と出てくる場所を下部以外に設定する項目がありますので色々と試してみると良いでしょう。
スクリーンショット 2019-12-19 13.46.41.png

これで、カッコよくターミナルを開く設定は完成です。
もし細かくカスタマイズをしたい場合は設定項目を調べてみると良いかもしれません。
iTermの設定に関しては、Qiitaやその他のサイトで設定例を公開している方がたくさんいらっしゃいますので、そうした記事を参考にしてみるのも良いかもしれません。

記事によってはバージョンが古く、レイアウトが変わっているため設定を読み解く若干の英語力が必要になってきます。まぁ、エラー文を読む労力とそこまで変わらないと思いますのでぜひぜひチャレンジしてみてください。

これまで私がカスタマイズしていく中で参考にした先駆者様の記事一覧
僕がiTerm2を使ってる理由 - Qiita
iTerm2のHotkeyを使わないなんてもったいない!! - Qiita


2. .zshrcを見つけよう

では、シェルの設定をしましょう。

設定を始める前に、現在使っているシェルを確認しましょう。

hogehoge[~] % echo $0
-zsh

hogehoge[~] %

シェルという言葉に聞き馴染みがなかったら、”ターミナルの中で動いているプログラム、パソコンを動かす時に使うプログラムなんだなー”ぐらいのイメージでOKです。

(ちょっと知っている人向けの蛇足)
ここで、少しシェルを齧ったことがある方であれば、なんでbashじゃなくてzshなの?と疑問に思うかもしれません。zshのカスタマイズ方法を書いている理由としては、macOS 10.15 Catalinaからデフォルトシェルがbashからzshに変更されたからです。
おそらく、macを最近買った方や、Catalinaにアプデートしている方のターミナルはzshが動いているハズなので、zshの設定ファイルをカスタマイズすれば問題ないと思います・・・!

自分は、Catalinaになる前からzshを使っていたため、アップデート後自動的にbashからzshに変わるかどうか定かではありません。もし「echo $0って入力したら-Bashって表示されたよー!」とか、「echo $SHELLと入力したら/bin/bashと表示されたよー!」などの現象がありましたら、コメント蘭でMacのバージョンを添えてお知らせいただけると幸いです。

まず、設定ファイルがある場所を確認します。
cd ~
でrootディレクトリ へ移動してください。

ls -a
で、カレントディレクトリ内にある隠しファイルを探しましょう。
.zshrcというファイルがあれば、それがシェルの設定ファイルです。
もしも.zshrcファイルが存在しなければ、

source .zshrc

で.zshrcファイルを作りましょう。

hogehoge[~] % ls -a
~(その他いろいろなファイルやディレクトリ)~
.zprofile
.zsh_history
.zshenv
.zshrc

hogehoge[~] %

rootディレクトリに.zshrcがあることが確認できましたら、いよいよ.zshrcの編集に移ります。

3. vimの基本的な使い方

設定ファイルの編集にはVimを使うと良いでしょう。.(ピリオド)から始まる設定ファイルは、Sublime TextやVisual Studio Codeのようなスクリプトエディタを使って編集することができないファイルです。
(カスタマイズ次第でできると思いますが、vimと触れ合う良い機会ですのでvimを使ってみましょう。)

Vimを使って設定ファイルを開いてみましょう。

hogehoge[~] % vi .zshrc

(もしファイルが見つからなければ、cd ~ でディレクトリを変えてから実行してみましょう。もしそれでもファイルが見つからなければ、touch .zshrcのコマンドを入力してください。)

すると、Vimのエディタが起動し.zshrcファイルの中身を見る事ができます。

Vimではコマンドを実行して保存などをします。

コマンド実行結果
escノーマルモードにする。(コマンドを入力できる状態にする)
i入力モードにする。
: wファイルの変更を保存する。
:wq変更点を保存してvimを終了する。
:q!変更点を保存せずにvimを終了する。

vimの操作についてさらに詳しく知りたければこちらのサイト( 知識0から始めるVim講座 - Qiita )や、vim 入門などのキーワードで調べてみてください。
また、ターミナル上でvimtutorのコマンドを実行すると、vimの日本語チュートリアルを見ることができます。

4. 簡単におしゃれにしたい人向け(コピー&ペーストでOK!)

1. Simple is the best
PROMPT='%*
%F{green}[%~]%f %# '

スクリーンショット 2019-12-18 1.50.51.png
現在の時刻と、カレントディレクトリを表示するプロンプトです。
作業時間を意識するため、常にプロンプトの脇に時間が表示されるようにしています。
(私はこのスタイルにしています。)

さらに改行を入れるとこんな感じ
PROMPT='
%*
%F{green}[%~]%f
%# '

スクリーンショット 2019-12-19 20.16.31.png
カレントディレクトリとコマンドラインを表示する行を分けると、ディレクトリが深くなっても良い感じにみやすく表示してくれます!

2. 見慣れたデフォルトプロンプトをカラフルに!
PROMPT='%F{magenta}%B%n%b%f@%F{blue}%U%m%u%f %F{green}[%~]%f %# '

スクリーンショット 2019-12-18 2.17.03.png

ユーザー名と現在利用しているPCの名前、カレントディレクトリを表示するプロンプトです。

User_name@UsernoMacBook-Pro ~ %

Zshプロンプトのデフォルトデザインがこんな感じなので、デフォルトデザインに慣れている人にとっては見やすいプロンプトかもしれません。

3. 左右を広く使ったプロンプト
PROMPT='%F{green}[%~]%f %# '
RPROMPT='%*'

スクリーンショット 2019-12-18 2.27.17.png

PROMPT='%F{magenta}%B%n%b%f@%F{blue}%U%m%u%f %# '
RPROMPT='%F{green}[%~]%f'

スクリーンショット 2019-12-19 16.47.46.png

RPROMPTで右側にもプロンプト の設定をすることができます。

4.コマンド実行結果ごとに、改行を入れたい!
PROMPT='
%*
%F{green}[%~]%f %# '

スクリーンショット 2019-12-18 2.39.54.png

プロンプト の頭に改行を入れるとこのようになります。
隙間が空いている方が見やすい!という方は、改行をしてみましょう。

ここまでカスタマイズができれば、だいぶ使いやすいターミナルになってきたと思います!

! 設定を変更したら実行してください

変更した設定を読み込み、画面に反映させるために

hogehoge[~] % source .zshrc

を実行してください。
そうすると、プロンプトが設定したデザインに変わります!

5. さらに自由なカスタマイズがしたい!(オススメ参考資料)

ここからは、ここまでのカスタマイズでも満足できない!もっとカスタマイズしたい!向けです。

紹介したカスタマイズの例で使用しているコードの意味をまとめていきます。

プロンプトの設定
PROMPT=''
RPROMPT=''

zshのプロンプトは、PROMPT=以降に書かれた内容は、コマンドラインの左端に表示。
RPROMPT=以降に記述した内容は、コマンドラインの右端に表示されます。

文字に色をつける
%F{color}お好きなコマンド%f

%F{color}%fで挟まれた場所は、colorで定義した色に文字色を変えます。
ここで使っているコマンド以外にも背景色を設定するやり方もあったりします。
詳しくは、こちらのQiitaを参考にすると良いです。

zshでプロンプトをカラー表示する - Qiita

その他のコード
コード出力
%#プロンプト右端の%
%~カレントディレクトリ
%nユーザー名
%mホスト名
%Bお好きなコード%b太文字
%Uお好きなコード%uアンダーバー

その他にも出力できる項目はまだまだありますので、調べてみると面白いかもしれません!

zshプロンプトのカスタマイズ - Qiita
zsh 設定 - プロンプト -

沼に挑戦したい方

fishシェルを導入してみよう!
何も、シェルはbashとzshしかないわけではありません。
世の中にはfishシェルというシェルも存在します。
もし、自分が今使っている環境以外のシェルにも興味が湧いたら、導入してみると楽しいですよ・・・!

fish shellが結構良かった話 - Qiita
シェルにあんまりこだわりのなかった僕がfishを使ってかんじたこと - SlideShare

shellスクリプトを勉強してみよう!

こんなサイトがあります。一通り中身に目を通せば、シェルスクリプトの意味がだいたい理解できるようになるかも・・・?

UNIX & Linux コマンド・シェルスクリプト リファレンス

もうここからは趣味の領域になってきます。興味がある人はググってみてください!

[補足]bashをカスタマイズする場合

周りの人に話を聞いてみたところ、「そもそもCatalinaにしてねーよ!」とお声をいただきましたので、bashでのカスタマイズ方法とカスタマイズ例を紹介していこうと思います。

今のターミナルでbashが動いているかを確認したい場合は、先ほどと同じようにターミナルでコマンドを入力すればわかります。

hogehoge[~] $ echo $0
-bash
hogehoge[~] $

ちなみにですが、

hogehoge[~] % ← プロンプトが`%`表示ならzsh
hogehoge[~] $ ← プロンプトが`$`表示ならbash

とざっくり目星をつけることもできます。(カスタマイズで変更できる部分なので、あてにはできません。)

では、

hogehoge[~] $ cd ~

でrootディレクトリへ移動しましょう。
移動したら、bashの設定ファイルを探します。

hogehoge[~] $ ls -a
~(その他いろいろなファイルやディレクトリ)~
.bashrc
.bash_profile

bashの場合は、.bashrc.bash_profileが設定ファイルです。
プロンプトカスタマイズするだけなら、.bashrcを設定すれば問題ないです!

hogehoge[~] $ vi .bashrc

でbashの設定ファイルを開きましょう。

プロンプトの設定例(コピペでOK!)

1. Simple is the best
export PS1='\n\t\n\[\e[1;32m[\w]\[\e[0m\] \n$ '

スクリーンショット 2019-12-19 16.33.38.png

2. 見慣れたデザインをカラフルに
export PS1='\[\e[35m\]\u\[\e[0m\]@\[\e[34m\]\h\[\e[0m\] \[\e[32m\][\w]\[\e[0m\] \$ '

スクリーンショット 2019-12-19 19.49.04.png

編集が終わりましたら、zshと同様に設定を適応する必要があります。

hogehoge[~] $ source .bashrc

これで設定したレイアウトが反映されました!

参考サイト
【Bash】ターミナルのプロンプトのカスタマイズ方法まとめ - Qiita

終わりに

ターミナルのカスタマイズは、ハマると結構楽しいです!oh-my-zshを導入してみたり、zshの補完機能を強化したり、gitのbranch名やcommit状況を表示するなどなど、できることは無限大と言って良いでしょう。
本当にハマってしまうと一日中ターミナルのカスタマイズを永遠とカスタマイズしてしまう・・・なんて状況も発生してしまうかもしれません。

もちろんハマってみるとかなりプログラミングの勉強になります。私も、bashやzshのカスタマイズを通じて、隠しファイルの存在やプログラムファイルの保存場所、ディレクトリの概念や"PATHを通す"という概念に触れることができました。

ポートフォリオ作りに疲れた時、休みの日にターミナル環境弄りに挑戦したいなと感じた時、時間に余裕があって心に余裕がある時。そんなタイミングがありましたら、ぜひターミナル環境弄りにハマってみてください!

npmやkubectlの補完関数の遅延読み込み

$
0
0

npm completionkubectl completionが重いので、 bashzshの起動時に毎回実行したくない、と思って最初の実行時まで遅延させるようにしています。

npm

最初の補完実行時に読み込むようにしています。
最初の補完は遅延読み込みのみ実行する関係で、補完できません。

zshの場合は fpath に _npmがすでに存在するので、それより優先させるためには compinitより後にする必要があります。

if type npm >/dev/null 2>&1;then# overwrite after compinit
  _npm (){
    unfunction _npm
    eval"$(npm completion)"}fi

この記事を書くにあたって、現状の /usr/share/zsh/5.3/functions/_npmを確認してみたところ、以下のようになっていたので、今だと zshだけなら不要そうで、初回も _npm_completionが呼ばれているので、ちゃんと補完できて良さそうです。
以前は _npmファイルに補完処理の内容が書いてあって、実際に使われる npmよりも補完内容が古くて不便だった覚えがあります。

#compdef npm# Node Package Manager completion, letting npm do all the completion workif type npm > /dev/null;then
  eval"$(npm completion)"

  _npm_completion "$@"fi

kubectl

こちらは補完関数の方ではなく、 kubectlの実行時に補完設定をするようにしています。
そのため、シェル起動後の初回実行時は補完がきかないので、引数なしで実行してヘルプ表示だけするとか、履歴から実行するなどして、補完設定することを想定しています。

if type kubectl >/dev/null 2>&1;then
  kubectl (){unset-f kubectl
    # lazy loadsource<(kubectl completion ${SHELL##*/})
    kubectl "$@"}fi

Local環境での環境変数の設定場所〜コマンド〜

$
0
0

はじめに

環境変数書くのってどこやっけ?
コマンドなんやっけ?
って割りとなるので、備忘録的な感じに書きます

コマンド

自分のterminalがbashなのかzshrcなのかで変わります。

terminal
$ vim ~/.bash_profile
$ vim ~/.zshrc

見分け方は、terminal開いて上を見ればわかります
スクリーンショット 2019-12-19 17.41.53.png

開いた後に環境変数を書いてやれば完了です

Sudo を使ってシェルスクリプトを実行するときに、環境変数も引き渡したい

$
0
0

プロビジョニングスクリプトを書いています。そのプロビジョニングスクリプトはRootで実行されるのですが、そのスクリプトから、他のユーザとして、別のスクリプトを実行したいというケースがありました。その子スクリプトは、サーバーを起動します。

ところが、そのサーバーの挙動がおかしく、原因は、親スクリプトで設定した環境変数が、子スクリプトに渡っていない様子です。そのサーバーをプロビジョニングしたVMで手動で起動するとすべての環境変数設定が出来て正しく起動しますので、一瞬不思議にみえますが、単純にプロビジョニングスクリプトでの実行時に環境変数がわかっていないのです。

他のユーザとして、シェルを実行する方法

他のユーザとしてシェルの実行はsudoを使います。現在のユーザが、そのユーザに対して権限がなければ、パスワードを求められますが、例えばRootユーザから、他のユーザになる場合は、パスワードは求められません。

$ sudo-u ushio ./child.sh

ところが、この方法では、親スクリプトで設定した環境変数が渡りません。試してみましょう。

parent.sh

#!/bin/bashexport FOO=BAR

sudo-u ushio ./child.sh 

child.sh

#!/bin/bash# source ~/.bashrcecho"FOO: "${FOO}

実行結果

sudo su 
[sudo] password for ushio: 
# ./parent.sh 
FOO: 

何も表示されません。ちなみに、source ~/.bashrcの部分を有効にすると、./child.sh: line 3: /root/.bashrc: Permission deniedのエラーになります。これは、別のユーザで実行しても、root としてみなされている雰囲気のようです。実際に、env コマンドをchild.shで実行してみると、パスの構成などからみて、ushioユーザの.bashrcは実行されていないようです。これが、envをchild.shで実行してみた結果ですが、なんとも中途半端な感じになっていて、パスは、Rootのものだけど、環境変数は特にわたっていません。

LANG=C.UTF-8
SUDO_GID=0
DISPLAY=127.0.0.1:0.0
COLORTERM=truecolor
USERNAME=ushio
SUDO_COMMAND=./child.sh
USER=ushio
PWD=/home/ushio/Codes/DevSecOps/volley/playground/environmentvariables
HOME=/root
SUDO_USER=root
SUDO_UID=0
MAIL=/var/mail/ushio
SHELL=/usr/bin/zsh
TERM=xterm-256color
SHLVL=1
LOGNAME=ushio
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
_=/usr/bin/env

 解決策

とても簡単で、-Eオプションを使います。

parent.sh

#!/bin/bashexport FOO=BAR

sudo-u ushio -E ./child.sh 

実行結果

# ./parent.sh 
FOO: BAR

よりより解決策

今回は、-Eで解決ですが、--preserve-env=で特定の環境変数も渡せるようですね。

sudo -u ushio --preserve-env=FOO ./child.shに変更しても結果は同じでうまくいきました。

-E, --preserve-env
                 Indicates to the security policy that the user wishes to preserve their existing environment vari‐
                 ables.  The security policy may return an error if the user does not have permission to preserve the
                 environment.

     --preserve-env=list
                 Indicates to the security policy that the user wishes to add the comma-separated list of environment
                 variables to those preserved from the user's environment.  The security policy may return an error if
                 the user does not have permission to preserve the environment.

複数のものも試してみましょう。カンマ区切りと書いてあります。

parent.sh

#!/bin/bashexport FOO=BAR
export BUZ=QUUX

sudo-u ushio --preserve-env=FOO,BUZ ./child.sh 

実行結果

# ./parent.sh 
FOO: BAR
BUZ: QUUX
``# 追記 $HOME 環境変数にご注意`-E`を追加したところ、スクリプトが思わぬところで失敗しました。`$HOME`環境変数が、`-E`なしの時はターゲットのユーザとして動作するので例えば `/home/ushio`になるのですが、`/root`になってしまうようです。先ほどのenv
を`--preserve-env=list`でやってみましょう。ああ!なるほど、だから`--preserve-env=list`オプションがあるのか!意図したもののみ入れ替えるわけですね。

```bash
LANG=C.UTF-8
SUDO_GID=0
DISPLAY=127.0.0.1:0.0
COLORTERM=truecolor
USERNAME=ushio
SUDO_COMMAND=./child.sh
USER=ushio
PWD=/home/ushio/Codes/DevSecOps/volley/playground/environmentvariables
HOME=/root
SUDO_USER=root
FOO=BAR
SUDO_UID=0
MAIL=/var/mail/ushio
SHELL=/usr/bin/zsh
TERM=xterm-256color
SHLVL=1
LOGNAME=ushio
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
_=/usr/bin/env
FOO: BAR

アイドルグループが46か48かわからなくなったときにワンライナーで解決する方法

$
0
0

これをシェル芸と言い張っていいものかわからないが、カレンダーに空きがあったので入れさせてもらった。

本題

環境変数$idolにわからないアイドルの地名を入れると、人数を教えてくれる。

echo$idol`if[\`echo$idol | grep"坂"\`];then echo 46;else echo 48;fi`

ポイント

  • バッククオートが2重になるので、内側はちゃんとエスケープする。
  • 文字列が含まれているかどうかを検知するにはechoとgrepをパイプで使う。

使用例

https://wandbox.org/permlink/x7oh4QEVlRtkAfnT

ls -lをすると、ls -lhになる、エイリアス的な関数を.bashrcに記述する

$
0
0

はじめに

ls -lで表示されるファイルの容量が、バイト単位なので、パッと見て非常に分かり難い。自動で、KB、MB、GB表示に変換してくれるように、エイリアスを設定したいのだが、オプション付きでエイリアスを設定する事ができないため、.bashrcに関数を作って対応する事にした。

環境

Ubuntu 16.04.5 LTS

手順

ホームに移動する。

cd ~/

.bashrcを開く。

vi .bashrc

Shift + gで、一番下に移動して、下記のls関数を記述する。

function ls(){if[["$@"=~ ^--color=auto.*l.*$ ]];then
    command ls"$@"-helse
    command ls"$@"fi}

.bashrcを実行して、変更内容を有効にする。

source .bashrc

下記のどのコマンドを実行しても単位の表示がOKになっている事を確認する。
lsコマンドはそのまま使えます。

ls-lls-lals-al

解説

$@には、lsコマンドの引数が入ってきます。.bashrcファイルの上の方を検索すると、alias ls='ls --color=auto'の記述があるため、ls -lをすると、$@の中身は、--color=auto -lで拾われる事になります。オプションが、-l or -la or -alに対応できるよう、正規表現でマッチングさせます。マッチングすれば、最後に、-hのオプションを追加しています。

参考

https://tutorialmore.com/questions-603168.htm

condaをオフにしておく方法

$
0
0

condaをオフにしておきたい

condaコマンドをオフにしておき、condaコマンドで有効にする方法です。
anacondaがインストールされていることが条件です。

.bashrc、.zshrcの設定

.bashrc、.zshrcに

# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/home/user/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
    eval "$__conda_setup"
else
    if [ -f "/home/user/anaconda3/etc/profile.d/conda.sh" ]; then
        . "/home/user/anaconda3/etc/profile.d/conda.sh"
    else
        export PATH="/home/user/anaconda3/bin:$PATH"
    fi
fi
unset __conda_setup
# <<< conda initialize <<<

みたいなものがあるはずです。
それを

function conda(){
    unset -f conda

}

で囲みましょう。

function conda(){
    unset -f conda
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/home/user/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
    eval "$__conda_setup"
else
    if [ -f "/home/user/anaconda3/etc/profile.d/conda.sh" ]; then
        . "/home/user/anaconda3/etc/profile.d/conda.sh"
    else
        export PATH="/home/user/anaconda3/bin:$PATH"
    fi
fi
unset __conda_setup
# <<< conda initialize <<<
}

解説

conda関数を定義してcondaを起動できるようにしました。
conda と入力すればこの関数が呼び出されます。
呼び出したらunset -f condaでこの関数をunsetしておきます。

最後に

授業中に書いたので雑な記事ですがお許しください。


GIthubにカレントディレクトリをプライベートでワンコマンドでぶん投げるシェルスクリプト

$
0
0

いままで一旦Webブラウザでリポジトリつくってーとかやっていたけれどもコマンド一発でGitHubまでアップできるスクリプトを組みました。
仕事ではこんな雑なgit作業はできないけれど、個人使いならありとおもいます。すくなくとも私の幸福度はあがりました。
hubコマンドについてはググってください。
oauth_tokenとか設定が必要です。(401喰らいます)

  • (初回は)GitHubにリポジトリつくって
  • コミットしてpushする

-pでプライベートリポジトリ作成なのでパブリックで作りたいときはコマンドの-p消してください。
git-one-pushとかいうファイルにして実行権限与えて使います。
使い方としては作業が終わったら初回は./git-one-push "<RepositoryName>" "<Commitコメント>"、次回以降は./git-one-push "<Commitコメント>"でGitHubにプッシュまでしてくれ、そこそこ使えます。

USERNAME変数を適宜自分のものに変えてください

#! /bin/bash############# setting############USERNAME=yourname

############# functions############function git_init(){
  git init
  REPONAME=$1if[-z"$REPONAME"];then
    REPONAME=`date +"%Y%m%d%H%M%S"`fi
  hub create -p${REPONAME}# publicにしたいなら-p消す}function git_commit_push(){MESSAGE=$1if[-z"$MESSAGE"];then
    MESSAGE=`date +"%Y-%m-%d %H:%M:%S"`fi
  git add .
  git commit -m"$MESSAGE"
  git push --all}############# main############cd`dirname$0`if git rev-parse --git-dir> /dev/null 2>&1;then# git 管理中
  git_commit_push $1;else# git 管理中ではない
  git_init $1;
  git_commit_push $2;fi
hub browse

以上です。よろしくおねがいします。

引数の初期化

$
0
0

この投稿はShell Script Advent Calendar 20日目です

また、Qiita 初投稿です
間違ったことなどを言っていたらコメント等でご指摘いただけると嬉しいです

はじめに

シェルスクリプト(bash)実行時に、引数が渡されなかった際に初期値(数値)を入れたい

引数が渡された時はその引数を使いたい

上記を実現したかったのにできなくて

至極基本的なところでハマったので、また同じことをするかもしれない()わたしのために備忘録

記事にすれば忘れないと思って。。

とりあえず思いついた方法で書いてみた(動いた)

if [ "$1" = "" ]; then
  NUM=5
else
  NUM=$1
fi

???「1行でかけるよ」 わたし「ええ なるほど?(驚愕)」

${変数名:-初期値}

なるほど(なるほど)

できないよ?

なぜ できなかったのか

代入してなかった(驚愕)(ケアレスミス)

自分で自分にびっくりした。。

$1(第一引数)が設定されていない時、以下のようにして引数の初期化をするんだと考えた

おそらく最初は、$1という引数に直接値を代入できないか考えたんだと思う

${1:-5}

これだけ書いて実行してた。しかしエラる(そりゃそうじゃ)

5: command not found

ぐぐるとだいたい初期化で代入されていたのが文字列だったので、数値だからダメなのかとか色々考えてみたけど、代入してみたらできた

NUM=${1:-5}

あれできた(驚愕)

最初に書いてたif文でも変数に代入してたじゃないか、、、

おわりに(感想)

先人たちが残してくれた記録は尊いし、だいたい合ってる。。

今抱えている問題を解決するために、 bash引数初期値変数展開とかでたんとぐぐったので、いろんな知識が少しだけついた気がした

この問題を解決するのにかかった時間は30分くらいだけど、日をまたいだら、勘違いに気がつけてあっさり解決した

やっぱり、休憩って大事だなと思いました(小並感)たくさん寝よう〜

シェルスクリプト:改行あり・なしの値の取得、改行あり・なしのecho

$
0
0

この投稿はShell Script Advent Calendar 21日目です

お願い

ええそれ違うんじゃない?もっとこういうやり方あるよ!

という方は、是非是非コメントで教えていただけると嬉しいです。。

はじめに

シェルスクリプト(bash)で、

改行入りの値を取得するコマンドを叩いた後に、

変数には改行ありの値が入っているはずなのに、

echoで表示した時に改行されたりされなかったりして混乱したというお話

そこで今回は、値の取得編値の表示編に分けて、改行に関する備忘録を残します

解決方法

サンプルとして、以下のテキストファイル内の値を取得するコマンドを叩くとします

テキストファイル内の値を取得するコマンドについては今回省略します。。

sample.txt

aaa
bb
ccc

値の取得編

  • sample.txtの値が改行なしで ${FUGA} に代入される
FUGA=$(echo `sample.txt の値を取ってくるコマンド`)
  • sample.txtの値が改行ありで ${HOGE} に代入される
HOGE=$(sample.txt の値を取ってくるコマンド)

値の取得時に改行を無視する OR しないについては、当初わたしが調べた際は期待した回答が得られなかった。。

圧倒的ぐぐり力不足。。

echoコマンドsample.txt の値を取ってくるコマンドを渡したもの」を変数に代入すると、改行が無視された値が入る

echoコマンドを付与せずに、「素?のsample.txt の値を取ってくるコマンド」を変数に代入すると、改行ありの値が入る

ちょっと考えると、それはそうなんだよなあ(困惑)

混乱が解けたのでよかった()

値の表示編

ちょっとややこしい。。

  • 改行があっても無視されるパターン: echo ${変数}
echo ${FUGA}
# -> そもそも改行が無視されて値が代入されているので、改行がない(されない)

echo ${HOGE}
# -> 改行ありで値が代入されているけれど、改行されない

実行結果:

  • FUGA

    aaa bb ccc

  • HOGE

    aaa bb ccc

  • 改行があっても無視されないパターン: echo "${変数}"

echo "${FUGA}"
# -> そもそも改行が無視されて値が代入されているので、改行がない(されない)
echo "${HOGE}"
# -> 改行ありで値が代入されているので、改行される!!

実行結果:

  • FUGA

    aaa bb ccc

  • HOGE

    aaa

    bb

    ccc

echoについては、ググったら先人たちの知恵がたくさん出てきた。。ありがとうございます。。

なぜこうなったのか

おそらく、

値の取得をする時点で、その値に対して何らかの処理(grepとか)をしたくて、echoをつけたりつけなかったり試行錯誤していて、

そのあと値の取得と処理ができるようになって、echoが必要なくなったので消したつもりだったんだけど、

ちゃんと消せたところと、消し忘れたところが混在してしまった(ヒューマンエラー)

がために、

改行されないことについて色々とググって調べて試しているうちに、

値の取得の時点ですでに改行が無視されているのか、値の表示の時点で改行を無視しているのかわからなくなってしまった(混乱)

のだと思われます。。落ち着こうね、休憩しようね

HOGE=$(echo "`なんかどっかからlistを取ってくるコマンド`")

↑こんな感じのコードを書いた痕跡もあった

おわりに(感想)

先人たちが残してくれた記録は尊いし、だいたいあってる。。(2回目)

ぐぐるチカラ(キーワードの選定とか、キーワードの繋げかたとか。。)はもっと磨いておこうと思いました。

Master/Slave 構成のクラスタにローカルPCからログインする

$
0
0

Master/Slave 構成のクラスタに、MasterのみがPublic IPを持っていて、Slaveはもっていない場合、一旦、マスタにログインしてから、スレーブにログインしますが、SSHのキーはどうしようということになると思います。PrivateKeyをマスターに転送するわけにもいかないですが、お約束のいい方法があります。ssh-agentを使う方法です。
 昔から知っていますが、使うたびに忘れるのでブログにメモしておくことにします。

を参考にしています。

ssh-agent

Man ページによると「ssh-agent」はPublic Key 認証(RSA, DSA, ECDSA, Ed25519)に使われる Private Keyを保持するプログラムです。ssh-agentは、Xセッションや、ログインセッションの最初で使われます。すべての他の Windowsや、プログラムは、ssh-agentのクライアントとしてスタートします。環境変数を通じて、agentは、自動的に配置され、ログイン時に認証に使われます。」とあります。何が環境変数なのでしょう?

ssh-agent is a program to hold private keys used for public key authentication (RSA, DSA, ECDSA, Ed25519).ssh-agent is usually started in the beginning of an X-session or a login session, and all other windows or pro‐grams are started as clients to the ssh-agent program. Through use of environment variables the agent can be located and automatically used for authentication when logging in to other machines using ssh(1).

ssh-agentの起動

今回は、WSL(Windows Subsystem of Linux) を使っています。Macだと不要ですが、その場合の最初の手順は次のようです。なぜevalなんでしょう?

eval`ssh-agent`

単独で、ssh-agentを実行すると次のようになります。これが、stdoutに出力されるだけです。だから、これをevalしてあげることで、このスクリプトが動いて設定がされるようになります。ssh-agentのソケットやPIDなどの情報を環境変数として出力しています。おそらく、他のコマンドがこれを参照するのでしょう。

$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-GTvAV4KkdXXT/agent.7611;export SSH_AUTH_SOCK;SSH_AGENT_PID=7612;export SSH_AGENT_PID;echo Agent pid 7612;

ssh-agent に private key を追加する。

ssh-agentを起動したのちに、private key を追加します。ssh-addコマンドを使います。

$ ssh-add ~/ssh/id_rsa

設定を確認する

設定できたようです。設定されていないとここで何も表示されません。
bash
$ ssh-add -l
ssh-add -l
2048 SHA256:{SOME LETTERS} /home/ushio/.ssh/id_rsa (RSA)

他のオプションはどうでしょう?

usage: ssh-add [options] [file ...]
Options:
  -l          List fingerprints of all identities.
  -Ehash     Specify hash algorithm used for fingerprints.
  -L          List public key parameters of all identities.
  -k          Load only keys and not certificates.
  -c          Require confirmation to sign using identities
  -t life     Set lifetime (in seconds) when adding identities.
  -d          Delete identity.
  -D          Delete all identities.
  -x          Lock agent.
  -X          Unlock agent.
  -s pkcs11   Add keys from PKCS#11 provider.
  -e pkcs11   Remove keys provided by PKCS#11 provider.
  -q          Be quiet after a successful operation.

-Lが気になったのでたたいてみると、Public Key がかえってきました。

ssh-add -L    
ssh-rsa {Some value} /home/ushio/.ssh/id_rsa

これは、プライベートキーのパブリックキーなので、内容がid_rsa.pub とかと同じになりました。(私は private key を一つしか登録していないので)

Master ノードでログインする

ssh-agentを使ってログインするときは、例えばsshだと-Aオプションを使います

$ ssh -A azureuser@some.domain

ssh は 先ほどの ssh-agentの設定(環境変数)をリスペクトする機能があるようです。下記はsshのManの抜粋です。ホストごとにコンフィグレーションファイルでも設定できるようです。今回は負荷びりしませんが。

     -A      Enables forwarding of the authentication agent connection.  This can also be spec‐
             ified on a per-host basis in a configuration file.

             Agent forwarding should be enabled with caution.  Users with the ability to bypass
             file permissions on the remote host (for the agent's UNIX-domain socket) can
             access the local agent through the forwarded connection.  An attacker cannot
             obtain key material from the agent, however they can perform operations on the
             keys that enable them to authenticate using the identities loaded into the agent.

-A 認証エージェントのコネクションのフォワーディングを可能にします。コンフィグファイルのなかで、pre-hostベースで指定することが可能です。
 エージェントフォワーディングは、注意しながらつかってください。リモートホストで、リモートファイルのパーミッションをバイパス出来るユーザは、フォワードコネクションを使って、ローカルエージェントにアクセス可能です。アタッカーは、エージェントから、キーマテリアルを取得できませんが、エージェントにロードされたIdentityを使って、認証が必要になるオペレーションが可能です。

Slave ノードでログインする

-Aオプション付きでsshでログインするとエージェントフォワーディング機能が有効になります。ですので、プライベートIPを使って、他のノードに-Aで同じようにログインします。キーを転送する必要はありません。

ssh -A azureuser@10.0.0.4

でログインできます。

git

git は普通にサポートしているようです。本当はサポートしてるぜと明確に書いているリソースを探したのですが、うまく探せませんでした。しかし、普通になんのオプションも追記せず、プライベートリポジトリのクローンが、slave 側でも可能になります。

Slave側で、env を叩くと、SSH_AUTH_SOCKが設定されているのがわかります。

$ env
SSH_AUTH_SOCK=/tmp/ssh-czWFbuHunV/agent.87078

リソース

調べている経過でいろいろ有用なブログを見つけたのではっておきます。

ボディビルダーが泳ぐシェル芸

$
0
0

ボディビルダーが泳ぐシェル芸とは?

t.gif
こういうアニメーションを作るシェル芸です。
ボディビルダーがなんか叫んでますね。ちょっとゆっくりにしてみましょう。
t.gif
正弦波泳法という泳ぎ方のようです。
作っていきましょう。
前提条件は、textimgmuscularがインストールされていることです。

コマンドができるまで

STEP1. ボディビルダーを出す

ボディビルダーを出します。
コマンドと実行結果

$ muscular shout フロントリラックス -p front-relax
        .-~-.          
        /   \          
        |   /          
     ,_-/ ,.*`--.,     
   .r ;``\    
  .`,`   ,:  ,.`A`,\   
 /,`/\`''''  ? \`\ _人人_
/  /  \ ; , ; /   )}> フ <
| /    \:':': |   | 7  > ロ <
| |    )':'  |  ,` /  > ン <
(\ `-,_,-~}  | l   > ト <
 `~   / `,  /' \ '"'   > リ <
     ,7   \/   |.      > ラ <
     {  ; |, ,  )      > ッ <
     |,`: |`,`: |      > ク <
     \` , /\`.; /      > ス <
      |`;/  \ , |       ̄Y^Y^ ̄
      \``\   |` (      
      \ . )  {  /      
       \ `/  (}\ |  | /       
        )\  | |       
     c~^_~d  V _`,     

qiitaのシンタクスハイライトでちょっとカラフルになっちゃってますが、
muscular shout-pオプションでポーズを指定しています。

STEP2. スクロールしてアニメートする

1行ずつスクロールしてアニメーションにしましょう。
コマンド

$ muscular shout 上がれ! -p front-relax|tee >(cat)>(cat)>(cat)>(cat)|tee >(cat)>(cat)>(cat)>(cat)|textimg -asl25

出力アニメ
t.gif
前ステップで出したボディビルダーは身長が24行あるので、
25人に分裂させて、25行ごとに区切ってやると
25行24フレームの、1行ずつずれたボディビルダーが得られます。
25人に分裂させるために、前ステップのコマンドのうしろに
|tee >(cat) >(cat) >(cat) >(cat)|tee >(cat) >(cat) >(cat) >(cat)
としていますね。ここが今回ちょっと苦しいところなんですけど、
5回リピートを2回かけて25回リピートしています。
続けてtextimg -asl25とすることで、25行ごとに区切ってアニメートしています。

STEP3. 正弦波のスペースを入れる

ボディビルダーの左側に正弦波のスペースを入れてやると、
正弦波泳法になります。
コマンド

$ muscular shout 正弦波泳法 -p front-relax|tee >(cat)>(cat)>(cat)>(cat)|tee >(cat)>(cat)>(cat)>(cat)|awk '{PI=4*atan2(1,1);for(i=0;i<(sin(NR/25*PI*2)+1)*5;i++){printf " "}{print $0}}'|textimg -asl25

出力アニメ
t.gif
前ステップのあと、awkのfor文で繰り返しスペースを入れています。
繰り返し回数を決めている部分は(sin(NR/25*PI*2)+1)*5となっています。
25行ごとに位相が2πだけ進んで正弦波が一周します。
円周率PIはatanで得ています。
1を加えて5をかけることで、0から10までの幅の正弦波になります。
スピードアップしましょう。
コマンド

$ muscular shout 正弦波泳法 -p front-relax|tee >(cat)>(cat)>(cat)>(cat)|tee >(cat)>(cat)>(cat)>(cat)|awk '{PI=4*atan2(1,1);for(i=0;i<(sin(NR/25*PI*2)+1)*5;i++){printf " "}{print $0}}'|textimg -asl25-d5

出力アニメ
t.gif
完成です。

まとめ

musculartextimgを使って、正弦波泳法で泳ぐボディビルダーのアニメを作ることができました。
いや正弦波泳法って何…?こわ…

Viewing all 2750 articles
Browse latest View live