- 投稿日:2020-06-02T21:18:09+09:00
Lubuntu 18.04で、ゴミ箱が使えないときの対処法。
数ヶ月前に、私はWindowsをきっぱりやめて、Lubuntu 18.04に移行したのであるが、そのとき、何故かゴミ箱が使えなかったので、当時の対処法をここに記述する。
現象
ファイルをゴミ箱に移動しようとすると、何故かエラーが出て(肝心のエラーの内容をメモするのを忘れてしまった。)ゴミ箱にファイルを移動できない現象であった。
至って簡単だった対処法
対処法は至って簡単だったのである。それは、rootでゴミ箱フォルダを消して、通常の権限でゴミ箱フォルダを再度作成するというものである。
root権限で、ファイルマネージャーを開く
通常、ゴミ箱のディレクトリは、"~/.local/share" にあるため、そこをまずは開く。Lubuntuの場合、標準のファイルマネージャはPCManFMであるため、以下のようにすればよいだろう。
sudo pcmanfm ~/.local/share
Trashフォルダを削除する。
そこには、「Trash」フォルダがある。それが問題のゴミ箱フォルダである。そのフォルダを削除する。このとき、ゴミ箱は正常に機能していないため、Shiftキーを押しながら、Deleteキーを押すことで、完全に削除できるため、この方法で完全削除する。
Trashフォルダーを作り直す。
今度は、通常の権限で "~/.local/share" ディレクトリに移動する。
移動できたら、そこに「Trash」という名前のフォルダを作成する。これで終わり。動作するか試す。
一応一旦ログアウトし、再度ログインして、適当なファイルをゴミ箱に入れてみよう。正常に動いていれば、そこにデータがあり、ゴミ箱も空にできるはずだ。
- 投稿日:2020-06-02T20:58:33+09:00
Linux : topコマンドで表示される情報を理解する
はじめに
会社の研修中にtopコマンドで実行中のプロセス一覧が見れることを教わりました。教わったことと調べたことを整理しつつ、topコマンドで表示される情報を理解するのが本記事の目的です。
こちらの記事を参考にしました
topコマンドとは
topコマンドは、そのシステムで実行されているプロセスの一覧を表示するlinuxコマンドです。システム全体の負荷や、プロセスごとのメモリ使用量などを見ることができます。
topコマンドを実行してみる
topコマンドを実行するとシステムのプロセス情報が一度に表示されます。
初心者目には情報が多いですが、少しづつ見ていきます。ヘッダー部分
画像での空行を区切りとして、そこから上部の部分をヘッダー部分として見ていきます。
時間とユーザー数
top - 19:41:02 up 3:35, 1 user,一行目「top」と書かれている箇所の情報です。
左から
- 現在時間
- サーバーの稼働時間(「up 3:35」の部分。「時:分」表記)
- ログインユーザー数
となります。
load average
load average: 0.52, 0.44, 0.53一行目残りの部分の情報です。
この欄には、単位時間あたりの平均待ちタスク(プロセス)数が表示されています。小数が3つ並んでいますが、左から直近で「1分, 5分, 15分」間の単位時間あたり待ちタスク数となっています。
上の画像だと例えば、直近1分間の平均待ちタスク数は0.52タスク、ということになります。Tasks
Tasks: 387 total, 1 running, 315 sleeping, 0 stopped, 0 zombie現在のタスクを状態ごとに見ることができます。
- total : 全タスク数
- running : 稼働中タスク数
- sleeping : 待機中タスク数
- stopped : 停止したタスク数
- zombie : ゾンビタスク数
CPU
%Cpu(s): 2.9 us, 0.3 sy, 0.0 ni, 96.6 id, 0.0 wa, 0.0 hi, 0.2 si, 0.0 stCPUの利用時間の割合をプロセスの種類ごとに見ることができます。上の画像では単位がありませんが、単位は「%」です。
- us : userプロセス
- sy : systemプロセス
- ni : niceプロセス
- id : idleプロセス
- wa : I/O waitプロセス
- hi : hardware interruptプロセス(interruptは「割り込み」という意味です)
- si : software interruptプロセス
(個々のプロセスがどういうプロセスなのかは他の機会に調べようと思います。)
画面で「1」を押すと、個々のCPUごとの情報に切り替えることができます。%Cpu0 : 1.0 us, 0.0 sy, 0.0 ni, 98.3 id, 0.0 wa, 0.0 hi, 0.7 si, 0.0 st %Cpu1 : 0.7 us, 0.0 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu2 : 1.4 us, 0.3 sy, 0.0 ni, 98.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu3 : 0.4 us, 0.7 sy, 0.0 ni, 98.9 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu4 : 0.7 us, 0.3 sy, 0.0 ni, 99.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu5 : 1.0 us, 0.7 sy, 0.0 ni, 98.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu6 : 0.3 us, 0.0 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu7 : 0.3 us, 0.0 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 stMemory/Swap
KiB Mem : 7965864 total, 336044 free, 5603244 used, 2026576 buff/cache KiB Swap: 2097148 total, 1692156 free, 404992 used. 800580 avail Mem物理メモリとスワップ領域の使用メモリ量が表示されています。「Mem」が物理領域、「Swap」がスワップ領域です。
スワップ領域についてはこちらのサイトがわかりやすかったです。
- total : 全メモリ量
- free : 使用していないメモリ量
- used : 使用中のメモリ量
- buff/cache : バッファ/キャッシュで使用されているメモリ量
最後の「avail Mem」は「新しいアプリがスワップせずに使えるメモリ量」です。
プロセス一覧部分
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1407 sada 20 0 604828 92172 63112 S 2.0 1.2 6:17.70 Xorg 2196 sada 20 0 7374224 476924 53408 S 1.7 6.0 8:05.10 java 1537 sada 20 0 4039788 274080 115156 S 1.3 3.4 8:13.99 gnome-shell 2768 sada 20 0 2008760 555128 310552 S 1.0 7.0 7:52.98 chrome 12359 sada 20 0 849556 48752 34872 S 1.0 0.6 0:07.22 gnome-terminal-空行より下の部分には実行中のプロセス一覧が表示されます。
- PID : プロセスID
- USER : そのプロセスを実行しているユーザー
- PR : 優先度 0を基準とした、相対的な優先度です。負の値もあります。
- VIRT : 確保されている仮想メモリ量
- RES : 使用している物理メモリ量
- SHR : 他のプロセスと共有される可能性のあるメモリ量
- S : プロセスのステータス アルファベットによって分類されています
- D: 割り込み不能押すと
- R: 実行中
- S: スリープ状態
- T: 停止中
- Z: ゾンビプロセス
- %CPU : CPUの使用率
- %MEM : メモリの使用率
- TIME+ : プロセスの実行時間
- COMMAND : プロセスの実行コマンド名
このプロセス一覧では、「Shift + p」でCPU使用率順(%CPU)、「Shift + m」でメモリ使用率順(%MEM)に並べ替えることができます。
また画面上で「c」を押すと「COMMAND」の部分が絶対パスで表示されます。メモリ使用率順で並び替えて、絶対パスを表示した画像がこちらです。
さいごに
topコマンドで表示されるプロセス一覧画面の見方をまとめました。
topコマンドには他にも便利な機能がたくさんあるようです。使いこなして、プロセス管理をスムーズに行っていきたいです。
- 投稿日:2020-06-02T17:17:18+09:00
シェルスクリプトでファイルの中身を順に処理
やりたいこと
ファイルの中身を取得して上から順番に処理していきます。
本記事ではファイル内の名前データ(name.txt)の中身を上から取得して、通し番号をつけてcsv(name.csv)に変換するループ文のシェルスクリプトを紹介します。コード紹介
現在のフォルダの状況
実行前の状態$ cat name.txt Taro Suzuki Jiro Suzuki Noriko Yamada Junko Nishidamain.sh#!/bin/sh cnt=1 cat name.txt | while read data do echo ${cnt},${data} >> name.csv #cnt変数のインクリメント cnt=`expr ${cnt} + 1` done実行例
main.shの実行sh main.sh実行後の状況$ cat name.csv 1,Taro Suzuki 2,Jiro Suzuki 3,Noriko Yamada 4,Junko Nishida
- 投稿日:2020-06-02T16:25:30+09:00
シェルスクリプトでフォルダ内のファイルを順番に処理
やりたいこと
フォルダ内のデータ(名前)を取得します。
本記事ではフォルダ内ファイルの拡張子を.txtから.logに変更するループ文のシェルスクリプトを紹介します。コード紹介
現在のフォルダの状況
実行前の状況$ ls 1.txt 2.txt 3.txt 4.txt 5.txt main.shmain.sh#!/bin/sh for filename in *.txt; do mv ${filename} ${filename%.txt}.log; done実行例
main.shの実行sh main.sh実行後の状況$ ls 1.log 2.log 3.log 4.log 5.log main.sh.txt拡張子が.logに変更されていることがわかります。
おまけ
何十万のデータに番号をつけたい場合も利用できますね。
for分の途中でカウンタを文字列付与すれば一気に大量のデータに番号をつけることもできます。main.sh#!/bin/sh cnt=1 for filename in *.txt; do mv ${filename} data_${cnt}.log; #cnt変数のインクリメント cnt=`expr ${cnt} + 1` done実行後の状況$ ls data_1.log data_2.log data_3.log data_4.log data_5.log main.sh
- 投稿日:2020-06-02T16:25:30+09:00
シェルスクリプトでフォルダ内のファイルを順に処理
やりたいこと
フォルダ内のデータ(名前)を取得します。
本記事ではフォルダ内ファイルの拡張子を.txtから.logに変更するループ文のシェルスクリプトを紹介します。コード紹介
現在のフォルダの状況
実行前の状況$ ls 1.txt 2.txt 3.txt 4.txt 5.txt main.shmain.sh#!/bin/sh for filename in *.txt do mv ${filename} ${filename%.txt}.log done実行例
main.shの実行sh main.sh実行後の状況$ ls 1.log 2.log 3.log 4.log 5.log main.sh.txt拡張子が.logに変更されていることがわかります。
おまけ
何十万のデータに番号をつけたい場合も利用できますね。
for分の途中でカウンタを文字列付与すれば一気に大量のデータに番号をつけることもできます。main.sh#!/bin/sh cnt=1 for filename in *.txt; do mv ${filename} data_${cnt}.log; #cnt変数のインクリメント cnt=`expr ${cnt} + 1` done実行後の状況$ ls data_1.log data_2.log data_3.log data_4.log data_5.log main.sh
- 投稿日:2020-06-02T15:20:32+09:00
Linux基礎15 -シェルスクリプトの基礎知識-
はじめに
今回はシェルスクリプトを書くための基礎知識を紹介します。少し長くなってしまいますが、よろしくお願いいたします。
シェルスクリプトの基本
シェルスクリプトを書く上で、最も基本となる、行の見方や、コメントについて紹介します。
シェルスクリプトの行
シェルスクリプトでは、実行したいコマンドラインをファイルに記述することでコマンドが実行されます。
次のシェルスクリプトでは、複数のコマンドを記述しています。複数のコマンドを実行するシェルスクリプト(rootls.sh)#!/bin/bash #シェバン echo "root directory" cd / ls -lこのシェルスクリプトを実行するとルートディレクトリのファイル一覧が表示されます。
また、複数のコマンドは;
で区切ることで、1行にまとめて書くことができます。次の先ほどのコマンドは次のように書き換えることもできます。;で区切ることで複数のコマンドを1行にまとめる(rootls.sh)#!/bin/bash echo "root directory";cd /;ls -lなおシェルスクリプトでは、
空行
は無視されるため、読みやすくするために空行
を入れても構いません。シェバンの後ろに1行空行を入れることで読みやすくすることが多く行われています。複数行での記述
コマンドラインが長くなってしまう場合には、
行末に\を置くことで途中で改行
できます。これは見た目が改行されているだけで、シェルスクリプトとして実行される際には、次の行に連結して実行されます。コマンドライン内での\による改行(echo_root.sh)#!/bin/bash echo \ #途中でechoコマンドが改行されている "root directory"
オプションや引数ををいくつも指定してコマンドラインが長くなってしまう場合には、この機能を利用するとシェルスクリプトが読みやすくなります。なお普段のシェルでも
\
を利用することができます。次のようにシェルで\
を入力することでプロンプトが>
に変化しました。これは、コマンドラインが終了していないため、続きを入力してくださいという入力待ちの状態を意味するプロンプトです。これをセカンダリプロンプト
といいます。この文字はシェル変数PS2
でカスタマイズすることもできます。
なお、|(パイプ)
を利用して、パイプラインでコマンドラインを繋ぐ際にも、|
の直後に改行を入れて、次のように記述しても構いません。|(パイプ)による改行の例sort file3 | #file3を行単位でASCIIコードの順に並べ替える uniq -c | #連続した行の重複したファイルを省略する -cで各行の前に出現回数を表示する sort -n #文字列を数値とみなして並べ替えるコメント
シェルスクリプトの中には
コメント
を挿入することができます。コメント
とは、動作に関係のない注意書きのことで、シェルスクリプトの説明を書くときに使います。
シェルスクリプトでは、#を書くとその行の終わりまでコメントとなります
。コメントの挿入#!/bin/bash echo "root directory" #ルートディレクトリに移動する cd / ls -l # ファイルサイズ、パーミッションなども合わせて表示する # echo "current directory"コメントは何が書かれていても無視されますので、そこにコマンドが書いてあったとしても実行されません。一時的にコマンドを実行させないためにコメント行にすることもあります。
変数
シェルスクリプトでも、通常のプログラムと同じように値を格納する変数を利用できます。これを
シェル変数
と呼びます。シェル変数
に値を代入するには<変数名>=<値>
という形式で指定します。変数の値を参照するには、変数名の前に$を付けます
。変数の値を参照する(var.sh)#!/bin/bash appdir=/home/nossy/work echo $appdir変数の書き方の注意
シェルスクリプトで変数を利用する際の注意点について、紹介します。
代入時には$を付けない
変数への代入時には、変数名の前に
$
を付けません。そのため次のように書くと、エラーになります
。変数名の前に$をつけるのは、変数展開して値を参照したいときだけ
です。変数名に$をつけることで値を取得するというイメージを持っておくといいかもしれません。エラーになる変数の書き方$appdir=/home/nossy/work=の前後にはスペースを入れない
多くのプログラミング言語では、変数に値を代入する際には=の前後にスペースを入れることができます。しかし、シェルスクリプトでは、スペースを入れることはできません。次のように=前後にスペースを入れるとエラーになります。
エラーになる書き方appdir = /home/nossy/work
### 変数名に利用できる文字
変数名に利用できる文字は、
アルファベットと数値と_(アンダースコア)だけ
です。また、数値は先頭の1文字目には使うことができません。そのため変数名の先頭は必ずアルファベットか_(アンダースコア)にします。変数名の良し悪し- 利用できる変数名 : appdir1、a13_box、_temp、OSAKA etc.. - 利用できない変数名 : 1appdir、my-app、that's etc..なお、大文字小文字の使い分けですが、
環境変数には大文字
を、それ以外には小文字
を使うケースが一般的です。変数名の区切りを明示する。
変数展開した値に文字列を連結したい場合、文字列の全体が変数名の一部とみなされてしまうことがあります。例えば次のような例です。
文字列の全体が変数名とみなされる場合#!/bin/bash filename=my_app echo $filename_backup #これではfilename_backupという変数であるとシェルに解釈されてしまう上のような問題を避けるには、変数名の部分を
{ }
で囲んで変数名の区切りを明示してあげる必要があります。文字列の一部の変数を明示する(sep_var.sh)#!/bin/bash filename=my_app echo ${filename}_backup #{変数名}として変数名の区切りを明示するこのシェルスクリプトを実行すると、次のようにmy_app_backupと出力されます。
クォーティング
bashではコマンドの引数はスペースによって区切られます。
2つの引数を渡す場合$ cat file1 file2
「my app」
のようにスペースを含むファイル名を指定したい場合には、コマンドの引数を'(シングルクォート)や"(ダブルクォート)で囲む必要があります。これをクォーティング
と言います。スペースを含むファイル名を引数にする$ cat 'my app' "my file"このほかにも、シェルに解釈される特別な意味の文字(メタ文字)を利用する際にはクォーティングを用います。次の例では、*がシェルのワイルドカードと認識されないように、クォーティングしています。
ワイルドカードのクォーティング$ grep 'Be*r' drink.txtクォート中の変数展開
クォートには'(シングルクォート)と"(ダブルクォート)の2つがあります。この2つの違いは、
$による変数展開がされるかどうか
です。例をみてみましょう。シングルクォートとダブルクォートの違い(quoto.sh)#!/bin/bash country=Japan echo 'I came from $country' echo "I came from $country"
' '
の中では変数展開が無効になるため、$countryがそのまま文字列として出力されています。
一方、" "
の場合は、変数展開が有効なため、Japanと出力されています。なお、
" "
の中でも、$の前に(バックスラッシュ)を置いてエスケープすることで、$記号そのものを出力することができます。$をエスケープするecho "I came from \$country" #=> I came from $countryコマンド置換
シェルスクリプトでは、こまんどの出力結果をシェルスクリプト中で利用したいことがあります。このようなケースでは
コマンド置換
という機能を利用して、コマンドの結果を文字列として取得することができます
。
コマンド置換
は$( )
という形式で、カッコ内に実行したいコマンドを記述します。シェルスクリプトの実行時に$( )
の部分がコマンドの標準出力で置換されます。例として、日付を出力するdateコマンド
を利用してみましょう。
現在日付のファイルを作成する(mkfile.sh)#!/bin/bash filename=$(date '+%Y-%m-%d') touch "$filename"上の例では、シェル変数filenameには現在の日付が代入されます。その後にtouchコマンドでファイルを作っていますので、これは現在の日付でファイルを作成するシェルスクリプトです。
コマンドの置換は、"(ダブルクォート)の中でも有効です
。
なお、コマンド置換は`(バッククォート)で囲む記法もありますが、コマンド置換内でコマンド置換を使うという入れ子構造を使用したい場合などに見辛いなどの欠点があるため、$( )を用いることが一般的です。位置パラメータ
多くのLinuxコマンドは、コマンドライン引数によって対象ファイルなど様々な値を指定します。
シェルスクリプトからコマンドライン引数を扱う
には、位置パラメータ
と呼ばれるシェル変数を使用します。位置パラメータ
とは$1, $2, $3...
と1から順に並んだ変数で、それぞれにシェルスクリプトを呼び出したときにコマンドライン引数が格納されています。コマンドライン引数と位置パラメータ$ ./parameters.sh aaa bbb ccc ./parameters => $0 #特殊パラメータ aaa => $1 #位置パラメータ bbb => $2 #位置パラメータ ccc => $3 #位置パラメータ位置パラメータの利用方法を確認する例を上げてみましょう。以下のようなシェルスクリプトを作ります。
位置パラメータの利用(parameters.sh)#!/bin/bash echo "\$0 = $0" echo "\$1 = $1" echo "\$2 = $2" echo "\$3 = $3" echo "\$4 = $4" echo "\$5 = $5"コマンドライン引数を3つほど適当に与えて実行してみます。
引数にワイルドカードを指定することもできます。カレントディレクトリのファイルが順番に引数に代入されてますね。
引数の個数
コマンドラインに指定された
引数の個数は、特殊パラメータ$#という変数で参照できます
。この変数には、シェルスクリプトを実行したときの引数の個数が格納されています。前回のファイルに1行加えて実行してみましょう。位置パラメータの利用(parameters.sh)#!/bin/bash echo "\$0 = $0" echo "\$1 = $1" echo "\$2 = $2" echo "\$3 = $3" echo "\$4 = $4" echo "\$5 = $5" echo "\$# = $#"
このように、引数の個数を表示することができました。引数の指定が必要なシェルスクリプトを作るときに役立つでしょう。引数全体の参照
位置パラメータはコマンドラインを自動的に分割しますが、逆に
引数を分割せずにまとめて扱う場合には$@または$*を利用します
。次のようなシェルスクリプトを用いてみていきましょう。まとめて引数を扱うサンプル例(args.sh)#!/bin/bash echo "\$@ = $@" echo "\$* = $*"このシェルスクリプトに引数を渡して実行しましょう。
一見すると、$@と$*は同じ動作のように見えますが、大きな違いがあります
。$@と$*の違い$@ = aaa bbb ccc => "$@" = "aaa" "bbb" "ccc" #""で囲むと位置パラメータがそれぞれ文字列として展開される $* = aaa bbb ccc => "$*" = "aaa bbb ccc" #""で囲むと引数全体が文字列として展開される多くのケースでは引数をそれぞれ扱いため
$@
が多く用いられています。
次の例は、シェルスクリプト実行時の引数を、そのままコマンドに渡す例です。このような用途でかかれるシェルスクリプトをラッパー(包むもの)と呼ばれます。ラッパー#!bin/bash export LANG=C #環境変数LANGをC(英語)に指定 ./some_command "$@" #英語環境下で、引数をそのまま引き継いでコマンドを実行コマンドライン引数に関係するシェル変数のまとめ
変数 内容 $0 実行時のシェルスクリプト名 \$1,\$2,\$3... コマンドライン引数の値(位置パラメータ) $# 位置パラメータの個数 $@ 全ての位置パラメータ。ダブルクォートで囲むと、それぞれの位置パラメータがダブルクォートで囲まれる。 $* 全ての意図パラメータ。ダブルクォートで囲むと、全体が1つの文字列として、ダブルクォートで囲まれる。 制御構造
bashは通常のプログラム言語と同じように、値による条件分岐や、繰り返し処理を行うことができます。これを
制御構造
と呼び、プログラム言語において非常に重要な機能です。
ここではよく使われる例として、if, for, case, while
の複合コマンドを紹介します。if文
if文は
条件を評価して、その真偽に応じて処理を分岐する
ための機能を持ちます。例をみていきましょう。if文の使用例#!/bin/bash if [ "$1" = "bin" ]; then #[ "$1" = "bin" ]の部分が条件判定 echo "OK" #条件判定が真なら実行 else echo "NG" #条件判定が偽なら実行 fi
なお、インデント
はタブでもスペースでも構いません。インデントはスクリプトを読みやすくするものなので、省略してもエラーにはなりません。記述上の注意点
if文を書く際の注意点についていくつか紹介します。
if文を書くときの注意点条件を書いた後の;を省略するとエラーになる if [ "$1" = "bin" ] then #エラーになる if [ "$1" = "bin" ] #改行すればエラーにはならない then [ ]の前後のスペースを省略するとエラー if[ "$1" = "bin" ]; then #ifと[の間にスペースがない if ["$1" = "bin" ]; then #"[と"$1"の間にスペースがないifの後ろにはコマンドを書く
多くのプログラム言語では、if文に書くものは条件式となっています。しかし、シェルスクリプトでは
if文の後ろに書くのは「コマンド」であって、条件式ではない
ことに注意してください。シェルスクリプトでのif文の書き方は次のようになります。
if文の書き方if <コマンド1>; then <コマンド1>が真である場合に実行 elsif <コマンド2>; then <コマンド2>が真である場合に実行 else 上記の結果が全て偽である場合に実行 fiif文では、コマンドの結果をどのように解釈しているのかを少し詳しくみていきましょう。そのためにLinuxコマンドと
終了ステータス
についての理解が必要なため、一旦if文から離れて、コマンドと終了ステータスについて、お話しします。コマンドと終了ステータス
lsやgrepなどのコマンドは全て終了時に
終了ステータス
と呼ばれる整数値を返します。この値は$?
というシェル変数で参照できます。lsコマンドの終了ステータスをみてみましょう。
$?
は直前のコマンドの終了ステータス格納します。コマンドにより若干の違いはありますが、基本的にコマンドが正常に終了した場合は0を、エラー時には0以外の値
を返します。次のようなシェルスクリプトを作って、コマンドの終了ステータスを確認してみましょう。showstatus.sh#!/bin/bash <img width="634" alt="スクリーンショット 2020-06-01 20.14.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630802/1047faab-784a-4725-284e-a9f668ae4f7d.png"> ls / echo "exit status = $?" ls /dammy #dammyは存在しないファイル・ディレクトリ echo "exit status = $?"
lsコマンドのマニュアルを見ると終了ステータスが2の場合は、存在しないディレクトリをしていますというメッセージです。
このように、コマンドの終了ステータスを$?
を用いることで確認できます。if文と終了ステータス
if文と
[
コマンドのお話しに戻りましょう。[
コマンドは引数に書かれた条件式を判定し、条件が正しければ0を、そうでなければ0以外の終了ステータスを返すコマンドです
。if文では、真偽の判定を行うとき、まず後ろに指定されているコマンドを実行します。そして、その終了ステータスが0であった場合は真、そうでない場合は偽と判定
します。if文はこのような仕組みを持つため、
[
以外にも任意のコマンドを持つことができます。例えばgrepコマンドは、パターンにマッチした場合に終了ステータスとして0を返すので、これを利用します。例として、/etc/passwdファイルにbashという文字列がマッチすれば、"bash found!!!"を表示するシェルスクリプトを作ってみましょう。ifの条件にgrepコマンド#!/bin/bash if grep -q "bash" /etc/passwd; then #grepでマッチした結果を表示させないための-qオプションを指定 echo "bash found!!!" fitestコマンドと演算子
[
とtestコマンド
は同様の機能を持ちます。次の2つの文は同じ意味を持ちます。testコマンド(同じ意味)if [ "$1" = "bin" ]; then if test "$1" = "bin"; then
[ ]
の方が、読みやすいので、基本的には[ ]
が用いられます。また、一般的には[
もtest
も合わせて、「テストコマンド」
と言います。文字列の比較
ここからは、テストコマンドと一緒に利用するたくさんの評価演算子をみていきます。まずは
比較の演算子
からです。
ここでstr1, str2は任意の文字列を示しています。
演算子 内容 str1 = str2 str1とstr2が等しい str1 != str2 str1とstr2が等しくない -n str1 str1が空文字列ではない -z str1 str1がから文字列である ここでは
-z
を例に上げてみましょう。-z
は引数が空文字列であれば真となるので、対象が空の時にデフォルト値を代入する条件文を作ってみましょう。-zの使い方例filename=$1 #$1は位置パラメータ if [ -z "$filename" ]; then #シェル変数filename(<=$1)に値が格納されていなければ filename="default" #filenameには"defaultという文字列を格納 fi整数の比較
次に整数値を比較する演算子を紹介します。下の表で、int1, int2は任意の整数です。
演算子 意味 int1 -eq int2 int1とint2が等しい int1 -ne int2 int1とint2が等しくない int1 -lt int2 int1がint2より小さい int1 -le int2 int1がint2以下 int1 -gt int2 int1がint2より大きい int1 -ge int2 int1がint2以上 なお、
これらの演算子は整数しか扱えません
。では、例をみていきましょう。2つの引数から、大きい方をシェル変数maxに代入する(if_int.sh)#!/bin/bash num1=$1 num2=$2 max=$num1 #maxにnum1を代入しておく if [ "$num1" -lt "$num2" ]; then #条件: num1がnum2よりも小さければ max=$num2 #maxにnum2を代入する fi echo $max
なお、少数を引数に指定した場合には次のようにエラーを返されます。
ファイル属性の評価
次にファイル属性を評価する演算子を紹介します。これは、多くの演算子が存在するため、使用頻度の高いものを紹介します。詳細を知りたい方はbashマニュアルの条件式(CONDITIONAL EXPRESSIONS)を参考にしてください。
演算子 意味 -e file fileが存在する -d file fileが存在し、ディレクトリである -h file fileが存在し、シンボリックリンクである -L file fileが存在し、シンボリックリンクdearu(-h)と同じ -f file fileが存在し、通常のファイルである -r file fileが存在し、読み取りパーミッションが与えられている -w file fileが存在し、書き込みパーミッションが与えられている -x file fileが存在し、実行パーミッションが与えられている file1 -nt file2 file1の変更時刻がfile2より新しい file1 -ot file2 file1の変更時刻がfile2より古い では使用例をみていきましょう。
ディレクトリの存在確認(logdir.sh)#!/bin/bash logdir=/home/nossy/work/logs if [ -d "$logdir" ]; then echo "ログディレクトリは: $logdir" else echo "[ERROR]ログディレクトリは見つかりません" fi/logsディレクトリはないので、エラーを表示してくれました。
/logsディレクトリを作成してから実行すると、パスを教えてくれましたね。
演算子の結合
次は演算子の結合です。複数の条件式を指定したい場合には、演算子を結合することができます。
演算子 意味 条件式1 -a 条件式2 条件式1と条件式2の両方が真の場合に真(AND) 条件式1 -o 条件式2 条件式1と条件式2の少なくとも1つが真の場合に真(OR) !条件式 条件式の真偽を逆にする(NOT) () 条件式をグループ化する では具体例をみていきましょう。
対象がディレクトリでかつ読み取りパーミッションがある場合という条件式if [ -d "$sample" -a -r "$sample" ]; thenディレクトリがないことの確認if [ ! -d "$sample" ]; then echo "$sample directory does not exist" fi
( )
で囲むと条件式をグループ化できます。-o
は-a
より優先度が低いので、`-a, -o, !"を組み合わせて使うときの優先度を決める時に使用します。ディレクトリであり、かつ、/homeまたは/etcというパス名であるという条件式if [ -d "$sample" -a \( "$sample" = "/home" -o "$sample" = "/etc" \) ]; then #()はメタ文字のため\でエスケープしています。&&と||
コマンドの終了ステータスに関連したbashの構文として、複数のコマンドを連結して順に評価する方法があります。それが、
&&と||
です。
記法 意味 コマンド1 && コマンド2 コマンド1の終了ステータスが0である場合に、コマンド2を実行する コマンド1||コマンド2 コマンド1の終了ステータスが0意外である場合に、コマンド2を実行する ファイルが存在すれば、catコマンドを実行する$ [ -f file.txt ] && cat file.txtファイルが存在しなければ、touchコマンドで空ファイルを作成する$ [ -f file.txt ] || touch file.txtif文での&&や||の利用
if文で
&&
を使用すると、複数コマンドの終了ステータス全てが0というAND条件を記述することができます。例をみていきましょう。if文での&&の利用(if_and.sh)#!/bin/bash int1=$1 if [ "$int1" -gt 3 ] && ["$int1" -lt 6 ]; then #$int1が3より大きく、かつ、6より小さい時にif文は真 echo "int1 > 3 and int1 < 6" fi同様に
||
を用いることで、いずれかのコマンドの終了ステータスが0というOR文を記述することができます。if文での||の利用(if_or.sh)#!/bin/bash str=$1 if [ "$str" = "home" ] || [ "$str" = "usr" ]; then #strがhomeかusrに一致すれば真 echo "str = home or usr" fiシェルスクリプトの終了ステータス
通常コマンドと同様に、作成したシェルスクリプトも終了ステータスを返すことができます。特に明示しなければ、
シェルスクリプトの中で最後に実行したコマンドの終了ステータスがシェルスクリプトの終了ステータス
になります。
明示的に終了ステータスを指定したい場合はexitコマンド
を使用します。明示的に終了ステータスを指定するexit <終了ステータス> #exitコマンドを実行するとそこでシェルスクリプトは終了して指定の終了ステータスを返します。では例をみていきましょう。
引数エラーの時に終了ステータスを1で終了する(error_test.sh)#!/bin/bash if [ -z "$1" ]; then #引数が指定されていない時 exit 1 #終了ステータス1を返してシェルスクリプトは終了する fi ls "$1"for文
for文
は、スペースやタブで区切られた単語のリストに対しての繰り返し処理を行う構文
です。for文の構造for 変数名 in リスト #リスト要素1つ1つに対して、do~doneまでの部分に記述された処理を実行する do 繰り返す処理 doneでは早速例をみていきましょう。
for文の使い方(for.sh)#!/bin/bash for name in aaa bbb ccc do echo $name #aaa bbb ccc というリストの要素を順番にシェル変数$nameに代入してecho $nameで繰り返し出力しています done例えば、カレントディレクトリの.htmlファイルの1行目を表示したい時には、以下のような例を書きます。
パス名展開を利用したfor文#!/bin/bash for filename in *.html do head -n 1 "$filename" doneまた、
リストの部分にはコマンド置換を記述することも可能
です。コマンド置換を利用したfor文#!/bin/bash for i in $(seq 1 5) #seqコマンドは数値列を出力するコマンド。 $ seq 1 5 => 1 2 3 4 5 do touch "000${i}.txt" doneコマンドライン引数とfor
for文ではリストtosite
$@
を指定して、全てのコマンドライン引数に対して処理を行うケースが頻繁にみられます。コマンドライン引数$@をリストに指定(parameters.sh)#!/bin/bash for parameter in "$@" do echo "$parameter" done
なお、for文では$@を対象とすることが多いのでin <リスト>
を省略すると自動的に$@
がリストの対象とみなされるようになっています。下の2行は同じ意味です。for文の省略系for parameter in "$@" for parameterここまでの復習
引数に複数ファイルをとって、引数がディレクトリの場合はlsを実行、ファイルの場合は先頭の5行を出力するシェルスクリプトを作ってみましょう。また、それぞれの引数がfileなのかdirectoryなのかを出力してみましょう(〇〇 is a regular file.)
復習(test.sh)#!/bin/bash for parameter in "$@" do if [ -d "$parameter" ]; then echo "$parameter is a directory." ls -l "$parameter" elif [ -f "$parameter" ]; then echo "$parameter is a regular file." head -n 5 "$parameter" fi donecase文
caseは、
指定された文字列がパターンにマッチするかどうかを判断して、マッチしたパターンに対応する処理を行う
ための制御構造です。case文の構造case <文字列> in <パターン1>) 処理1 ;; <パターン2>) 処理2 ;; ... esaccaseで指定された文字列は、各パターンにマッチするかどうか上から順に評価されて、マッチしたパターンのブロックに書かれた処理を実行します。どのパターンにもマッチしない場合には、そのままcase文を抜けます。早速例をみていきましょう。
ファイル名によって処理を分岐(case.sh)#!/bin/bash case "$1" in *.txt) #ワイルドカードが使用できる less "$1" ;; *.sh) #ワイルドカードが使用できる vim "$1" ;; *) # *)は上記のどの条件にも一致しなかった場合の処理として使用される echo "not supported file : $1" ;; esacまた
|
を使って複数のパターンを記述することも可能です。|を使った複数パターンの記述#!/bin/bash case "$1" in start|stop) #startまたはstopにマッチした場合はOK echo "OK" ;; *) echo "NG" ;; esacwhile文
while文は
指定した条件が真である限り繰り返し処理を行う
制御構文です。while文の構造while <コマンド> do 繰り返し処理 done早速例をみていきましょう。次の例は、シェル変数iが10以下の数値である場合に\$iの値を表示してから、2を加えるという動作を繰り返します。$iが10よりも大きくなったら処理を終了します。
testコマンドによるwhile文のループ#!bin/bash i=1 while [ "$i" -le 10 ] do echo "$i" i=$((i + 2)) #bashの算術式展開の表記 whileと一緒に用いられることが多い。下記で解説 done算術式展開
shで書かれたシェルスクリプトは、簡単な足し算をするときも次のようにexprという外部コマンドを使っています。これはループの中で使用する場合など、回数をこなさないといけない場合に、処理速度が非常に遅くなります。
exprコマンドi=`expr $i + 2`一方、
$(( ))
はbashの算術式展開と呼ばれる機能を使用しています。$(( ))
と括ることにより、中の文字列を計算式として扱うことができます。またbashの算術式展開は読みやすく、動作も早い
という利点を持っています。そのため、bashスクリプトでは積極的に利用しましょう。算術式展開i=$((i + 2))シェル関数
シェルスクリプトを書いていると、同じ処理を何度も実行する場面がよくみられます。このような時は処理をひとまとめにして、関数にしておくと便利です。
シェルスクリプトで利用される関数は、シェル関数と呼びます。これは次のようにfunction
を用いて定義します。シェル関数の定義基本形 function <関数名> () { 処理 } 省略形1 #()を省略した形 function <関数名> { 処理 } 省略形2 #functionを省略した形 最もよく使われている <関数名> () { 処理 }では、早速例をみていきましょう。次の例ではhomesizeという関数を定義して、シェルスクリプトの最後で呼び出しています。
シェル関数の定義と使用例(function.sh)#!/bin/bash homesize () #関数を定義します { date du -h ~ | tail -n 1 } homesize #シェルスクリプトを実行すると、まずhomesize関数が呼び出されます。その中身として、duやtailコマンドが実行されます。なお、シェル関数を使用する際には、
必ず利用する箇所よりも前に定義しておく必要があります
。関数定義のうしろで関数を呼び出すとエラーになります。シェル関数内での位置パラメータ
シェル関数ないでも位置パラメータ
$1,$2...
は利用できます。ただし、シェル関数の中ではこれらはコマンドライン引数ではなく、関数への引数が参照されます。次のようなシェルスクリプトを作成して確認してみましょう。シェル関数での位置パラメータ(func_parameters.sh)#!bin/bash print_parameters () { echo "\$1 = $1" echo "\$2 = $2" echo "\$3 = $3" echo "\$4 = $4" echo echo "$# arguments" echo "script name = $0" } print_parameters aaa bbb ccc #シェル関数に引数を渡している
上の例では、コマンドライン引数には何も与えていませんが、シェル関数への引数が、位置パラメータとして参照されているのがわかります。
なお、$0
だけは、元のシェルスクリプトのままになっているので、$1,$2...とは扱いが異なるため、特殊パラメータと言われています。シェル関数のステータス
通常のコマンドと同様にシェル関数も終了ステータスを返します。通常は
シェル関数内で最後に実行されたコマンドの終了ステータスが、そのままシェル関数の終了ステータスとなります
。明示的に終了ステータスを返したい場合は、
return
コマンドを使用します。明示的にシェル関数の終了ステータスを返すreturn <終了ステータス> #returnコマンドを実行するとそこでシェル関数の動作は終了して呼び出し元に返ります。引数が指定されていない場合は終了ステータスとして1を返す関数checkparam () { if [ -z "$1" ]; then return 1 fi ls "$1" }関数を実行後に
$?
を出力すると、エラーが起きたかどうかを確認することができます。参考資料
- 投稿日:2020-06-02T14:09:44+09:00
お気に入りのtmuxの複数ペインとvimのセッションの復元・自動化
MacやLinuxのターミナルマルチプレクサtmuxで開発作業は、複数のペインやウインドウを開いて作業しますが、毎回同じな作業が発生するため、自動化します。
プロジェクトのパスに移動し、tmuxの上部ペインにvim起動と同時にセッションを復元し、tmuxの下部ペインに
カレンダーを表示するバッチファイルです。自動化のバッチファイルの内容
$ cat project.sh #!/bin/bash # 作業ディレクトリフルパス名 WORK_DIR="$HOME/project/" # セッション名 SESSION="project01" # ウインドウ名 WINDOW="main_window" tmux new-session -d -s $SESSION -n $WINDOW -c $WORK_DIR #tmux split-window -h -c "$DIR" tmux split-window -v -c "$DIR" # 下部ペインのサイズ変更 tmux resize-pane -D 5 # ペイン0に移動 tmux select-pane -t 0 # vimセッションの再開 tmux send-keys -t 0.0 'vim -S Session.vim' C-m # calコマンドの実行 tmux send-keys -t 0.1 'cal' C-m # セッション名を指定してアタッチ tmux attach -t $SESSIONバッチの実行方法
$ bash project.shターミナルマルチプレクサtmuxの表示結果
tmuxのバージョンの確認
$ tmux -V tmux 3.1b
- 投稿日:2020-06-02T12:25:47+09:00
ツール・環境厨がメインPCをLinuxからWindows+WSL2に乗換えた理由と作業メモ
はじめに
偉そうなことばかり言ってますが他人の作ったソフトを使うことしかできない素人です。そして宗教色も強いです。詳しい方もっとスマートなやり方・ご意見等あれば教えて下さい。
筆者の環境
- Thinkpad X1 Carbon 2018
- 家ではUSB Type-C ドッキングステーションに接続し、見た目はデスクトップ
- 4K, FHD, FHDのトリプルディスプレイ
- US Keyboard
- 日常用途も開発用途も両方
乗り換えを決意した経緯
アドバンスドユーザにはLinuxこそ至高だと思っていた。全て自分で設定・選択できる自由。アドバンスドユーザ用の豊富な無料のツール。そして最高のラップトップ(=Thinkpad)にも自由に入れられる。
しかし、Linuxには大きな問題がある。基本的にGUI周りが弱い。数ある商用サービスはたいていLinuxをきちんとサポートしていない。(逆にサポートしているDropbox, Spotify等は素晴らしい)
それでもLinuxの便利さは、これらの欠点を補って余りあると思っていた。しかし、ある日久しぶりにWindowsを立ち上げたら(当然デュアルブート環境なのだ)ブラウザのレンダリングが爆速ではないか。ウィンドウを電光石火で切り替えて移動しても描画がしっかり追いついてくる。私は家ではノートPCのオンボードのグラフィックで計6K外部出力しているので、gnomeを使っているときに動作がカクついてもそれはある程度仕方ないと思っていた。しかし、Windowsでは快適にそれらが動作するのだ。LinuxでもHardware accelerationが動作するようにドライバーの設定はしたはずだが、やはり対応していないアプリも多いし(zoom, chromeのvideo decode等)、なぜかカクカクなのである。きっと計算プログラムを走らせるだけならLinuxにCLIでログインしてコマンドを叩けばLinuxのほうが速いのだが、日常用途も考えるとWindowsのほうがサクサクなのだ。そして、Windowsは最近WSL2でLinuxカーネルが動くようになり、wingetみたいなスマートな取組みも始まっている。正直ここが一番大きな乗り換えた理由である。
そして第二には、やはりほぼ全てのソフトがWindows向けに最適化されたアプリ・ドライバを提供しているのも大きい。Windowsに乗り換えれば公式Google Driveクライアントもあるし、
ゴミLINEもネイティブアプリを提供している。4kHDRの動画をYoutubeでみてもHardware支援が効くし、Amazon Prime VideoもFull HDで見れる。そして第三には、今は学生だが就職したらLinuxを使えるような職場かは現時点ではわからない。Windowsでも効率的な作業ができるようになっておけば、就職してから活躍すること間違いなしである。()
gnomeをやめてi3とかにすれば、カクカクする問題は解決するかもとかは考えたが、また時間をかけて環境を整えても、結局いろんなアプリが非対応という事実は変わらないので、ならWindowsを快適にしたほうがイイ気がしてきてこうなった。
Why not MBP?
大抵の人はmacでいいじゃんと言うだろう。もちろんmacにもいいところはあるのだがハードがやはりおもちゃであるのだ。MacOSがThinkpadに乗ればいいのだが、、、以下数ある理由を抜粋。
- パソコンなのになぜかキーボードの形をしたまな板が本体の約半分を占めている。
- 見栄えしか考えてないグレアディスプレイ(デザイナーとかはいいのだろうが、この記事はあくまでもdeveloper視点である。)
- 物理的に重い。ベゼルも細くはない。
- Ligitning()じゃなくてType-Cなのは当然だとしても、逆になんでType-Cしかないの?確かにそれ将来的には理想形だけど現実的にはアダプタ持ち歩くだけにしかならないよね
- なぜかProのほうで物理キーを廃止してTouch Bar()
- トラックパッドはいいらしいが、男は黙ってキーボードなのでどうせ使わない関係ない。
- スペックに対してやはり高い、高すぎる。(筆者はコンピュータに関しては金にあまり糸目をつけないので直接の理由ではないが、こんなに高いのにもっと安いThinkpadにボロ負けしていると考えるとやるせない)
- デザイン重視など実用的な工業製品としての質が低い
- すぐ故障する
- 排熱性能()
- 低クロック推移()
- mac OSは確かにWindowsより使いやすいだろう。しかしやはり欠点はある
- Appleサービスと親和性は高いけど、Appleサービス(iCloudとか)は
ゴミが多いのでどうせGoogleサービスしか使わない。というかGoogleが強すぎる。Appleサービスと親和性が高かろうが関係ない。- Dockerがネイティブで使えない
- Unixではあるが、細かなところがLinuxと違ってうざい
以上を考えるとWindows on Thinkpadが最高なのではないかという結論に至った。(但し開発用途にしか使わないとかシングルディスプレイでGPU支援がいらないとか環境によってはLinux on Thinkpadであろう)
さて御託を並べるのはここらへんにしてここからはWindowsに乗換えるにあたって調査したこと・メモを記す。
Windowsの環境構築
方針
- 開発は全てWSL2上、間違ってもwindowsのゴミのようなpath環境や改行コードとは関わらなくていいようにする。
- 但し、VSCodeとJetbrainsIDEの問題はある。少なくともWSL1ではVSCodeはWSLにアタッチするのに1秒弱はかかるし、Jetbrainsについては未調査。Linuxのときは
$ code .
を叩けば一瞬で開いた。- ブラウザとかのその他日常用途アプリは全部windowsに任せよう。きっとwingetにすぐほとんどは対応するだろう。GPU支援アプリ万歳
以下乗り換えにあたって調べたツール達
WSL2
- ディストリビューションはやっぱり安定したローリングリリースなManjaroがいいんだけどうまくインストールできるのだろうか?
- 一応有志が取り組んでいたけど不安定そうなので、素直にUbuntuを導入して、
パッケージ管理はlinuxbrewにした。Path管理とかめんどくさかったし、普通にaptに戻した。- shellはいままでzsh+zgen+preztoでサクサクだったけど、これを機にfishに乗り換え。
- 現時点ではfish+fisherでやってる。shell scriptの文法がbash/zshと大きく異なる以外は満足
- dockerはUbuntu上でそのままaptで持ってくるか、windowsのdocker for desktop使うか迷い中。aptのほうがwindows側の環境汚さずに済みそうだけど、windowsのほうが後々便利だったりするのかな?
ターミナル
guakeみたいなdropdown terminalがよい。
現時点での候補
- Hyper: 分割もあるしプラグインもよい。しかし少し遅い。
- Fluent Terminal: 若干遅い。Dropdownオプションがなさそう。Storeにあるのはよい
- alacritty: 確かに速い。但しdrop downのオプションはない。Windows Managerがサポートするべき機能だとissueで言われてる。(だったらWindowsでそれを実現するツールを教えてくれ)
- Windows Terminal: 発展途上だが公式なので安定感はある。
- cmder: Dropdownあり、重いのでなしか
- ConEmu: cmderのフォーク元らしい。きっとこれも重い
- Terminus: issueによればdropdownに対応しているらしい
guakeが使えなくなるので、いい機会だしtmuxも導入することにする。
参考リンク
とりあえずHyperにしてみようかな。
Windows TerminalはGPUサポートしてるからこれにDrop down optionが実装されたら乗換えるかも。
Hyperとりあえず動いた。overlayのパッケージがうまく動かなかったが㏚のコードを参考にして修正したらうまくいった。Terminusにした。マルチプラットフォームだがWindowsをメインターゲットにしててバグが少ない。Hyperではtabのvertical splitさえバグでできなったので乗り換えた。欠点としてパフォーマンスが悪い。今まで重いと言われてるzsh使ってるのにシェルが重いとか思ったことなかったけど、初めてシェルが重いとかいう概念がわかった。
っていうか今更だけどdropdownがないターミナルでもホットキーでshow/hideできるツールいれれば疑似的に再現できるのでは?もう疲れたからとりあえずTerminusのままいくけど。
さらに追記、Terminus重すぎてストレスマックスだったのWindows Terminalに乗り換えた。むちゃくちゃ速い。やっぱ公式は安定感が違う。速いと言われてるalacrittyより速い気がする。多少機能が少なくても、一番使うところなので基礎がしっかりしてるものを選ぶといいね。こんな便利なものをMicrosoftが公式に出してると考えると感動する。
Package manager
どうせchocolateyとかも不完全だし期待を込めてwingetにする。これで全てが済む世界になってほしい。pamacが恋しい
Tiling Window Manager
ここはちゃんとしたものがあるか心配。有料でもいいので安定してキーボードで操作できるものがほしい。
- bug.n: だめだったうまく動かない。
- HashTWM: だめだったうまく動かない。
- MaxTo: 試用版はあるが用途が異なる気がする。
- AquaSnap Pro: 試用版試した。バグ等なくきちんと動作するが、これはTile WMではない。単にWindows分割とかの便利ツール
- Stack Window Manager: これもAquaSnapと同じ系統
- divvy: 用途が異なる。
どうやらbug.nはうまく動かなかったが、きちんとconfigすればうまくいくかも。モニタごとにscalingが違うからちょっと無理そうだけど。それなりに動くようになったけど、遅い。ネイティブでWindow Managerを入れ替えられるわけではないのでしょうがないか。こんなUXならもう標準のものでよい。
色々試した結果どうにかしてbug.nを動かすしかないかも。ファイルエクスプローラ
WSL2上のrangerでプレビューとか含めてうまく見れるんだろうか。不安。
エディタ
VSCodeしかないよね
IDE
- Jetbrains系がVSCodeみたいに手軽にWSL2とアタッチできるのか調査が必要
- X Serverを立ち上げてGUIもLinux側で立ち上げればいいかもしれないけど、勝手なイメージでなんかカクつきそう。せっかくwindowsなのでGUIはWindowsから使いたい。
- こちらの末尾で言及されているところを見ると大丈夫そう。
Windowsのためのツール
システム変更系
fastwindowswitcher: windowsのalt-tabむちゃくちゃ見にくいので導入。Gnomeではalt-tab中にフォーカスウィンドウに色がつけれてすごい見やすかった。うまく動作しないマルチディスプレイ対応とは書いてあるけどおそらくバグがある。win-10-virtual-desktop-enhancer: デフォルトでwindowsを隣のvirtual desktopに持っていくshortcutないのやばくない?これもオリジナルは開発が止まっており、一番活発そうなフォーク版を試したがダメだった。代わりにMoveToDesktopは動いた。- StrokersPlus: ゆうてご飯食べてるときとかは片手でマウス使うので、そのときのマウスジェスチャ用
- tascher: windowをインクリメンタルサーチで切り替えられる。Alt-Tabを連打しなくてもよくなったが、手順に従ってインストールしてもmigemoに対応させることができないがとりあえず放置。
クリップボードマネージャ
Win + Vはいいんだけど、あれキーボードで操作完結しないの?俺の使い方が間違ってる?要調査。(テキスト入力中に限りキーボードで選択できました。これならとりあえずは看過できる)
プロセス管理
Windows側のプロセスが暴走したときってどうすればいいの?WSL2のhtopとかgtopじゃwindowsプロセスは扱えないよね?
訳わからないPowershell立ち上げてコマンド叩くのも嫌だけど、タスクマネージャを立ち上げてマウスポチポチとかはもっと勘弁。ファイルエクスプローラ
最低限tab化ができるもの。
Clover3(トロイの木馬だった笑、Windows Defender万歳)かQTTabbar。QTTabbar使ってみたが想像よりよい。標準のエクスプローラに拡張で入れる形なので動作が不安定になったら嫌だなとか思っていたが、細く設定できるし、動作も安定してるしこのレベルのものを個人で作れるとは、、、そりゃ海外サイトでも紹介されるわけだ。(日本の方が開発されているが英語にも対応している。)
ただかなり重いので、使わない機能はできる限りオフにすること。便利ツール
- Powertoys: 恥ずかしいことにこのMicrosoft公式の便利ツールの存在を最近知った。これいれよう。プレビュー版なので公式なのに、ctrlキーのswapがうまく行かなかった。代わりにkeyswap.exeを使った。
- Mini Tool Partition Wizard: LinuxのほうにPartitionを侵食させるときに使えるだろう。
exif関連
これはただの自分用忘備録である。
- GPSBabel: これでtimeline jsonをgpxに変換
- Geotag: これを使って写真にタグ付けする。デバイスドライバ
- Driver Booster: 以前使っていて機能には不満ないんだけど、勝手に他のソフトいれるし、スタートアップ自動起動も意地でもしたいみたいだし、ちょっとマルウェアちっく。代替を探しておく。
ウェブサービスのクライアントアプリ達
Station・bitwarden・mendeleyとかいれといた。
感想
- Windowsは情報が一番多いと思ってたけど、英語で探しててもLinux文化圏の人間がほしいような情報が少ない。やはりまともな人間は誰も使ってないのか?ちょっとmacOSが羨ましくなった。
- Windowsは日常用途アプリはしっかりサポートされててこの点はとてもよい。Chromeがサクサクになったのはほんとに快適。しかしターミナルとかはあまりのまともなものの少なさには参ってしまった。
- アドバンスドユーザなら当然変更したいような(エクスプローラのタブ化や仮想デスクトップの拡張など)の機能であっても、それなりにツールはあるが個人でやっていてメンテナンスされていなかったり、商用で有料だったりで、選択肢はとても少ない。世の中の星の数ほどいるWindowsユーザはこれでいいのか?
- GUIであっても開発系のアプリに関してはLinuxのほうが安定してるし、種類も豊富だし、当然どこのパーツも入れ替えが効くのですごい快適だったと気づいた。またしばらくしたらLinuxに戻るかも。
- 2020のmacbookは一応キーボードを積むようになったらしいので、一回限りと思って試しに買ってみるかも。ゆうてMac OSは全然触ったことないので、ちゃんと触ってもっとOS自体の使い勝手も知りたい。
ToDo
- rangerのpreviwe設定
Terminusのhide後にたまにwindowにfocusが戻らない事象を改善- tascherのmigemoを動くようにする。
- Jetbrains系のアタッチテスト
- 投稿日:2020-06-02T12:20:01+09:00
tsharkコマンドでpcapデータを解析
1.tsharkコマンドとは
2.環境設定
3.実行
4.pcapファイルのフィルタリング方法
5.オプション
6.参考tsharkコマンドとは
Wiresharkの実行をCLIで実現できるものです。
CLIなので、並列処理、シェルスクリプトでの記載、cron、grepなどなど、CLI職人にとってはpcapデータをかなり楽に扱えるようになります!環境設定
本記事ではMacOSで試しています。
まずお持ちのMacでtsharkを利用できる状態にします。GUIでもCLIでもどちらからでも可能です。GUI(Webから)でインストールの場合
下記からインストールできます。
https://www.wireshark.org/download.htmlCLI(ターミナル)でインストールの場合
インストールbrew install wireshark※まだhomebrew(brewコマンド)が利用できない場合は、下記を参考に利用できるようにしてみてください!
Homebrewのインストール方法実行
早速実行していきましょう!今回はtest.pcapというデータを見ていきます。
実行tshark -r test.pcapこれでデータの中身が確認できたと思います。
ちなみにデータの並び方と表示されている項目はデフォルト状態ですが、確認したいデータや表示順などを指定することができます。
GUIのWiresharkで列の表示変更を行った場合もtsharkコマンドの結果に影響されます。pcapファイルのフィルタリング方法
今回は下記の条件をつけてフィルタリングして、再度実行してみましょう。
条件
(※)通常のWireShark(GUI)で利用できるフィルター
・smb2プロトコルの通信に絞る
smb2.tree && tcp.dstport==445
・ファイル名や利用アカウント名が抜けている余分な通信は除去する
smb2.filename != "" && smb2.acct != ""
表示
(※)通常のWireShark(GUI)で利用できる列の書き方
・アカウント名
smb2.acct
・フォルダパス(共有パス)
smb2.tree
・操作ファイル名
smb2.filename
・アクセスしている端末名
smb2.host
実行tshark -r test.pcap -T fields -e smb2.acct -e smb2.tree -e smb2.filename -e smb2.host -Y 'smb2.tree && tcp.dstport==445 && smb2.filename != "" && smb2.acct != ""'下記のようにパイプやリダイレクトを利用して簡単に扱えるデータに変換ももちろん可能です。
参考tshark -r test.pcap <オプション系> | grep -i test tshark -r test.pcap <オプション系> > test.csvオプション
オプション 内容 -i <interface> キャプチャするインターフェイスを指定 -f <capture filter> libpcapフィルタsyntaxによるフィルタを指定 -s <snaplen> snapshot lengthを指定(デフォルト:65535) -p プロミスキャスモードを使用しない -y <link type> リンクレイヤータイプを指定(デフォルト:first appropriate) -D インターフェイスリストを表示 -L インターフェイスのリンクレイヤータイプリストを表示 -c <packet count> 指定したパケット数で停止(デフォルト:無限) -a <autostop cond.> ・duration:NUM
NUMで指定した秒数経過により停止
・filesize:NUM
NUMで指定したサイズ(KB)に保存ファイルが達したら停止
・files:NUM
NUMで指定した数の保存ファイル数に達したら停止-b <ringbuffer opt.> ・duration:NUM
NUMで指定した秒数経過により次のファイルへ保存
・filesize:NUM
NUMで指定したサイズ(KB)に保存ファイルが達したら次のファイルへ保存
・files:NUM
NUMで指定した数の保存ファイル数に達したらファイルの置き換え-r <infile> パケットfileから読出し R <read filter> Wiresharkディスプレイフィルタを指定 -n すべての名前解決を無効にする(デフォルト:有効) -N <name resolve flags> 特定の名前解決を有効にする -d <layer_type>==<selector>,<decode_as_protocol> 特定のポートを特定のプロトコルと紐付け
tcp.port==8888,httpの場合は
「tcpポート8888番はhttpとする」となる-C <config profile> 設定ファイルを指定 -F <output file type> 出力ファイルタイプを指定 -V 表示にパケットツリーを追加 -S [-w]オプションを有効にしている場合でもパケットを表示 -x hex、ACSIIダンプ表示を追加 -e <field> アウトプットしたいフィールドを指定 参考
- 投稿日:2020-06-02T11:18:44+09:00
Bulls and Cowsをシェルプログラムで作成してみた
はじめに
Bashプログラミングの小ネタとして作成しました。
第6弾です。今回はなかなか手強かったです。Bulls and Cowsとは
Bulls and Cowsに関してはWikipediaやこちらをご確認ください。
もともとは文字列当てゲームですが、
今回は数字当てゲームとして作成してみます。ソース
#!/bin/bash function chkAns { bull=0 cow=0 num=$1 dig=$2 ans=$3 for i in $(seq 1 $dig) do for j in $(seq 1 $dig) do if [[ ${num:i:1} == ${ans:j:1} && $i == $j ]] then # echo bull: $bull #for debug (( bull = bull + 1 )) elif [[ ${num:i:1} == ${ans:j:1} && $i != $j ]] then # echo cow: $cow #for debug (( cow = cow + 1 )) fi done done if (( bull == dig )) then echo -e "$dig bulls ! You did it !" exit else echo -e "$bull bull and $cow cow." fi } echo "Welcome 'Bulls and Cows' Game" echo -e "Please input digits of numbers => \c" read digits tmp=$(shuf -i 0-9 -n $digits -z) answer=${tmp:0:3} #echo $answer #for debug for k in $(seq 1 10) do echo -e "Input $digits numbers of your answer. (${k} time) => \c" read num chkAns $num $digits $answer if (( $k == 10 )) then echo "You failed 10 times..." fi done echo -e "The answer is '$answer'"$RANDOMでも良かったですが、
信用してないので採用しませんでした。
代わりに、shufコマンドを使いました。実行結果(正解する)
$ ./bulls_and_cows.sh Welcome 'Bulls and Cows' Game Please input digits of numbers => 3 ./bulls_and_cows.sh: 行 39: 警告: command substitution: ignored null byte in input Input 3 numbers of your answer. (1 time) => 321 2 bull and 0 cow. Input 3 numbers of your answer. (2 time) => 324 2 bull and 0 cow. Input 3 numbers of your answer. (3 time) => 325 3 bulls ! You did it !「警告: command substitution: ignored null byte in input」のメッセージは、ヌルバイトが含まれていると出るようです。
ただ、Nullを使わないとN桁の生成が難しかったので無視しています。
良い対処方法があればコメントください。実行結果(失敗する)
真面目に正解しようとしています。$ ./bulls_and_cows.sh Welcome 'Bulls and Cows' Game Please input digits of numbers => 3 ./bulls_and_cows.sh: 行 39: 警告: command substitution: ignored null byte in input Input 3 numbers of your answer. (1 time) => 345 1 bull and 0 cow. Input 3 numbers of your answer. (2 time) => 219 1 bull and 0 cow. Input 3 numbers of your answer. (3 time) => 398 1 bull and 0 cow. Input 3 numbers of your answer. (4 time) => 470 1 bull and 1 cow. Input 3 numbers of your answer. (5 time) => 709 1 bull and 0 cow. Input 3 numbers of your answer. (6 time) => 507 2 bull and 0 cow. Input 3 numbers of your answer. (7 time) => 504 1 bull and 0 cow. Input 3 numbers of your answer. (8 time) => 570 1 bull and 1 cow. Input 3 numbers of your answer. (9 time) => 407 2 bull and 0 cow. Input 3 numbers of your answer. (10 time) => 307 2 bull and 0 cow. You failed 10 times... The answer is '567'おわりに
このプログラムを作成することで
- 変数
- 変数の操作
- 条件式
- 繰り返し構文
- 関数
- readコマンド
- shuf(シャッフル)コマンド
が理解できました。
- 投稿日:2020-06-02T06:08:20+09:00
Remote Processor Framework (2/3)
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/remoteproc.txt
Remote Processor Framework
API for implementors
struct rproc *rproc_alloc(struct device *dev, const char *name, const struct rproc_ops *ops, const char *firmware, int len)Allocate a new remote processor handle, but don't register it yet. Required parameters are the underlying device, the name of this remote processor, platform-specific ops handlers, the name of the firmware to boot this rproc with, and the length of private data needed by the allocating rproc driver (in bytes).
新しいremote processor handleを確保しますが、まだ登録は行いません。要求されるパラメータは、基礎となるデバイス、このremote processorの名称、プラットフォーク特有のops handlers, このrpocを起動するためのファームウェアの名称、そして、rpoc driverが必要とするprivate dataの長さ(byte単位) です。
This function should be used by rproc implementations during initialization of the remote processor.
この関数は、remote processorの初期化している間の、rpoc 実装によって利用されるでしょう。
After creating an rproc handle using this function, and when ready, implementations should then call rproc_add() to complete the registration of the remote processor.
この関数を用いてrproc handlerを生成した後、準備ができたら、実装ではremote processorの登録を完了するために、rpoc_add()を呼び出します。
On success, the new rproc is returned, and on failure, NULL.
成功したら、新しいrpocが戻り値になります、失敗したNULLです。
note::
never directly deallocate @rproc, even if it was not registered yet. Instead, when you need to unroll rproc_alloc(), use rproc_free().
「絶対に」 rpocで直接deallocateしないでください。仮にそれが登録されていなかったとしても、その代わりに、rproc_alloc()を基に戻すためには、rproc_free()を使ってください。
void rproc_free(struct rproc *rproc)Free an rproc handle that was allocated by rproc_alloc.
rproc_alloc()で確保したrpoc handleを開放します。
This function essentially unrolls rproc_alloc(), by decrementing the rproc's refcount. It doesn't directly free rproc; that would happen only if there are no other references to rproc and its refcount now dropped to zero.
この関数は、rprocのrefcountを減らし、rproc_alloc()を基に戻します。これは直接cprocを開放しません。もし、他からrpocが参照されておらず、refcountが0にまで落ち込んだ時だけ、解放します。
int rproc_add(struct rproc *rproc)Register @rproc with the remoteproc framework, after it has been allocated with rproc_alloc().
rproc_alloc()で確保した後、rpocをremoteproc frameworkに登録します。
This is called by the platform-specific rproc implementation, whenever a new remote processor device is probed.
これは、新しいremote processor deviceがprobeされるたびに、platform特有のrpoc実装によって呼び出されます。
Returns 0 on success and an appropriate error code otherwise.
成功時には0が、それ以外の場合にはおそらくエラーが戻り値になります。
Note: this function initiates an asynchronous firmware loading context, which will look for virtio devices supported by the rproc's firmware.
注意:この関数は非同期にfirmware load contextを開始し、rprocのfirmwareがサポートするvirtio deviceを探します。
If found, those virtio devices will be created and added, so as a result of registering this remote processor, additional virtio drivers might get probed.
もし見つかった場合、それらのvirtio deviceは生成され追加されます。そのため、このremote processorを登録した結果、追加のvirtio driverが追加されることがあります。
int rproc_del(struct rproc *rproc)Unroll rproc_add().
rproc_add() を基に戻します。
This function should be called when the platform specific rproc implementation decides to remove the rproc device. it should only be called if a previous invocation of rproc_add() has completed successfully.
この関数は、platform特有のrpoc実装をproc deviceから削除する時に呼び出します。それは、rpoc_add()が完全に成功した場合にだけ、呼び出す必要ががあります。
After rproc_del() returns, @rproc is still valid, and its last refcount should be decremented by calling rproc_free().
rproc_del()から処理が戻った後、rprocはまだ有効であり、その最後のrefcountはrpoc_free()を呼び出す事で減少します。
Returns 0 on success and -EINVAL if @rproc isn't valid.
成功した場合には0が、有効なrprocではない場合には-EINVALが帰ります。
void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type)Report a crash in a remoteproc
remoteprocのcrashを報告します。
This function must be called every time a crash is detected by the platform specific rproc implementation. This should not be called from a non-remoteproc driver. This function can be called from atomic/interrupt context.
この関数は、platform特有のrpoc実装によって、crashが検知されたら毎回呼ばれるべき関数です。これは、remote-proc driver以外から呼ばれるべきではありません。この関数は、atomic/interrupt contextから呼び出すことができます。
Implementation callbacks
These callbacks should be provided by platform-specific remoteproc drivers::
これらのコールバックは、platform特有のremoteproc driverによって提供されます。
/** * struct rproc_ops - platform-specific device handlers * @start: power on the device and boot it * @stop: power off the device * @kick: kick a virtqueue (virtqueue id given as a parameter) */ /** * struct rproc_ops - platform-specific device handlers * @start: 電源投入及び起動 * @stop: 電源切断 * @kick: virtqueueを実行(virtqueueはパラメータで与えられる) */ struct rproc_ops { int (*start)(struct rproc *rproc); int (*stop)(struct rproc *rproc); void (*kick)(struct rproc *rproc, int vqid); };Every remoteproc implementation should at least provide the ->start and ->stop handlers. If rpmsg/virtio functionality is also desired, then the ->kick handler should be provided as well.
それぞれのremoteproc実装には、->start, ->stop handlerが少なくとも提供されます。もし、rpmsg/virtio 機能がまた必要であれば、->kick handlerもまた提供されます。
The ->start() handler takes an rproc handle and should then power on the device and boot it (use rproc->priv to access platform-specific private data). The boot address, in case needed, can be found in rproc->bootaddr (remoteproc core puts there the ELF entry point). On success, 0 should be returned, and on failure, an appropriate error code.
->start() handlerは、rproc handleを用い、デバイスの電源を投入し起動します(rpoc->priveを、platform特有のprivate dataとして用います)。起動アドレスが必要な場合には、rptoc->bootaddr()にて見つけることができます(remoteproc coreはこれをELF entry pointとしてセットします)。成功した場合には0が戻り、失敗した場合には適切なエラーコードが入ります。
The ->stop() handler takes an rproc handle and powers the device down. On success, 0 is returned, and on failure, an appropriate error code.
-> stop() handlerは、rpoc handleを伴い、デバイスの電源を切断します。成功した場合には0が戻り、失敗した場合には適切なエラーコードが入ります。
The ->kick() handler takes an rproc handle, and an index of a virtqueue where new message was placed in. Implementations should interrupt the remote processor and let it know it has pending messages. Notifying remote processors the exact virtqueue index to look in is optional: it is easy (and not too expensive) to go through the existing virtqueues and look for new buffers in the used rings.
-> kick() handlerはrpoc handleと、新しいメッセージをとして設定されるvirtqueueのindexを伴います。実装ではremote processorの輪割り込み、messageがpendingされていることを知ります。検索する正確なvirtqueueインデックスをremote processorに通知することはオプションです。既存のvirtqueueを調べて、使用済みのringで新しいbufferを探すのは簡単です(計算コストは高くありません)。
もともと、Linux Kernelのソースコードの一部なので、GPLv2扱いになる(はずの認識)。
https://www.kernel.org/doc/html/latest/index.html
Licensing documentation
The following describes the license of the Linux kernel source code (GPLv2), how to properly mark the license of individual files in the source tree, as well as links to the full license text.
https://www.kernel.org/doc/html/latest/process/license-rules.html#kernel-licensing
- 投稿日:2020-06-02T01:11:44+09:00
フィボナッチ数列を表示するシェルプログラム
はじめに
Bashプログラミングの小ネタとして作成しました。
第5弾です。フィボナッチ数列を表示
フィボナッチ数列とは何か、詳しくはこちらをご確認ください。
簡単にいうと、2つ前の項と1つ前の項を足し合わせていくことでできる数列です。
ソース
#!/bin/bash m=0 n=1 echo -n "please input number => " read num if (( $num <= 1 || $num >= 2)) then echo $m echo $n fi (( num +=2 )) for i in $(seq 1 $num) do (( o = $m + $n )) echo $o m=$n n=$o doneもっときれいに書けそうですね…
実行結果
$ ./fibonacci.sh please input number => 8 0 1 1 2 3 5 8 13 21 34 55 89おわりに
このプログラムを作成することで
- readコマンド
- 条件式
- 条件演算子
- 変数
- Bashのお作法
が理解できました。
- 投稿日:2020-06-02T00:49:57+09:00
九九を表示するシェルプログラム
はじめに
Bashプログラミングの小ネタとして作成しました。
第4弾です。九九の表を表示する
ソース
#!/bin/bash ans=0 spc=' ' for i in $(seq 1 9) do for j in $(seq 1 9) do (( ans = $i * $j )) printf "%2d" $ans echo -e "${spc}\c" if (( $j == 9 )) then echo #改行させる fi done doneprintfを使って、1桁のときも強制的に2桁になるようにしました。
数字が連続すると見づらいため、各値の間に空白を入れました。実行結果
$ ./kuku.sh 1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 4 8 12 16 20 24 28 32 36 5 10 15 20 25 30 35 40 45 6 12 18 24 30 36 42 48 54 7 14 21 28 35 42 49 56 63 8 16 24 32 40 48 56 64 72 9 18 27 36 45 54 63 72 81おわりに
このプログラムを作成することで
- 繰り返し構文
- printfコマンド
- (( ))を使用した計算
- Bashのお作法
が理解出来ました。
- 投稿日:2020-06-02T00:15:56+09:00
FizzBuzz問題をシェルプログラムで作成してみる
はじめに
Bashプログラミングの小ネタとして作成しました。
とある事情で急ピッチで記事を書いています。
ちなみに今回第3弾となります。FizzBuzzとは
FizzBuzzに関してはこちらを確認ください。
1から順にカウントアップし、
- 3で割り切れるときは「Fizz」を表示
- 5で割り切れるときは「Buzz」を表示
- 両方で割り切れるときは「FizzBuzz」を表示
といったことをします。
ソース
#!/bin/bash echo -n "Please input number => " read num for i in $(seq 1 ${num}) do if (( $i % 3 == 0 && $i % 5 == 0 )) then echo "FizzBuzz" else if (( $i % 3 == 0)) then echo "Fizz" else if (( $i % 5 == 0 )) then echo "Buzz" else echo $i fi fi fi sleep 1 done実行結果
$ ./fizzbuzz.sh Please input number => 15 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz終わりに
3の倍数と3の文字列があるときにahoになるプログラムを応用させれば作れますね。
このプログラムを作成することで
- アルゴリズム
- 条件式
- 条件演算子
- readコマンド
が理解できました。