💎 Ruby on Shell

A handbook on using Ruby for shell scripting!

Introduction

Welcome to Ruby on Shell! This is a guide/handbook on using Ruby for shell scripting. This handbook will list most shell commands, and it's Ruby equivalent. This page is using the Ruby's document for version 3.2.2 as a referent. If you have questions or want to feedback, please open an issue.

Why not Bash?

Why try to reinvent bash?

Quote from Closh's README:

  • Bash has obscure syntax for non-trivial operations and lots of WTF moments.
  • It treats everything as text while we mostly need to manipulate structured information.
  • It is a large codebase which makes it difficult to hack on it and try innovative ideas. Which is one of the reasons why the shell did not improve much in recent decades.
When to use Bash

Quote from Replacing Bash Scripting with Python:

I do believe that for a program which deals primarily with starting processes and connecting their inputs and outputs, as well as certain kinds of file management tasks, the shell should still be the first candidate. A good example might be setting up a server. I keep config files for my shell environment in Git (like any sane person), and I use sh for all the setup. That's fine. In fact, it's great. Running some commands and symlinking files is a usecase that fits perfectly to the strengths of the shell.

I also have shell scripts for automating certain parts of my build, testing and publishing workflow for my programming, and I will probably continue to use such scripts for a long time.

Warning Signs

Many people have rule about the length of their Bash scripts. It is oft repeated on the Internet that, "If your shell script gets to fifty lines, rewrite in another language," or something similar. The number of lines varies from 10 to 20 to 50 to 100. Among the Unix old guard, "another language" is basically always Perl.

This kind of rule isn't too bad. Length isn't the problem, but length can be a side-effect of complexity, and complexity is sort of the arch-enemy of Bash. I look for the use of certain features to be an indicator that it's time to consider a rewrite. (note that "rewrite" can mean moving certain parts of the logic into another language while still doing orchestration in Bash). These "warning signs are" listed in order of more to less serious.

  • If you ever need to type the characters IFS=, rewrite immediately. You're on the highway to Hell.
  • If data is being stored in Bash arrays, either refactor so the data can be streamed through pipelines or use a different language. As with IFS, it means you're entering the wild world of the shell's string splitting rules. That's not the world for you.
  • If you find yourself using braced parameter expansion syntax, ${my_var}, and anything is between those braces besides the name of your variable, it's a bad sign. For one, it means you might be using an array, and that's not good. If you're not using an array, it means you're using the shell's string manipulation capabilities. There are cases where this might be allowable (determining the basename of a file, for example), but the syntax for that kind of thing is very strange, and so many other languages supply better string manipulating tools.
  • Dealing with process output in a loop is not a great idea. If you HAVE to do it, the only right way is with while IFS= read -r line. Don't listen to anyone who tells you differently, ever. Always try to refactor this case as a one-liner with AWK or Perl, or write a script in another language to process the data and call it from Bash. If you have a loop like this, and you are starting any processes inside the loop, you will have major performance problems. This will eventually lead to refactoring with Bash built-ins. In the final stages, it results in madness and suicide.
  • Bash functions, while occasionally useful, can be a sign of trouble. All the variables are global by default. It also means there is enough complexity that you can't do it with a completely linear control flow. That's also not a good sign for Bash. A few Bash functions might be alright, but it's a warning sign.
  • Conditional logic, while it can definitely be useful, is also a sign of increasing complexity. As with functions, using it doesn't mean you have to rewrite, but every time you write one, you should ask yourself the question as to whether the task you're doing isn't better suited to another language.

Finally, whenever you use a $ in Bash (parameter expansion), you must use quotation marks. Always only ever use quotation marks. Never forget. Never be lazy. This is a security hazard. As previously mentioned, Bash is an injection honeypot. There are a few cases where you don't need the quotation marks. They are the exceptions. Do not learn them. Just use quotes all the time. It is always correct.

Why Ruby?

Roots of Rubyism

Quote from Idiosyncratic Ruby:

It is a language with a terrific community (welcoming and always questioning itself) and ecosystem (a lot of problems already solved), which is beautiful (focus on productivity), a little conservative (in the sense that it is easy to work with), and general purpose (a good choice in most cases).

Familiarity:

The Ruby's syntax is extremely similar to the established shell scripting languages. From it's semi-whitespace-significant style to it's keyword-base blocks syntax...

In Ruby everything is an object of some class, and every class have ton of powerful methods. Because of that, you could write a straightforward method chaining just like a pipeline in shell.

# Bash
echo 'zab rab oof' | rev | sed -e 's/bar/banana/g' | tr '[[:lower:]]' '[[:upper:]]' | cut -d ' ' -f 2  #=> "BANANA"

# Ruby
'zab rab oof'.reverse.gsub('bar', 'banana').upcase.split[1]  #=> "BANANA"

Convenient:

Although Ruby in not a shell language, it can call shell command (with its syntax) inside Ruby just by wrapping it with backticks:

`ls`  # List directory contents

bar = 'banana'
`echo foo #{bar}`  #=> "foo banana\n"

`true && echo '!dlroW ,olleH' | rev`  #=> "Hello, World!\n"

The more you understand Ruby, the shorter and nicer your code can be:

# Count lines of file:
File.open('path/to/file') { |file| file.read.split("\n").size }
File.open('path/to/file') { |file| file.read.lines.size }
File.open('path/to/file') { |file| file.readlines.size }
File.open('path/to/file') { _1.readlines.size }
File.read('path/to/file').lines.size
File.readlines('path/to/file').size

# Count the number of even bytes in a string:
'Hello, World!'.bytes.select { |number| number % 2 == 0 }.size
'Hello, World!'.bytes.select { |number| number.even? }.size
'Hello, World!'.bytes.select { _1.even? }.size
'Hello, World!'.bytes.select(&:even?).size
'Hello, World!'.bytes.count(&:even?)

It's Fun:

Ruby is a joy to read and write with. The language is elegantly designed to make the script we write in feel natural.

Ruby is also flexible, it gives you the freedom to write the code the way you want. E.g: Instead of the keyword-base blocks syntax you can write blocks in C-style { ... }.

The language is so expressive, it's perfect for code-golfing or do some crazy tricks like in the TRIC contest.

Getting started

First, you need to learn the basic of Ruby. There are many ways to learn Ruby, but I found this tutorial to be the best one to introduce you to the languages:

Ruby Programming in One Video

If you prefer reading, The Odin Project is a great alternative.

Or if you come from other programming languages, Ruby From Other Languages is the quickest path to learn Ruby.

Next you can read Enhanced Shell Scripting with Ruby which is focused way more on using Ruby for shell scripting.

The Ruby document is a very organized and easy to digest resource. You can easily go through all the basic objects and those are methods to utilize the most out of the language power:

Some other useful resource: Idiosyncratic Ruby, Ruby Style Guide.

Ruby as interactive shell

Ruby is great for scripting but it's syntax is a bit strict for quick and frequent tasks. The best way to use Ruby in the command-line is to bind irb to a key like Alt + R for example, so you can quickly toggle between simple shell mode and Ruby scripting mode.

Add the keybind to your prefer interactive shell:

For Bash (~/.bashrc):

bind -x '"\er":"irb"'

For Zsh (~/.zshrc):

bindkey -s "\er" '^Qirb^J'

For Fish (~/.config/fish/config.fish):

bind \er 'irb; commandline -f repaint'

Shell's Builtin Command

Shell's Basic

COMMAND #

Kernel#`

Kernel#‘

(from ruby core)


`command` -> string

Returns the $stdout output from running command in a subshell; sets global variable $? to the process status.

This method has potential security vulnerabilities if called with untrusted input; see Command Injection.

Examples:

$ `date`                 # => "Wed Apr  9 08:56:30 CDT 2003\n"
$ `echo oops && exit 99` # => "oops\n"
$ $?                     # => #<Process::Status: pid 17088 exit 99>
$ $?.status              # => 99>

The built-in syntax %x{...} uses this method.

Read more on Ruby API
Kernel#system

Kernel#system

(from ruby core)


system([env,] command... [,options], exception: false)    -> true, false or nil

Executes command… in a subshell. command… is one of following forms.

This method has potential security vulnerabilities if called with untrusted input; see Command Injection.

commandline:

command line string which is passed to the standard shell

cmdname, arg1, ...:

command name and one or more arguments (no shell)

[cmdname, argv0], arg1, ...:

command name, <tt>argv[0]</tt> and zero or more arguments (no shell)

system returns true if the command gives zero exit status, false for non zero exit status. Returns nil if command execution fails. An error status is available in $?.

If the exception: true argument is passed, the method raises an exception instead of returning false or nil.

The arguments are processed in the same way as for Kernel#spawn.

The hash arguments, env and options, are same as #exec and #spawn. See Kernel#spawn for details.

system("echo *")
system("echo", "*")

produces:

config.h main.rb
*

Error handling:

system("cat nonexistent.txt")
# => false
system("catt nonexistent.txt")
# => nil

system("cat nonexistent.txt", exception: true)
# RuntimeError (Command failed with exit 1: cat)
system("catt nonexistent.txt", exception: true)
# Errno::ENOENT (No such file or directory - catt)

See Kernel#exec for the standard shell.

