20210416のLinuxに関する記事は8件です。

Linuxで手っ取り早くBGPを使うためのBIRDセットアップ

BIRDとは BIRDはLinux等で動作するBGPやRIPなどのルーティングプロトコルを実装したプログラムです。2021年4月時点で2.0系と1.6系の両系列がメンテナンスされています。 フリーで利用可能な選択肢としてOSレベルで動作するVyOSなどがありますが、そちらと比較してパフォーマンスは劣る一方で、既存のアプリケションと共存する形でソフトウェアとして導入できる点がメリット。個人的には超簡易にBGPの検証を行う際にも使えるかと思っています。 本記事では、現在主流の2.0系を利用して、Ubuntu20.04上でBGPを動作させ、サーバと直接接続されたセグメントを広告+網側からの経路を受け取る機能を機能を持った簡易的なルータを動作させるところまで備忘録的にまとめています。 BIRD2.0導入手順 apt経由でBIRDをインストール $ sudo apt update $ sudo apt install bird2 BIRD設定 以下の設定例の通りに書き換え local AS: 65001(Ubuntu側の所属するAS) remote AS: 65002(対向側ルータの所属するAS) router id: 172.16.1.1(Ubuntu側のIPアドレス) neighbor ip: 172.16.1.2(対向側ルータのIPアドレス) bgp: (export): interface"eth0"のdirect経路のみ (import): すべて $ sudo vim /etc/bird/bird.conf /etc/bird/bird.conf log syslog all; router id 172.16.1.1; protocol device { scan time 10; } protocol kernel { scan time 10; ipv4 { export filter { if proto = "direct1" then reject; accept; }; }; } protocol direct direct1 { ipv4; interface "eth0"; } protocol bgp { ipv4 { import all; export all; }; local as 65001; neighbor 172.16.1.2 as 65002; } $ sudo systemctl restart bird # うまく行かない場合再起動 ステータス確認 $ sudo birdc >bird show protocol all # bgp neighborとの接続がESTABLISHEDになっているか show route # 経路配信、受領できているか [ctrl+c] $ ip route # birdによるbgpの経路がルーティングテーブルに乗っているか ip_forward設定 Ubuntuではデフォルトでルーティング機能が無効化されているため、 /etc/sysctl.conf 内の net.ipv4.ip_forward = 0をnet.ipv4.ip_forward = 1に変更 参考リンク サイボウズエンジニアのブログ ルーティングソフトウェア BIRD の使いかた BIRD - User's guide 2.0 BIRD - Wiki パケット転送をオンにする
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Linuxでのコード読み (vim/GNU global)

1. はじめに 比較的軽い環境でのコード読みを実現するためのvim/global環境設定をメモしておく。すでに同じような記事があちこちあるが、自分用のメモである。キーバインドはいろいろあるそうなので、徐々に増やす。 2. 環境設定 2.1. コマンド実行 以下のコマンドを実行する sudo apt update sudo apt install global mkdir -p .vim/plugin wget -P .vim/plugin https://raw.githubusercontent.com/harai/gnu-global/origin/gtags.vim 2.2. vim設定 .vimrcに以下の設定を追加する。 cat >> ~/.vimrc << "EOF" map <C-g> :Gtags map <C-h> :Gtags -f %<CR> map <C-j> :GtagsCursor<CR> nmap <C-k> :Gtags -r <C-r><C-w><CR> map <C-n> :cn<CR> map <C-p> :cp<CR> EOF 3. コード読み 3.1. コード作成 以下のコマンドで、該当コードに対してタグを作成する。 gtags -v 3.2. コード検索(vim内で) Ctrl + j 関数定義に移動する。 Ctrl + k 関数の使用場所を探す。 Ctrl + o カーソルを戻す。 Ctrl + n カーソルを下に動かす。 Ctrl + p カーソルを上に動かす。 Ctrl + w k 上のウィンドウへ移動する。 Ctrl + w j 下のウィンドウへ移動する。 A. 参考資料 GNU GLOBALとvimで巨大なコードでも快適にコードリーディング
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【数値解析入門】C言語で漸化式で解く Vol.1

