これまでは基本的にシェルに用意されているコマンド、機能を使ってきました。様々なコマンド、シェル機能がありますが、万能ではありません。コマンドの組み合わせ、シェルスクリプトでうまく処理できればよいのですが、実際には機能がなかったりする事があります。
そんな時に便利なのがプログラム言語です。一般的にはプログラム言語のハードルは高く、それなりに勉強してプログラムを作るような感覚があるかもしれません。プログラムの難易度は実行する環境や、プログラム言語そのものの難しさ、実現しようとしている事の難しさなどがあります。

とは言えシェルで不足している機能を補うくらいであれば、何とかなる範囲かもしれません。都合がいいのは標準入力・標準出力を利用すればプログラムで作る部分は単機能でも何とかなるという点です。

そこで、今回は国産のプログラム言語のRubyを使ってリアルタイムキー入力を行う処理を実現してみましょう。リアルタイムキー入力はシェルでは難しい処理の1つです。これをプログラミング言語を利用することで手軽に使えるようにしてみます。

Ruby言語がインストールされているか確認する

 環境によってはすでにRuby言語がインストールされている場合があります。例えばmacOSには古くからRuby言語がインストールされています。

Ruby言語がインストールされているか確認するには以下のようにコマンドを入力します。

ruby -v

エラーにならずバージョンが表示されればOKです。
エラーが表示された場合はRuby言語をインストールする必要があります(以下の画像はRaspberry PI OSでの実行結果。Ruby言語が入っていない状態です)。
なお、今回の処理はRuby言語のバージョンは問いません。すでにインストールされていた場合は次に説明するインストール作業は不要ですので、その次に進んでください。

Ruby言語をインストールする

 先ほどのruby -vコマンドを実行してRubyが入ってない場合はインストールする作業が必要になります。ここではRaspberry PI OSにRuby言語をインストールします。  以下のようにコマンドを入力します。

sudo apt update

 アップデートするものがある場合は以下のコマンドを入力します。

sudo apt upgrade -y

終了したらRubyをインストールします。とりあえず全部丸ごと一式インストールしておきます。以下のコマンドを入力します。

sudo apt install ruby-full -y

インストールが終わったら以下のコマンドを入力してRubyのバージョンを確認してください。エラーにならなければOKです。

ruby -v

簡単なプログラムを作成する

 まずは簡単なプログラムを作成してみましょう。3.14という数値(円周率)を表示させてみます。数値を表示する命令はputsです。エディタで以下のようにプログラムを入力します。入力したらpi.rbというファイル名で保存します。Ruby言語のプログラムの拡張子はrbです。また、以後のプログラムは保存したファイルがあるディレクトリをカレントディレクトリとして実行しています。もし、異なる場所に保存した場合は、そのファイルがある場所のパスを指定してください。(例:ruby /home/pi/Desktop/pi.rb)

puts 3.14

このプログラムを実行するには以下のようにコマンドを入力します。環境によっては結果が表示されるまでに時間がかかることがあります。

ruby pi.rb

数値でなく文字列を表示することもできます。Ruby言語は国産ですので日本語もバッチリです。以下のようにプログラムを入力しmes.rbというファイル名で保存します。

puts "ルビーの埴輪"

保存したら以下のようにコマンドを入力し実行します。

ruby mes.rb

putsは表示した数値や文字列の後に改行するようになっています。改行したくない場合もあります。そのような場合はputsではなくprintを使います。以下のプログラムを入力したらmes2.rbのファイル名で保存します。

print "ルビーの埴輪"

以下のコマンドを入力して実行します。

ruby mes2.rb

標準入力からのデータを加工して出力する

 次に標準入力からのデータを処理します。結果は標準出力へ流します。標準入力のデータから1行読み込むにはgetsを使います。先ほどのputsと組み合わせて以下のようにすると標準入力からの文字列の前後に「」をつけて出力します。このプログラムをstd1.rbという名前で保存しておきます。

puts "「"+gets+"」"

実行するには以下のように入力します。

echo "Sample" | ruby std1.rb

よく見ると最後の閉じカッコの」の前で改行されています。改行まで含めたくはない場合は、chomp!を付けます。以下のようにすると期待通りの結果になります。(保存するファイル名はstd2.rb)

puts "「"+gets.chomp!+"」"
echo "Sample" | ruby std2.rb

リアルタイムキー入力

 それでは次にリアルタイムキー入力を行うプログラムを作りましょう。プログラムについて詳しく説明したいところですが、諸々の都合で以下にプログラムを示します。6行しかないのでリファレンスで調べるなりAIに尋ねればわかるでしょう。以下のプログラムを入力したらkey1.rbというファイル名で保存します。

require 'io/console'
loop do
  k = STDIN.getch
  print k
  break if k == "\e"
end

このプログラムを実行するには以下のようにコマンドを入力します。

ruby key1.rb

何かキー入力を行うと画面に文字が表示されます。escキーを押すと終了します。

入力された文字は標準出力に出ているので以下のようにすると入力した文字が1.txtというファイルに保存されます。ただし、この状態では画面には入力された文字は表示されません。

ruby key1.rb > 1.txt

標準出力を画面とファイルに分岐させるにはteeコマンドを使います。以下のようにすると画面に入力された文字が表示され、1.txtにも同じ内容が保存されます。ただし、多くの環境では期待通り動作しません。

ruby key1.rb | tee 1.txt

これは標準出力がバッファリング処理されているためで、プログラムを以下のように変更する必要があります。このプログラムはkey2.rbというファイル名で保存しておきます。

require 'io/console'
loop do
  k = STDIN.getch
  print k
  STDOUT.flush
  break if k == "\e"
end

以下のようにコマンドを入力し実行します。今度は画面にもファイルにも同じ内容が出力されています。

ruby key2.rb | tee 1.txt

スペースキーが押されるまで待つ

 それでは最後に簡単なプログラムを作成します。といってもスペースキーが押されるまで待つだけのプログラムです。先ほどのプログラムを修正するだけですので簡単です。プログラムは以下のようになります。ファイル名はspc.rbとして保存しておきます。

require 'io/console'
loop do
  k = STDIN.getch
  STDOUT.flush
  break if k == " "
end

以下のようにコマンドを入力して使用します。スペースキーが押されると終了します。

ruby spc.rb

 このようなシンプルなプログラムでも作っておくと後々便利なことがあります。シェルスクリプトやコマンドの組み合わせだけでは大変そうだな、という場合は手軽にできそうなプログラム言語を使うという選択肢も入れておくとよいでしょう。

では、また次回。

著者 仲村次郎
いろいろな事に手を出してみたものの結局身につかず、とりあえず目的の事ができればいいんじゃないかみたいな感じで生きております。