Read more on Ruby API
Note:
  • Kernel#system print the result, while Kernel#` returns the result as a string and print nothing.
  • Kernel#` it can be written as %x{ command } (use it only when necessary).
  • You can use string interpolation (#{ ... }) inside Kernel#`:
foo = 'bar'
`echo #{foo}`  #=> "bar\n" 
You can read more on How to call shell commands from Ruby | Stack Overflow.

{ COMMANDS } #

You can write a block like begin some_methods end or { some_methods } in Ruby.

$(( expression )) let #

Most mathematical operators in Ruby are the same as in Bash. But unlike Bash, you can do math operators anywhere.

. source #

Kernel#require_relative

Kernel#require_relative

(from ruby core)


require_relative(file)

Ruby tries to load the library named string relative to the directory containing the requiring file. If the file does not exist a LoadError is raised. Returns true if the file was loaded and false if the file was already loaded before.

Read more on Ruby API

: true false #

Equivalent Ruby keyword: true false

TrueClass

TrueClass < Object

(from ruby core)


The global value true is the only instance of class TrueClass and represents a logically true value in boolean expressions. The class provides operators allowing true to be used in logical expressions.


Instance methods:

&
===
^
inspect
to_s
|
Read more on Ruby API
FalseClass

FalseClass < Object

(from ruby core)


The global value false is the only instance of class FalseClass and represents a logically false value in boolean expressions. The class provides operators allowing false to participate correctly in logical expressions.


Instance methods:

&
===
^
inspect
to_s
|
Read more on Ruby API

COMMAND1 && COMMAND2 #

Equivalent Ruby code: method1 && method2 or object1 && object2

COMMAND1 || COMMAND2 #

Equivalent Ruby code: method1 || method2 or object1 || object2

[ [[ test #

Kernel#test

Kernel#test

(from ruby core)


test(cmd, file1 [, file2] ) -> obj

Uses the character cmd to perform various tests on file1 (first table below) or on file1 and file2 (second table).

File tests on a single file:

Cmd    Returns   Meaning
"A"  | Time    | Last access time for file1
"b"  | boolean | True if file1 is a block device
"c"  | boolean | True if file1 is a character device
"C"  | Time    | Last change time for file1
"d"  | boolean | True if file1 exists and is a directory
"e"  | boolean | True if file1 exists
"f"  | boolean | True if file1 exists and is a regular file
"g"  | boolean | True if file1 has the setgid bit set
"G"  | boolean | True if file1 exists and has a group
     |         | ownership equal to the caller's group
"k"  | boolean | True if file1 exists and has the sticky bit set
"l"  | boolean | True if file1 exists and is a symbolic link
"M"  | Time    | Last modification time for file1
"o"  | boolean | True if file1 exists and is owned by
     |         | the caller's effective uid
"O"  | boolean | True if file1 exists and is owned by
     |         | the caller's real uid
"p"  | boolean | True if file1 exists and is a fifo
"r"  | boolean | True if file1 is readable by the effective
     |         | uid/gid of the caller
"R"  | boolean | True if file is readable by the real
     |         | uid/gid of the caller
"s"  | int/nil | If file1 has nonzero size, return the size,
     |         | otherwise return nil
"S"  | boolean | True if file1 exists and is a socket
"u"  | boolean | True if file1 has the setuid bit set
"w"  | boolean | True if file1 exists and is writable by
     |         | the effective uid/gid
"W"  | boolean | True if file1 exists and is writable by
     |         | the real uid/gid
"x"  | boolean | True if file1 exists and is executable by
     |         | the effective uid/gid
"X"  | boolean | True if file1 exists and is executable by
     |         | the real uid/gid
"z"  | boolean | True if file1 exists and has a zero length

Tests that take two files:

"-"  | boolean | True if file1 and file2 are identical
"="  | boolean | True if the modification times of file1
     |         | and file2 are equal
"<"  | boolean | True if the modification time of file1
     |         | is prior to that of file2
">"  | boolean | True if the modification time of file1
     |         | is after that of file2
Read more on Ruby API

help #

You can use show_doc inside Ruby or ri from the command-line.

export #

ENV::[]=

ENV::[]=

(from ruby core)


ENV[name] = value      -> value
ENV.store(name, value) -> value

ENV.store is an alias for ENV.[]=.

Creates, updates, or deletes the named environment variable, returning the value. Both name and value may be instances of String. See Valid Names and Values.

  • If the named environment variable does not exist:

    • If value is nil, does nothing.

      ENV.clear
      ENV['foo'] = nil # => nil
      ENV.include?('foo') # => false
      ENV.store('bar', nil) # => nil
      ENV.include?('bar') # => false
      
    • If value is not nil, creates the environment variable with name and value:

      # Create 'foo' using ENV.[]=.
      ENV['foo'] = '0' # => '0'
      ENV['foo'] # => '0'
      # Create 'bar' using ENV.store.
      ENV.store('bar', '1') # => '1'
      ENV['bar'] # => '1'
      
  • If the named environment variable exists:

    • If value is not nil, updates the environment variable with value value:

      # Update 'foo' using ENV.[]=.
      ENV['foo'] = '2' # => '2'
      ENV['foo'] # => '2'
      # Update 'bar' using ENV.store.
      ENV.store('bar', '3') # => '3'
      ENV['bar'] # => '3'
      
    • If value is nil, deletes the environment variable:

      # Delete 'foo' using ENV.[]=.
      ENV['foo'] = nil # => nil
      ENV.include?('foo') # => false
      # Delete 'bar' using ENV.store.
      ENV.store('bar', nil) # => nil
      ENV.include?('bar') # => false
      

Raises an exception if name or value is invalid. See Invalid Names and Values.

Read more on Ruby API

readonly #

Object#freeze

Object#freeze

(from ruby core)


obj.freeze    -> obj

Prevents further modifications to obj. A FrozenError will be raised if modification is attempted. There is no way to unfreeze a frozen object. See also Object#frozen?.

This method returns self.

a = [ "a", "b", "c" ]
a.freeze
a << "z"

produces:

prog.rb:3:in `<<': can't modify frozen Array (FrozenError)
 from prog.rb:3

Objects of the following classes are always frozen: Integer, Float, Symbol.

Read more on Ruby API

echo #

Kernel#print

Kernel#print

(from ruby core)


print(*objects) -> nil

Equivalent to $stdout.print(*objects), this method is the straightforward way to write to $stdout.

Writes the given objects to $stdout; returns nil. Appends the output record separator $OUTPUT_RECORD_SEPARATOR $</tt>), if it is not <tt>nil.

With argument objects given, for each object:

  • Converts via its method to_s if not a string.

  • Writes to stdout.

  • If not the last object, writes the output field separator $OUTPUT_FIELD_SEPARATOR ($, if it is not nil.

With default separators:

objects = [0, 0.0, Rational(0, 1), Complex(0, 0), :zero, 'zero']
$OUTPUT_RECORD_SEPARATOR
$OUTPUT_FIELD_SEPARATOR
print(*objects)

Output:

nil
nil
00.00/10+0izerozero

With specified separators:

$OUTPUT_RECORD_SEPARATOR = "\n"
$OUTPUT_FIELD_SEPARATOR = ','
print(*objects)

Output:

0,0.0,0/1,0+0i,zero,zero

With no argument given, writes the content of $_ (which is usually the most recent user input):

gets  # Sets $_ to the most recent user input.
print # Prints $_.
Read more on Ruby API
Kernel#puts

Kernel#puts

(from ruby core)


puts(*objects)    -> nil

Equivalent to

$stdout.puts(objects)
Read more on Ruby API
Kernel#p

Kernel#p

(from ruby core)


p(object)   -> obj
p(*objects) -> array of objects
p           -> nil

For each object obj, executes:

$stdout.write(obj.inspect, "\n")

With one object given, returns the object; with multiple objects given, returns an array containing the objects; with no object given, returns nil.

Examples:

r = Range.new(0, 4)
p r                 # => 0..4
p [r, r, r]         # => [0..4, 0..4, 0..4]
p                   # => nil

Output:

0..4
[0..4, 0..4, 0..4]
Read more on Ruby API
print display an object (e.g: a string) as it is.
puts automatically adds a new line at the end.
p print object in raw form (mostly use for debug).

printf #

Kernel#printf

Kernel#printf

(from ruby core)


printf(format_string, *objects)               -> nil
printf(io, format_string, *objects) -> nil

Equivalent to:

io.write(sprintf(format_string, *objects))

For details on format_string, see Format Specifications.

With the single argument format_string, formats objects into the string, then writes the formatted string to $stdout:

printf('%4.4d %10s %2.2f', 24, 24, 24.0)

Output (on $stdout):

0024         24 24.00#

With arguments io and format_string, formats objects into the string, then writes the formatted string to io:

printf($stderr, '%4.4d %10s %2.2f', 24, 24, 24.0)

Output (on $stderr):

0024         24 24.00# => nil

With no arguments, does nothing.

Read more on Ruby API

read #

Kernel#gets

Kernel#gets

(from ruby core)


gets(sep=$/ [, getline_args])     -> string or nil
gets(limit [, getline_args])      -> string or nil
gets(sep, limit [, getline_args]) -> string or nil

Returns (and assigns to $_) the next line from the list of files in ARGV (or $*), or from standard input if no files are present on the command line. Returns nil at end of file. The optional argument specifies the record separator. The separator is included with the contents of each record. A separator of nil reads the entire contents, and a zero-length separator reads the input one paragraph at a time, where paragraphs are divided by two consecutive newlines. If the first argument is an integer, or optional second argument is given, the returning string would not be longer than the given value in bytes. If multiple filenames are present in ARGV, gets(nil) will read the contents one file at a time.

ARGV << "testfile"
print while gets

produces:

This is line one
This is line two
This is line three
And so on...

The style of programming using $_ as an implicit parameter is gradually losing favor in the Ruby community.

Read more on Ruby API
IO#getpass

IO#getpass

(from ruby core)


io.getpass(prompt=nil)       -> string

Reads and returns a line without echo back. Prints prompt unless it is nil.

The newline character that terminates the read line is removed from the returned string, see String#chomp!.

You must require ‘io/console’ to use this method.

Read more on Ruby API

select #

Equivalent Ruby gem: tty-prompt

getopts #

OptionParser#getopts

OptionParser#getopts

(from ruby core)


getopts(*args)

Wrapper method for getopts.rb.

params = ARGV.getopts("ab:", "foo", "bar:", "zot:Z;zot option")
# params["a"] = true   # -a
# params["b"] = "1"    # -b1
# params["foo"] = "1"  # --foo
# params["bar"] = "x"  # --bar x
# params["zot"] = "z"  # --zot Z
Read more on Ruby API

eval #

Kernel#eval

Kernel#eval

(from ruby core)


eval(string [, binding [, filename [,lineno]]])  -> obj

Evaluates the Ruby expression(s) in string. If binding is given, which must be a Binding object, the evaluation is performed in its context. If the optional filename and lineno parameters are present, they will be used when reporting syntax errors.

def get_binding(str)
  return binding
end
str = "hello"
eval "str + ' Fred'"                      #=> "hello Fred"
eval "str + ' Fred'", get_binding("bye")  #=> "bye Fred"
Read more on Ruby API

exec #

Kernel#exec

Kernel#exec

(from ruby core)


exec([env,] command... [,options])

Replaces the current process by running the given external command, which can take one of the following forms:

exec(commandline):

command line string which is passed to the standard shell

exec(cmdname, arg1, ...):

command name and one or more arguments (no shell)

exec([cmdname, argv0], arg1, ...):

command name, <tt>argv[0]</tt> and zero or more arguments (no shell)

In the first form, the string is taken as a command line that is subject to shell expansion before being executed.

The standard shell always means "/bin/sh" on Unix-like systems, otherwise, ENV["RUBYSHELL"] or ENV["COMSPEC"] on Windows and similar. The command is passed as an argument to the "-c" switch to the shell, except in the case of COMSPEC.

If the string from the first form (exec("command")) follows these simple rules:

  • no meta characters,

  • not starting with shell reserved word or special built-in,

Ruby invokes the command directly without shell.

You can force shell invocation by adding “;” to the string (because “;” is a meta character).

Note that this behavior is observable by pid obtained (return value of spawn() and IO#pid for IO.popen) is the pid of the invoked command, not shell.

In the second form (exec("command1", "arg1", ...)), the first is taken as a command name and the rest are passed as parameters to command with no shell expansion.

In the third form (exec(["command", "argv0"], "arg1", ...)), starting a two-element array at the beginning of the command, the first element is the command to be executed, and the second argument is used as the argv[0] value, which may show up in process listings.

In order to execute the command, one of the exec(2) system calls are used, so the running command may inherit some of the environment of the original program (including open file descriptors).

This behavior is modified by the given env and options parameters. See ::spawn for details.

If the command fails to execute (typically Errno::ENOENT when it was not found) a SystemCallError exception is raised.

This method modifies process attributes according to given options before exec(2) system call. See ::spawn for more details about the given options.

The modified attributes may be retained when exec(2) system call fails.

For example, hard resource limits are not restorable.

Consider to create a child process using ::spawn or Kernel#system if this is not acceptable.

exec "echo *"       # echoes list of files in current directory
# never get here

exec "echo", "*"    # echoes an asterisk
# never get here
Read more on Ruby API

exit #

Kernel#exit

Kernel#exit

(from ruby core)


exit(status=true)
Kernel::exit(status=true)
Process::exit(status=true)

Initiates the termination of the Ruby script by raising the SystemExit exception. This exception may be caught. The optional parameter is used to return a status code to the invoking environment. true and FALSE of status means success and failure respectively. The interpretation of other integer values are system dependent.

begin
  exit
  puts "never get here"
rescue SystemExit
  puts "rescued a SystemExit exception"
end
puts "after begin block"

produces:

rescued a SystemExit exception
after begin block

Just prior to termination, Ruby executes any at_exit functions (see Kernel::at_exit) and runs any object finalizers (see ObjectSpace::define_finalizer).

at_exit { puts "at_exit function" }
ObjectSpace.define_finalizer("string",  proc { puts "in finalizer" })
exit

produces:

at_exit function
in finalizer
Read more on Ruby API

trap #

Kernel#trap

Kernel#trap

(from ruby core)


Signal.trap( signal, command ) -> obj
Signal.trap( signal ) {| | block } -> obj

Specifies the handling of signals. The first parameter is a signal name (a string such as “SIGALRM”, “SIGUSR1”, and so on) or a signal number. The characters “SIG” may be omitted from the signal name. The command or block specifies code to be run when the signal is raised. If the command is the string “IGNORE” or “SIG_IGN”, the signal will be ignored. If the command is “DEFAULT” or “SIG_DFL”, the Ruby’s default handler will be invoked. If the command is “EXIT”, the script will be terminated by the signal. If the command is “SYSTEM_DEFAULT”, the operating system’s default handler will be invoked. Otherwise, the given command or block will be run. The special signal name “EXIT” or signal number zero will be invoked just prior to program termination. trap returns the previous handler for the given signal.

Signal.trap(0, proc { puts "Terminating: #{$$}" })
Signal.trap("CLD")  { puts "Child died" }
fork && Process.wait

produces:

Terminating: 27461
Child died
Terminating: 27460
Read more on Ruby API

cd #

Dir::chdir

Dir::chdir

(from ruby core)


Dir.chdir( [ string] ) -> 0
Dir.chdir( [ string] ) {| path | block }  -> anObject

Changes the current working directory of the process to the given string. When called without an argument, changes the directory to the value of the environment variable HOME, or LOGDIR. SystemCallError (probably Errno::ENOENT) if the target directory does not exist.

If a block is given, it is passed the name of the new current directory, and the block is executed with that as the current directory. The original working directory is restored when the block exits. The return value of chdir is the value of the block. chdir blocks can be nested, but in a multi-threaded program an error will be raised if a thread attempts to open a chdir block while another thread has one open or a call to chdir without a block occurs inside a block passed to chdir (even in the same thread).

Dir.chdir("/var/spool/mail")
puts Dir.pwd
Dir.chdir("/tmp") do
  puts Dir.pwd
  Dir.chdir("/usr") do
    puts Dir.pwd
  end
  puts Dir.pwd
end
puts Dir.pwd

produces:

/var/spool/mail
/tmp
/usr
/tmp
/var/spool/mail
Read more on Ruby API

pwd #

Dir::pwd

Dir::pwd

(from ruby core)


Dir.getwd -> string
Dir.pwd -> string

Returns the path to the current working directory of this process as a string.

Dir.chdir("/tmp")   #=> 0
Dir.getwd           #=> "/tmp"
Dir.pwd             #=> "/tmp"
Read more on Ruby API

Keywords

function #

Equivalent Ruby keyword: def

if #

Equivalent Ruby keyword: if

case #

Equivalent Ruby keyword: case

while #

Equivalent Ruby keyword: while

until #

Equivalent Ruby keyword: until

for #

Equivalent Ruby keyword: for

Although Ruby have for keyword, most of the time iterators should be used instead.

return #

Equivalent Ruby keyword: return

Note that you can (and should) eliminate the return keyword where it's not required for flow of control.

break #

Equivalent Ruby keyword: break

continue #

Equivalent Ruby keyword: next

alias #

Equivalent Ruby keyword: alias

Process Management

COMMAND & #

Thread::new

Thread::new

(from ruby core)


Thread.new { ... }                  -> thread
Thread.new(*args, &proc)            -> thread
Thread.new(*args) { |args| ... }    -> thread

Creates a new thread executing the given block.

Any args given to ::new will be passed to the block:

arr = []
a, b, c = 1, 2, 3
Thread.new(a,b,c) { |d,e,f| arr << d << e << f }.join
arr #=> [1, 2, 3]

A ThreadError exception is raised if ::new is called without a block.

If you’re going to subclass Thread, be sure to call super in your initialize method, otherwise a ThreadError will be raised.

Read more on Ruby API
Kernel#fork

Kernel#fork

(from ruby core)


Kernel.fork  [{ block }]   -> integer or nil
Process.fork [{ block }]   -> integer or nil

Creates a subprocess. If a block is specified, that block is run in the subprocess, and the subprocess terminates with a status of zero. Otherwise, the fork call returns twice, once in the parent, returning the process ID of the child, and once in the child, returning nil. The child process can exit using Kernel.exit! to avoid running any at_exit functions. The parent process should use Process.wait to collect the termination statuses of its children or use Process.detach to register disinterest in their status; otherwise, the operating system may accumulate zombie processes.

The thread calling fork is the only thread in the created child process. fork doesn’t copy other threads.

If fork is not usable, Process.respond_to?(:fork) returns false.

Note that fork(2) is not available on some platforms like Windows and NetBSD 4. Therefore you should use spawn() instead of fork().

Read more on Ruby API

jobs #

Thread::list

Thread::list

(from ruby core)


Thread.list   -> array

Returns an array of Thread objects for all threads that are either runnable or stopped.

Thread.new { sleep(200) }
Thread.new { 1000000.times {|i| i*i } }
Thread.new { Thread.stop }
Thread.list.each {|t| p t}

This will produce:

#<Thread:0x401b3e84 sleep>
#<Thread:0x401b3f38 run>
#<Thread:0x401b3fb0 sleep>
#<Thread:0x401bdf4c run>
Read more on Ruby API

bg #

Thread#run

Thread#run

(from ruby core)


thr.run   -> thr

Wakes up thr, making it eligible for scheduling.

a = Thread.new { puts "a"; Thread.stop; puts "c" }
sleep 0.1 while a.status!='sleep'
puts "Got here"
a.run
a.join

This will produce:

a
Got here
c

See also the instance method #wakeup.

Read more on Ruby API

fg #

Thread#join

Thread#join

(from ruby core)


thr.join          -> thr
thr.join(limit)   -> thr

The calling thread will suspend execution and run this thr.

Does not return until thr exits or until the given limit seconds have passed.

If the time limit expires, nil will be returned, otherwise thr is returned.

Any threads not joined will be killed when the main program exits.

If thr had previously raised an exception and the ::abort_on_exception or $DEBUG flags are not set, (so the exception has not yet been processed), it will be processed at this time.

a = Thread.new { print "a"; sleep(10); print "b"; print "c" }
x = Thread.new { print "x"; Thread.pass; print "y"; print "z" }
x.join # Let thread x finish, thread a will be killed on exit.
#=> "axyz"

The following example illustrates the limit parameter.

y = Thread.new { 4.times { sleep 0.1; puts 'tick... ' }}
puts "Waiting" until y.join(0.15)

This will produce:

tick...
Waiting
tick...
Waiting
tick...
tick...
Read more on Ruby API

suspend #

Thread::stop

Thread::stop

(from ruby core)


Thread.stop   -> nil

Stops execution of the current thread, putting it into a “sleep” state, and schedules execution of another thread.

a = Thread.new { print "a"; Thread.stop; print "c" }
sleep 0.1 while a.status!='sleep'
print "b"
a.run
a.join
#=> "abc"
Read more on Ruby API

kill #

Process::kill

Process::kill

(from ruby core)


Process.kill(signal, pid, *pids)    -> integer

Sends the given signal to the specified process id(s) if pid is positive. If pid is zero, signal is sent to all processes whose group ID is equal to the group ID of the process. If pid is negative, results are dependent on the operating system. signal may be an integer signal number or a POSIX signal name (either with or without a SIG prefix). If signal is negative (or starts with a minus sign), kills process groups instead of processes. Not all signals are available on all platforms. The keys and values of Signal.list are known signal names and numbers, respectively.

pid = fork do
   Signal.trap("HUP") { puts "Ouch!"; exit }
   # ... do some work ...
end
# ...
Process.kill("HUP", pid)
Process.wait

produces:

Ouch!

If signal is an integer but wrong for signal, Errno::EINVAL or RangeError will be raised. Otherwise unless signal is a String or a Symbol, and a known signal name, ArgumentError will be raised.

Also, Errno::ESRCH or RangeError for invalid pid, Errno::EPERM when failed because of no privilege, will be raised. In these cases, signals may have been sent to preceding processes.

Read more on Ruby API

wait #

Process::wait

Process::wait

(from ruby core)


Process.wait()                     -> integer
Process.wait(pid=-1, flags=0)      -> integer
Process.waitpid(pid=-1, flags=0)   -> integer

Waits for a child process to exit, returns its process id, and sets $? to a Process::Status object containing information on that process. Which child it waits on depends on the value of pid:

> 0:

Waits for the child whose process ID equals <em>pid</em>.

0:

Waits for any child whose process group ID equals that of the calling
process.

-1:

Waits for any child process (the default if no <em>pid</em> is given).

< -1:

Waits for any child whose process group ID equals the absolute value
of <em>pid</em>.

The flags argument may be a logical or of the flag values Process::WNOHANG (do not block if no child available) or Process::WUNTRACED (return stopped children that haven’t been reported). Not all flags are available on all platforms, but a flag value of zero will work on all platforms.

Calling this method raises a SystemCallError if there are no child processes. Not available on all platforms.

include Process
fork { exit 99 }                 #=> 27429
wait                             #=> 27429
$?.exitstatus                    #=> 99

pid = fork { sleep 3 }           #=> 27440
Time.now                         #=> 2008-03-08 19:56:16 +0900
waitpid(pid, Process::WNOHANG)   #=> nil
Time.now                         #=> 2008-03-08 19:56:16 +0900
waitpid(pid, 0)                  #=> 27440
Time.now                         #=> 2008-03-08 19:56:19 +0900
Read more on Ruby API

time #

Benchmark::measure

Benchmark::measure

(from ruby core)


measure(label = "") { || ... }

Returns the time used to execute the given block as a Benchmark::Tms object. Takes label option.

require 'benchmark'

n = 1000000

time = Benchmark.measure do
  n.times { a = "1" }
end
puts time

Generates:

0.220000   0.000000   0.220000 (  0.227313)
Read more on Ruby API

disown #

Kernel#fork

Kernel#fork

(from ruby core)


Kernel.fork  [{ block }]   -> integer or nil
Process.fork [{ block }]   -> integer or nil

Creates a subprocess. If a block is specified, that block is run in the subprocess, and the subprocess terminates with a status of zero. Otherwise, the fork call returns twice, once in the parent, returning the process ID of the child, and once in the child, returning nil. The child process can exit using Kernel.exit! to avoid running any at_exit functions. The parent process should use Process.wait to collect the termination statuses of its children or use Process.detach to register disinterest in their status; otherwise, the operating system may accumulate zombie processes.

The thread calling fork is the only thread in the created child process. fork doesn’t copy other threads.

If fork is not usable, Process.respond_to?(:fork) returns false.

Note that fork(2) is not available on some platforms like Windows and NetBSD 4. Therefore you should use spawn() instead of fork().

Read more on Ruby API

Special Variables

$* $@ #

You can just use $* or the ARGV constant.

$# #

Equivalent Ruby code: ARGV.size

$1 $2 $3 $4 $5 $6 $7 $8 $9 #

Equivalent Ruby code: ARGV[0], ARGV[1], ARGV[2], ...

$0 #

Equivalent Ruby code: __FILE__

$? #

Equivalent Ruby code: $?

$$ $BASHPID #

You can just use $$ or Process.pid.

$PPID #

Process::ppid

Process::ppid

(from ruby core)


Process.ppid   -> integer

Returns the process id of the parent of this process. Returns untrustworthy value on Win32/64. Not available on all platforms.

puts "I am #{Process.pid}"
Process.fork { puts "Dad is #{Process.ppid}" }

produces:

I am 27417
Dad is 27417
Read more on Ruby API

$BASH_VERSINFO $BASH_VERSION #

Equivalent Ruby code: RUBY_VERSION

$HOSTNAME #

Socket::gethostname

Socket::gethostname

(from ruby core)


Socket.gethostname => hostname

Returns the hostname.

p Socket.gethostname #=> "hal"

Note that it is not guaranteed to be able to convert to IP address using gethostbyname, getaddrinfo, etc. If you need local IP address, use Socket.ip_address_list.

Read more on Ruby API

$EUID #

Process::uid

Process::uid

(from ruby core)


Process.uid           -> integer
Process::UID.rid      -> integer
Process::Sys.getuid   -> integer

Returns the (real) user ID of this process.

Process.uid   #=> 501
Read more on Ruby API
You can check for root/admin prvileges from the user by Process.uid == 0.

$HOSTTYPE #

Equivalent Ruby code: Gem::Platform.local.cpu

$LINES #

Equivalent Ruby code: IO.console.winsize[0]

$COLUMNS #

Equivalent Ruby code: IO.console.winsize[1]

$PWD #

Dir::pwd

Dir::pwd

(from ruby core)


Dir.getwd -> string
Dir.pwd -> string

Returns the path to the current working directory of this process as a string.

Dir.chdir("/tmp")   #=> 0
Dir.getwd           #=> "/tmp"
Dir.pwd             #=> "/tmp"
Read more on Ruby API

$HOME #

Dir::home

Dir::home

(from ruby core)


Dir.home()       -> "/home/me"
Dir.home("root") -> "/root"

Returns the home directory of the current user or the named user if given.

Read more on Ruby API

$RANDOM $SRANDOM #

Kernel#rand

Kernel#rand

(from ruby core)


rand(max=0)    -> number

If called without an argument, or if max.to_i.abs == 0, rand returns a pseudo-random floating point number between 0.0 and 1.0, including 0.0 and excluding 1.0.

rand        #=> 0.2725926052826416

When max.abs is greater than or equal to 1, rand returns a pseudo-random integer greater than or equal to 0 and less than max.to_i.abs.

rand(100)   #=> 12

When max is a Range, rand returns a random number where range.member?(number) == true.

Negative or floating point values for max are allowed, but may give surprising results.

rand(-100) # => 87
rand(-0.5) # => 0.8130921818028143
rand(1.9)  # equivalent to rand(1), which is always 0

Kernel.srand may be used to ensure that sequences of random numbers are reproducible between different runs of a program.

See also Random.rand.

Read more on Ruby API

$SECONDS #

Time

Time < Object


Includes:

Comparable (from ruby core)

(from ruby core)


A Time object represents a date and time:

Time.new(2000, 1, 1, 0, 0, 0) # => 2000-01-01 00:00:00 -0600

Although its value can be expressed as a single numeric (see Epoch Seconds below), it can be convenient to deal with the value by parts:

t = Time.new(-2000, 1, 1, 0, 0, 0.0)
# => -2000-01-01 00:00:00 -0600
t.year # => -2000
t.month # => 1
t.mday # => 1
t.hour # => 0
t.min # => 0
t.sec # => 0
t.subsec # => 0

t = Time.new(2000, 12, 31, 23, 59, 59.5)
# => 2000-12-31 23:59:59.5 -0600
t.year # => 2000
t.month # => 12
t.mday # => 31
t.hour # => 23
t.min # => 59
t.sec # => 59
t.subsec # => (1/2)

Epoch Seconds

Epoch seconds is the exact number of seconds (including fractional subseconds) since the Unix Epoch, January 1, 1970.

You can retrieve that value exactly using method Time.to_r:

Time.at(0).to_r        # => (0/1)
Time.at(0.999999).to_r # => (9007190247541737/9007199254740992)

Other retrieval methods such as Time#to_i and Time#to_f may return a value that rounds or truncates subseconds.

Time Resolution

A Time object derived from the system clock (for example, by method Time.now) has the resolution supported by the system.

Examples

All of these examples were done using the EST timezone which is GMT-5.

Creating a New Time Instance

You can create a new instance of Time with Time.new. This will use the current system time. Time.now is an alias for this. You can also pass parts of the time to Time.new such as year, month, minute, etc. When you want to construct a time this way you must pass at least a year. If you pass the year with nothing else time will default to January 1 of that year at 00:00:00 with the current system timezone. Here are some examples:

Time.new(2002)         #=> 2002-01-01 00:00:00 -0500
Time.new(2002, 10)     #=> 2002-10-01 00:00:00 -0500
Time.new(2002, 10, 31) #=> 2002-10-31 00:00:00 -0500

You can pass a UTC offset:

Time.new(2002, 10, 31, 2, 2, 2, "+02:00") #=> 2002-10-31 02:02:02 +0200

Or a timezone object:

zone = timezone("Europe/Athens")      # Eastern European Time, UTC+2
Time.new(2002, 10, 31, 2, 2, 2, zone) #=> 2002-10-31 02:02:02 +0200

You can also use Time.local and Time.utc to infer local and UTC timezones instead of using the current system setting.

You can also create a new time using Time.at which takes the number of seconds (with subsecond) since the Unix Epoch.

Time.at(628232400) #=> 1989-11-28 00:00:00 -0500

Working with an Instance of Time

Once you have an instance of Time there is a multitude of things you can do with it. Below are some examples. For all of the following examples, we will work on the assumption that you have done the following:

t = Time.new(1993, 02, 24, 12, 0, 0, "+09:00")

Was that a monday?

t.monday? #=> false

What year was that again?

t.year #=> 1993

Was it daylight savings at the time?

t.dst? #=> false

What’s the day a year later?

t + (60*60*24*365) #=> 1994-02-24 12:00:00 +0900

How many seconds was that since the Unix Epoch?

t.to_i #=> 730522800

You can also do standard functions like compare two times.

t1 = Time.new(2010)
t2 = Time.new(2011)

t1 == t2 #=> false
t1 == t1 #=> true
t1 <  t2 #=> true
t1 >  t2 #=> false

Time.new(2010,10,31).between?(t1, t2) #=> true

What’s Here

First, what’s elsewhere. Class Time:

Here, class Time provides methods that are useful for:

Methods for Creating

  • ::new: Returns a new time from specified arguments (year, month, etc.), including an optional timezone value.

  • ::local (aliased as ::mktime): Same as ::new, except the timezone is the local timezone.

  • ::utc (aliased as ::gm): Same as ::new, except the timezone is UTC.

  • ::at: Returns a new time based on seconds since epoch.

  • ::now: Returns a new time based on the current system time.

  • #+ (plus): Returns a new time increased by the given number of seconds.

  • #- (minus): Returns a new time decreased by the given number of seconds.

Methods for Fetching

  • #year: Returns the year of the time.

  • #month (aliased as #mon): Returns the month of the time.

  • #mday (aliased as #day): Returns the day of the month.

  • #hour: Returns the hours value for the time.

  • #min: Returns the minutes value for the time.

  • #sec: Returns the seconds value for the time.

  • #usec (aliased as #tv_usec): Returns the number of microseconds in the subseconds value of the time.

  • #nsec (aliased as #tv_nsec: Returns the number of nanoseconds in the subsecond part of the time.

  • #subsec: Returns the subseconds value for the time.

  • #wday: Returns the integer weekday value of the time (0 == Sunday).

  • #yday: Returns the integer yearday value of the time (1 == January 1).

  • #hash: Returns the integer hash value for the time.

  • #utc_offset (aliased as #gmt_offset and #gmtoff): Returns the offset in seconds between time and UTC.

  • #to_f: Returns the float number of seconds since epoch for the time.

  • #to_i (aliased as #tv_sec): Returns the integer number of seconds since epoch for the time.

  • #to_r: Returns the Rational number of seconds since epoch for the time.

  • #zone: Returns a string representation of the timezone of the time.

Methods for Querying

  • #utc? (aliased as #gmt?): Returns whether the time is UTC.

  • #dst? (aliased as #isdst): Returns whether the time is DST (daylight saving time).

  • #sunday?: Returns whether the time is a Sunday.

  • #monday?: Returns whether the time is a Monday.

  • #tuesday?: Returns whether the time is a Tuesday.

  • #wednesday?: Returns whether the time is a Wednesday.

  • #thursday?: Returns whether the time is a Thursday.

  • #friday?: Returns whether time is a Friday.

  • #saturday?: Returns whether the time is a Saturday.

Methods for Comparing

  • #<=>: Compares self to another time.

  • #eql?: Returns whether the time is equal to another time.

Methods for Converting

  • #asctime (aliased as #ctime): Returns the time as a string.

  • #inspect: Returns the time in detail as a string.

  • #strftime: Returns the time as a string, according to a given format.

  • #to_a: Returns a 10-element array of values from the time.

  • #to_s: Returns a string representation of the time.

  • #getutc (aliased as #getgm): Returns a new time converted to UTC.

  • #getlocal: Returns a new time converted to local time.

  • #utc (aliased as #gmtime): Converts time to UTC in place.

  • #localtime: Converts time to local time in place.

  • #deconstruct_keys: Returns a hash of time components used in pattern-matching.

Methods for Rounding

  • #round:Returns a new time with subseconds rounded.

  • #ceil: Returns a new time with subseconds raised to a ceiling.

  • #floor: Returns a new time with subseconds lowered to a floor.

For the forms of argument zone, see Timezone Specifiers.


Class methods:

at
gm
httpdate
iso8601
json_create
local
mktime
new
now
parse
rfc2822
rfc822
strptime
utc
xmlschema
zone_offset

Instance methods:

+
-
<=>
as_json
asctime
ceil
ctime
day
deconstruct_keys
dst?
eql?
floor
friday?
getgm
getlocal
getutc
gmt?
gmt_offset
gmtime
gmtoff
hash
hour
httpdate
inspect
isdst
iso8601
localtime
mday
min
mon
monday?
month
nsec
rfc2822
rfc822
round
saturday?
sec
strftime
subsec
sunday?
thursday?
to_a
to_date
to_datetime
to_f
to_i
to_json
to_r
to_s
to_time
tuesday?
tv_nsec
tv_sec
tv_usec
usec
utc
utc?
utc_offset
wday
wednesday?
xmlschema
yday
year
zone
Read more on Ruby API

$EPOCHREALTIME #

Time#to_f

Time#to_f

(from ruby core)


to_f -> float

Returns the value of self as a Float number Epoch seconds; subseconds are included.

The stored value of self is a Rational, which means that the returned value may be approximate:

Time.utc(1970, 1, 1, 0, 0, 0).to_f         # => 0.0
Time.utc(1970, 1, 1, 0, 0, 0, 999999).to_f # => 0.999999
Time.utc(1950, 1, 1, 0, 0, 0).to_f         # => -631152000.0
Time.utc(1990, 1, 1, 0, 0, 0).to_f         # => 631152000.0

Related: Time#to_i, Time#to_r.

Read more on Ruby API

$EPOCHSECONDS #

Time#to_i

Time#to_i

(from ruby core)


to_i -> integer

Returns the value of self as integer Epoch seconds; subseconds are truncated (not rounded):

Time.utc(1970, 1, 1, 0, 0, 0).to_i         # => 0
Time.utc(1970, 1, 1, 0, 0, 0, 999999).to_i # => 0
Time.utc(1950, 1, 1, 0, 0, 0).to_i         # => -631152000
Time.utc(1990, 1, 1, 0, 0, 0).to_i         # => 631152000

Time#tv_sec is an alias for Time#to_i.

Related: Time#to_f Time#to_r.

Read more on Ruby API

$TMPDIR #

Dir::tmpdir

Dir::tmpdir

(from ruby core)


tmpdir()

Returns the operating system’s temporary file path.

Read more on Ruby API

System's Executables

Basic Commands

clear #

Equivalent Ruby code: print "\033c"

bc dc expr #

You can do math operators anywhere in Ruby with number. For more advanced mathematical operators, take a look at the Math module.

env printenv locale #

ENV

ENV < Object

(from ruby core)


ENV is a hash-like accessor for environment variables.

Interaction with the Operating System

The ENV object interacts with the operating system’s environment variables:

  • When you get the value for a name in ENV, the value is retrieved from among the current environment variables.

  • When you create or set a name-value pair in ENV, the name and value are immediately set in the environment variables.

  • When you delete a name-value pair in ENV, it is immediately deleted from the environment variables.

Names and Values

Generally, a name or value is a String.

Valid Names and Values

Each name or value must be one of the following:

  • A String.

  • An object that responds to #to_str by returning a String, in which case that String will be used as the name or value.

Invalid Names and Values

A new name:

  • May not be the empty string:

    ENV[''] = '0'
    # Raises Errno::EINVAL (Invalid argument - ruby_setenv())
    
  • May not contain character "=":

    ENV['='] = '0'
    # Raises Errno::EINVAL (Invalid argument - ruby_setenv(=))
    

A new name or value:

  • May not be a non-String that does not respond to #to_str:

    ENV['foo'] = Object.new
    # Raises TypeError (no implicit conversion of Object into String)
    ENV[Object.new] = '0'
    # Raises TypeError (no implicit conversion of Object into String)
    
  • May not contain the NUL character "\0":

    ENV['foo'] = "\0"
    # Raises ArgumentError (bad environment variable value: contains null byte)
    ENV["\0"] == '0'
    # Raises ArgumentError (bad environment variable name: contains null byte)
    
  • May not have an ASCII-incompatible encoding such as UTF-16LE or ISO-2022-JP:

    ENV['foo'] = '0'.force_encoding(Encoding::ISO_2022_JP)
    # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: ISO-2022-JP)
    ENV["foo".force_encoding(Encoding::ISO_2022_JP)] = '0'
    # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: ISO-2022-JP)
    

About Ordering

ENV enumerates its name/value pairs in the order found in the operating system’s environment variables. Therefore the ordering of ENV content is OS-dependent, and may be indeterminate.

This will be seen in:

  • A Hash returned by an ENV method.

  • An Enumerator returned by an ENV method.

  • An Array returned by ENV.keys, ENV.values, or ENV.to_a.

  • The String returned by ENV.inspect.

  • The Array returned by ENV.shift.

  • The name returned by ENV.key.

About the Examples

Some methods in ENV return ENV itself. Typically, there are many environment variables. It’s not useful to display a large ENV in the examples here, so most example snippets begin by resetting the contents of ENV:

  • ENV.replace replaces ENV with a new collection of entries.

  • ENV.clear empties ENV.

What’s Here

First, what’s elsewhere. Class ENV:

Here, class ENV provides methods that are useful for:

Methods for Querying

  • ::[]: Returns the value for the given environment variable name if it exists:

  • ::empty?: Returns whether ENV is empty.

  • ::has_value?, ::value?: Returns whether the given value is in ENV.

  • ::include?, ::has_key?, ::key?, ::member?: Returns whether the given name is in ENV.

  • ::key: Returns the name of the first entry with the given value.

  • ::size, ::length: Returns the number of entries.

  • ::value?: Returns whether any entry has the given value.

Methods for Assigning

  • ::[]=, ::store: Creates, updates, or deletes the named environment variable.

  • ::clear: Removes every environment variable; returns ENV:

  • ::update, ::merge!: Adds to ENV each key/value pair in the given hash.

  • ::replace: Replaces the entire content of the ENV with the name/value pairs in the given hash.

Methods for Deleting

  • ::delete: Deletes the named environment variable name if it exists.

  • ::delete_if: Deletes entries selected by the block.

  • ::keep_if: Deletes entries not selected by the block.

  • ::reject!: Similar to #delete_if, but returns nil if no change was made.

  • ::select!, ::filter!: Deletes entries selected by the block.

  • ::shift: Removes and returns the first entry.

Methods for Iterating

  • ::each, ::each_pair: Calls the block with each name/value pair.

  • ::each_key: Calls the block with each name.

  • ::each_value: Calls the block with each value.

Methods for Converting

  • ::assoc: Returns a 2-element array containing the name and value of the named environment variable if it exists:

  • ::clone: Returns ENV (and issues a warning).

  • ::except: Returns a hash of all name/value pairs except those given.

  • ::fetch: Returns the value for the given name.

  • ::inspect: Returns the contents of ENV as a string.

  • ::invert: Returns a hash whose keys are the ENV values, and whose values are the corresponding ENV names.

  • ::keys: Returns an array of all names.

  • ::rassoc: Returns the name and value of the first found entry that has the given value.

  • ::reject: Returns a hash of those entries not rejected by the block.

  • ::select, ::filter: Returns a hash of name/value pairs selected by the block.

  • ::slice: Returns a hash of the given names and their corresponding values.

  • ::to_a: Returns the entries as an array of 2-element Arrays.

  • ::to_h: Returns a hash of entries selected by the block.

  • ::to_hash: Returns a hash of all entries.

  • ::to_s: Returns the string 'ENV'.

  • ::values: Returns all values as an array.

  • ::values_at: Returns an array of the values for the given name.

More Methods

  • ::dup: Raises an exception.

  • ::freeze: Raises an exception.

  • ::rehash: Returns nil, without modifying ENV.


Class methods:

[]
[]=
assoc
clear
clone
delete
delete_if
dup
each
each_key
each_pair
each_value
empty?
except
fetch
filter
filter!
freeze
has_key?
has_value?
include?
inspect
invert
keep_if
key
key?
keys
length
member?
merge!
rassoc
rehash
reject
reject!
replace
select
select!
shift
size
slice
store
to_a
to_h
to_hash
to_s
update
value?
values
values_at
Read more on Ruby API

xargs #

Kernel#then

Kernel#then

(from ruby core)


obj.then {|x| block }          -> an_object

Yields self to the block and returns the result of the block.

3.next.then {|x| x**x }.to_s             #=> "256"

Good usage for then is value piping in method chains:

require 'open-uri'
require 'json'

construct_url(arguments).
  then {|url| URI(url).read }.
  then {|response| JSON.parse(response) }

When called without block, the method returns Enumerator, which can be used, for example, for conditional circuit-breaking:

# meets condition, no-op
1.then.detect(&:odd?)            # => 1
# does not meet condition, drop value
2.then.detect(&:odd?)            # => nil
Read more on Ruby API
Tip: you can shorten the code with Numbered parameters: an_object.then { do_somethings_with _1 }

watch #

Kernel#loop

Kernel#loop

(from ruby core)


loop { block }
loop            -> an_enumerator

Repeatedly executes the block.

If no block is given, an enumerator is returned instead.

loop do
  print "Input: "
  line = gets
  break if !line or line =~ /^q/i
  # ...
end

StopIteration raised in the block breaks the loop. In this case, loop returns the “result” value stored in the exception.

enum = Enumerator.new { |y|
  y << "one"
  y << "two"
  :ok
}

result = loop {
  puts enum.next
} #=> :ok
Read more on Ruby API

pee #

Kernel#tap

Kernel#tap

(from ruby core)


obj.tap {|x| block }    -> obj

Yields self to the block, and then returns self. The primary purpose of this method is to “tap into” a method chain, in order to perform operations on intermediate results within the chain.

(1..10)                  .tap {|x| puts "original: #{x}" }
  .to_a                  .tap {|x| puts "array:    #{x}" }
  .select {|x| x.even? } .tap {|x| puts "evens:    #{x}" }
  .map {|x| x*x }        .tap {|x| puts "squares:  #{x}" }
Read more on Ruby API

tee #

Equivalent Ruby code: an_object.tap(&:display).other_method

sponge #

Equivalent Ruby code: 'string'.then { File.write 'path/to/file', _1 }

getopt #

OptionParser

OptionParser < Object

(from ruby core)


OptionParser

New to OptionParser?

See the Tutorial.

Introduction

OptionParser is a class for command-line option analysis. It is much more advanced, yet also easier to use, than GetoptLong, and is a more Ruby-oriented solution.

Features

  1. The argument specification and the code to handle it are written in the same place.

  2. It can output an option summary; you don’t need to maintain this string separately.

  3. Optional and mandatory arguments are specified very gracefully.

  4. Arguments can be automatically converted to a specified class.

  5. Arguments can be restricted to a certain set.

All of these features are demonstrated in the examples below. See #make_switch for full documentation.

Minimal example

require 'optparse'

options = {}
OptionParser.new do |parser|
  parser.banner = "Usage: example.rb [options]"

  parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
    options[:verbose] = v
  end
end.parse!

p options
p ARGV

Generating Help

OptionParser can be used to automatically generate help for the commands you write:

require 'optparse'

Options = Struct.new(:name)

class Parser
  def self.parse(options)
    args = Options.new("world")

    opt_parser = OptionParser.new do |parser|
      parser.banner = "Usage: example.rb [options]"

      parser.on("-nNAME", "--name=NAME", "Name to say hello to") do |n|
        args.name = n
      end

      parser.on("-h", "--help", "Prints this help") do
        puts parser
        exit
      end
    end

    opt_parser.parse!(options)
    return args
  end
end
options = Parser.parse %w[--help]

#=>
   # Usage: example.rb [options]
   #     -n, --name=NAME                  Name to say hello to
   #     -h, --help                       Prints this help

Required Arguments

For options that require an argument, option specification strings may include an option name in all caps. If an option is used without the required argument, an exception will be raised.

require 'optparse'

options = {}
OptionParser.new do |parser|
  parser.on("-r", "--require LIBRARY",
            "Require the LIBRARY before executing your script") do |lib|
    puts "You required #{lib}!"
  end
end.parse!

Used:

$ ruby optparse-test.rb -r
optparse-test.rb:9:in `<main>': missing argument: -r (OptionParser::MissingArgument)
$ ruby optparse-test.rb -r my-library
You required my-library!

Type Coercion

OptionParser supports the ability to coerce command line arguments into objects for us.

OptionParser comes with a few ready-to-use kinds of type coercion. They are:

  • Date – Anything accepted by Date.parse

  • DateTime – Anything accepted by DateTime.parse

  • Time – Anything accepted by Time.httpdate or Time.parse

  • URI – Anything accepted by URI.parse

  • Shellwords – Anything accepted by Shellwords.shellwords

  • String – Any non-empty string

  • Integer – Any integer. Will convert octal. (e.g. 124, -3, 040)

  • Float – Any float. (e.g. 10, 3.14, -100E+13)

  • Numeric – Any integer, float, or rational (1, 3.4, 1/3)

  • DecimalInteger – Like Integer, but no octal format.

  • OctalInteger – Like Integer, but no decimal format.

  • DecimalNumeric – Decimal integer or float.

  • TrueClass – Accepts ‘+, yes, true, -, no, false’ and defaults as true

  • FalseClass – Same as TrueClass, but defaults to false

  • Array – Strings separated by ‘,’ (e.g. 1,2,3)

  • Regexp – Regular expressions. Also includes options.

We can also add our own coercions, which we will cover below.

Using Built-in Conversions

As an example, the built-in Time conversion is used. The other built-in conversions behave in the same way. OptionParser will attempt to parse the argument as a Time. If it succeeds, that time will be passed to the handler block. Otherwise, an exception will be raised.

require 'optparse'
require 'optparse/time'
OptionParser.new do |parser|
  parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
    p time
  end
end.parse!

Used:

$ ruby optparse-test.rb  -t nonsense
... invalid argument: -t nonsense (OptionParser::InvalidArgument)
$ ruby optparse-test.rb  -t 10-11-12
2010-11-12 00:00:00 -0500
$ ruby optparse-test.rb  -t 9:30
2014-08-13 09:30:00 -0400

Creating Custom Conversions

The accept method on OptionParser may be used to create converters. It specifies which conversion block to call whenever a class is specified. The example below uses it to fetch a User object before the on handler receives it.

require 'optparse'

User = Struct.new(:id, :name)

def find_user id
  not_found = ->{ raise "No User Found for id #{id}" }
  [ User.new(1, "Sam"),
    User.new(2, "Gandalf") ].find(not_found) do |u|
    u.id == id
  end
end

op = OptionParser.new
op.accept(User) do |user_id|
  find_user user_id.to_i
end

op.on("--user ID", User) do |user|
  puts user
end

op.parse!

Used:

$ ruby optparse-test.rb --user 1
#<struct User id=1, name="Sam">
$ ruby optparse-test.rb --user 2
#<struct User id=2, name="Gandalf">
$ ruby optparse-test.rb --user 3
optparse-test.rb:15:in `block in find_user': No User Found for id 3 (RuntimeError)

Store options to a Hash

The into option of order, parse and so on methods stores command line options into a Hash.

require 'optparse'

options = {}
OptionParser.new do |parser|
  parser.on('-a')
  parser.on('-b NUM', Integer)
  parser.on('-v', '--verbose')
end.parse!(into: options)

p options

Used:

$ ruby optparse-test.rb -a
{:a=>true}
$ ruby optparse-test.rb -a -v
{:a=>true, :verbose=>true}
$ ruby optparse-test.rb -a -b 100
{:a=>true, :b=>100}

Complete example

The following example is a complete Ruby program. You can run it and see the effect of specifying various options. This is probably the best way to learn the features of optparse.

require 'optparse'
require 'optparse/time'
require 'ostruct'
require 'pp'

class OptparseExample
  Version = '1.0.0'

  CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]
  CODE_ALIASES = { "jis" => "iso-2022-jp", "sjis" => "shift_jis" }

  class ScriptOptions
    attr_accessor :library, :inplace, :encoding, :transfer_type,
                  :verbose, :extension, :delay, :time, :record_separator,
                  :list

    def initialize
      self.library = []
      self.inplace = false
      self.encoding = "utf8"
      self.transfer_type = :auto
      self.verbose = false
    end

    def define_options(parser)
      parser.banner = "Usage: example.rb [options]"
      parser.separator ""
      parser.separator "Specific options:"

      # add additional options
      perform_inplace_option(parser)
      delay_execution_option(parser)
      execute_at_time_option(parser)
      specify_record_separator_option(parser)
      list_example_option(parser)
      specify_encoding_option(parser)
      optional_option_argument_with_keyword_completion_option(parser)
      boolean_verbose_option(parser)

      parser.separator ""
      parser.separator "Common options:"
      # No argument, shows at tail.  This will print an options summary.
      # Try it and see!
      parser.on_tail("-h", "--help", "Show this message") do
        puts parser
        exit
      end
      # Another typical switch to print the version.
      parser.on_tail("--version", "Show version") do
        puts Version
        exit
      end
    end

    def perform_inplace_option(parser)
      # Specifies an optional option argument
      parser.on("-i", "--inplace [EXTENSION]",
                "Edit ARGV files in place",
                "(make backup if EXTENSION supplied)") do |ext|
        self.inplace = true
        self.extension = ext || ''
        self.extension.sub!(/\A\.?(?=.)/, ".")  # Ensure extension begins with dot.
      end
    end

    def delay_execution_option(parser)
      # Cast 'delay' argument to a Float.
      parser.on("--delay N", Float, "Delay N seconds before executing") do |n|
        self.delay = n
      end
    end

    def execute_at_time_option(parser)
      # Cast 'time' argument to a Time object.
      parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
        self.time = time
      end
    end

    def specify_record_separator_option(parser)
      # Cast to octal integer.
      parser.on("-F", "--irs [OCTAL]", OptionParser::OctalInteger,
                "Specify record separator (default \\0)") do |rs|
        self.record_separator = rs
      end
    end

    def list_example_option(parser)
      # List of arguments.
      parser.on("--list x,y,z", Array, "Example 'list' of arguments") do |list|
        self.list = list
      end
    end

    def specify_encoding_option(parser)
      # Keyword completion.  We are specifying a specific set of arguments (CODES
      # and CODE_ALIASES - notice the latter is a Hash), and the user may provide
      # the shortest unambiguous text.
      code_list = (CODE_ALIASES.keys + CODES).join(', ')
      parser.on("--code CODE", CODES, CODE_ALIASES, "Select encoding",
                "(#{code_list})") do |encoding|
        self.encoding = encoding
      end
    end

    def optional_option_argument_with_keyword_completion_option(parser)
      # Optional '--type' option argument with keyword completion.
      parser.on("--type [TYPE]", [:text, :binary, :auto],
                "Select transfer type (text, binary, auto)") do |t|
        self.transfer_type = t
      end
    end

    def boolean_verbose_option(parser)
      # Boolean switch.
      parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
        self.verbose = v
      end
    end
  end

  #
  # Return a structure describing the options.
  #
  def parse(args)
    # The options specified on the command line will be collected in
    # *options*.

    @options = ScriptOptions.new
    @args = OptionParser.new do |parser|
      @options.define_options(parser)
      parser.parse!(args)
    end
    @options
  end

  attr_reader :parser, :options
end  # class OptparseExample

example = OptparseExample.new
options = example.parse(ARGV)
pp options # example.options
pp ARGV

Shell Completion

For modern shells (e.g. bash, zsh, etc.), you can use shell completion for command line options.

Further documentation

The above examples, along with the accompanying Tutorial, should be enough to learn how to use this class. If you have any questions, file a ticket at bugs.ruby-lang.org.


Constants:

DecimalInteger:

Decimal integer format, to be converted to Integer.

DecimalNumeric:

Decimal integer/float number format, to be converted to Integer for
integer format, Float for float format.

OctalInteger:

Ruby/C like octal/hexadecimal/binary integer format, to be converted
to Integer.

Version:

[not documented]

Class methods:

accept
each_const
getopts
inc
new
reject
search_const
show_version
terminate
top
with

Instance methods:

abort
accept
additional_message
banner
base
candidate
def_head_option
def_option
def_tail_option
default_argv
define
define_by_keywords
define_head
define_tail
environment
getopts
help
inc
load
make_switch
new
on
on_head
on_tail
order
order!
parse
parse!
permute
permute!
program_name
raise_unknown
reject
release
remove
require_exact
separator
set_banner
set_program_name
set_summary_indent
set_summary_width
summarize
summary_indent
summary_width
terminate
to_a
to_s
top
ver
version
warn

Attributes:

attr_accessor default_argv
attr_accessor raise_unknown
attr_accessor require_exact
attr_accessor set_summary_indent
attr_accessor set_summary_width
attr_accessor summary_indent
attr_accessor summary_width
attr_writer banner
attr_writer program_name
attr_writer release
attr_writer set_banner
attr_writer set_program_name
attr_writer version
Read more on Ruby API

seq #

Range#to_a

Range#to_a

(from ruby core)


to_a -> array

Returns an array containing the elements in self, if a finite collection; raises an exception otherwise.

(1..4).to_a     # => [1, 2, 3, 4]
(1...4).to_a    # => [1, 2, 3]
('a'..'d').to_a # => ["a", "b", "c", "d"]

Range#entries is an alias for Range#to_a.

Read more on Ruby API
You can also write [*1..5] and it will return [1, 2, 3, 4, 5].

date #

Time

Time < Object


Includes:

Comparable (from ruby core)

(from ruby core)


A Time object represents a date and time:

Time.new(2000, 1, 1, 0, 0, 0) # => 2000-01-01 00:00:00 -0600

Although its value can be expressed as a single numeric (see Epoch Seconds below), it can be convenient to deal with the value by parts:

t = Time.new(-2000, 1, 1, 0, 0, 0.0)
# => -2000-01-01 00:00:00 -0600
t.year # => -2000
t.month # => 1
t.mday # => 1
t.hour # => 0
t.min # => 0
t.sec # => 0
t.subsec # => 0

t = Time.new(2000, 12, 31, 23, 59, 59.5)
# => 2000-12-31 23:59:59.5 -0600
t.year # => 2000
t.month # => 12
t.mday # => 31
t.hour # => 23
t.min # => 59
t.sec # => 59
t.subsec # => (1/2)

Epoch Seconds

Epoch seconds is the exact number of seconds (including fractional subseconds) since the Unix Epoch, January 1, 1970.

You can retrieve that value exactly using method Time.to_r:

Time.at(0).to_r        # => (0/1)
Time.at(0.999999).to_r # => (9007190247541737/9007199254740992)

Other retrieval methods such as Time#to_i and Time#to_f may return a value that rounds or truncates subseconds.

Time Resolution

A Time object derived from the system clock (for example, by method Time.now) has the resolution supported by the system.

Examples

All of these examples were done using the EST timezone which is GMT-5.

Creating a New Time Instance

You can create a new instance of Time with Time.new. This will use the current system time. Time.now is an alias for this. You can also pass parts of the time to Time.new such as year, month, minute, etc. When you want to construct a time this way you must pass at least a year. If you pass the year with nothing else time will default to January 1 of that year at 00:00:00 with the current system timezone. Here are some examples:

Time.new(2002)         #=> 2002-01-01 00:00:00 -0500
Time.new(2002, 10)     #=> 2002-10-01 00:00:00 -0500
Time.new(2002, 10, 31) #=> 2002-10-31 00:00:00 -0500

You can pass a UTC offset:

Time.new(2002, 10, 31, 2, 2, 2, "+02:00") #=> 2002-10-31 02:02:02 +0200

Or a timezone object:

zone = timezone("Europe/Athens")      # Eastern European Time, UTC+2
Time.new(2002, 10, 31, 2, 2, 2, zone) #=> 2002-10-31 02:02:02 +0200

You can also use Time.local and Time.utc to infer local and UTC timezones instead of using the current system setting.

You can also create a new time using Time.at which takes the number of seconds (with subsecond) since the Unix Epoch.

Time.at(628232400) #=> 1989-11-28 00:00:00 -0500

Working with an Instance of Time

Once you have an instance of Time there is a multitude of things you can do with it. Below are some examples. For all of the following examples, we will work on the assumption that you have done the following:

t = Time.new(1993, 02, 24, 12, 0, 0, "+09:00")

Was that a monday?

t.monday? #=> false

What year was that again?

t.year #=> 1993

Was it daylight savings at the time?

t.dst? #=> false

What’s the day a year later?

t + (60*60*24*365) #=> 1994-02-24 12:00:00 +0900

How many seconds was that since the Unix Epoch?

t.to_i #=> 730522800

You can also do standard functions like compare two times.

t1 = Time.new(2010)
t2 = Time.new(2011)

t1 == t2 #=> false
t1 == t1 #=> true
t1 <  t2 #=> true
t1 >  t2 #=> false

Time.new(2010,10,31).between?(t1, t2) #=> true

What’s Here

First, what’s elsewhere. Class Time:

Here, class Time provides methods that are useful for:

Methods for Creating

  • ::new: Returns a new time from specified arguments (year, month, etc.), including an optional timezone value.

  • ::local (aliased as ::mktime): Same as ::new, except the timezone is the local timezone.

  • ::utc (aliased as ::gm): Same as ::new, except the timezone is UTC.

  • ::at: Returns a new time based on seconds since epoch.

  • ::now: Returns a new time based on the current system time.

  • #+ (plus): Returns a new time increased by the given number of seconds.

  • #- (minus): Returns a new time decreased by the given number of seconds.

Methods for Fetching

  • #year: Returns the year of the time.

  • #month (aliased as #mon): Returns the month of the time.

  • #mday (aliased as #day): Returns the day of the month.

  • #hour: Returns the hours value for the time.

  • #min: Returns the minutes value for the time.

  • #sec: Returns the seconds value for the time.

  • #usec (aliased as #tv_usec): Returns the number of microseconds in the subseconds value of the time.

  • #nsec (aliased as #tv_nsec: Returns the number of nanoseconds in the subsecond part of the time.

  • #subsec: Returns the subseconds value for the time.

  • #wday: Returns the integer weekday value of the time (0 == Sunday).

  • #yday: Returns the integer yearday value of the time (1 == January 1).

  • #hash: Returns the integer hash value for the time.

  • #utc_offset (aliased as #gmt_offset and #gmtoff): Returns the offset in seconds between time and UTC.

  • #to_f: Returns the float number of seconds since epoch for the time.

  • #to_i (aliased as #tv_sec): Returns the integer number of seconds since epoch for the time.

  • #to_r: Returns the Rational number of seconds since epoch for the time.

  • #zone: Returns a string representation of the timezone of the time.

Methods for Querying

  • #utc? (aliased as #gmt?): Returns whether the time is UTC.

  • #dst? (aliased as #isdst): Returns whether the time is DST (daylight saving time).

  • #sunday?: Returns whether the time is a Sunday.

  • #monday?: Returns whether the time is a Monday.

  • #tuesday?: Returns whether the time is a Tuesday.

  • #wednesday?: Returns whether the time is a Wednesday.

  • #thursday?: Returns whether the time is a Thursday.

  • #friday?: Returns whether time is a Friday.

  • #saturday?: Returns whether the time is a Saturday.

Methods for Comparing

  • #<=>: Compares self to another time.

  • #eql?: Returns whether the time is equal to another time.

Methods for Converting

  • #asctime (aliased as #ctime): Returns the time as a string.

  • #inspect: Returns the time in detail as a string.

  • #strftime: Returns the time as a string, according to a given format.

  • #to_a: Returns a 10-element array of values from the time.

  • #to_s: Returns a string representation of the time.

  • #getutc (aliased as #getgm): Returns a new time converted to UTC.

  • #getlocal: Returns a new time converted to local time.

  • #utc (aliased as #gmtime): Converts time to UTC in place.

  • #localtime: Converts time to local time in place.

  • #deconstruct_keys: Returns a hash of time components used in pattern-matching.

Methods for Rounding

  • #round:Returns a new time with subseconds rounded.

  • #ceil: Returns a new time with subseconds raised to a ceiling.

  • #floor: Returns a new time with subseconds lowered to a floor.

For the forms of argument zone, see Timezone Specifiers.


Class methods:

at
gm
httpdate
iso8601
json_create
local
mktime
new
now
parse
rfc2822
rfc822
strptime
utc
xmlschema
zone_offset

Instance methods:

+
-
<=>
as_json
asctime
ceil
ctime
day
deconstruct_keys
dst?
eql?
floor
friday?
getgm
getlocal
getutc
gmt?
gmt_offset
gmtime
gmtoff
hash
hour
httpdate
inspect
isdst
iso8601
localtime
mday
min
mon
monday?
month
nsec
rfc2822
rfc822
round
saturday?
sec
strftime
subsec
sunday?
thursday?
to_a
to_date
to_datetime
to_f
to_i
to_json
to_r
to_s
to_time
tuesday?
tv_nsec
tv_sec
tv_usec
usec
utc
utc?
utc_offset
wday
wednesday?
xmlschema
yday
year
zone
Read more on Ruby API

sleep usleep #

Kernel#sleep

Kernel#sleep

(from ruby core)


sleep([duration])    -> integer

Suspends the current thread for duration seconds (which may be any number, including a Float with fractional seconds). Returns the actual number of seconds slept (rounded), which may be less than that asked for if another thread calls Thread#run. Called without an argument, sleep() will sleep forever.

Time.new    #=> 2008-03-08 19:56:19 +0900
sleep 1.2   #=> 1
Time.new    #=> 2008-03-08 19:56:20 +0900
sleep 1.9   #=> 2
Time.new    #=> 2008-03-08 19:56:22 +0900
Read more on Ruby API

timeout #

Timeout

Timeout

(from ruby core)


Timeout long-running blocks

Synopsis

require 'timeout'
status = Timeout::timeout(5) {
  # Something that should be interrupted if it takes more than 5 seconds...
}

Description

Timeout provides a way to auto-terminate a potentially long-running operation if it hasn’t finished in a fixed amount of time.

Previous versions didn’t use a module for namespacing, however #timeout is provided for backwards compatibility. You should prefer Timeout.timeout instead.

Copyright:

(C) 2000  Network Applied Communication Laboratory, Inc.

Copyright:

(C) 2000  Information-technology Promotion Agency, Japan

Constants:

VERSION:

[not documented]

Class methods:

timeout

Instance methods:

timeout
Read more on Ruby API

errno #

Errno

Errno

(from ruby core)


Ruby exception objects are subclasses of Exception. However, operating systems typically report errors using plain integers. Module Errno is created dynamically to map these operating system errors to Ruby classes, with each error number generating its own subclass of SystemCallError. As the subclass is created in module Errno, its name will start Errno::.

The names of the Errno:: classes depend on the environment in which Ruby runs. On a typical Unix or Windows platform, there are Errno classes such as Errno::EACCES, Errno::EAGAIN, Errno::EINTR, and so on.

The integer operating system error number corresponding to a particular error is available as the class constant Errno::error::Errno.

Errno::EACCES::Errno   #=> 13
Errno::EAGAIN::Errno   #=> 11
Errno::EINTR::Errno    #=> 4

The full list of operating system errors on your particular platform are available as the constants of Errno.

Errno.constants   #=> :E2BIG, :EACCES, :EADDRINUSE, :EADDRNOTAVAIL, ...

Read more on Ruby API

which #

MakeMakefile#find_executable

MakeMakefile#find_executable

(from ruby core)


find_executable(bin, path = nil)

Searches for the executable bin on path. The default path is your PATH environment variable. If that isn’t defined, it will resort to searching /usr/local/bin, /usr/ucb, /usr/bin and /bin.

If found, it will return the full path, including the executable name, of where it was found.

Note that this method does not actually affect the generated Makefile.

Read more on Ruby API

yes #

Equivalent Ruby code: loop { puts 'y' }

curl wget #

Use Curl-to-Ruby to convert curl commands to Ruby's code.
require 'open-uri'

URI.open('http://example.com').read

# Download a file:
URI.open('http://example.com').then { IO.copy_stream _1, 'path/to/file' }

more less #

Equivalent Ruby gem: tty-pager

tput #

Equivalent Ruby gem: tty-cursor

factor #

Equivalent Ruby gem: prime

nohup #

Kernel#fork

Kernel#fork

(from ruby core)


Kernel.fork  [{ block }]   -> integer or nil
Process.fork [{ block }]   -> integer or nil

Creates a subprocess. If a block is specified, that block is run in the subprocess, and the subprocess terminates with a status of zero. Otherwise, the fork call returns twice, once in the parent, returning the process ID of the child, and once in the child, returning nil. The child process can exit using Kernel.exit! to avoid running any at_exit functions. The parent process should use Process.wait to collect the termination statuses of its children or use Process.detach to register disinterest in their status; otherwise, the operating system may accumulate zombie processes.

The thread calling fork is the only thread in the created child process. fork doesn’t copy other threads.

If fork is not usable, Process.respond_to?(:fork) returns false.

Note that fork(2) is not available on some platforms like Windows and NetBSD 4. Therefore you should use spawn() instead of fork().

Read more on Ruby API

Data Processing

Array#first

Array#first

(from ruby core)


array.first -> object or nil
array.first(n) -> new_array

Returns elements from self; does not modify self.

When no argument is given, returns the first element:

a = [:foo, 'bar', 2]
a.first # => :foo
a # => [:foo, "bar", 2]

If self is empty, returns nil.

When non-negative Integer argument n is given, returns the first n elements in a new Array:

a = [:foo, 'bar', 2]
a.first(2) # => [:foo, "bar"]

If n >= array.size, returns all elements:

a = [:foo, 'bar', 2]
a.first(50) # => [:foo, "bar", 2]

If n == 0 returns an new empty Array:

a = [:foo, 'bar', 2]
a.first(0) # []

Related: #last.

Read more on Ruby API

tail #

Array#last

Array#last

(from ruby core)


array.last  -> object or nil
array.last(n) -> new_array

Returns elements from self; self is not modified.

When no argument is given, returns the last element:

a = [:foo, 'bar', 2]
a.last # => 2
a # => [:foo, "bar", 2]

If self is empty, returns nil.

When non-negative Integer argument n is given, returns the last n elements in a new Array:

a = [:foo, 'bar', 2]
a.last(2) # => ["bar", 2]

If n >= array.size, returns all elements:

a = [:foo, 'bar', 2]
a.last(50) # => [:foo, "bar", 2]

If n == 0, returns an new empty Array:

a = [:foo, 'bar', 2]
a.last(0) # []

Related: #first.

Read more on Ruby API

sort #

Array#sort

Array#sort

(from ruby core)


array.sort -> new_array
array.sort {|a, b| ... } -> new_array

Returns a new Array whose elements are those from self, sorted.

With no block, compares elements using operator <=> (see Comparable):

a = 'abcde'.split('').shuffle
a # => ["e", "b", "d", "a", "c"]
a1 = a.sort
a1 # => ["a", "b", "c", "d", "e"]

With a block, calls the block with each element pair; for each element pair a and b, the block should return an integer:

  • Negative when b is to follow a.

  • Zero when a and b are equivalent.

  • Positive when a is to follow b.

Example:

a = 'abcde'.split('').shuffle
a # => ["e", "b", "d", "a", "c"]
a1 = a.sort {|a, b| a <=> b }
a1 # => ["a", "b", "c", "d", "e"]
a2 = a.sort {|a, b| b <=> a }
a2 # => ["e", "d", "c", "b", "a"]

When the block returns zero, the order for a and b is indeterminate, and may be unstable:

a = 'abcde'.split('').shuffle
a # => ["e", "b", "d", "a", "c"]
a1 = a.sort {|a, b| 0 }
a1 # =>  ["c", "e", "b", "d", "a"]

Related: Enumerable#sort_by.

Read more on Ruby API

rev tac #

String#reverse

String#reverse

(from ruby core)


reverse -> string

Returns a new string with the characters from self in reverse order.

'stressed'.reverse # => "desserts"
Read more on Ruby API
Array#reverse

Array#reverse

(from ruby core)


array.reverse -> new_array

Returns a new Array with the elements of self in reverse order:

a = ['foo', 'bar', 'two']
a1 = a.reverse
a1 # => ["two", "bar", "foo"]
Read more on Ruby API

shuf #

Array#shuffle

Array#shuffle

(from ruby core)


array.shuffle(random: Random) -> new_ary

Returns a new array with elements of self shuffled.

a = [1, 2, 3] #=> [1, 2, 3]
a.shuffle     #=> [2, 3, 1]
a             #=> [1, 2, 3]

The optional random argument will be used as the random number generator:

a.shuffle(random: Random.new(1))  #=> [1, 3, 2]
Read more on Ruby API

uniq #

Array#uniq

Array#uniq

(from ruby core)


array.uniq -> new_array
array.uniq {|element| ... } -> new_array

Returns a new Array containing those elements from self that are not duplicates, the first occurrence always being retained.

With no block given, identifies and omits duplicates using method eql? to compare:

a = [0, 0, 1, 1, 2, 2]
a.uniq # => [0, 1, 2]

With a block given, calls the block for each element; identifies (using method eql?) and omits duplicate values, that is, those elements for which the block returns the same value:

a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb']
a.uniq {|element| element.size } # => ["a", "aa", "aaa"]
Read more on Ruby API

split csplit #

Enumerable#each_slice

Enumerable#each_slice

(from ruby core)


each_slice(n) { ... }  ->  self
each_slice(n)          ->  enumerator

Calls the block with each successive disjoint n-tuple of elements; returns self:

a = []
(1..10).each_slice(3) {|tuple| a.push(tuple) }
a # => [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]

a = []
h = {foo: 0, bar: 1, baz: 2, bat: 3, bam: 4}
h.each_slice(2) {|tuple| a.push(tuple) }
a # => [[[:foo, 0], [:bar, 1]], [[:baz, 2], [:bat, 3]], [[:bam, 4]]]

With no block given, returns an Enumerator.

Read more on Ruby API

wc #

Array#size

Array#size

(from ruby core)


size()

Returns the count of elements in self.

(This method is an alias for Array#length.)

Returns the count of elements in self.

Read more on Ruby API
Equivalent Ruby code:
chars_count = 'string'.chars.size
words_count = 'Hello, World!'.split.size
lines_count = "1\n2\n3".lines.size

tr #

String#tr

String#tr

(from ruby core)


tr(selector, replacements) -> new_string

Returns a copy of self with each character specified by string selector translated to the corresponding character in string replacements. The correspondence is positional:

  • Each occurrence of the first character specified by selector is translated to the first character in replacements.

  • Each occurrence of the second character specified by selector is translated to the second character in replacements.

  • And so on.

Example:

'hello'.tr('el', 'ip') #=> "hippo"

If replacements is shorter than selector, it is implicitly padded with its own last character:

'hello'.tr('aeiou', '-')   # => "h-ll-"
'hello'.tr('aeiou', 'AA-') # => "hAll-"

Arguments selector and replacements must be valid character selectors (see Character Selectors), and may use any of its valid forms, including negation, ranges, and escaping:

# Negation.
'hello'.tr('^aeiou', '-') # => "-e--o"
# Ranges.
'ibm'.tr('b-z', 'a-z') # => "hal"
# Escapes.
'hel^lo'.tr('\^aeiou', '-')     # => "h-l-l-"    # Escaped leading caret.
'i-b-m'.tr('b\-z', 'a-z')       # => "ibabm"     # Escaped embedded hyphen.
'foo\\bar'.tr('ab\\', 'XYZ')    # => "fooZYXr"   # Escaped backslash.
Read more on Ruby API

cut #

Array#[]

Array#[]

(from ruby core)


array[index] -> object or nil
array[start, length] -> object or nil
array[range] -> object or nil
array[aseq] -> object or nil
array.slice(index) -> object or nil
array.slice(start, length) -> object or nil
array.slice(range) -> object or nil
array.slice(aseq) -> object or nil

Returns elements from self; does not modify self.

When a single Integer argument index is given, returns the element at offset index:

a = [:foo, 'bar', 2]
a[0] # => :foo
a[2] # => 2
a # => [:foo, "bar", 2]

If index is negative, counts relative to the end of self:

a = [:foo, 'bar', 2]
a[-1] # => 2
a[-2] # => "bar"

If index is out of range, returns nil.

When two Integer arguments start and length are given, returns a new Array of size length containing successive elements beginning at offset start:

a = [:foo, 'bar', 2]
a[0, 2] # => [:foo, "bar"]
a[1, 2] # => ["bar", 2]

If start + length is greater than self.length, returns all elements from offset start to the end:

a = [:foo, 'bar', 2]
a[0, 4] # => [:foo, "bar", 2]
a[1, 3] # => ["bar", 2]
a[2, 2] # => [2]

If start == self.size and length >= 0, returns a new empty Array.

If length is negative, returns nil.

When a single Range argument range is given, treats range.min as start above and range.size as length above:

a = [:foo, 'bar', 2]
a[0..1] # => [:foo, "bar"]
a[1..2] # => ["bar", 2]

Special case: If range.start == a.size, returns a new empty Array.

If range.end is negative, calculates the end index from the end:

a = [:foo, 'bar', 2]
a[0..-1] # => [:foo, "bar", 2]
a[0..-2] # => [:foo, "bar"]
a[0..-3] # => [:foo]

If range.start is negative, calculates the start index from the end:

a = [:foo, 'bar', 2]
a[-1..2] # => [2]
a[-2..2] # => ["bar", 2]
a[-3..2] # => [:foo, "bar", 2]

If range.start is larger than the array size, returns nil.

a = [:foo, 'bar', 2]
a[4..1] # => nil
a[4..0] # => nil
a[4..-1] # => nil

When a single Enumerator::ArithmeticSequence argument aseq is given, returns an Array of elements corresponding to the indexes produced by the sequence.

a = ['--', 'data1', '--', 'data2', '--', 'data3']
a[(1..).step(2)] # => ["data1", "data2", "data3"]

Unlike slicing with range, if the start or the end of the arithmetic sequence is larger than array size, throws RangeError.

a = ['--', 'data1', '--', 'data2', '--', 'data3']
a[(1..11).step(2)]
# RangeError (((1..11).step(2)) out of range)
a[(7..).step(2)]
# RangeError (((7..).step(2)) out of range)

If given a single argument, and its type is not one of the listed, tries to convert it to Integer, and raises if it is impossible:

a = [:foo, 'bar', 2]
# Raises TypeError (no implicit conversion of Symbol into Integer):
a[:foo]

Array#slice is an alias for Array#[].

Read more on Ruby API

join paste pr #

Array#transpose

Array#transpose

(from ruby core)


array.transpose -> new_array

Transposes the rows and columns in an Array of Arrays; the nested Arrays must all be the same size:

a = [[:a0, :a1], [:b0, :b1], [:c0, :c1]]
a.transpose # => [[:a0, :b0, :c0], [:a1, :b1, :c1]]
Read more on Ruby API
Array#zip

Array#zip

(from ruby core)


array.zip(*other_arrays) -> new_array
array.zip(*other_arrays) {|other_array| ... } -> nil

When no block given, returns a new Array new_array of size self.size whose elements are Arrays.

Each nested array new_array[n] is of size other_arrays.size+1, and contains:

  • The nth element of self.

  • The nth element of each of the other_arrays.

If all other_arrays and self are the same size:

a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2, :b3]
c = [:c0, :c1, :c2, :c3]
d = a.zip(b, c)
d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]]

If any array in other_arrays is smaller than self, fills to self.size with nil:

a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2]
c = [:c0, :c1]
d = a.zip(b, c)
d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, nil], [:a3, nil, nil]]

If any array in other_arrays is larger than self, its trailing elements are ignored:

a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2, :b3, :b4]
c = [:c0, :c1, :c2, :c3, :c4, :c5]
d = a.zip(b, c)
d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]]

When a block is given, calls the block with each of the sub-arrays (formed as above); returns nil:

a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2, :b3]
c = [:c0, :c1, :c2, :c3]
a.zip(b, c) {|sub_array| p sub_array} # => nil

Output:

[:a0, :b0, :c0]
[:a1, :b1, :c1]
[:a2, :b2, :c2]
[:a3, :b3, :c3]
Read more on Ruby API

combine #

Equivalent Ruby code:
file1 = File.readlines('path/to/file1', chomp: true) # Get array of lines in file1
file2 = File.readlines('path/to/file1', chomp: true) # Get array of lines in file2

combine_and = file1 & file2  # Outputs lines that are in file1 if they are also present in file2.
combine_not = file1 - file2  # Outputs lines that are in file1 but not in file2.
combine_or  = file1 | file2  # Outputs lines that are in file1 or file2.
combine_xor = combine_or - combine_and  # Outputs lines that are in either file1 or file2, but not in both files.

grep #

Enumerable#grep

Enumerable#grep

(from ruby core)


grep(pattern) -> array
grep(pattern) {|element| ... } -> array

Returns an array of objects based elements of self that match the given pattern.

With no block given, returns an array containing each element for which pattern === element is true:

a = ['foo', 'bar', 'car', 'moo']
a.grep(/ar/)                   # => ["bar", "car"]
(1..10).grep(3..8)             # => [3, 4, 5, 6, 7, 8]
['a', 'b', 0, 1].grep(Integer) # => [0, 1]

With a block given, calls the block with each matching element and returns an array containing each object returned by the block:

a = ['foo', 'bar', 'car', 'moo']
a.grep(/ar/) {|element| element.upcase } # => ["BAR", "CAR"]

Related: #grep_v.

Read more on Ruby API

sed #

String#sub

String#sub

(from ruby core)


sub(pattern, replacement)   -> new_string
sub(pattern) {|match| ... } -> new_string

Returns a copy of self with only the first occurrence (not all occurrences) of the given pattern replaced.

See Substitution Methods.

Related: String#sub!, String#gsub, String#gsub!.

Read more on Ruby API
String#gsub

String#gsub

(from ruby core)


gsub(pattern, replacement)   -> new_string
gsub(pattern) {|match| ... } -> new_string
gsub(pattern)                -> enumerator

Returns a copy of self with all occurrences of the given pattern replaced.

See Substitution Methods.

Returns an Enumerator if no replacement and no block given.

Related: String#sub, String#sub!, String#gsub!.

Read more on Ruby API

awk #

Ruby can be use as a great text-processing tool. Check out Ruby one-liners cookbook to learn more. Also check out Ru.

expand #

Equivalent Ruby code: string_with_tabs.gsub(/^[ \t]*/) { _1.gsub "\t", ' ' * 4 }

unexpand #

Equivalent Ruby code: string_with_spaces.gsub(/^[ \t]*/) { _1.gsub ' ' * 4, "\t" }

strings #

Equivalent Ruby code: a_multiline_string.lines.select { _1.size >= 4 }

ascii #

String#ord

String#ord

(from ruby core)


ord -> integer

Returns the integer ordinal of the first character of self:

'h'.ord         # => 104
'hello'.ord     # => 104
'тест'.ord      # => 1090
'こんにちは'.ord  # => 12371
Read more on Ruby API

od xxd hexdump #

Integer#to_s

Integer#to_s

(from ruby core)


to_s(base = 10)  ->  string

Returns a string containing the place-value representation of self in radix base (in 2..36).

12345.to_s               # => "12345"
12345.to_s(2)            # => "11000000111001"
12345.to_s(8)            # => "30071"
12345.to_s(10)           # => "12345"
12345.to_s(16)           # => "3039"
12345.to_s(36)           # => "9ix"
78546939656932.to_s(36)  # => "rubyrules"

Raises an exception if base is out of range.

Integer#inspect is an alias for Integer#to_s.

Read more on Ruby API
String#to_i

String#to_i

(from ruby core)


to_i(base = 10) -> integer

Returns the result of interpreting leading characters in self as an integer in the given base (which must be in (0, 2..36)):

'123456'.to_i     # => 123456
'123def'.to_i(16) # => 1195503

With base zero, string object may contain leading characters to specify the actual base:

'123def'.to_i(0)   # => 123
'0123def'.to_i(0)  # => 83
'0b123def'.to_i(0) # => 1
'0o123def'.to_i(0) # => 83
'0d123def'.to_i(0) # => 123
'0x123def'.to_i(0) # => 1195503

Characters past a leading valid number (in the given base) are ignored:

'12.345'.to_i   # => 12
'12345'.to_i(2) # => 1

Returns zero if there is no leading valid number:

'abcdef'.to_i # => 0
'2'.to_i(2)   # => 0
Read more on Ruby API

ifne #

String#empty?

String#empty?

(from ruby core)


empty? -> true or false

Returns true if the length of self is zero, false otherwise:

"hello".empty? # => false
" ".empty? # => false
"".empty? # => true
Read more on Ruby API

iconv #

String#encode

String#encode

(from ruby core)


encode(dst_encoding = Encoding.default_internal, **enc_opts) -> string
encode(dst_encoding, src_encoding, **enc_opts)   -> string

Returns a copy of self transcoded as determined by dst_encoding. By default, raises an exception if self contains an invalid byte or a character not defined in dst_encoding; that behavior may be modified by encoding options; see below.

With no arguments:

  • Uses the same encoding if Encoding.default_internal is nil (the default):

    Encoding.default_internal # => nil
    s = "Ruby\x99".force_encoding('Windows-1252')
    s.encoding                # => #<Encoding:Windows-1252>
    s.bytes                   # => [82, 117, 98, 121, 153]
    t = s.encode              # => "Ruby\x99"
    t.encoding                # => #<Encoding:Windows-1252>
    t.bytes                   # => [82, 117, 98, 121, 226, 132, 162]
    
  • Otherwise, uses the encoding Encoding.default_internal:

    Encoding.default_internal = 'UTF-8'
    t = s.encode              # => "Ruby™"
    t.encoding                # => #<Encoding:UTF-8>
    

With only argument dst_encoding given, uses that encoding:

s = "Ruby\x99".force_encoding('Windows-1252')
s.encoding            # => #<Encoding:Windows-1252>
t = s.encode('UTF-8') # => "Ruby™"
t.encoding            # => #<Encoding:UTF-8>

With arguments dst_encoding and src_encoding given, interprets self using src_encoding, encodes the new string using dst_encoding:

s = "Ruby\x99"
t = s.encode('UTF-8', 'Windows-1252') # => "Ruby™"
t.encoding                            # => #<Encoding:UTF-8>

Optional keyword arguments enc_opts specify encoding options; see Encoding Options.

Read more on Ruby API

isutf8 #

String#isutf8

String#isutf8

(from ruby core)


String#isutf8   => true or false

Returns whether self‘s encoding is UTF-8 or not.

Read more on Ruby API

jq #

JSON

JSON

(from ruby core)


JavaScript Object Notation (JSON)

JSON is a lightweight data-interchange format.

A JSON value is one of the following:

  • Double-quoted text: "foo".

  • Number: 1, 1.0, 2.0e2.

  • Boolean: true, false.

  • Null: null.

  • Array: an ordered list of values, enclosed by square brackets:

    ["foo", 1, 1.0, 2.0e2, true, false, null]
    
  • Object: a collection of name/value pairs, enclosed by curly braces; each name is double-quoted text; the values may be any JSON values:

    {"a": "foo", "b": 1, "c": 1.0, "d": 2.0e2, "e": true, "f": false, "g": null}
    

A JSON array or object may contain nested arrays, objects, and scalars to any depth:

{"foo": {"bar": 1, "baz": 2}, "bat": [0, 1, 2]}
[{"foo": 0, "bar": 1}, ["baz", 2]]

Using Module JSON

To make module JSON available in your code, begin with:

require 'json'

All examples here assume that this has been done.

Parsing JSON

You can parse a String containing JSON data using either of two methods:

  • JSON.parse(source, opts)

  • JSON.parse!(source, opts)

where

  • source is a Ruby object.

  • opts is a Hash object containing options that control both input allowed and output formatting.

The difference between the two methods is that JSON.parse! omits some checks and may not be safe for some source data; use it only for data from trusted sources. Use the safer method JSON.parse for less trusted sources.

Parsing JSON Arrays

When source is a JSON array, JSON.parse by default returns a Ruby Array:

json = '["foo", 1, 1.0, 2.0e2, true, false, null]'
ruby = JSON.parse(json)
ruby # => ["foo", 1, 1.0, 200.0, true, false, nil]
ruby.class # => Array

The JSON array may contain nested arrays, objects, and scalars to any depth:

json = '[{"foo": 0, "bar": 1}, ["baz", 2]]'
JSON.parse(json) # => [{"foo"=>0, "bar"=>1}, ["baz", 2]]

Parsing JSON Objects

When the source is a JSON object, JSON.parse by default returns a Ruby Hash:

json = '{"a": "foo", "b": 1, "c": 1.0, "d": 2.0e2, "e": true, "f": false, "g": null}'
ruby = JSON.parse(json)
ruby # => {"a"=>"foo", "b"=>1, "c"=>1.0, "d"=>200.0, "e"=>true, "f"=>false, "g"=>nil}
ruby.class # => Hash

The JSON object may contain nested arrays, objects, and scalars to any depth:

json = '{"foo": {"bar": 1, "baz": 2}, "bat": [0, 1, 2]}'
JSON.parse(json) # => {"foo"=>{"bar"=>1, "baz"=>2}, "bat"=>[0, 1, 2]}

Parsing JSON Scalars

When the source is a JSON scalar (not an array or object), JSON.parse returns a Ruby scalar.

String:

ruby = JSON.parse('"foo"')
ruby # => 'foo'
ruby.class # => String

Integer:

ruby = JSON.parse('1')
ruby # => 1
ruby.class # => Integer

Float:

ruby = JSON.parse('1.0')
ruby # => 1.0
ruby.class # => Float
ruby = JSON.parse('2.0e2')
ruby # => 200
ruby.class # => Float

Boolean:

ruby = JSON.parse('true')
ruby # => true
ruby.class # => TrueClass
ruby = JSON.parse('false')
ruby # => false
ruby.class # => FalseClass

Null:

ruby = JSON.parse('null')
ruby # => nil
ruby.class # => NilClass

Parsing Options

Input Options

Option max_nesting (Integer) specifies the maximum nesting depth allowed; defaults to 100; specify false to disable depth checking.

With the default, false:

source = '[0, [1, [2, [3]]]]'
ruby = JSON.parse(source)
ruby # => [0, [1, [2, [3]]]]

Too deep:

# Raises JSON::NestingError (nesting of 2 is too deep):
JSON.parse(source, {max_nesting: 1})

Bad value:

# Raises TypeError (wrong argument type Symbol (expected Fixnum)):
JSON.parse(source, {max_nesting: :foo})

Option allow_nan (boolean) specifies whether to allow NaN, Infinity, and MinusInfinity in source; defaults to false.

With the default, false:

# Raises JSON::ParserError (225: unexpected token at '[NaN]'):
JSON.parse('[NaN]')
# Raises JSON::ParserError (232: unexpected token at '[Infinity]'):
JSON.parse('[Infinity]')
# Raises JSON::ParserError (248: unexpected token at '[-Infinity]'):
JSON.parse('[-Infinity]')

Allow:

source = '[NaN, Infinity, -Infinity]'
ruby = JSON.parse(source, {allow_nan: true})
ruby # => [NaN, Infinity, -Infinity]
Output Options

Option symbolize_names (boolean) specifies whether returned Hash keys should be Symbols; defaults to false (use Strings).

With the default, false:

source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}'
ruby = JSON.parse(source)
ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil}

Use Symbols:

ruby = JSON.parse(source, {symbolize_names: true})
ruby # => {:a=>"foo", :b=>1.0, :c=>true, :d=>false, :e=>nil}

Option object_class (Class) specifies the Ruby class to be used for each JSON object; defaults to Hash.

With the default, Hash:

source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}'
ruby = JSON.parse(source)
ruby.class # => Hash

Use class OpenStruct:

ruby = JSON.parse(source, {object_class: OpenStruct})
ruby # => #<OpenStruct a="foo", b=1.0, c=true, d=false, e=nil>

Option array_class (Class) specifies the Ruby class to be used for each JSON array; defaults to Array.

With the default, Array:

source = '["foo", 1.0, true, false, null]'
ruby = JSON.parse(source)
ruby.class # => Array

Use class Set:

ruby = JSON.parse(source, {array_class: Set})
ruby # => #<Set: {"foo", 1.0, true, false, nil}>

Option create_additions (boolean) specifies whether to use JSON additions in parsing. See JSON Additions.

Generating JSON

To generate a Ruby String containing JSON data, use method JSON.generate(source, opts), where

  • source is a Ruby object.

  • opts is a Hash object containing options that control both input allowed and output formatting.

Generating JSON from Arrays

When the source is a Ruby Array, JSON.generate returns a String containing a JSON array:

ruby = [0, 's', :foo]
json = JSON.generate(ruby)
json # => '[0,"s","foo"]'

The Ruby Array array may contain nested arrays, hashes, and scalars to any depth:

ruby = [0, [1, 2], {foo: 3, bar: 4}]
json = JSON.generate(ruby)
json # => '[0,[1,2],{"foo":3,"bar":4}]'

Generating JSON from Hashes

When the source is a Ruby Hash, JSON.generate returns a String containing a JSON object:

ruby = {foo: 0, bar: 's', baz: :bat}
json = JSON.generate(ruby)
json # => '{"foo":0,"bar":"s","baz":"bat"}'

The Ruby Hash array may contain nested arrays, hashes, and scalars to any depth:

ruby = {foo: [0, 1], bar: {baz: 2, bat: 3}, bam: :bad}
json = JSON.generate(ruby)
json # => '{"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"}'

Generating JSON from Other Objects

When the source is neither an Array nor a Hash, the generated JSON data depends on the class of the source.

When the source is a Ruby Integer or Float, JSON.generate returns a String containing a JSON number:

JSON.generate(42) # => '42'
JSON.generate(0.42) # => '0.42'

When the source is a Ruby String, JSON.generate returns a String containing a JSON string (with double-quotes):

JSON.generate('A string') # => '"A string"'

When the source is true, false or nil, JSON.generate returns a String containing the corresponding JSON token:

JSON.generate(true) # => 'true'
JSON.generate(false) # => 'false'
JSON.generate(nil) # => 'null'

When the source is none of the above, JSON.generate returns a String containing a JSON string representation of the source:

JSON.generate(:foo) # => '"foo"'
JSON.generate(Complex(0, 0)) # => '"0+0i"'
JSON.generate(Dir.new('.')) # => '"#<Dir>"'

Generating Options

Input Options

Option allow_nan (boolean) specifies whether NaN, Infinity, and -Infinity may be generated; defaults to false.

With the default, false:

# Raises JSON::GeneratorError (920: NaN not allowed in JSON):
JSON.generate(JSON::NaN)
# Raises JSON::GeneratorError (917: Infinity not allowed in JSON):
JSON.generate(JSON::Infinity)
# Raises JSON::GeneratorError (917: -Infinity not allowed in JSON):
JSON.generate(JSON::MinusInfinity)

Allow:

ruby = [Float::NaN, Float::Infinity, Float::MinusInfinity]
JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,-Infinity]'

Option max_nesting (Integer) specifies the maximum nesting depth in obj; defaults to 100.

With the default, 100:

obj = [[[[[[0]]]]]]
JSON.generate(obj) # => '[[[[[[0]]]]]]'

Too deep:

# Raises JSON::NestingError (nesting of 2 is too deep):
JSON.generate(obj, max_nesting: 2)
Output Options

The default formatting options generate the most compact JSON data, all on one line and with no whitespace.

You can use these formatting options to generate JSON data in a more open format, using whitespace. See also JSON.pretty_generate.

  • Option array_nl (String) specifies a string (usually a newline) to be inserted after each JSON array; defaults to the empty String, ''.

  • Option object_nl (String) specifies a string (usually a newline) to be inserted after each JSON object; defaults to the empty String, ''.

  • Option indent (String) specifies the string (usually spaces) to be used for indentation; defaults to the empty String, ''; defaults to the empty String, ''; has no effect unless options array_nl or object_nl specify newlines.

  • Option space (String) specifies a string (usually a space) to be inserted after the colon in each JSON object’s pair; defaults to the empty String, ''.

  • Option space_before (String) specifies a string (usually a space) to be inserted before the colon in each JSON object’s pair; defaults to the empty String, ''.

In this example, obj is used first to generate the shortest JSON data (no whitespace), then again with all formatting options specified:

obj = {foo: [:bar, :baz], bat: {bam: 0, bad: 1}}
json = JSON.generate(obj)
puts 'Compact:', json
opts = {
  array_nl: "\n",
  object_nl: "\n",
  indent: '  ',
  space_before: ' ',
  space: ' '
}
puts 'Open:', JSON.generate(obj, opts)

Output:

Compact:
{"foo":["bar","baz"],"bat":{"bam":0,"bad":1}}
Open:
{
  "foo" : [
    "bar",
    "baz"
],
  "bat" : {
    "bam" : 0,
    "bad" : 1
  }
}

JSON Additions

When you “round trip” a non-String object from Ruby to JSON and back, you have a new String, instead of the object you began with:

ruby0 = Range.new(0, 2)
json = JSON.generate(ruby0)
json # => '0..2"'
ruby1 = JSON.parse(json)
ruby1 # => '0..2'
ruby1.class # => String

You can use JSON additions to preserve the original object. The addition is an extension of a ruby class, so that:

  • JSON.generate stores more information in the JSON string.

  • JSON.parse, called with option create_additions, uses that information to create a proper Ruby object.

This example shows a Range being generated into JSON and parsed back into Ruby, both without and with the addition for Range:

ruby = Range.new(0, 2)
# This passage does not use the addition for Range.
json0 = JSON.generate(ruby)
ruby0 = JSON.parse(json0)
# This passage uses the addition for Range.
require 'json/add/range'
json1 = JSON.generate(ruby)
ruby1 = JSON.parse(json1, create_additions: true)
# Make a nice display.
display = <<EOT
Generated JSON:
  Without addition:  #{json0} (#{json0.class})
  With addition:     #{json1} (#{json1.class})
Parsed JSON:
  Without addition:  #{ruby0.inspect} (#{ruby0.class})
  With addition:     #{ruby1.inspect} (#{ruby1.class})
EOT
puts display

This output shows the different results:

Generated JSON:
  Without addition:  "0..2" (String)
  With addition:     {"json_class":"Range","a":[0,2,false]} (String)
Parsed JSON:
  Without addition:  "0..2" (String)
  With addition:     0..2 (Range)

The JSON module includes additions for certain classes. You can also craft custom additions. See Custom JSON Additions.

Built-in Additions

The JSON module includes additions for certain classes. To use an addition, require its source:

  • BigDecimal: require 'json/add/bigdecimal'

  • Complex: require 'json/add/complex'

  • Date: require 'json/add/date'

  • DateTime: require 'json/add/date_time'

  • Exception: require 'json/add/exception'

  • OpenStruct: require 'json/add/ostruct'

  • Range: require 'json/add/range'

  • Rational: require 'json/add/rational'

  • Regexp: require 'json/add/regexp'

  • Set: require 'json/add/set'

  • Struct: require 'json/add/struct'

  • Symbol: require 'json/add/symbol'

  • Time: require 'json/add/time'

To reduce punctuation clutter, the examples below show the generated JSON via puts, rather than the usual inspect,

BigDecimal:

require 'json/add/bigdecimal'
ruby0 = BigDecimal(0) # 0.0
json = JSON.generate(ruby0) # {"json_class":"BigDecimal","b":"27:0.0"}
ruby1 = JSON.parse(json, create_additions: true) # 0.0
ruby1.class # => BigDecimal

Complex:

require 'json/add/complex'
ruby0 = Complex(1+0i) # 1+0i
json = JSON.generate(ruby0) # {"json_class":"Complex","r":1,"i":0}
ruby1 = JSON.parse(json, create_additions: true) # 1+0i
ruby1.class # Complex

Date:

require 'json/add/date'
ruby0 = Date.today # 2020-05-02
json = JSON.generate(ruby0) # {"json_class":"Date","y":2020,"m":5,"d":2,"sg":2299161.0}
ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02
ruby1.class # Date

DateTime:

require 'json/add/date_time'
ruby0 = DateTime.now # 2020-05-02T10:38:13-05:00
json = JSON.generate(ruby0) # {"json_class":"DateTime","y":2020,"m":5,"d":2,"H":10,"M":38,"S":13,"of":"-5/24","sg":2299161.0}
ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02T10:38:13-05:00
ruby1.class # DateTime

Exception (and its subclasses including RuntimeError):

require 'json/add/exception'
ruby0 = Exception.new('A message') # A message
json = JSON.generate(ruby0) # {"json_class":"Exception","m":"A message","b":null}
ruby1 = JSON.parse(json, create_additions: true) # A message
ruby1.class # Exception
ruby0 = RuntimeError.new('Another message') # Another message
json = JSON.generate(ruby0) # {"json_class":"RuntimeError","m":"Another message","b":null}
ruby1 = JSON.parse(json, create_additions: true) # Another message
ruby1.class # RuntimeError

OpenStruct:

require 'json/add/ostruct'
ruby0 = OpenStruct.new(name: 'Matz', language: 'Ruby') # #<OpenStruct name="Matz", language="Ruby">
json = JSON.generate(ruby0) # {"json_class":"OpenStruct","t":{"name":"Matz","language":"Ruby"}}
ruby1 = JSON.parse(json, create_additions: true) # #<OpenStruct name="Matz", language="Ruby">
ruby1.class # OpenStruct

Range:

require 'json/add/range'
ruby0 = Range.new(0, 2) # 0..2
json = JSON.generate(ruby0) # {"json_class":"Range","a":[0,2,false]}
ruby1 = JSON.parse(json, create_additions: true) # 0..2
ruby1.class # Range

Rational:

require 'json/add/rational'
ruby0 = Rational(1, 3) # 1/3
json = JSON.generate(ruby0) # {"json_class":"Rational","n":1,"d":3}
ruby1 = JSON.parse(json, create_additions: true) # 1/3
ruby1.class # Rational

Regexp:

require 'json/add/regexp'
ruby0 = Regexp.new('foo') # (?-mix:foo)
json = JSON.generate(ruby0) # {"json_class":"Regexp","o":0,"s":"foo"}
ruby1 = JSON.parse(json, create_additions: true) # (?-mix:foo)
ruby1.class # Regexp

Set:

require 'json/add/set'
ruby0 = Set.new([0, 1, 2]) # #<Set: {0, 1, 2}>
json = JSON.generate(ruby0) # {"json_class":"Set","a":[0,1,2]}
ruby1 = JSON.parse(json, create_additions: true) # #<Set: {0, 1, 2}>
ruby1.class # Set

Struct:

require 'json/add/struct'
Customer = Struct.new(:name, :address) # Customer
ruby0 = Customer.new("Dave", "123 Main") # #<struct Customer name="Dave", address="123 Main">
json = JSON.generate(ruby0) # {"json_class":"Customer","v":["Dave","123 Main"]}
ruby1 = JSON.parse(json, create_additions: true) # #<struct Customer name="Dave", address="123 Main">
ruby1.class # Customer

Symbol:

require 'json/add/symbol'
ruby0 = :foo # foo
json = JSON.generate(ruby0) # {"json_class":"Symbol","s":"foo"}
ruby1 = JSON.parse(json, create_additions: true) # foo
ruby1.class # Symbol

Time:

require 'json/add/time'
ruby0 = Time.now # 2020-05-02 11:28:26 -0500
json = JSON.generate(ruby0) # {"json_class":"Time","s":1588436906,"n":840560000}
ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02 11:28:26 -0500
ruby1.class # Time

Custom JSON Additions

In addition to the JSON additions provided, you can craft JSON additions of your own, either for Ruby built-in classes or for user-defined classes.

Here’s a user-defined class Foo:

class Foo
  attr_accessor :bar, :baz
  def initialize(bar, baz)
    self.bar = bar
    self.baz = baz
  end
end

Here’s the JSON addition for it:

# Extend class Foo with JSON addition.
class Foo
  # Serialize Foo object with its class name and arguments
  def to_json(*args)
    {
      JSON.create_id  => self.class.name,
      'a'             => [ bar, baz ]
    }.to_json(*args)
  end
  # Deserialize JSON string by constructing new Foo object with arguments.
  def self.json_create(object)
    new(*object['a'])
  end
end

Demonstration:

require 'json'
# This Foo object has no custom addition.
foo0 = Foo.new(0, 1)
json0 = JSON.generate(foo0)
obj0 = JSON.parse(json0)
# Lood the custom addition.
require_relative 'foo_addition'
# This foo has the custom addition.
foo1 = Foo.new(0, 1)
json1 = JSON.generate(foo1)
obj1 = JSON.parse(json1, create_additions: true)
#   Make a nice display.
display = <<EOT
Generated JSON:
  Without custom addition:  #{json0} (#{json0.class})
  With custom addition:     #{json1} (#{json1.class})
Parsed JSON:
  Without custom addition:  #{obj0.inspect} (#{obj0.class})
  With custom addition:     #{obj1.inspect} (#{obj1.class})
EOT
puts display

Output:

Generated JSON:
  Without custom addition:  "#<Foo:0x0000000006534e80>" (String)
  With custom addition:     {"json_class":"Foo","a":[0,1]} (String)
Parsed JSON:
  Without custom addition:  "#<Foo:0x0000000006534e80>" (String)
  With custom addition:     #<Foo:0x0000000006473bb8 @bar=0, @baz=1> (Foo)

Constants:

CREATE_ID_TLS_KEY:

[not documented]

DEFAULT_CREATE_ID:

[not documented]

Infinity:

[not documented]

JSON_LOADED:

[not documented]

MinusInfinity:

[not documented]

NaN:

[not documented]

VERSION:

JSON version

Class methods:

[]
create_fast_state
create_id
create_id=
create_pretty_state
dump_default_options
generator
iconv
load_default_options
parser
restore
state

Instance methods:

dump
fast_generate
generate
load
load_file
load_file!
parse
parse!
pretty_generate
restore

Attributes:

attr_accessor dump_default_options
attr_accessor load_default_options
attr_accessor state
attr_reader generator
attr_reader parser
Read more on Ruby API

tsort #

TSort

TSort

(from ruby core)


TSort implements topological sorting using Tarjan’s algorithm for strongly connected components.

TSort is designed to be able to be used with any object which can be interpreted as a directed graph.

TSort requires two methods to interpret an object as a graph, tsort_each_node and tsort_each_child.

  • tsort_each_node is used to iterate for all nodes over a graph.

  • tsort_each_child is used to iterate for child nodes of a given node.

The equality of nodes are defined by eql? and hash since TSort uses Hash internally.

A Simple Example

The following example demonstrates how to mix the TSort module into an existing class (in this case, Hash). Here, we’re treating each key in the hash as a node in the graph, and so we simply alias the required #tsort_each_node method to Hash’s #each_key method. For each key in the hash, the associated value is an array of the node’s child nodes. This choice in turn leads to our implementation of the required #tsort_each_child method, which fetches the array of child nodes and then iterates over that array using the user-supplied block.

require 'tsort'

class Hash
  include TSort
  alias tsort_each_node each_key
  def tsort_each_child(node, &block)
    fetch(node).each(&block)
  end
end

{1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort
#=> [3, 2, 1, 4]

{1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}.strongly_connected_components
#=> [[4], [2, 3], [1]]

A More Realistic Example

A very simple ‘make’ like tool can be implemented as follows:

require 'tsort'

class Make
  def initialize
    @dep = {}
    @dep.default = []
  end

  def rule(outputs, inputs=[], &block)
    triple = [outputs, inputs, block]
    outputs.each {|f| @dep[f] = [triple]}
    @dep[triple] = inputs
  end

  def build(target)
    each_strongly_connected_component_from(target) {|ns|
      if ns.length != 1
        fs = ns.delete_if {|n| Array === n}
        raise TSort::Cyclic.new("cyclic dependencies: #{fs.join ', '}")
      end
      n = ns.first
      if Array === n
        outputs, inputs, block = n
        inputs_time = inputs.map {|f| File.mtime f}.max
        begin
          outputs_time = outputs.map {|f| File.mtime f}.min
        rescue Errno::ENOENT
          outputs_time = nil
        end
        if outputs_time == nil ||
           inputs_time != nil && outputs_time <= inputs_time
          sleep 1 if inputs_time != nil && inputs_time.to_i == Time.now.to_i
          block.call
        end
      end
    }
  end

  def tsort_each_child(node, &block)
    @dep[node].each(&block)
  end
  include TSort
end

def command(arg)
  print arg, "\n"
  system arg
end

m = Make.new
m.rule(%w[t1]) { command 'date > t1' }
m.rule(%w[t2]) { command 'date > t2' }
m.rule(%w[t3]) { command 'date > t3' }
m.rule(%w[t4], %w[t1 t3]) { command 'cat t1 t3 > t4' }
m.rule(%w[t5], %w[t4 t2]) { command 'cat t4 t2 > t5' }
m.build('t5')

Bugs

  • ‘tsort.rb’ is wrong name because this library uses Tarjan’s algorithm for strongly connected components. Although ‘strongly_connected_components.rb’ is correct but too long.

References

A. Tarjan, "Depth First Search and Linear Graph Algorithms",

SIAM Journal on Computing, Vol. 1, No. 2, pp. 146-160, June 1972.


Class methods:

each_strongly_connected_component
each_strongly_connected_component_from
strongly_connected_components
tsort
tsort_each

Instance methods:

each_strongly_connected_component
each_strongly_connected_component_from
strongly_connected_components
tsort
tsort_each
tsort_each_child
tsort_each_node
Read more on Ruby API

File System

find #

Dir::[]

Dir::[]

(from ruby core)


Dir[ string [, string ...] [, base: path] [, sort: true] ] -> array

Equivalent to calling Dir.glob([string,…], 0).

Read more on Ruby API
Find

Find

(from ruby core)


The Find module supports the top-down traversal of a set of file paths.

For example, to total the size of all files under your home directory, ignoring anything in a “dot” directory (e.g. $HOME/.ssh):

require 'find'

total_size = 0

Find.find(ENV["HOME"]) do |path|
  if FileTest.directory?(path)
    if File.basename(path).start_with?('.')
      Find.prune       # Don't look any further into this directory.
    else
      next
    end
  else
    total_size += FileTest.size(path)
  end
end

Class methods:

find
prune

Instance methods:

find
prune
Read more on Ruby API

ls dir vdir #

Dir::children

Dir::children

(from ruby core)


Dir.children( dirname )                -> array
Dir.children( dirname, encoding: enc ) -> array

Returns an array containing all of the filenames except for “.” and “..” in the given directory. Will raise a SystemCallError if the named directory doesn’t exist.

The optional encoding keyword argument specifies the encoding of the directory. If not specified, the filesystem encoding is used.

Dir.children("testdir")   #=> ["config.h", "main.rb"]
Read more on Ruby API

stat #

File::Stat

File::Stat < Object


Includes:

Comparable (from ruby core)

(from ruby core)


Objects of class File::Stat encapsulate common status information for File objects. The information is recorded at the moment the File::Stat object is created; changes made to the file after that point will not be reflected. File::Stat objects are returned by IO#stat, File::stat, File#lstat, and File::lstat. Many of these methods return platform-specific values, and not all values are meaningful on all systems. See also Kernel#test.


Class methods:

new

Instance methods:

<=>
atime
birthtime
blksize
blockdev?
blocks
chardev?
ctime
dev
dev_major
dev_minor
directory?
executable?
executable_real?
file?
ftype
gid
grpowned?
ino
inspect
mode
mtime
nlink
owned?
pipe?
rdev
rdev_major
rdev_minor
readable?
readable_real?
setgid?
setuid?
size
size?
socket?
sticky?
symlink?
uid
world_readable?
world_writable?
writable?
writable_real?
zero?
Read more on Ruby API

realpath #

File::realpath

File::realpath

(from ruby core)


File.realpath(pathname [, dir_string])  ->  real_pathname

Returns the real (absolute) pathname of pathname in the actual filesystem not containing symlinks or useless dots.

If dir_string is given, it is used as a base directory for interpreting relative pathname instead of the current directory.

All components of the pathname must exist when this method is called.

Read more on Ruby API

basename #

File::basename

File::basename

(from ruby core)


File.basename(file_name [, suffix] )  ->  base_name

Returns the last component of the filename given in file_name (after first stripping trailing separators), which can be formed using both File::SEPARATOR and File::ALT_SEPARATOR as the separator when File::ALT_SEPARATOR is not nil. If suffix is given and present at the end of file_name, it is removed. If suffix is “.*”, any extension will be removed.

File.basename("/home/gumby/work/ruby.rb")          #=> "ruby.rb"
File.basename("/home/gumby/work/ruby.rb", ".rb")   #=> "ruby"
File.basename("/home/gumby/work/ruby.rb", ".*")    #=> "ruby"
Read more on Ruby API

dirname #

File::dirname

File::dirname

(from ruby core)


File.dirname(file_name, level = 1)  ->  dir_name

Returns all components of the filename given in file_name except the last one (after first stripping trailing separators). The filename can be formed using both File::SEPARATOR and File::ALT_SEPARATOR as the separator when File::ALT_SEPARATOR is not nil.

File.dirname("/home/gumby/work/ruby.rb")   #=> "/home/gumby/work"

If level is given, removes the last level components, not only one.

File.dirname("/home/gumby/work/ruby.rb", 2) #=> "/home/gumby"
File.dirname("/home/gumby/work/ruby.rb", 4) #=> "/"
Read more on Ruby API
File::readlink

File::readlink

(from ruby core)


File.readlink(link_name)  ->  file_name

Returns the name of the file referenced by the given link. Not available on all platforms.

File.symlink("testfile", "link2test")   #=> 0
File.readlink("link2test")              #=> "testfile"
Read more on Ruby API

cat #

File::read

File::read

(from ruby core)

Implementation from IO


IO.read(command, length = nil, offset = 0, **opts) -> string or nil
IO.read(path, length = nil, offset = 0, **opts)    -> string or nil

Opens the stream, reads and returns some or all of its content, and closes the stream; returns nil if no bytes were read.

When called from class IO (but not subclasses of IO), this method has potential security vulnerabilities if called with untrusted input; see Command Injection.

The first argument must be a string; its meaning depends on whether it starts with the pipe character ('|'):

  • If so (and if self is IO), the rest of the string is a command to be executed as a subprocess.

  • Otherwise, the string is the path to a file.

With only argument command given, executes the command in a shell, returns its entire $stdout:

IO.read('| cat t.txt')
# => "First line\nSecond line\n\nThird line\nFourth line\n"

With only argument path given, reads in text mode and returns the entire content of the file at the given path:

IO.read('t.txt')
# => "First line\nSecond line\n\nThird line\nFourth line\n"

On Windows, text mode can terminate reading and leave bytes in the file unread when encountering certain special bytes. Consider using IO.binread if all bytes in the file should be read.

For both forms, command and path, the remaining arguments are the same.

With argument length, returns length bytes if available:

IO.read('t.txt', 7) # => "First l"
IO.read('t.txt', 700)
# => "First line\r\nSecond line\r\n\r\nFourth line\r\nFifth line\r\n"

With arguments length and offset, returns length bytes if available, beginning at the given offset:

IO.read('t.txt', 10, 2)   # => "rst line\nS"
IO.read('t.txt', 10, 200) # => nil

Optional keyword arguments opts specify:

Read more on Ruby API

touch #

FileUtils::touch

FileUtils::touch

(from ruby core)


touch(list, noop: nil, verbose: nil, mtime: nil, nocreate: nil)

Updates modification times (mtime) and access times (atime) of the entries given by the paths in list (a single path or an array of paths); returns list if it is an array, [list] otherwise.

By default, creates an empty file for any path to a non-existent entry; use keyword argument nocreate to raise an exception instead.

Argument list or its elements should be interpretable as paths.

Examples:

# Single path.
f = File.new('src0.txt') # Existing file.
f.atime # => 2022-06-10 11:11:21.200277 -0700
f.mtime # => 2022-06-10 11:11:21.200277 -0700
FileUtils.touch('src0.txt')
f = File.new('src0.txt')
f.atime # => 2022-06-11 08:28:09.8185343 -0700
f.mtime # => 2022-06-11 08:28:09.8185343 -0700

# Array of paths.
FileUtils.touch(['src0.txt', 'src0.dat'])

Keyword arguments:

  • mtime: time - sets the entry’s mtime to the given time, instead of the current time.

  • nocreate: true - raises an exception if the entry does not exist.

  • noop: true - does not touch entries; returns nil.

  • verbose: true - prints an equivalent command:

    FileUtils.touch('src0.txt', noop: true, verbose: true)
    FileUtils.touch(['src0.txt', 'src0.dat'], noop: true, verbose: true)
    FileUtils.touch(path, noop: true, verbose: true)
    

    Output:

    touch src0.txt
    touch src0.txt src0.dat
    touch src0.txt
    

Related: FileUtils.uptodate?.

Read more on Ruby API

mkdir #

FileUtils::mkdir

FileUtils::mkdir

(from ruby core)


mkdir(list, mode: nil, noop: nil, verbose: nil)

Creates directories at the paths in the given list (a single path or an array of paths); returns list if it is an array, [list] otherwise.

Argument list or its elements should be interpretable as paths.

With no keyword arguments, creates a directory at each path in list by calling: Dir.mkdir(path, mode); see Dir.mkdir:

FileUtils.mkdir(%w[tmp0 tmp1]) # => ["tmp0", "tmp1"]
FileUtils.mkdir('tmp4')        # => ["tmp4"]

Keyword arguments:

  • mode: mode - also calls File.chmod(mode, path); see File.chmod.

  • noop: true - does not create directories.

  • verbose: true - prints an equivalent command:

    FileUtils.mkdir(%w[tmp0 tmp1], verbose: true)
    FileUtils.mkdir(%w[tmp2 tmp3], mode: 0700, verbose: true)
    

    Output:

    mkdir tmp0 tmp1
    mkdir -m 700 tmp2 tmp3
    

Raises an exception if any path points to an existing file or directory, or if for any reason a directory cannot be created.

Related: FileUtils.mkdir_p.

Read more on Ruby API

mkfifo #

File::mkfifo

File::mkfifo

(from ruby core)


File.mkfifo(file_name, mode=0666)  => 0

Creates a FIFO special file with name file_name. mode specifies the FIFO’s permissions. It is modified by the process’s umask in the usual way: the permissions of the created file are (mode & ~umask).

Read more on Ruby API

mktemp #

Tempfile::create

Tempfile::create

(from ruby core)


create(basename="", tmpdir=nil, mode: 0, **options) { |tmpfile| ... }

Creates a file in the underlying file system; returns a new File object based on that file.

With no block given and no arguments, creates and returns file whose:

  • Class is File (not Tempfile).

  • Directory is the system temporary directory (system-dependent).

  • Generated filename is unique in that directory.

  • Permissions are 0600; see File Permissions.

  • Mode is 'w+' (read/write mode, positioned at the end).

With no block, the file is not removed automatically, and so should be explicitly removed.

Example:

f = Tempfile.create     # => #<File:/tmp/20220505-9795-17ky6f6>
f.class                 # => File
f.path                  # => "/tmp/20220505-9795-17ky6f6"
f.stat.mode.to_s(8)     # => "100600"
File.exist?(f.path)     # => true
File.unlink(f.path)
File.exist?(f.path)     # => false

Argument basename, if given, may be one of:

  • A string: the generated filename begins with basename:

    Tempfile.create('foo') # => #<File:/tmp/foo20220505-9795-1gok8l9>
    
  • An array of two strings [prefix, suffix]: the generated filename begins with prefix and ends with suffix:

    Tempfile.create(%w/foo .jpg/) # => #<File:/tmp/foo20220505-17839-tnjchh.jpg>
    

With arguments basename and tmpdir, the file is created in directory tmpdir:

Tempfile.create('foo', '.') # => #<File:./foo20220505-9795-1emu6g8>

Keyword arguments mode and options are passed directly to method File.open:

  • The value given with mode must be an integer, and may be expressed as the logical OR of constants defined in File::Constants.

  • For options, see Open Options.

With a block given, creates the file as above, passes it to the block, and returns the block’s value; before the return, the file object is closed and the underlying file is removed:

Tempfile.create {|file| file.path } # => "/tmp/20220505-9795-rkists"

Related: Tempfile.new.

Read more on Ruby API

cp #

FileUtils::cp

FileUtils::cp

(from ruby core)


cp(src, dest, preserve: nil, noop: nil, verbose: nil)

Copies files.

Arguments src (a single path or an array of paths) and dest (a single path) should be interpretable as paths.

If src is the path to a file and dest is not the path to a directory, copies src to dest:

FileUtils.touch('src0.txt')
File.exist?('dest0.txt') # => false
FileUtils.cp('src0.txt', 'dest0.txt')
File.file?('dest0.txt')  # => true

If src is the path to a file and dest is the path to a directory, copies src to dest/src:

FileUtils.touch('src1.txt')
FileUtils.mkdir('dest1')
FileUtils.cp('src1.txt', 'dest1')
File.file?('dest1/src1.txt') # => true

If src is an array of paths to files and dest is the path to a directory, copies from each src to dest:

src_file_paths = ['src2.txt', 'src2.dat']
FileUtils.touch(src_file_paths)
FileUtils.mkdir('dest2')
FileUtils.cp(src_file_paths, 'dest2')
File.file?('dest2/src2.txt') # => true
File.file?('dest2/src2.dat') # => true

Keyword arguments:

  • preserve: true - preserves file times.

  • noop: true - does not copy files.

  • verbose: true - prints an equivalent command:

    FileUtils.cp('src0.txt', 'dest0.txt', noop: true, verbose: true)
    FileUtils.cp('src1.txt', 'dest1', noop: true, verbose: true)
    FileUtils.cp(src_file_paths, 'dest2', noop: true, verbose: true)
    

    Output:

    cp src0.txt dest0.txt
    cp src1.txt dest1
    cp src2.txt src2.dat dest2
    

Raises an exception if src is a directory.

FileUtils.copy is an alias for FileUtils.cp.

Related: methods for copying.

Read more on Ruby API
FileUtils::cp_lr

FileUtils::cp_lr

(from ruby core)


cp_lr(src, dest, noop: nil, verbose: nil, dereference_root: true, remove_destination: false)

Creates hard links.

Arguments src (a single path or an array of paths) and dest (a single path) should be interpretable as paths.

If src is the path to a directory and dest does not exist, creates links dest and descendents pointing to src and its descendents:

tree('src0')
# => src0
#    |-- sub0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- sub1
#        |-- src2.txt
#        `-- src3.txt
File.exist?('dest0') # => false
FileUtils.cp_lr('src0', 'dest0')
tree('dest0')
# => dest0
#    |-- sub0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- sub1
#        |-- src2.txt
#        `-- src3.txt

If src and dest are both paths to directories, creates links dest/src and descendents pointing to src and its descendents:

tree('src1')
# => src1
#    |-- sub0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- sub1
#        |-- src2.txt
#        `-- src3.txt
FileUtils.mkdir('dest1')
FileUtils.cp_lr('src1', 'dest1')
tree('dest1')
# => dest1
#    `-- src1
#        |-- sub0
#        |   |-- src0.txt
#        |   `-- src1.txt
#        `-- sub1
#            |-- src2.txt
#            `-- src3.txt

If src is an array of paths to entries and dest is the path to a directory, for each path filepath in src, creates a link at dest/filepath pointing to that path:

tree('src2')
# => src2
#    |-- sub0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- sub1
#        |-- src2.txt
#        `-- src3.txt
FileUtils.mkdir('dest2')
FileUtils.cp_lr(['src2/sub0', 'src2/sub1'], 'dest2')
tree('dest2')
# => dest2
#    |-- sub0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- sub1
#        |-- src2.txt
#        `-- src3.txt

Keyword arguments:

  • dereference_root: false - if src is a symbolic link, does not dereference it.

  • noop: true - does not create links.

  • remove_destination: true - removes dest before creating links.

  • verbose: true - prints an equivalent command:

    FileUtils.cp_lr('src0', 'dest0', noop: true, verbose: true)
    FileUtils.cp_lr('src1', 'dest1', noop: true, verbose: true)
    FileUtils.cp_lr(['src2/sub0', 'src2/sub1'], 'dest2', noop: true, verbose: true)
    

    Output:

    cp -lr src0 dest0
    cp -lr src1 dest1
    cp -lr src2/sub0 src2/sub1 dest2
    

Raises an exception if dest is the path to an existing file or directory and keyword argument remove_destination: true is not given.

Related: methods for copying.

Read more on Ruby API
FileUtils::cp_r

FileUtils::cp_r

(from ruby core)


cp_r(src, dest, preserve: nil, noop: nil, verbose: nil, dereference_root: true, remove_destination: nil)

Recursively copies files.

Arguments src (a single path or an array of paths) and dest (a single path) should be interpretable as paths.

The mode, owner, and group are retained in the copy; to change those, use FileUtils.install instead.

If src is the path to a file and dest is not the path to a directory, copies src to dest:

FileUtils.touch('src0.txt')
File.exist?('dest0.txt') # => false
FileUtils.cp_r('src0.txt', 'dest0.txt')
File.file?('dest0.txt')  # => true

If src is the path to a file and dest is the path to a directory, copies src to dest/src:

FileUtils.touch('src1.txt')
FileUtils.mkdir('dest1')
FileUtils.cp_r('src1.txt', 'dest1')
File.file?('dest1/src1.txt') # => true

If src is the path to a directory and dest does not exist, recursively copies src to dest:

tree('src2')
# => src2
#    |-- dir0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- dir1
#    |-- src2.txt
#    `-- src3.txt
FileUtils.exist?('dest2') # => false
FileUtils.cp_r('src2', 'dest2')
tree('dest2')
# => dest2
#    |-- dir0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- dir1
#    |-- src2.txt
#    `-- src3.txt

If src and dest are paths to directories, recursively copies src to dest/src:

tree('src3')
# => src3
#    |-- dir0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- dir1
#    |-- src2.txt
#    `-- src3.txt
FileUtils.mkdir('dest3')
FileUtils.cp_r('src3', 'dest3')
tree('dest3')
# => dest3
#    `-- src3
#      |-- dir0
#      |   |-- src0.txt
#      |   `-- src1.txt
#      `-- dir1
#          |-- src2.txt
#          `-- src3.txt

If src is an array of paths and dest is a directory, recursively copies from each path in src to dest; the paths in src may point to files and/or directories.

Keyword arguments:

  • dereference_root: false - if src is a symbolic link, does not dereference it.

  • noop: true - does not copy files.

  • preserve: true - preserves file times.

  • remove_destination: true - removes dest before copying files.

  • verbose: true - prints an equivalent command:

    FileUtils.cp_r('src0.txt', 'dest0.txt', noop: true, verbose: true)
    FileUtils.cp_r('src1.txt', 'dest1', noop: true, verbose: true)
    FileUtils.cp_r('src2', 'dest2', noop: true, verbose: true)
    FileUtils.cp_r('src3', 'dest3', noop: true, verbose: true)
    

    Output:

    cp -r src0.txt dest0.txt
    cp -r src1.txt dest1
    cp -r src2 dest2
    cp -r src3 dest3
    

Raises an exception of src is the path to a directory and dest is the path to a file.

Related: methods for copying.

Read more on Ruby API

mv #

FileUtils::mv

FileUtils::mv

(from ruby core)


mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)

Moves entries.

Arguments src (a single path or an array of paths) and dest (a single path) should be interpretable as paths.

If src and dest are on different file systems, first copies, then removes src.

May cause a local vulnerability if not called with keyword argument secure: true; see Avoiding the TOCTTOU Vulnerability.

If src is the path to a single file or directory and dest does not exist, moves src to dest:

tree('src0')
# => src0
#    |-- src0.txt
#    `-- src1.txt
File.exist?('dest0') # => false
FileUtils.mv('src0', 'dest0')
File.exist?('src0')  # => false
tree('dest0')
# => dest0
#    |-- src0.txt
#    `-- src1.txt

If src is an array of paths to files and directories and dest is the path to a directory, copies from each path in the array to dest:

File.file?('src1.txt') # => true
tree('src1')
# => src1
#    |-- src.dat
#    `-- src.txt
Dir.empty?('dest1')    # => true
FileUtils.mv(['src1.txt', 'src1'], 'dest1')
tree('dest1')
# => dest1
#    |-- src1
#    |   |-- src.dat
#    |   `-- src.txt
#    `-- src1.txt

Keyword arguments:

  • force: true - if the move includes removing src (that is, if src and dest are on different file systems), ignores raised exceptions of StandardError and its descendants.

  • noop: true - does not move files.

  • secure: true - removes src securely; see details at FileUtils.remove_entry_secure.

  • verbose: true - prints an equivalent command:

    FileUtils.mv('src0', 'dest0', noop: true, verbose: true)
    FileUtils.mv(['src1.txt', 'src1'], 'dest1', noop: true, verbose: true)
    

    Output:

    mv src0 dest0
    mv src1.txt src1 dest1
    

FileUtils.move is an alias for FileUtils.mv.

Read more on Ruby API

rm #

FileUtils::rm

FileUtils::rm

(from ruby core)


rm(list, force: nil, noop: nil, verbose: nil)

Removes entries at the paths in the given list (a single path or an array of paths) returns list, if it is an array, [list] otherwise.

Argument list or its elements should be interpretable as paths.

With no keyword arguments, removes files at the paths given in list:

FileUtils.touch(['src0.txt', 'src0.dat'])
FileUtils.rm(['src0.dat', 'src0.txt']) # => ["src0.dat", "src0.txt"]

Keyword arguments:

  • force: true - ignores raised exceptions of StandardError and its descendants.

  • noop: true - does not remove files; returns nil.

  • verbose: true - prints an equivalent command:

    FileUtils.rm(['src0.dat', 'src0.txt'], noop: true, verbose: true)
    

    Output:

    rm src0.dat src0.txt
    

FileUtils.remove is an alias for FileUtils.rm.

Related: methods for deleting.

Read more on Ruby API
FileUtils::rm_f

FileUtils::rm_f

(from ruby core)


rm_f(list, noop: nil, verbose: nil)

Equivalent to:

FileUtils.rm(list, force: true, **kwargs)

Argument list (a single path or an array of paths) should be interpretable as paths.

See FileUtils.rm for keyword arguments.

FileUtils.safe_unlink is an alias for FileUtils.rm_f.

Related: methods for deleting.

Read more on Ruby API
FileUtils::rm_r

FileUtils::rm_r

(from ruby core)


rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil)

Removes entries at the paths in the given list (a single path or an array of paths); returns list, if it is an array, [list] otherwise.

Argument list or its elements should be interpretable as paths.

May cause a local vulnerability if not called with keyword argument secure: true; see Avoiding the TOCTTOU Vulnerability.

For each file path, removes the file at that path:

FileUtils.touch(['src0.txt', 'src0.dat'])
FileUtils.rm_r(['src0.dat', 'src0.txt'])
File.exist?('src0.txt') # => false
File.exist?('src0.dat') # => false

For each directory path, recursively removes files and directories:

tree('src1')
# => src1
#    |-- dir0
#    |   |-- src0.txt
#    |   `-- src1.txt
#    `-- dir1
#        |-- src2.txt
#        `-- src3.txt
FileUtils.rm_r('src1')
File.exist?('src1') # => false

Keyword arguments:

  • force: true - ignores raised exceptions of StandardError and its descendants.

  • noop: true - does not remove entries; returns nil.

  • secure: true - removes src securely; see details at FileUtils.remove_entry_secure.

  • verbose: true - prints an equivalent command:

    FileUtils.rm_r(['src0.dat', 'src0.txt'], noop: true, verbose: true)
    FileUtils.rm_r('src1', noop: true, verbose: true)
    

    Output:

    rm -r src0.dat src0.txt
    rm -r src1
    

Related: methods for deleting.

Read more on Ruby API
FileUtils::rm_rf

FileUtils::rm_rf

(from ruby core)


rm_rf(list, noop: nil, verbose: nil, secure: nil)

Equivalent to:

FileUtils.rm_r(list, force: true, **kwargs)

Argument list or its elements should be interpretable as paths.

May cause a local vulnerability if not called with keyword argument secure: true; see Avoiding the TOCTTOU Vulnerability.

See FileUtils.rm_r for keyword arguments.

FileUtils.rmtree is an alias for FileUtils.rm_rf.

Related: methods for deleting.

Read more on Ruby API

rmdir #

FileUtils::rmdir

FileUtils::rmdir

(from ruby core)


rmdir(list, parents: nil, noop: nil, verbose: nil)

Removes directories at the paths in the given list (a single path or an array of paths); returns list, if it is an array, [list] otherwise.

Argument list or its elements should be interpretable as paths.

With no keyword arguments, removes the directory at each path in list, by calling: Dir.rmdir(path); see Dir.rmdir:

FileUtils.rmdir(%w[tmp0/tmp1 tmp2/tmp3]) # => ["tmp0/tmp1", "tmp2/tmp3"]
FileUtils.rmdir('tmp4/tmp5')             # => ["tmp4/tmp5"]

Keyword arguments:

  • parents: true - removes successive ancestor directories if empty.

  • noop: true - does not remove directories.

  • verbose: true - prints an equivalent command:

    FileUtils.rmdir(%w[tmp0/tmp1 tmp2/tmp3], parents: true, verbose: true)
    FileUtils.rmdir('tmp4/tmp5', parents: true, verbose: true)
    

    Output:

    rmdir -p tmp0/tmp1 tmp2/tmp3
    rmdir -p tmp4/tmp5
    

Raises an exception if a directory does not exist or if for any reason a directory cannot be removed.

Related: methods for deleting.

Read more on Ruby API
FileUtils::ln

FileUtils::ln

(from ruby core)


ln(src, dest, force: nil, noop: nil, verbose: nil)

Creates hard links.

Arguments src (a single path or an array of paths) and dest (a single path) should be interpretable as paths.

When src is the path to an existing file and dest is the path to a non-existent file, creates a hard link at dest pointing to src; returns zero:

Dir.children('tmp0/')                    # => ["t.txt"]
Dir.children('tmp1/')                    # => []
FileUtils.ln('tmp0/t.txt', 'tmp1/t.lnk') # => 0
Dir.children('tmp1/')                    # => ["t.lnk"]

When src is the path to an existing file and dest is the path to an existing directory, creates a hard link at dest/src pointing to src; returns zero:

Dir.children('tmp2')               # => ["t.dat"]
Dir.children('tmp3')               # => []
FileUtils.ln('tmp2/t.dat', 'tmp3') # => 0
Dir.children('tmp3')               # => ["t.dat"]

When src is an array of paths to existing files and dest is the path to an existing directory, then for each path target in src, creates a hard link at dest/target pointing to target; returns src:

Dir.children('tmp4/')                               # => []
FileUtils.ln(['tmp0/t.txt', 'tmp2/t.dat'], 'tmp4/') # => ["tmp0/t.txt", "tmp2/t.dat"]
Dir.children('tmp4/')                               # => ["t.dat", "t.txt"]

Keyword arguments:

  • force: true - overwrites dest if it exists.

  • noop: true - does not create links.

  • verbose: true - prints an equivalent command:

    FileUtils.ln('tmp0/t.txt', 'tmp1/t.lnk', verbose: true)
    FileUtils.ln('tmp2/t.dat', 'tmp3', verbose: true)
    FileUtils.ln(['tmp0/t.txt', 'tmp2/t.dat'], 'tmp4/', verbose: true)
    

    Output:

    ln tmp0/t.txt tmp1/t.lnk
    ln tmp2/t.dat tmp3
    ln tmp0/t.txt tmp2/t.dat tmp4/
    

Raises an exception if dest is the path to an existing file and keyword argument force is not true.

FileUtils#link is an alias for FileUtils#ln.

Related: FileUtils.link_entry (has different options).

Read more on Ruby API
FileUtils::ln_s

FileUtils::ln_s

(from ruby core)


ln_s(src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil)

Creates symbolic links.

Arguments src (a single path or an array of paths) and dest (a single path) should be interpretable as paths.

If src is the path to an existing file:

  • When dest is the path to a non-existent file, creates a symbolic link at dest pointing to src:

    FileUtils.touch('src0.txt')
    File.exist?('dest0.txt')   # => false
    FileUtils.ln_s('src0.txt', 'dest0.txt')
    File.symlink?('dest0.txt') # => true
    
  • When dest is the path to an existing file, creates a symbolic link at dest pointing to src if and only if keyword argument force: true is given (raises an exception otherwise):

    FileUtils.touch('src1.txt')
    FileUtils.touch('dest1.txt')
    FileUtils.ln_s('src1.txt', 'dest1.txt', force: true)
    FileTest.symlink?('dest1.txt') # => true
    
    FileUtils.ln_s('src1.txt', 'dest1.txt') # Raises Errno::EEXIST.
    

If dest is the path to a directory, creates a symbolic link at dest/src pointing to src:

FileUtils.touch('src2.txt')
FileUtils.mkdir('destdir2')
FileUtils.ln_s('src2.txt', 'destdir2')
File.symlink?('destdir2/src2.txt') # => true

If src is an array of paths to existing files and dest is a directory, for each child child in src creates a symbolic link dest/child pointing to child:

FileUtils.mkdir('srcdir3')
FileUtils.touch('srcdir3/src0.txt')
FileUtils.touch('srcdir3/src1.txt')
FileUtils.mkdir('destdir3')
FileUtils.ln_s(['srcdir3/src0.txt', 'srcdir3/src1.txt'], 'destdir3')
File.symlink?('destdir3/src0.txt') # => true
File.symlink?('destdir3/src1.txt') # => true

Keyword arguments:

  • force: true - overwrites dest if it exists.

  • relative: false - create links relative to dest.

  • noop: true - does not create links.

  • verbose: true - prints an equivalent command:

    FileUtils.ln_s('src0.txt', 'dest0.txt', noop: true, verbose: true)
    FileUtils.ln_s('src1.txt', 'destdir1', noop: true, verbose: true)
    FileUtils.ln_s('src2.txt', 'dest2.txt', force: true, noop: true, verbose: true)
    FileUtils.ln_s(['srcdir3/src0.txt', 'srcdir3/src1.txt'], 'destdir3', noop: true, verbose: true)
    

    Output:

    ln -s src0.txt dest0.txt
    ln -s src1.txt destdir1
    ln -sf src2.txt dest2.txt
    ln -s srcdir3/src0.txt srcdir3/src1.txt destdir3
    

FileUtils.symlink is an alias for FileUtils.ln_s.

Related: FileUtils.ln_sf.

Read more on Ruby API
FileUtils::ln_sf

FileUtils::ln_sf

(from ruby core)


ln_sf(src, dest, noop: nil, verbose: nil)

Like FileUtils.ln_s, but always with keyword argument force: true given.

Read more on Ruby API
FileUtils::ln_sr

FileUtils::ln_sr

(from ruby core)


ln_sr(src, dest, target_directory: true, force: nil, noop: nil, verbose: nil)

Like FileUtils.ln_s, but create links relative to dest.

Read more on Ruby API
File::unlink

File::unlink

(from ruby core)


File.delete(file_name, ...)  -> integer
File.unlink(file_name, ...)  -> integer

Deletes the named files, returning the number of names passed as arguments. Raises an exception on any error. Since the underlying implementation relies on the unlink(2) system call, the type of exception raised depends on its error type (see linux.die.net/man/2/unlink) and has the form of e.g. Errno::ENOENT.

See also Dir::rmdir.

Read more on Ruby API

chmod #

File::chmod

File::chmod

(from ruby core)


File.chmod(mode_int, file_name, ... )  ->  integer

Changes permission bits on the named file(s) to the bit pattern represented by mode_int. Actual effects are operating system dependent (see the beginning of this section). On Unix systems, see chmod(2) for details. Returns the number of files processed.

File.chmod(0644, "testfile", "out")   #=> 2
Read more on Ruby API

chown #

File::chown

File::chown

(from ruby core)


File.chown(owner_int, group_int, file_name, ...)  ->  integer

Changes the owner and group of the named file(s) to the given numeric owner and group id’s. Only a process with superuser privileges may change the owner of a file. The current owner of a file may change the file’s group to any group to which the owner belongs. A nil or -1 owner or group id is ignored. Returns the number of files processed.

File.chown(nil, 100, "testfile")
Read more on Ruby API

cmp #

FileUtils::cmp

FileUtils::cmp

(from ruby core)


cmp(a, b)

(This method is an alias for FileUtils#compare_file.)

Returns true if the contents of files a and b are identical, false otherwise.

Arguments a and b should be interpretable as a path.

FileUtils.identical? and FileUtils.cmp are aliases for FileUtils.compare_file.

Related: FileUtils.compare_stream.

Read more on Ruby API

install #

FileUtils::install

FileUtils::install

(from ruby core)


install(src, dest, mode: nil, owner: nil, group: nil, preserve: nil, noop: nil, verbose: nil)

Copies a file entry. See install(1).

Arguments src (a single path or an array of paths) and dest (a single path) should be interpretable as paths;

If the entry at dest does not exist, copies from src to dest:

File.read('src0.txt')    # => "aaa\n"
File.exist?('dest0.txt') # => false
FileUtils.install('src0.txt', 'dest0.txt')
File.read('dest0.txt')   # => "aaa\n"

If dest is a file entry, copies from src to dest, overwriting:

File.read('src1.txt')  # => "aaa\n"
File.read('dest1.txt') # => "bbb\n"
FileUtils.install('src1.txt', 'dest1.txt')
File.read('dest1.txt') # => "aaa\n"

If dest is a directory entry, copies from src to dest/src, overwriting if necessary:

File.read('src2.txt')       # => "aaa\n"
File.read('dest2/src2.txt') # => "bbb\n"
FileUtils.install('src2.txt', 'dest2')
File.read('dest2/src2.txt') # => "aaa\n"

If src is an array of paths and dest points to a directory, copies each path path in src to dest/path:

File.file?('src3.txt') # => true
File.file?('src3.dat') # => true
FileUtils.mkdir('dest3')
FileUtils.install(['src3.txt', 'src3.dat'], 'dest3')
File.file?('dest3/src3.txt') # => true
File.file?('dest3/src3.dat') # => true

Keyword arguments:

  • group: group - changes the group if not nil, using File.chown.

  • mode: permissions - changes the permissions. using File.chmod.

  • noop: true - does not copy entries; returns nil.

  • owner: owner - changes the owner if not nil, using File.chown.

  • preserve: true - preserve timestamps using File.utime.

  • verbose: true - prints an equivalent command:

    FileUtils.install('src0.txt', 'dest0.txt', noop: true, verbose: true)
    FileUtils.install('src1.txt', 'dest1.txt', noop: true, verbose: true)
    FileUtils.install('src2.txt', 'dest2', noop: true, verbose: true)
    

    Output:

    install -c src0.txt dest0.txt
    install -c src1.txt dest1.txt
    install -c src2.txt dest2
    

Related: methods for copying.

Read more on Ruby API

truncate #

File::truncate

File::truncate

(from ruby core)


File.truncate(file_name, integer)  -> 0

Truncates the file file_name to be at most integer bytes long. Not available on all platforms.

f = File.new("out", "w")
f.write("1234567890")     #=> 10
f.close                   #=> nil
File.truncate("out", 5)   #=> 0
File.size("out")          #=> 5
Read more on Ruby API

chroot #

Dir::chroot

Dir::chroot

(from ruby core)


Dir.chroot( string ) -> 0

Changes this process’s idea of the file system root. Only a privileged process may make this call. Not available on all platforms. On Unix systems, see chroot(2) for more information.

Read more on Ruby API

file #

Equivalent Ruby gem: ruby-filemagic

tree #

Equivalent Ruby gem: tty-tree

System Infomations

users #

Equivalent Ruby code: ENV['USERNAME']

logname #

Equivalent Ruby code: Etc.getpwuid.name

hostname #

Socket::gethostname

Socket::gethostname

(from ruby core)


Socket.gethostname => hostname

Returns the hostname.

p Socket.gethostname #=> "hal"

Note that it is not guaranteed to be able to convert to IP address using gethostbyname, getaddrinfo, etc. If you need local IP address, use Socket.ip_address_list.

Read more on Ruby API

arch #

Equivalent Ruby code: Gem::Platform.local.cpu

uptime #

Equivalent Ruby code: IO.read('/proc/uptime').to_f

uname #

Equivalent Ruby gem: os

ps #

Equivalent Ruby gem: sys-proctable

Security Related

base64 #

Base64

Base64

(from ruby core)


The Base64 module provides for the encoding (#encode64, #strict_encode64, #urlsafe_encode64) and decoding (#decode64, #strict_decode64, #urlsafe_decode64) of binary data using a Base64 representation.

Example

A simple encoding and decoding.

require "base64"

enc   = Base64.encode64('Send reinforcements')
                    # -> "U2VuZCByZWluZm9yY2VtZW50cw==\n"
plain = Base64.decode64(enc)
                    # -> "Send reinforcements"

The purpose of using base64 to encode data is that it translates any binary data into purely printable characters.


Instance methods:

decode64
encode64
strict_decode64
strict_encode64
urlsafe_decode64
urlsafe_encode64
Read more on Ruby API

cksum #

Digest

Digest

(from ruby core)


This module provides a framework for message digest libraries.

You may want to look at OpenSSL::Digest as it supports more algorithms.

A cryptographic hash function is a procedure that takes data and returns a fixed bit string: the hash value, also known as digest. Hash functions are also called one-way functions, it is easy to compute a digest from a message, but it is infeasible to generate a message from a digest.

Examples

require 'digest'

# Compute a complete digest
Digest::SHA256.digest 'message'       #=> "\xABS\n\x13\xE4Y..."

sha256 = Digest::SHA256.new
sha256.digest 'message'               #=> "\xABS\n\x13\xE4Y..."

# Other encoding formats
Digest::SHA256.hexdigest 'message'    #=> "ab530a13e459..."
Digest::SHA256.base64digest 'message' #=> "q1MKE+RZFJgr..."

# Compute digest by chunks
md5 = Digest::MD5.new
md5.update 'message1'
md5 << 'message2'                     # << is an alias for update

md5.hexdigest                         #=> "94af09c09bb9..."

# Compute digest for a file
sha256 = Digest::SHA256.file 'testfile'
sha256.hexdigest

Additionally digests can be encoded in “bubble babble” format as a sequence of consonants and vowels which is more recognizable and comparable than a hexadecimal digest.

require 'digest/bubblebabble'

Digest::SHA256.bubblebabble 'message' #=> "xopoh-fedac-fenyh-..."

See the bubble babble specification at web.mit.edu/kenta/www/one/bubblebabble/spec/jrtrjwzi/draft-huima- 01.txt.

Digest algorithms

Different digest algorithms (or hash functions) are available:

MD5:

See RFC 1321 The MD5 Message-Digest Algorithm

RIPEMD-160:

As Digest::RMD160. See
http://homes.esat.kuleuven.be/~bosselae/ripemd160.html.

SHA1:

See FIPS 180 Secure Hash Standard.

SHA2 family:

See FIPS 180 Secure Hash Standard which defines the following
algorithms:
* SHA512
* SHA384
* SHA256

The latest versions of the FIPS publications can be found here: csrc.nist.gov/publications/PubsFIPS.html.


Constants:

REQUIRE_MUTEX:

A mutex for Digest().

VERSION:

[not documented]

Class methods:

bubblebabble
hexencode
Read more on Ruby API

md5sum #

Digest::MD5

Digest::MD5 < Digest::Base

(from ruby core)


A class for calculating message digests using the MD5 Message-Digest Algorithm by RSA Data Security, Inc., described in RFC1321.

MD5 calculates a digest of 128 bits (16 bytes).

Examples

require 'digest'

# Compute a complete digest
Digest::MD5.hexdigest 'abc'      #=> "90015098..."

# Compute digest by chunks
md5 = Digest::MD5.new               # =>#<Digest::MD5>
md5.update "ab"
md5 << "c"                           # alias for #update
md5.hexdigest                        # => "90015098..."

# Use the same object to compute another digest
md5.reset
md5 << "message"
md5.hexdigest                        # => "78e73102..."

Read more on Ruby API

sha1sum #

Digest::SHA1

Digest::SHA1 < Digest::Base

(from ruby core)


A class for calculating message digests using the SHA-1 Secure Hash Algorithm by NIST (the US’ National Institute of Standards and Technology), described in FIPS PUB 180-1.

See Digest::Instance for digest API.

SHA-1 calculates a digest of 160 bits (20 bytes).

Examples

require 'digest'

# Compute a complete digest
Digest::SHA1.hexdigest 'abc'      #=> "a9993e36..."

# Compute digest by chunks
sha1 = Digest::SHA1.new               # =>#<Digest::SHA1>
sha1.update "ab"
sha1 << "c"                           # alias for #update
sha1.hexdigest                        # => "a9993e36..."

# Use the same object to compute another digest
sha1.reset
sha1 << "message"
sha1.hexdigest                        # => "6f9b9af3..."

Read more on Ruby API

sha224sum sha256sum sha384sum sha512sum #

Digest::SHA2

Digest::SHA2 < Digest::Class

(from ruby core)


A meta digest provider class for SHA256, SHA384 and SHA512.

FIPS 180-2 describes SHA2 family of digest algorithms. It defines three algorithms:

  • one which works on chunks of 512 bits and returns a 256-bit digest (SHA256),

  • one which works on chunks of 1024 bits and returns a 384-bit digest (SHA384),

  • and one which works on chunks of 1024 bits and returns a 512-bit digest (SHA512).

Examples

require 'digest'

# Compute a complete digest
Digest::SHA2.hexdigest 'abc'          # => "ba7816bf8..."
Digest::SHA2.new(256).hexdigest 'abc' # => "ba7816bf8..."
Digest::SHA256.hexdigest 'abc'        # => "ba7816bf8..."

Digest::SHA2.new(384).hexdigest 'abc' # => "cb00753f4..."
Digest::SHA384.hexdigest 'abc'        # => "cb00753f4..."

Digest::SHA2.new(512).hexdigest 'abc' # => "ddaf35a19..."
Digest::SHA512.hexdigest 'abc'        # => "ddaf35a19..."

# Compute digest by chunks
sha2 = Digest::SHA2.new               # =>#<Digest::SHA2:256>
sha2.update "ab"
sha2 << "c"                           # alias for #update
sha2.hexdigest                        # => "ba7816bf8..."

# Use the same object to compute another digest
sha2.reset
sha2 << "message"
sha2.hexdigest                        # => "ab530a13e..."

Class methods:

new

Instance methods:

<<
block_length
digest_length
reset
update
Read more on Ruby API

uuidgen #

Random::Formatter#uuid

Random::Formatter#uuid

(from ruby core)

Implementation from Formatter


uuid()

Generate a random v4 UUID (Universally Unique IDentifier).

require 'random/formatter'

Random.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594"
Random.uuid #=> "bad85eb9-0713-4da7-8d36-07a8e4b00eab"
# or
prng = Random.new
prng.uuid #=> "62936e70-1815-439b-bf89-8492855a7e6b"

The version 4 UUID is purely random (except the version). It doesn’t contain meaningful information such as MAC addresses, timestamps, etc.

The result contains 122 random bits (15.25 random bytes).

See RFC4122 for details of UUID.

Read more on Ruby API