実現したいこと 今回はC言語で漸化式と解く. この記事に掲載してあるソースコードは私のGitHubからダウンロードできます. 必要に応じて活用してください. 漸化式とは Wikipediaに漸化式について次のように書かれている. 数学における漸化式(ぜんかしき、英: recurrence relation; 再帰関係式)は、各項がそれ以前の項の関数として定まるという意味で数列を再帰的に定める等式である。 引用:Wikipedia 漸化式 数学の学問的な範囲でいうならば,高校数学Bの「数列」の範囲で扱うことになるので,知っている人も多いかと思う. 漸化式の2つの顔 漸化式は引用にも示したような,再帰的な方程式を用いて一意的に定義することができる. しかし,特別な漸化式において「一般項」というものが存在する.ただし,全ての漸化式においてこの一般項を定義したり求めることができるというわけではない. 基本的な漸化式 以下, $n \in \mathbb{N}$とする. 一般項が簡単にもとまるという点で,高校数学でも扱う基本的な漸化式は次の3パターンが存在する 等差数列の漸化式 等比数列の漸化式 階差数列の漸化式 それぞれの漸化式について順に書きたいと思います. 等差数列の漸化式 等差数列の漸化式は以下のような形をしています. $$a_{n+1}-a_{n}=d \;\;\;(d\,は定数)$$ これは等差数列の漸化式でありながら,等差数列の定義でもある. この数列の一般項は次ののようになる. 初項 $a_1$, 公差 $d$ の等差数列 $a_{n}$ の一般項は $$ a_{n}=a_1+(n-1) d $$ もし余裕があれば,証明を自分で確認して欲しい. 等比数列の漸化式 等比数列の漸化式は $$ a_{n+1} = ra_n \;\;\;(r\,は定数) $$ 等差数列同様,これが等比数列の定義式でもある.一般に$r \neq 0,1$を除く.もちろん,それらの場合でも等比数列といってもいいかもしれないが,初項を$a_1$に対して,漸化式から $r = 0$の場合, $$ a_1 ,0,0, \cdots $$ のように第2項以降が0になってしまうため,わざわざ,等比数列であると認識しなくてもよいかもしれない. $r = 1$の場合, $$ a_1 ,a_1,a_1, \cdots $$ なので,定数列となる.これは等比数列の特殊な場合と捉えるのが妥当かもしれない. とにかく先に進もう. ここで等比数列の一般項は 初項 $a_1$, 公比 $r$ の等比数列 $a_{n}$ の一般項は $$ a_{n}=a_1 r^{n-1} $$ である.これも自分で証明を確認されたい. 階差数列の漸化式 階差数列の定義は,数列$\{a_n\}$に対して隣り合う2つの項の差 $$ b_n = a_{n+1} - a_n $$ を項とする数列$\{b_n\}$を数列$\{a_n\}$の階差数列と定義する. 階差数列の漸化式は,$f(n)$を階差数列の一般項として,次のような形で表される. $$ a_{n + 1} = a_n + f(n) $$ そして階差数列の一般項は $$ a_n = \begin{cases} a_1 &(n=1) \newline a_1 + \displaystyle \sum^{n-1}_{k=1} b_k &(n\geqq2) \end{cases} $$ となる. これも証明を確認しよう. ここまで基本的な漸化式を紹介してきたが,これらをあえて数値解析で扱いたいと思う. 基本的な漸化式の数値解析 等差数列 次のような等差数列の$a_{100}$を求めよ. $$ \{a_n\} : 1,5,9,13,\cdots $$ ここではあえて一般項を用いず,ひたすら漸化式で第100項まで計算することにします. tousa/iterative.c #include <stdio.h> #define N 100 int main(void) { int an; an = 1; // 初項 for (int n = 1; n <= N; n++) { printf("a[%d] = %d\n", n, an); an = an + 4; } return 0; } 実行結果(一部)は次のようになる. result a[95] = 377 a[96] = 381 a[97] = 385 a[98] = 389 a[99] = 393 a[100] = 397 一般項の公式から求めても $a_{100} = 397$ なので正しく実行できていることがわかる. 実行結果としてはうまく行っているのでこれで終わりとしてもよいがこれではあまり面白くない. というのも,漸化式そのものが再帰的なものなので,再帰関数でこれを扱いたい. 再帰(さいき)は、あるものについて記述する際に、記述しているものそれ自身への参照が、その記述中にあらわれることをいう。 引用: Wikipedia 再帰関数 実際に再帰関数化したものは次のようになる. tousa/recursive.c #include <stdio.h> #define N 100 /* プロトタイプ宣言 */ int an(int n); int main(void) { for (int n = 1; n <= N; n++) printf("a[%d] = %d\n", n, an(n)); return 0; } /* 漸化式(再帰関数) */ int an(int n) { if (n == 1) return 1; else return (an(n - 1) + 4); } これも結果は先ほどの実行結果と同じようになる. 引数にnを受け取り,戻り値に$an(n-1) + 4$を返す. これぞ漸化式と言わんばかりの形をしている.私はこの書き方の方がしっくりくるが人それぞれかもしれない. 等比数列 次のような等比数列の$a_{10}$を求めよ. $$ \{a_n\} : 1,3,9,27,\cdots $$ これも,普通に書くと touhi/iterative.c #include <stdio.h> #define N 10 int main(void) { int an; an = 1; for (int n = 1; n <= N; n++) { printf("a[%d] = %d\n", n, an); an = an * 3; } return 0; } 実行結果は a[7] = 729 a[8] = 2187 a[9] = 6561 a[10] = 19683 となり,これもあっている. 再帰関数で表現すると, touhi/recursive.c #include <stdio.h> #define N 10 /* プロトタイプ宣言 */ int an(int n); int main(void) { for (int n = 1; n <= N; n++) printf("a[%d] = %d\n", n, an(n)); return 0; } /* 漸化式(再帰関数) */ int an(int n) { if (n == 1) return 1; else return (an(n - 1) * 3); } 階差数列 次のような階差数列の$a_{10}$を求めよ. $$ \{a_n\} : 6,11,18,27,38\cdots $$ 階差数列の定義にしたがって階差数列$(=b_n)$を考えると, $$ b_n = a_{n+1} - a_n $$ より, $$ \{b_n\} : 5,7,9,11\cdots $$ となるので,これで計算してみる. ちなみに一般項は $$ a_n = n^2 + 2n + 3 $$ である. kaisa/iterative.c #include <stdio.h> #define N 10 int main(void) { int an, bn; an = 6; bn = 5; for (int n = 1; n <= N; n++) { printf("a[%d] = %d\n", n, an); an = an + bn; bn = bn + 2; } return 0; } 実行結果は a[7] = 66 a[8] = 83 a[9] = 102 a[10] = 123 となり,一般項の値と一致する. 再帰で表現してみる. kaisa/recursive.c #include <stdio.h> #define N 10 /* プロトタイプ宣言 */ int an(int n); int bn(int b); int main(void) { for (int n = 1; n <= N; n++) printf("a[%d] = %d\n", n, an(n)); return 0; } /* 漸化式(再帰関数) */ int an(int n) { if (n == 1) return 6; else return (an(n - 1) + bn(n - 1)); } /* 漸化式(再帰関数) */ int bn(int n) { if (n == 1) return 5; else return (bn(n - 1) + 2); } これは再帰関数の中で再帰関数を呼び出しているので,沢山計算させていることになるが,これくらいはパソコンはなんなくやってくれるのが文明の利器といったところだろうか. おわりに 今回はここら辺で一旦区切ろうかと思う. ここで扱った内容はとても簡単だったかもしれないが,とても重要な概念なのでここでしっかりとイメージをつかみい. 自分の復習のためでもあり,学科の友達に共有するためにこの記事を書いている.続きも書く予定なので,ぜひチェックしていただけるとありがたい.
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【数値解析入門】C言語で漸化式で解く

