コマンド引数のうち便利そうなのをピックアップする。
情報源
Rubyの起動
ruby --help
Usage: ruby [switches] [--] [programfile] [arguments] -0[octal] specify record separator (\0, if no argument) -a autosplit mode with -n or -p (splits $_ into $F) -c check syntax only -Cdirectory cd to directory before executing your script -d, --debug set debugging flags (set $DEBUG to true) -e 'command' one line of script. Several -e's allowed. Omit [programfile] -Eex[:in], --encoding=ex[:in] specify the default external and internal character encodings -Fpattern split() pattern for autosplit (-a) -i[extension] edit ARGV files in place (make backup if extension supplied) -Idirectory specify $LOAD_PATH directory (may be used more than once) -l enable line ending processing -n assume 'while gets(); ... end' loop around your script -p assume loop like -n but print line also like sed -rlibrary require the library before executing your script -s enable some switch parsing for switches after script name -S look for the script using PATH environment variable -v print the version number, then turn on verbose mode -w turn warnings on for your script -W[level=2|:category] set warning level; 0=silence, 1=medium, 2=verbose -x[directory] strip off text before #!ruby line and perhaps cd to directory --jit enable JIT with default options (experimental) --jit-[option] enable JIT with an option (experimental) --copyright print the copyright --dump={insns|parsetree|...}[,...] dump debug information. see below for available dump list --enable={gems|rubyopt|...}[,...], --disable={gems|rubyopt|...}[,...] enable or disable features. see below for available features --external-encoding=encoding, --internal-encoding=encoding specify the default external or internal character encoding --verbose turn on verbose mode and disable script from stdin --version print the version number, then exit --help show this message, -h for short message --backtrace-limit=num limit the maximum length of backtrace Dump List: insns instruction sequences yydebug yydebug of yacc parser generator parsetree AST parsetree_with_comment AST with comments Features: gems rubygems (default: enabled) did_you_mean did_you_mean (default: enabled) rubyopt RUBYOPT environment variable (default: enabled) frozen-string-literal freeze all string literals (default: disabled) jit JIT compiler (default: disabled) Warning categories: deprecated deprecated features experimental experimental features JIT options (experimental): --jit-warnings Enable printing JIT warnings --jit-debug Enable JIT debugging (very slow), or add cflags if specified --jit-wait Wait until JIT compilation finishes every time (for testing) --jit-save-temps Save JIT temporary files in $TMP or /tmp (for testing) --jit-verbose=num Print JIT logs of level num or less to stderr (default: 0) --jit-max-cache=num Max number of methods to be JIT-ed in a cache (default: 100) --jit-min-calls=num Number of calls to trigger JIT (for testing, default: 10000)
-c
実行せず構文チェックだけする。
ruby -c a.rb
問題なければSyntax OK
と出る。
Syntax OK
エラーがあればエラー内容を出す。
でもRubyはインタプリタだから実行することではじめてエラーが発覚することがよくある。なので単体テストで全ルートを通すようにしないとバグを残してしまう。そんな感じだから構文チェックだけしたいときなんて、たぶんほとんどない。一応、そういうこともできますよってだけ。
-C <DIR>
-Cdirectory cd to directory before executing your script
ひとつ上の階層にあるa.rb
を実行するには以下。
ruby -C../ a.rb
使いどころがありそうで、よくわからない。以下のように実行したのと同じ状態になる。
ruby ../a.rb
cd ../; ruby a.rb;
ただ、カレントディレクトリを指定するということは相対パスに影響する。
たとえばテストコードを書くときに以下のような相対パス参照をすることがある。
require './lib.rb'
でも、src/
とtest/
で同じ階層にしていたら以下のようにしないといけない。
require '../src/lib.rb'
それを以下のようにできるのだと思う。
ruby -C../src test_lib.rb
require './lib.rb'
でもそれってシバンに定義したいよね。なので以下のように定義したんだけど。
#!/usr/bin/env ruby -C../src require './lib.rb'
実行権限をつけて実行してみると……
chmod +x ./test_lib.rb ./test_lib.rb
以下のように怒られた。
/usr/bin/env: `ruby -C../src': そのようなファイルやディレクトリはありません /usr/bin/env: use -[v]S to pass options in shebang lines
env
に-V
オプションを渡せばいいっぽい。
#!/usr/bin/env -S ruby -C../src require './lib.rb'
実行するとエラー。
$ ./test_lib.rb ruby: No such file or directory -- ./test_lib.rb (LoadError)
なんと、実行した自分自身がみつからないという。
ですよねー。だってruby -C../src
しちゃったから。カレントディレクトリが移動してしまい、その移動先には実行ファイルがないもんね。
無駄だろうけど、やり方を変えてみる。
前回学習したときWikipediaには、Rubyならシェルにみせかけたシバンを書けとあった。なのでそれに-C
オプションを追記した形にしてみる。
#!/bin/sh # -*- ruby -*- exec ruby -C../src -x "$0" "$@" require './lib.rb'
./test_lib.rb
ruby: No such file or directory -- ./test_lib.rb (LoadError)
同じ結果。ですよねー。
フルパスで実行すると、また別のエラーになった。
$ /tmp/work/ruby__/test/test_lib.rb ruby: no Ruby script found in input (LoadError)
これはよくわからん。
なんにせよ、せっかく-C
コマンドがあってもやりたいことはできなかった。
やりたかったのは、以下のようなファイル構成にしつつ、test_lib.rb
を./test_lib.rb
として実行したらそのファイル単体でテストが実行されるようにしたかった。さらに./rakefile
またはrake
とすれば全テストが実行されるようにしたかった。
- root/
- src/
- lib.rb
- test/
- test_lib.rb
- rakefile
- src/
現状、これができない。以下のような構成になっており、カレントディレクトリがsrc/
直下のときにrake
をすることで全テストできるようになっている。カレントディレクトリが変わったら実行できないし、./test_lib.rb
単体での実行もできない。
- root/
- src/
- lib.rb
- rakefile
- test/
- test_lib.rb
- src/
まあいいや。放置で。
結局-C
の使いどころがわからなかった。
-S
スクリプト名が`/'で始まっていない場合, 環境変数 PATHの値を使ってスクリプトを探すことを指定します。 これは、#!をサポートしていないマシンで、 #! による実行をエミュレートするために、以下のようにして使うことができます:
#!/bin/sh exec ruby -S -x $0 "$@" #! ruby
ちゃんとシバン対策がされているみたい。
-e
Rubyをインライン実行する。
-e 'command' one line of script. Several -e's allowed. Omit [programfile]
ruby -e 'p "Hello Ruby !!"' ruby -e '7.times {|i| p "Hello Ruby !!"}'
-i
引数で指定されたファイルの内容を置き換える。sed
の-i.bak
と同じ。
echo matz > /tmp/junk cat /tmp/junk ruby -p -i.bak -e '$_.upcase!' /tmp/junk cat /tmp/junk cat /tmp/junk.bak
$ echo matz > /tmp/junk $ cat /tmp/junk matz $ ruby -p -i.bak -e '$_.upcase!' /tmp/junk $ cat /tmp/junk MATZ $ cat /tmp/junk.bak matz
ついていけないのだが、そもそも$_
ってなに? 第一引数かな?
第一引数はファイル/tmp/junk
。これを大文字化しているっぽい。通常ならその結果をstdoutに出して終わる。でも-i.bak
することで同名ファイルに.bak
をつけた別ファイルを生成して結果を保存する。つまり結果の出力先をstdoutから.bak
ファイルに変えた。これは便利かもね。
-l
行末の自動処理を行います。まず、
$\
を$/
と同じ値に設定し,-n
フラグまたは-p
フラグが指定されているとgets
で読み込まれた各行の最後に対してString#chomp!
を行います。
String#chomp!をみる。末尾から改行コードを削除するらしい。
getsは標準入力。
OSにおけるパス区切文字と改行コードを統一する処理ってことかな?
それと末尾の改行を消してくれるのは嬉しい。ただ、スペースは消さないのかな? スペースも削除するトリムとは違うのかも。
-n
プログラム全体が以下でで囲まれているように動作する。
while gets ... end
REPLのような動作になる。面白いけど、いつ使うかな? 引数だけ変えて何度も動かしたいときに使うんだろうけど。
-p
-n
とほぼ同じ。各ループの最後に変数 $_ の値を出力する。
-s
スクリプト名に続く,
-'で始まる引数を解釈して, 同名のグローバル変数に値を設定します。
--'なる引数以降は解釈を行ないません。該当する引数は Object::ARGV から取り除かれます。
Object::ARGで引数を取得するっぽいね。
#! /usr/local/bin/ruby -s # prints "true" if invoked with `-xyz' switch. print "true\n" if $xyz
env
シバンで書くと以下のようになるってことかな?
#!/usr/bin/env -S ruby -s # prints "true" if invoked with `-xyz' switch. print "true\n" if $xyz
実行する。
chmod +x ./b.rb ./b.rb -xyz
true
引数-xyz
を渡さないと何も出ない。
./b.rb
OK! 面白いけど、使わないかな。
所感
絶対に覚えられない。
対象環境
- Raspbierry pi 4 Model B
- Raspberry Pi OS buster 10.0 2020-08-20 ※
- bash 5.0.3(1)-release
- Ruby 3.0.2
$ uname -a Linux raspberrypi 5.10.52-v7l+ #1441 SMP Tue Aug 3 18:11:56 BST 2021 armv7l GNU/Linux