vim で 読み取り専用ファイルを強制保存する
1. sudo で開いた場合
1) sudo vim filename
2) 編集する
3) :wq
2. sudo なしで開いた場合編集→コマンドモードで強制保存
1) vim filename
2) 編集する
3) :w !sudo tee %
- w: 内容を保存する
- !sudo tee: 「:w」の内容を「!sudo tee」で受け取ることができる
- %: 現在のファイル名を指定する
4) q!
SSH接続でタイムアウトによる自動切断を防ぐ
サーバー:さくらVPSサーバー(Debian 10.6)
クライアント:macOS catalina 10.15.7
Macで一定期間何もせずにいると、タイムアウトにより、さくらVPSサーバーへのSSH接続が自動的に切断されます。
これを防ぐための覚書です。
1. クライアント側の設定
sshd サーバと応答確認する間隔 ServerAliveInterval を設定する。
ServerAliveInterval のデフォルト値は0で、デフォルトでは応答確認しないようになっている。
~/.ssh/config または /etc/ssh/ssh_config に
ServerAliveInterval 60
設定した60秒ごとにサーバにメッセージを送り応答がないと、ServerAliveCountMax の回数(デフォルト値: 3)まで繰り返す。
サーバが応答しなくなった180秒後にタイムアウトする。
2. サーバ側の設定
sshd サーバ側でも同じ設定をすることができる。
Rubyの二次元配列
これは「フィヨルドブートキャンプ Part 1 Advent Calendar 2020」の7日目の記事です。
昨日は、Sakiさんの 「初めて輪読会をやってみたらいいことばかりだったので、良かったことをまとめました 」でした。
Part. 2 もあります。
私はWebエンジニアに転職したいと思い、現在フィヨルドブートキャンプで学んでいます。
そのフィヨルドブートキャンプで、Advent Calendarの企画が立ち上がりました。
私はAdvent Calendarに参加するのは初めてなのですが、アウトプットを現在意識しているため書いてみることにしました。
とはいえ、Rubyのプラクティスに入ったばかりで何を書いたらいいのか迷いました。
先日、Unixのcalコマンド(カレンダー表示)をRubyで実装するプラクティスを行った際に、Rubyにおける二次元配列について少し調べたので、そのことを書くことにしました。
カレンダーつながりですね!☺️
Ruby初心者ですので、暖かい目で読んでいただけると助かります。
一次元配列
まず、一次元配列から考えます。
(参考:「スラスラ読める Rubyふりがなプログラミング」「ゼロからわかる Ruby 超入門」)
配列は要素として複数のオブジェクトをまとめて扱うクラスです。
オブジェクトとして、数値や文字列を扱います。
そして、配列自身もまた、オブジェクトです。
オブジェクトの種類のことをクラスと言います。
作成
配列を作成します。
wdays = ["月", "火", "水", "木", "金", "土", "日"]
要素を取得する
配列内の要素を取得する時は、インデックス(添え字)を使います。
puts wdays[2]
とすると
と表示されます。
配列全体を表示する時は、
puts wdays
とすると、
と各要素が縦に表示されます。
要素書き換え
配列の要素を書き換える時は、
wdays[1] = "雨"
puts wdays
とすると
と配列の要素が変わっています。
その他のメソッド
配列はArrayというクラスの一つで、元々色々便利なメソッドが備わっています。
(参考 Ruby 2.7.0 リファレンスマニュアル>ライブラリ一覧>組み込みライブラリ>Arrayクラス)
Arrayクラスの主なメソッド
メソッド | 働き |
---|---|
配列.first | 配列の最初の要素を返す |
配列.last | 配列の最後の要素を返す |
配列.push(要素) | 配列の末尾に要素を追加する |
配列.unshift(要素 | 配列の先頭に要素を追加する |
配列.delete(値) | 配列から値と一致する要素を全て削除する |
配列.shift | 配列の先頭から要素を1つ削除し、削除した要素を返す |
配列.pop | 配列の末尾から要素を1つ削除し、削除した要素を返す |
配列1 + 配列2 | 2つの配列の要素をつなげた配列を作る |
配列1 - 配列2 | 配列1から配列2の要素を削除した新しい配列を作る |
配列.size | 配列の要素数を返す |
配列.sum | 配列の全要素の合計を返す |
配列.sample | 配列からランダムに要素を取得する |
配列.shuffle | 配列をランダムに並び換える |
配列.sort | 配列の要素を順に並び換える(数値:小さい順、文字列:abc順) |
配列.sort.reverse | 配列の要素の並びが逆順になる(数値:大きい順、文字列:cba順) |
配列.join | 配列中の文字列を連結する |
初めから色々揃っていて便利ですね!
例1:deleteメソッド
例えば、deleteメソッドを使ってみます。
wdays.delete("雨")
puts wdays
"雨"が消えています!
例2:revereseメソッド
reverseメソッドがややこしかったので詳しく書きますと、
① 要素が数値の場合
p [4, 2, 8].sort
p [4, 2, 8].sort.reverse
p[4, 2, 8].reverse
reverseだけだと、先頭だけ逆順になり、全体はうまく並ばないので注意が必要です。
reverseだと、ただひっくり返った逆順になります。
(指摘していただき訂正しました! 2020.12.08)
② 要素が文字列の場合
p ["midori", "aka", "kiiro"].sort
p ["midori", "aka", "kiiro"].sort.reverse
p["midori", "aka", "kiiro"].reverse
reverseだけだと、同様に、先頭だけ逆順になり、全体はうまく並ばないので注意が必要です。
reverseだと、同様に、ただひっくり返った逆順になります。
(指摘していただき訂正しました! 2020.12.08)
例3:joinメソッド
joinメソッドは、配列の各要素をつなげるだけでなく、つなげるときに間へ入れる文字を指定できます。
puts ["空", "海", "太陽"].join("と")
二次元配列
配列は複数のオブジェクトを要素として扱うことができる。
配列自身もまたオブジェクトである。
それなら、配列の中で配列を要素として持てるはず…。
ということで、Rubyでは二次元配列も可能になっています。
しかし、どうやって作ればいいのだろう…。
calendar = [["1月1日", "1月2日", "1月3日"], ["2月1日", "2月2日", "2月3日"], ["3月1日", "3月2日", "3月3日"]]
とすれば初期化された二次元配列を作成することができ、
puts calendar[0][2]
puts calendar[2][1]
とすれば、各要素を表示することがわかりました。
でも、宣言はどうやってするのだろう...?
色々調べた結果、配列の宣言と初期化はnewメソッドを使えばできるようです。
calendar = Array.new(3, " 月 日")
calendar[2] = "2月1日"
puts calendar
できています!
それでは、二次元配列は、配列の中に要素として配列を持つのだから、こう書けばいいのかしら…
calendar = Array.new(3, Array.new(3, 0))
p calendar
calendar[0][1] = 2
puts calendar
…残念。初期化はうまくいっていますが、[0][1]要素に代入したことにより、[0][1]、[1][1]、[2][1]全ての要素が変化しています。
この書き方だと、[0]、[1]、[2]の要素が全て同じ配列オブジェクトを参照するようになっているようです。
(参照:Rubyで二次元配列の初期化)
それでは、どう書けばいいかというと、結論は、
calendar = Array.new(3) { Array.new(3, 0) }
とし、Array.newにブロックを渡せば、0で初期化された3x3の二次元配列を作成することができるとわかりました。
p calendar
calendar[0][1] = 2
puts calendar
初期化がうまくいっていて、代入した後も、[0][1]要素しか変化していません!
Rubyの標準ライブラリには多次元配列はなく、配列をネストすることで代用できます。特定の値で初期化するには、ブロック付きで「Array#new」を使用します。
ただし、ネストした配列は代用品に過ぎず、範囲を超えたインデックスに代入したときに問題があります。本書では「擬似多次元配列」と呼ぶことにします。
数値計算が目的ならばNArrayクラスを、行列計算が目的ならばMatrixクラスやVectorクラスを使用しましょう。
(参考:「改訂2版 Ruby逆引きハンドブック」)
ここまでたどりつくのが結構大変でしたので、ブログ記事に残すことができて良かったです!
Rubyのインストール
macにはrubyが既にインストールされている。
しかし、プロジェクト毎に使うRubyのバージョンは違うため、複数のRubyをインストールしておき、rbenvを使って切り替える必要がある。
使用環境 macOS catalina10.15.7
1. Command line tools
Homebrewを使うために必要。
XCode(iOS/MAC OS用アプリの統合開発環境 6GB程ある)をMac App Storeからインストールすると中に含まれているが、容量が大きいのでこちらの方法で行う
- Command line toolsをインストール
xcode-select --install
参考資料
Rails Girls インストール・レシピ
MavericksでCommand Line Tools for Xcodeをインストールする - Qiita
Xcodeをインストールする方法【iOSアプリの統合開発環境】 | TechAcademyマガジン
2. Homebrew
MacOS用のパッケージ管理システム(Package Manager)
rbenvをインストールするために必要
- Homebrewをインストールする
/user/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew doctor
Homebrewに問題がないか確認
Your system is ready to brew
と表示されればOKbrew update
Homebrewをアップデートし最新パッケージリストを取得する
Already up-to-date.
と表示されればOKbrew search パッケージ名
パッケージを検索するbrew install パッケージ名
パッケージをインストールするbrew uninstall パッケージ名
パッケージをアンインストールするbrew list
インストールされたパッケージのリストを表示するbrew upgrade
Homebrewのアップデートに加えて、Homebrewでインストールしたパッケージのアップデートも行うbrew -v
Homebrewのバージョンチェック/user/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"
Homebrewとインストールしたパッケージのアンインストール
参考資料
MacにHomebrewを導入する方法 - Qiita
https://qiita.com/3yatsu/items/47470091277d46f3fde2
Command Line Tools のインストール
brewのupdateとupgradeの違い - Qiita
【簡単】MacにHomebrewをインストールする方法と基本的な使い方|新卒エンジニアの開発日記
3. rbenv
異なったバージョンのRubyを切り替えるソフトウェア
- rvenvをインストール
ruby-build(Rubyをインストールするrvenvのプラグイン)も同時にインストールされる
brew install rbenv
- シェルにrbenvを設定する(rbenvを使い始める準備をするが 、ターミナルを開く毎に必ず実行する必要があるので、シェルの設定ファイルに追記する)。
rbenv init
- ~/.zshrcに
eval "$(rbenv init -)"
を加える
- シェルを再起動する
- 適切にrbenvが設定されたか確認する
curl -fsSL https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-doctor | bash
- 公開されているRubyの安定版バージョンを表示する。
rbenv install -l
- Ruby公式サイトでもRubyの安定版最新バージョンを確認する。
- Rubyの安定版最新バージョンをインストールする
rbenv install 2.7.2
- Rubyの他の使いたい安定版バージョンをインストールする
rbenv install 2.6.6
- インストールされrbenvが知ってい全Rubyバージョンを表示する
現在アクティブなRubyバージョンには*が付いている
rbenv versions
- 現在アクティブなRubyバージョンを表示する
rbenv version
またはruby -v
- 使用するRuyのバージョンを切り替える
rbenv global 2.7.2
rbenv global と rbenv localの違い
fjordbootcampで質問し、回答いただき理解したことをまとめました。
rbenv global : 全体で有効になる
- 使用例
- 原則として安定版の最新バージョンのRubyを指定する
確認方法
- インストールされているRubyの各バージョンを確認
- 現在設定されているRubyの全体バージョンを確認する (「~/.rbenv/version」は全体バージョンの設定ファイル)
- rbenv globalでRubyの全体バージョンを変更する
- Rubyのバージョンが変わったことを確認する
rbenv local : 今いるディレクトリだけで有効になる
- 使用例
- プロジェクト毎に設定して、「このプロジェクトで使うRubyのバージョンはこれ」と固定する
確認方法
- 新しいディレクトリを作成し移動する
- 現在のRubyのバージョンを確認する(まだ、globalで設定されたバージョンが有効になっている)
- rbenv localでこのディレクトリでのRubyのバージョンを変更する 「.ruby-version」ファイル(このディレクトリだけで有効なバージョンが書き込まれている)が作成されている
- このディレクトリのRubyのバージョンが変更されたことを確認する
- homeディレクトリに戻り、Rubyの全体バージョンは変わっていないことを確認する
- new_dirに戻り、「.ruby-version」ファイルを消すと、new_dirディレクトリも再びRubyの全体バージョンに依存するようになる
参考資料
rbenv/rbenv: Groom your app’s Ruby environment
パッケージ管理システム Homebrew
Mountain Lion に rbenv を導入 - hrysd の旧ブログ
RVMからrbenvに乗り換えてRuby2.0.0-p0を入れる - 納豆には卵を入れる派です。
【macOS Sierra】Mac OSX 10.12 macOS Sierra にRuby + Rails4 開発環境の構築 【初心者必見】 - Qiita
Homebrew + rbenv 環境の Ruby を 2.1.0 に変更する | deadwood
Ruby バージョン変更に苦戦 | goemonhanaのブログ
標準入出力・リダイレクション・/dev/null・パイプ
ファイル(file)
コンピュータ上で記録・管理される情報の単位。UNIX/ Linux, Windows, Mac OS X等ほとんどのコンピュータシステムは、ファイルによるデータ管理を行っている。
標準入出力
コマンド(その実体であるプログラム)には、何らかの入力と出力がある。これを標準入力、標準出力と呼ぶ。
リダイレクション(re-direction)
通常、標準入出力はキーボードとディスプレイに結び付けられている。しかし、この結びつきを変更することができる。これをリダイレクションと呼ぶ。
標準入出力の数値
入出力チャンネル | 数値 |
---|---|
標準入力 | 0 |
標準出力 | 1 |
標準エラー出力 | 2 |
コマンド < ファイル名
標準入力の入力元をキーボードではなくファイルに変更。コマンド > ファイル名
標準出力の出力先をディスプレイではなくファイルに変更。出力先のファイルが既存だった場合には、ファイルの先頭から結果を書き込む。コマンド >> ファイル名
標準出力の出力先をディスプレイではなくファイルに変更。出力先のファイルが既存だった場合には、ファイルの末尾に書き足す。コマンド < 入力元ファイル名 > 出力先ファイル名
または
コマンド > 出力先ファイル名 < 入力元ファイル名
入出力の両方を変更する。コマンド 2> ファイル名
標準エラー出力の出力先をディスプレイではなくファイルに変更。出力先のファイルが既存だった場合には、ファイルの先頭から結果を書き込む。コマンド > ファイル名 2> エラーファイル名
標準出力と標準エラー 出力をそれぞれ別のファイルにリダイレクト。コマンド > ファイル名 2>&1
または
コマンド &> ファイル名
標準出力と標準エラー出力を1つのファフィルにまとめてリダイレクト。
/dev/null
スペシャルファイル。入力先として指定しても何も内容を返さない。出力先として指定しても、書き込んだデータはどこにも保存されずに消えてなくなる。
- コマンド < /dev/null
- 標準入力を空っぽにする(コマンドのテスト)
- ls /xxxxx > /dev/null
- 標準出力を捨てる(コマンドの表示結果が大量にあり、標準エラー出力に表示されるエラーメッセージだけを読みたいとき)
- ls /xxxx 2> /dev/null
- エラーメッセージを非表示にしてコマンドの通常の出力結果だけを読み取る(エラーメッセージが大量に出るとき、あらかじめわかっているエラーメッセージが表示されるとき)
- ls /xxxx > /dev/null 2>&1
- 標準出力と標準エラー出力を両方とも捨てる(あらかじめわかっている不要なメッセージを非表示にするとき、コマンドの実行時間を測る際メッセー出力を抑止したいとき)
パイプ
あるプログラムの標準出力を、他のプログラムの標準入力に接続すること。
コマンド | コマンド
参考資料
新しいLinuxの教科書(三宅秀明・大角祐介著) 標準入出力とパイプライン
stdio.pdf
Redirection( Shell )
参考:Linuxでのパイプの活用方法
MacからDebian(さくらVPSサーバー)にssh接続する
ssh接続の設定が初心者には難しかったので備忘録を残します。
サーバー:Debian10.6
クライアント:macOS catalina10.15.7
1. (Macから)(Debianに)ssh接続をパスワード認証で行う
まずはいったんパスワード認証で接続する(後にパスワード認証は無効にする)。
ssh root@xxx.xxx.xx.xxx
rootではデフォルトで拒否される(さくらVPSの場合)ssh -l username xxx.xxx.xx.xxx
一般ユーザーでは認証される
参考資料
ネコでもわかる!さくらのVPS講座 ~第二回「サーバーをさわってみよう!」 | さくらのナレッジ
2. (Debianで)sshサーバーの設定を変更して、rootで直接アクセスできないようにする
root権限で大切なファイルを消してしまうのを避けるため。
cd /etc/ssh
cp sshd_config sshd_config.old
vim sshd_config
#PermitRootLogin yes
→PermitRootLogin no
sudo systemctl restart ssh
sshdの再起動
3. (Debianで)sshサーバーのポート番号を変更する
セキュリティーホールを探す検索ロボットによる攻撃を避けるため。
cd /etc/ssh
cp sshd_config sshd_config.old
`vim sshd_config
#Port 22
→Port xxxxx
xxxxxは新しいポート番号
(ポート番号は0~65535番まであるが、0~1023のウェルノウンポートは避ける)(できるだけ大きい番号の方がいい)sudo systemctl restart ssh
sshdの再起動
設定の確認
- ssh -p xxxxx -l username xxx.xxx.xx.xxx
- ssh -p 22 -l username xxx.xxx.xx.xxx
22番ポートではログインできない
参考資料
ウェルノウンポート(well-knownポート)とは - IT用語辞典 e-Words
SSHのポート番号を変更 - SSHサーバーの設定 - Linux入門 - Webkaru
4. (Macから)(Debianに)ssh接続を鍵認証で行う
セキュリティーホールを探す検索ロボットが適当なパスワードを入れて検索しているので、パスワード認証を無効にするため。
1) (Debianで).sshディレクトリを作成する
mkdir ~/.ssh
chmod 700 ~/.ssh
2) (Macで)RSA鍵を作成する
ssh-keygen -t rsa
パスワード不要ならEnterls ~/.ssh
作成した鍵を確認する
3) (Macで)作成した公開鍵をDebianに送る
scp -P xxxxx ~/.ssh/id_rsa.pub username@xxx.xxx.xx.xxx:~/.ssh/authorized_keys
4) (Debianで)受け取った公開鍵のパーミッションを変更する
cd ~/.ssh
chmod 600 authorized_keys
所有者(自分のアカウント)だけが読み書きできる
5) (Macで)公開鍵でパスワードなしでssh接続できるか確認する
-ssh -p xxxxx username@xxx.xxx.xx.xxx
6) (Debianで)ssh接続を公開鍵認証のみにし、パスワード認証を不許可にする
-cd /etc/ssh
-cp sshd_config sshd_config.old
-vim sshd_config
-#PasswordAuthentication yes
→PasswordAuthentication no
-sudo systemctl restart ssh
sshdの再起動
参考資料
Mac OS X から Linuxサーバ へ、RSA 鍵を用いて SSH 接続する - joker8phoenix's diary
初期設定
Debianで使うaptコマンド(インストール)
apt(Advanced Packaging Tool)は、パッケージと呼ばれるコンパイル済みバイナリファイルのアーカイブを、パッケージ管理システムを利用してリポジトリからインストールするコマンドである。
apt-cache search vim
vimパッケージを検索するsudo apt-get install vim
vimパッケージをインストールするsudo apt upgrade vim
vimパッケージを更新するsudo apt-get remove vim
vimパッケージを削除する。依存性のあるパッケージも自動的に削除されるsudo apt edit-sources
/etc/apt/sources.listにパッケージの入手先を追加する(直接編集するのではなく、apt edit-sourcesを使って編集すると書式を自動的にチェックできる)Devian 10/Busterのsources.listのデフォルト
deb http://ftp.jp.debian.org/debian buster main contrib non-free
deb-src http://ftp.jp.debian.org/debian buster main contrib non-free
deb http://security.debian.org/debian-security buster/udpdates main contrib non-free
deb-src http://security.debian.org/debian-security buster/updates main contrib non-free
- contribを追記…「ソフトウェア作成者によってフリーであるとされているが、他のフリーでないソフトウェアもインストールしないと使えないもの」もダウンロードできるようになる
- non-freeを追記…「そのソフトウェアの利用や再配布に何らかの煩わしい制限があるもの」もダウンロードできるようになる。
- 一般的なDebianユーザーはcontribとnon-freeを追記している場合が多いとのこと
sudo apt update
パッケージリストを再取得する
参考資料
【 apt 】コマンド(基礎編)――ソフトウェアをインストールする:Linux基本コマンドTips(139) - @IT
『新しいLinuxの教科書』(三宅秀明・大角祐介著)Chapter20 ソフトウェアパッケージ
Debianのsources.listの編集方法
apt-getの基本的なこと - 豆腐とコンソメ
SourcesList - Debian Wiki