実現したいこと 今回はC言語で漸化式と解く. この記事に掲載してあるソースコードは私のGitHubからダウンロードできます. 必要に応じて活用してください. 漸化式とは Wikipediaに漸化式について次のように書かれている. 数学における漸化式(ぜんかしき、英: recurrence relation; 再帰関係式)は、各項がそれ以前の項の関数として定まるという意味で数列を再帰的に定める等式である。 引用:Wikipedia 漸化式 数学の学問的な範囲でいうならば,高校数学Bの「数列」の範囲で扱うことになるので,知っている人も多いかと思う. 漸化式の2つの顔 漸化式は引用にも示したような,再帰的な方程式を用いて一意的に定義することができる. しかし,特別な漸化式において「一般項」というものが存在する.ただし,全ての漸化式においてこの一般項を定義したり求めることができるというわけではない. 基本的な漸化式 以下, $n \in \mathbb{N}$とする. 一般項が簡単にもとまるという点で,高校数学でも扱う基本的な漸化式は次の3パターンが存在する 等差数列の漸化式 等比数列の漸化式 階差数列の漸化式 それぞれの漸化式について順に書きたいと思います. 等差数列の漸化式 等差数列の漸化式は以下のような形をしています. $$a_{n+1}-a_{n}=d \;\;\;(d\,は定数)$$ これは等差数列の漸化式でありながら,等差数列の定義でもある. この数列の一般項は次ののようになる. 初項 $a_1$, 公差 $d$ の等差数列 $a_{n}$ の一般項は $$ a_{n}=a_1+(n-1) d $$ もし余裕があれば,証明を自分で確認して欲しい. 等比数列の漸化式 等比数列の漸化式は $$ a_{n+1} = ra_n \;\;\;(r\,は定数) $$ 等差数列同様,これが等比数列の定義式でもある.一般に$r \neq 0,1$を除く.もちろん,それらの場合でも等比数列といってもいいかもしれないが,初項を$a_1$に対して,漸化式から $r = 0$の場合, $$ a_1 ,0,0, \cdots $$ のように第2項以降が0になってしまうため,わざわざ,等比数列であると認識しなくてもよいかもしれない. $r = 1$の場合, $$ a_1 ,a_1,a_1, \cdots $$ なので,定数列となる.これは等比数列の特殊な場合と捉えるのが妥当かもしれない. とにかく先に進もう. ここで等比数列の一般項は 初項 $a_1$, 公比 $r$ の等比数列 $a_{n}$ の一般項は $$ a_{n}=a_1 r^{n-1} $$ である.これも自分で証明を確認されたい. 階差数列の漸化式 階差数列の定義は,数列$\{a_n\}$に対して隣り合う2つの項の差 $$ b_n = a_{n+1} - a_n $$ を項とする数列$\{b_n\}$を数列$\{a_n\}$の階差数列と定義する. 階差数列の漸化式は,$f(n)$を階差数列の一般項として,次のような形で表される. $$ a_{n + 1} = a_n + f(n) $$ そして階差数列の一般項は $$ a_n = \begin{cases} a_1 &(n=1) \newline a_1 + \displaystyle \sum^{n-1}_{k=1} b_k &(n\geqq2) \end{cases} $$ となる. これも証明を確認しよう. ここまで基本的な漸化式を紹介してきたが,これらをあえて数値解析で扱いたいと思う. 基本的な漸化式の数値解析 等差数列 次のような等差数列の$a_{100}$を求めよ. $$ \{a_n\} : 1,5,9,13,\cdots $$ ここではあえて一般項を用いず,ひたすら漸化式で第100項まで計算することにします. tousa/iterative.c #include <stdio.h> #define N 100 int main(void) { int an; an = 1; // 初項 for (int n = 1; n <= N; n++) { printf("a[%d] = %d\n", n, an); an = an + 4; } return 0; } 実行結果(一部)は次のようになる. result a[95] = 377 a[96] = 381 a[97] = 385 a[98] = 389 a[99] = 393 a[100] = 397 一般項の公式から求めても $a_{100} = 397$ なので正しく実行できていることがわかる. 実行結果としてはうまく行っているのでこれで終わりとしてもよいがこれではあまり面白くない. というのも,漸化式そのものが再帰的なものなので,再帰関数でこれを扱いたい. 再帰(さいき)は、あるものについて記述する際に、記述しているものそれ自身への参照が、その記述中にあらわれることをいう。 引用: Wikipedia 再帰関数 実際に再帰関数化したものは次のようになる. tousa/recursive.c #include <stdio.h> #define N 100 /* プロトタイプ宣言 */ int an(int n); int main(void) { for (int n = 1; n <= N; n++) printf("a[%d] = %d\n", n, an(n)); return 0; } /* 漸化式(再帰関数) */ int an(int n) { if (n == 1) return 1; else return (an(n - 1) + 4); } これも結果は先ほどの実行結果と同じようになる. 引数にnを受け取り,戻り値に$an(n-1) + 4$を返す. これぞ漸化式と言わんばかりの形をしている.私はこの書き方の方がしっくりくるが人それぞれかもしれない. 等比数列 次のような等比数列の$a_{10}$を求めよ. $$ \{a_n\} : 1,3,9,27,\cdots $$ これも,普通に書くと touhi/iterative.c #include <stdio.h> #define N 10 int main(void) { int an; an = 1; for (int n = 1; n <= N; n++) { printf("a[%d] = %d\n", n, an); an = an * 3; } return 0; } 実行結果は a[7] = 729 a[8] = 2187 a[9] = 6561 a[10] = 19683 となり,これもあっている. 再帰関数で表現すると, touhi/recursive.c #include <stdio.h> #define N 10 /* プロトタイプ宣言 */ int an(int n); int main(void) { for (int n = 1; n <= N; n++) printf("a[%d] = %d\n", n, an(n)); return 0; } /* 漸化式(再帰関数) */ int an(int n) { if (n == 1) return 1; else return (an(n - 1) * 3); } 階差数列 次のような階差数列の$a_{10}$を求めよ. $$ \{a_n\} : 6,11,18,27,38\cdots $$ 階差数列の定義にしたがって階差数列$(=b_n)$を考えると, $$ b_n = a_{n+1} - a_n $$ より, $$ \{b_n\} : 5,7,9,11\cdots $$ となるので,これで計算してみる. ちなみに一般項は $$ a_n = n^2 + 2n + 3 $$ である. kaisa/iterative.c #include <stdio.h> #define N 10 int main(void) { int an, bn; an = 6; bn = 5; for (int n = 1; n <= N; n++) { printf("a[%d] = %d\n", n, an); an = an + bn; bn = bn + 2; } return 0; } 実行結果は a[7] = 66 a[8] = 83 a[9] = 102 a[10] = 123 となり,一般項の値と一致する. 再帰で表現してみる. kaisa/recursive.c #include <stdio.h> #define N 10 /* プロトタイプ宣言 */ int an(int n); int bn(int b); int main(void) { for (int n = 1; n <= N; n++) printf("a[%d] = %d\n", n, an(n)); return 0; } /* 漸化式(再帰関数) */ int an(int n) { if (n == 1) return 6; else return (an(n - 1) + bn(n - 1)); } /* 漸化式(再帰関数) */ int bn(int n) { if (n == 1) return 5; else return (bn(n - 1) + 2); } これは再帰関数の中で再帰関数を呼び出しているので,沢山計算させていることになるが,これくらいはパソコンはなんなくやってくれるのが文明の利器といったところだろうか. おわりに 今回はここら辺で一旦区切ろうかと思う. ここで扱った内容はとても簡単だったかもしれないが,とても重要な概念なのでここでしっかりとイメージをつかみい. 自分の復習のためでもあり,学科の友達に共有するためにこの記事を書いている.
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Bash コマンド備忘録

