実験環境:Ubuntu18.04 リモートサーバー + WSL2 ローカル
機能要件#
最終成果#
上記の機能を実現した上で、【リアルタイム株データ、最終ログイン時間、今月の総使用時間】を追加し、一定の耐障害性【Shell 判断、API 呼び出し失敗時のデフォルト値返却】を持ち、いくつかの試すべき機能もあり、文末に記載【歴史上の今日、拒否された訪問者、最終ログイン時に入力したコマンドの統計、ターミナルで画像を表示】
- em.. 今日はどうやら良い日ではないようです、株式市場は赤です:)
——> 以下、時間を巻き戻す <——
実現プロセス#
【まずは接続先ホストのデフォルトメッセージを見てみましょう】
- これらのメッセージは不要です、すべてを最初からやり直し、完全に自分で [あちこちから寄せ集めた] メッセージ通知を作成します
初期起動情報の削除#
上記の情報をどうやって取り除くのでしょうか?
- 高名な [宿船長] の指導を受け、「/etc/update-motd.d を探してみて」と言われ、vim update-motd.d を表示すると以下のようになります:
- 最初はファイルだと思っていましたが... 各ファイルを開くと上記のログイン情報に対応しています
- ここで motd の意味は message of the day—— 今日のメッセージです
- それは毎回ログイン時に更新されることもあれば、事前に保存されて変わらないこともあります
- man 5 update-motd を参照できます。こちらはMOTD とは?-cnblogs を参照
- その中で言及されています:MOTD の出力は pam というサービスの login モジュールによって管理されており、sudo vim /etc/pam.d/login で motd に関連する機能をコメントアウトしましたが、しかし効果がありませんでした
- 実は /etc/pam.d/login はローカルログインを制御するためのもので、私は SSH でログインしているため、別の設定ファイル /etc/pam.d/sshd があります
- Disable everything in update-motd.d dir in ubuntu server-StackExchange を参照
- SSH 接続後のログインメッセージを無効にしたいので、sudo vim /etc/pam.d/sshd に入ります
- motd に関連する機能をコメントアウトします
- 私が無効にしたいのは update-motd.d の表示メッセージで、動的情報に属するので、33 行目をコメントアウトすれば良いです
- 静的メッセージのソースである /etc/motd はホスト上に存在しないので、無視しても構いません
【ホストに再接続すると、すっきりしました】
- しかし、Last login 情報がまだ残っています
- これは sshd によって制御されているので、sshd の設定ファイルを見つけます
- sudo vim /etc/ssh/sshd_config で PrintLastLog を no に設定します
- その後、sshd サービスを再起動して効果を発揮させます。sudo service sshd restart [見覚えがあります]
【これで、解放前に戻りました】
前期準備#
起動時に実行されるファイルを見つける#
【zsh 起動設定ファイルを使用】
Shell:zsh
- man zsh で FILES を検索し、zsh の起動設定ファイルを確認します。たくさんあります
- 文脈に応じて、.zlogin を使用します
- ホームディレクトリに.zlogin を作成し、vim ~/.zlogin
最近のログイン回数 [今月]#
【今月のログイン:40 回】
【last を通じて取得】
- 現在のユーザー
- who am i の最初の要素を切り取ります:who am i | cut -d " " -f 1
- USER 環境変数を取得します:env | grep USER | cut -d "=" -f 2
- last でログイン情報を取得→現在のユーザーのログイン情報を検索してカウントします
last | grep -c `env | grep USER | cut -d "=" -f 2`
[PS] より多くの情報を表示するには:
- /var/log/wtmp.x、x ∈ [0-9]
- How to read older login info using the “last” command?——StackExchange を参照
最後の滞在時間 [今月]#
【最後の滞在:01 時間 03 分】
【last を通じて取得】
- last でログイン情報を取得→そのユーザーのログイン情報を見つける→「()」形式の接続時間の行をマッチさせる→最近のものを取得する→「 ( 」と「) 」で切り取って最後の滞在時間を得ます、
- 時間形式は時間:分
- AWK - 正規表現—— 簡単なチュートリアルを参照
last | grep `env | grep USER | cut -d "=" -f 2` | awk '/\(*\)/' | head -1 | cut -d "(" -f 2 | cut -d ")" -f 1
名言の API を探す#
【名言表示】
【出典:名言——Free API】
- 毎日最大 100 回申請可能
- curl リクエストを通じて:curl https://v1.alapi.cn/api/mingyan
- 戻り値の形式:json
- オプションのパラメータ:typeid [1~45]
- ランダムに取得した json データは以下の通りです:
【jqを使用して json データを処理】
- sudo apt install jq でインストールします
- 以下のコマンドを使用します
curl -s https://v1.alapi.cn/api/mingyan | jq '.data | [.content, .author]' | jq 'join("————")'
- jq tutorial(簡単な使用法)、jq manual(詳細な操作)を参照
- また、Shell スクリプトを使用して JSON を処理する—— ブログを参照
- awk や sed コマンドを使用して異なる json データを処理することもできますが、ここでは強力な jq を使用することでより強い堅牢性を持ちます
地元の当日の天気予報 API を探す#
【天気表示】
【出典:wttr.in——Github】
- 一行で出力でき、より簡潔です
- カスタマイズ可能なパラメータは以下の通りです:
- 主に位置、天気アイコン、体感温度、夜の月の形を表示し、以下のコマンドを呼び出します
curl wttr.in/\?format="%l:+%c+%t+feels+like+%f,+moon+tonight:+%m\n"
温かい挨拶を設定#
【挨拶、ランダムな色】
- sudo apt install figlet でインストールできます
- [フォントライブラリの拡張]figlet-fonts——Github、git clone 後、すべてのファイルを /usr/share/figlet/ に置きます
- showfigfonts "Hey Double" を使用して、Hey Double のすべてのフォントデモを確認できます
- figlet のオプションは多く、以下の通りです:
- 自分の好きなスタイルを選ぶために組み合わせてみてください。私の組み合わせ:figlet -t -r Hey Double -f miniwi
- さらに lolcat を使用して挨拶に色を付けます:sudo apt install lolcat でインストールできます
- 以下のコマンドを使用します
figlet Hey Double -f miniwi | lolcat
figlet -t -r You\'re back -f miniwi | lolcat
スクリプト制作 [含色の最適化]⭐#
~/.login.sh#
- 【重要】jq、awk、sed の使用にあります
- curl が期待通りの結果を返さない場合、保護メカニズムを作成します
- 一部の境界や配列、変数の操作については、今後さらに考慮します
- ⭐zsh、bash の互換性に注意
- zsh では:配列のインデックスは 1 から始まり、特殊記号は必ずエスケープ❗
- [PS]
- 追加された機能【リアルタイム株データ、最終ログイン時間、今月の総使用時間】は文末に記載 —— 追加部分
- 株データの appkey と sign は公式サイトで自分のものを生成する必要があります
.zlogin#
- ⭐スクリプトを source で呼び出すのではなく、Shell の種類に応じて zsh/bash [デフォルトは bash] を使用します。なぜなら
- この起動スクリプトは表示するためだけに使用され、環境変数を追加する必要はありません
- zsh/bash を使用すると、サブシェルでスクリプトが実行され、source を使用すると現在のシェルで実行され、スクリプト内で追加された変数は環境に反映されます [set でローカルに定義されたすべての環境変数を確認できます]
【考察】source と bash でスクリプトを呼び出す違い#
- bash と source スクリプトの結果は一致せず、前回のテストは bash を使用していましたが、起動スクリプトは source を使用して実行され、現在のシェル ——zsh で実行されます
- 起動時の表示は以下の通りです
- set -x を使用してスクリプトデバッグを有効にすると、完全なプロセスが表示されます
- 左側がコード、右側がデバッグ結果です
- index 変数が空になっているのがわかります!
- 【①】実は zsh と bash の間で、いわゆる【配列の開始インデックス】の不一致の問題です
- そこで、スクリプトを実行するシェルを判断することを考えます
- ${SHELL} を使用して判断することは効果がなく、zsh では source でも bash でも /usr/bin/zsh を指します
- しかし、別の検出方法があります
- How to get shell to self-detect using zsh or bash——Stackoverflow を参照
- 【また】以下の方法を参考にして、配列要素の奇門絶技を呼び出す?未試行ですが、上記の方法は有効です🆗
- Behavior of Arrays in bash scripting and zsh shell (Start Index 0 or 1?)——Stackoverflow を参照
- 【②】配列インデックスの問題が解決されたら、zsh の他の互換性の問題にも注意が必要です
- ❗ 特殊記号、ここで jq の後の [] はエスケープ文字 \ を使用する必要があります
【参考】
- Shell コマンド置換:コマンドの出力結果を変数に代入する——C 言語中文網
- $() はネストをサポートし、バッククォートはサポートしません
- $() は Bash でのみ有効で、バッククォートは多くの Shell で使用できます
- Shell で文字列を切り取る方法——CSDN
- ⭐arr=(${parameter//pattern/string})
- echo args | tr "oldSpilt" "newSpilt"
- awk 入門チュートリアル—— 阮一峰
- awk フォーマット印刷—— 易百教程
- Shell source コマンド:環境変数設定ファイルを強制的に有効にする——C 言語中文網
追加#
世界の株式指数#
curl http://api.k780.com/\?app=finance.globalindex\&inxids=1010,1011,1013\&appkey=あなたのkey\&sign=あなたのsign | jq .
最後のログイン時間#
- last
last | grep `env | grep USER | cut -d "=" -f 2` | awk '/\(*\)/' | head -1 | awk '{printf "%s %s %s —— %s", $4, $5, $6, $7}'
- 改善の余地があり、切り取り方法が硬直的です
今月の総使用時間#
ac | awk '{print int($NF)}'
- ac コマンド:ユーザーの接続時間データを表示
- ac そのユーザーの今月の総使用時間
- ac -d そのユーザーの今月の毎日の接続時間
- ac コマンドの詳細解説——commandnotfound を参照
—— 試してみる ——#
歴史上の今日#
curl http://api.juheapi.com/japi/toh\?key=あなたのkey\&v=1.0\&month=11\&day=1
- 何件の記録があるかを統計
curl -s http://api.juheapi.com/japi/toh\?key=あなたのkey\&v=1.0\&month=1\&day=1 | jq '.result | length'
- その中の 1 件をランダムに出力
- 0~N のランダム数を生成
$(( ${RANDOM} % ${N} ))
拒否された訪問者の数#
- 最後のログインから現在まで、何回の失敗したログイン記録があるか
sudo lastb
- sudo 権限が必要で、スクリプトにパスワードを埋め込むのは安全ではありません
最後のログイン時に入力したコマンドの統計#
【history を通じて統計】
- 何件のコマンドを入力したか
- どのコマンドがあなたのお気に入りか
- よく間違えるコマンドは何か
見たところ、かなり時間がかかりそうです
参考資料#
- ターミナルで画像を表示するには、termpix——Github を参照
- curl の使い方ガイド—— 阮一峰
- Free API インターフェース大全
- NowAPI
- Linux の文字インターフェースで天気予報を取得する—— 知乎
- Is there a reason why the first element of a Zsh array is indexed by 1 instead of 0?——StackExchange
- Bash の配列インデックスは 0 から始まり、zsh は 1 から始まります
- Linux で SSH ログインの導入を設定する [静的情報:バナー、motd]—— ブログ