Bash 備忘録 grepでコメント行と空行を表示しない ubuntu@ubuntu18.04$ grep -vE "^#|\s*#|^\s*$" /etc/nginx/nginx.conf user www-data; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf; events { worker_connections 768; } http { sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; ssl_prefer_server_ciphers on; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; gzip on; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } sed で(半角の)空白文字をアンダーバーに置換する echo -e "hoge huga \thage" >foo ubuntu@ubuntu18.04$ cat foo hoge huga hage ubuntu@ubuntu18.04$ sed -e 's/[[:space:]]/_/g' foo hoge_huga__hage 参考: https://qiita.com/richmikan@github/items/b6fb641e5b2b9af3522e 参考: https://ja.wikipedia.org/wiki/%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE 1時間以内にログインしたユーザ ※ログイン中のユーザは除く # lastlog -t 1|grep "$(date +'%-d %H' -d '1 hour ago')" root pts/5 Thu Aug 5 05:55:55 +0900 2019 2時間以内のユーザログインチェックはこんな感じ # lastlog -t 2 | grep -E "$(date +'%-d %H' -d '2 hour ago')|$(date +'%-d %H' -d '1 hour ago')|$(date +'%-d %H')"| grep -v "^root"| sed -e "s/\s*pts...\s*/ /g" ubuntu 127.0.0.1 Thu Aug 5 05:55:55 +0900 2019 簡易的に,(Comma)での文字列分割(変数展開とcut) #!/bin/bash moji="hoge,huga,hige" # hoge echo "${moji%%,*}" # huga echo "$(echo ${moji}|cut -d',' -f 2)" # hige echo "${moji##*,}" 実行結果 hoge huga hige IFS変更なしでもっと簡単なのないかな 1コマンド限定でIFS変更Ver(@angel_p_57 2021-04-16 12:43 ) moji="hoge,huga,hige" IFS=, read -a mojis <<< "$moji" echo "${mojis[0]}" echo "${mojis[1]}" echo "${mojis[2]}" Netcat Tips netcatでcurl代替 https://stackoverflow.com/questions/27745104/convert-curl-command-to-netcat
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Windows の GUI 操作を Linux の CLI で操作したい

Windows だとあーやったけど, Linux だとどーやるの? の簡易まとめ。 フォルダー (ディレクトリー) を作りたい。 mkdir <ディレクトリー名> で作れます。 Make Directories の略ですね。 $ mkdir test10 $ ls -l total 0 drwxrwxr-x. 2 vagrant vagrant 6 Apr 16 00:07 test10 フォルダー (ディレクトリー) を移動したい。 cd <ディレクトリー名> で移動できます。 Change the current Directory の略ですね。 $ cd test10 $ pwd /home/vagrant/hoge/test10 空のファイルを作りたい。 touch <ファイル名> で作れます。 $ touch test1.txt $ ls -l test1.txt -rw-rw-r--. 1 vagrant vagrant 0 Apr 16 00:07 test1.txt ファイルを切り取って貼り付けたい。(ファイルの移動) mv <ファイル名> <ディレクトリー名> で移動できます。 MoVe の略ですね。 $ mv test1.txt test10 $ ls -l test10/test1.txt -rw-rw-r--. 1 vagrant vagrant 0 Apr 16 00:07 test10/test1.txt ファイルをコピーしたい。 cp <コピー元> <コピー先> でコピーできます。 CoPy の略ですね。 $ cp test1.txt test2.txt $ ls -l test*.txt -rw-rw-r--. 1 vagrant vagrant 0 Apr 16 00:07 test1.txt -rw-rw-r--. 1 vagrant vagrant 0 Apr 16 00:09 test2.txt ショートカット (シンボリックリンク) を作りたい。 ln -s <リンク元> <リンク先> でリンクを作れます。 LiNk の略ですね。 -s はおまじない。 $ ln -s test2.txt test3.txt $ ls -l test*.txt -rw-rw-r--. 1 vagrant vagrant 0 Apr 16 00:07 test1.txt -rw-rw-r--. 1 vagrant vagrant 0 Apr 16 00:09 test2.txt lrwxrwxrwx. 1 vagrant vagrant 9 Apr 16 00:10 test3.txt -> test2.txt ファイルを削除したい。 rm <ファイル名> で削除できます。 ReMove の略ですね。 ただし, ゴミ箱に入るわけではなく, 完全に削除されます。 $ rm test4.txt ファイル名を変更したい。 mv <変更前ファイル名> <変更後ファイル名> で変更できます。 $ mv test2.txt test4.txt $ ls -l test*.txt lrwxrwxrwx. 1 vagrant vagrant 9 Apr 16 00:10 test3.txt -> test2.txt -rw-rw-r--. 1 vagrant vagrant 0 Apr 16 00:09 test4.txt ファイルのプロパティ (詳細) を見たい。 stat <ファイル名> で見れます。 $ stat test1.txt File: test1.txt Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 801h/2049d Inode: 16802907 Links: 1 Access: (0664/-rw-rw-r--) Uid: ( 1000/ vagrant) Gid: ( 1000/ vagrant) Context: unconfined_u:object_r:user_home_t:s0 Access: 2021-04-16 00:09:49.374640772 +0900 Modify: 2021-04-16 00:07:31.435894824 +0900 Change: 2021-04-16 00:07:31.435894824 +0900 Birth: - どっとはらい。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

バックグラウンドジョブがあるときだけプロンプトにジョブの数を表示する (bash)

プロンプト設定用の環境変数 PS1 に追記して、プロンプトの末尾にバックグラウンドジョブの数を表示するようにします。(ジョブ数0なら表示しません) 結論 .bashrc の PS1 を設定している部分より後に以下を追記します。 PS1=${PS1}'$([ \j -gt 0 ] && echo "[\j] ")' 実行するとプロンプトの末尾に [] でジョブ数が表示され、ジョブが無くなればうまく消えています。 動作環境 以下で動作確認しました。 WSL2 bash : GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu) Git bash : GNU bash, version 4.4.23(1)-release (x86_64-pc-msys) (bash ならどこでも動く?) 説明 bash に慣れていない人向けに、すこし丁寧に説明してみます。 変数 まず ${変数名} で変数を展開しています。なので以下は変数 PS1 に文字列 'str' を結合して再代入していることになります。 PS1=${PS1}'str' プロンプト用エスケープシーケンス PS1 ではプロンプト用のエスケープシーケンスが使えて、特にジョブ数は \j で参照できます。 以下のようにすればジョブ数を末尾に表示できます。 PS1=${PS1}'[\j] ' 条件分岐 ただ、このままではジョブが 0 個のときもジョブ数が表示されてしまい、少し邪魔な気がするので、0 より多いときのみ表示するように条件分岐することを考えます。 ジョブ数を見て条件分岐するワンライナーは次のように書けます。(プロンプト用なので、普通のコマンドラインでは動きません。) [ \j -gt 0 ] && echo \j 順番に見ると [ \j -gt 0 ] は \j が 0より大きい場合に1 (真) を返すテストコマンドです。 気持ち悪いですが、左括弧のあとにスペース・右括弧の前にスペースが無いと動きません。仕様です。 && はアンドで、左側が真の場合のみ右が実行されます。 echo は \j を文字列として返します。 これを PS1 に追加すれば良さそうですが、このまま文字列として追加するとコマンドと解釈されません。 $(command) $(command) を使うとカッコ内で実行したコマンドの出力を文字列として扱えます。したがって次のようにすれば上手く行きそうです。 が、まだ正しく動きません。 PS1=${PS1}$([ \j -gt 0 ] && echo \j) なぜなら $(command) 実行時点の出力が PS1 に保存されるため、\j がその時のジョブ数として解釈され、ジョブ数が変わってもプロンプトの表示が変わりません。 まとめ 毎度ワンライナーを評価させるには、$(command) を文字列として PS1 に追加すれば良いようです。 したがって最終的な式は以下の形になります。(見た目を整えるために echo の引数をいじりました。) PS1=${PS1}'$([ \j -gt 0 ] && echo "[\j] ")' 参考元 ググったらやりたいこととピッタリの記事が出ました。 https://stackoverflow.com/questions/12646917/show-job-count-in-bash-prompt-only-if-nonzero コピペすればいいところを手書きしてみたら$() のクォテーションを忘れるなどして割とハマり、そのおかげで知見が溜まったのでメモしました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Bashプロンプトにバックグラウンドジョブの数を表示する

プロンプト設定用の環境変数 PS1 に追記して、プロンプトの末尾にバックグラウンドジョブの数を表示するようにします。(ジョブ数0なら表示しません) 結論 .bashrc の PS1 を設定している部分より後に以下を追記します。 PS1=${PS1}'$([ \j -gt 0 ] && echo "[\j] ")' 実行するとプロンプトの末尾に [] でジョブ数が表示され、ジョブが無くなればうまく消えています。 動作環境 以下で動作確認しました。 WSL2 bash : GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu) Git bash : GNU bash, version 4.4.23(1)-release (x86_64-pc-msys) (bash ならどこでも動く?) 説明 bash に慣れていない人向けに、すこし丁寧に説明してみます。 変数 まず ${変数名} で変数を展開しています。なので以下は変数 PS1 に文字列 'str' を結合して再代入していることになります。 PS1=${PS1}'str' プロンプト用エスケープシーケンス PS1 ではプロンプト用のエスケープシーケンスが使えて、特にジョブ数は \j で参照できます。 以下のようにすればジョブ数を末尾に表示できます。 PS1=${PS1}'[\j] ' 条件分岐 ただ、このままではジョブが 0 個のときもジョブ数が表示されてしまい、少し邪魔な気がするので、0 より多いときのみ表示するように条件分岐することを考えます。 ジョブ数を見て条件分岐するワンライナーは次のように書けます。(プロンプト用なので、普通のコマンドラインでは動きません。) [ \j -gt 0 ] && echo \j 順番に見ると [ \j -gt 0 ] は \j が 0より大きい場合に1 (真) を返すテストコマンドです。 気持ち悪いですが、左括弧のあとにスペース・右括弧の前にスペースが無いと動きません。仕様です。 && はアンドで、左側が真の場合のみ右が実行されます。 echo は \j を文字列として返します。 これを PS1 に追加すれば良さそうですが、このまま文字列として追加するとコマンドと解釈されません。 $(command) $(command) を使うとカッコ内で実行したコマンドの出力を文字列として扱えます。したがって次のようにすれば上手く行きそうです。 が、まだ正しく動きません。 PS1=${PS1}$([ \j -gt 0 ] && echo \j) なぜなら $(command) 実行時点の出力が PS1 に保存されるため、\j がその時のジョブ数として解釈され、ジョブ数が変わってもプロンプトの表示が変わりません。 まとめ 毎度ワンライナーを評価させるには、$(command) を文字列として PS1 に追加すれば良いようです。 したがって最終的な式は以下の形になります。(見た目を整えるために echo の引数をいじりました。) PS1=${PS1}'$([ \j -gt 0 ] && echo "[\j] ")' 参考元 ググったらやりたいこととピッタリの記事が出ました。 https://stackoverflow.com/questions/12646917/show-job-count-in-bash-prompt-only-if-nonzero コピペすればいいところを手書きしてみたら$() のクォテーションを忘れるなどして割とハマり、そのおかげで知見が溜まったのでメモしました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む