Power user
Your first Ruby script
Write a script in rsh, Ruby with terminal commands in it: a file ending in .rsh, Ruby and commands on the same page, why each value stays one argument, catching a command that failed, and running it with ./ and with wol script.
On this page
What it is
Ruby with commands in it: one script can hold Ruby and terminal commands side by side. It comes with WolOS. is A programming language known for reading almost like English. WolOS runs Ruby scripts the same way as shell scripts. with terminal One instruction you type in a terminal, such as ls (list the files here). Return runs it. in it. A script in rsh is a Ruby program, and any line that starts with a word Ruby does not know is run as a command, exactly as you would type it in the terminal. So one file holds both: Ruby to count, decide and repeat, and commands such as ls, mkdir and cp to do the work.
rsh comes with WolOS. Its scripts end in .rsh. If you have read Your first shell script, this page climbs the same ladder: a file, the first line, making it run, running it, then values, a loop and what to do when something fails.
Why WolOS does it this way
A shell script is quick to write and easy to get wrong. Every value is text that the shell splits again at each space, so a file called Summer Trip.jpg turns into two files that do not exist unless you remember the quote marks every time. A command that fails is easy to miss, and the script carries on.
Ruby has none of those traps, but in plain Ruby running a command takes a whole line of code. rsh keeps both: you write commands the way you type them, and they get Ruby's care. A value you put into a command is always exactly one Extra words after a command that tell it what to work on, such as Documents in ls Documents., whatever it holds. A command that fails stops the script and says where, unless you catch it and decide what to do.
How
1. Make a file
Open Text Editor (press Super+Space and type "text"), and type:
#!/usr/bin/env rsh
# My first rsh script: Ruby and commands together.
name = ENV.fetch("USER")
puts "Hello, #{name}!"
ls ~/Pictures/HolidaySave it in your home folder as hello.rsh.
What each line does:
| Line | Means |
|---|---|
#!/usr/bin/env rsh | The first line, the The first line of a script, starting with #! (hash and exclamation mark). It names the program that reads the rest of the file.: "read this file with rsh". |
# My first rsh … | A comment, for people. |
name = ENV.fetch("USER") | Ruby: puts your account name in the A name that holds a value, such as a word or a number, so you can use it again further down. name. |
puts "Hello, #{name}!" | Ruby: prints a line. #{…} puts a value into the text. |
ls ~/Pictures/Holiday | A command: Ruby has nothing called ls, so rsh runs it as in the terminal. |
How rsh tells them apart is the first word of the line. Something Ruby knows (name, puts, if, end, a name starting with a capital) makes the line Ruby. A word Ruby does not know makes it a command.
2. Make it run and run it
Open a terminal (Super+Return) and type, once:
chmod +x hello.rshThen run it:
./hello.rshYou see:
Hello, aliceliddell!
Summer Trip.jpg
beach.jpg
cake.JPGThe first line came from Ruby, the rest from ls.
WolOS's own command runs it too, with no chmod needed, and can read it for mistakes first without running anything:
wol script check hello.rsh
wol script run hello.rshThe check answers hello.rsh: rsh script, parses and rsh is clean: every line made sense, and rsh found nothing risky in it.
3. Ruby uses what a command says
Put a command between back-quotes, `, and Ruby gets its answer as text. Save this as count.rsh:
#!/usr/bin/env rsh
# Counts the photos in a folder of Pictures.
# How: ./count.rsh Holiday
folder = ARGV.fetch(0)
photos = `ls ~/Pictures/#{folder}`.lines.size
puts "#{folder} holds #{photos} photos."ARGV.fetch(0) is the first argument you give the script. .lines.size counts the lines of what ls printed. Run chmod +x count.rsh, then ./count.rsh Holiday, and you see Holiday holds 3 photos.
4. A loop, with one argument per value
This script moves the photos of a folder into a new folder, Sorted, and writes the ending .JPG in small letters on the way. Save it as sort.rsh:
#!/usr/bin/env rsh
# Moves the photos of a folder into Sorted, with .jpg in small letters.
# How: ./sort.rsh Holiday
folder = File.join(ENV.fetch("HOME"), "Pictures", ARGV.fetch(0))
mkdir -p #{folder}/Sorted
count = 0
Dir.glob("#{folder}/*.{jpg,JPG}").each do |photo|
name = File.basename(photo).sub(/\.JPG\z/, ".jpg")
mv #{photo} #{folder}/Sorted/#{name}
count += 1
end
puts "Moved #{count} photos into Sorted."Run chmod +x sort.rsh, then ./sort.rsh Holiday. You see Moved 3 photos into Sorted., and in Files, Pictures/Holiday/Sorted holds Summer Trip.jpg, beach.jpg and cake.jpg.
| Lines | Mean |
|---|---|
folder = File.join(…) | Ruby builds the The address of a file: the folders you go through to reach it, separated by /. For example /home/alice/Documents/notes.txt. of the folder from its parts. |
mkdir -p #{folder}/Sorted | A command, with a Ruby value inside: #{…} in a command line puts the value in. |
Dir.glob(…).each do |photo| … end | A A part of a script that runs again for each item in a list, such as each photo in a folder.: for every file ending in .jpg or .JPG, photo holds its path and the lines up to end run. |
name = File.basename(photo).sub(…) | Ruby: the file name, with .JPG at the end changed to .jpg. |
mv #{photo} #{folder}/Sorted/#{name} | A command: moves the file. |
Summer Trip.jpg moved as one file, with no quote marks anywhere. That is the rule that keeps you safe: a value in a command is always exactly one argument. It is never split at a space, never read as a pattern, and never read as another command. Try it:
#!/usr/bin/env rsh
name = "Summer Trip; rm -rf ~"
echo #{name}This prints Summer Trip; rm -rf ~ and does nothing else. In a careless shell script the ; would end one command and start the next, and the next one would delete your home folder. A file name from the web, from a download or from someone else's folder can hold anything; in rsh it stays a name.
5. When a command fails
Every command ends with an A number every command leaves behind when it ends: 0 means it worked, any other number means something went wrong., 0 when it worked. When a command in an rsh script ends with anything else, the script stops there and tells you the file, the line and the number. Here is copy.rsh, run when there is no folder called Backup:
#!/usr/bin/env rsh
cp ~/Documents/notes.txt ~/Backup/
puts "Notes copied."cp: cannot create regular file '/home/aliceliddell/Backup/': Not a directory
rsh: ./copy.rsh:2: cp exited 1The first line is what cp said; the second is rsh telling you that line 2 failed, so Notes copied. was never printed. A script never carries on as if a step had worked.
To decide yourself what happens, put the command between begin and rescue. Ruby calls this rescuing a failure:
begin
cp -r ~/Documents ~/Backups
puts "Saved a copy."
rescue => e
puts "The copy did not work: #{e.stderr.strip}"
exit 1
endIf cp works, you see Saved a copy. If it fails, the lines after rescue run: e holds what went wrong, and e.stderr is what the command said about it. exit 1 ends the script and reports the failure.
A command used as a question, after if or unless, never stops the script; it is just yes or no:
if grep -q milk ~/Documents/notes.txt
puts "Milk is on the list."
endA worked example
Alice wants a copy of Documents in a folder named after today, and a clear sentence when something stops it. She writes backup.rsh:
#!/usr/bin/env rsh
# Copies Documents into a folder in Backups named after today.
# How: ./backup.rsh
today = Time.now.strftime("%Y-%m-%d")
target = File.join(ENV.fetch("HOME"), "Backups", today)
mkdir -p #{target}
begin
cp -r ~/Documents #{target}
puts "Saved a copy in Backups/#{today}."
rescue => e
puts "The copy did not work: #{e.stderr.strip}"
exit 1
endTime.now.strftime("%Y-%m-%d") is Ruby for today's date, as 2026-11-04. She runs wol script check backup.rsh, which answers backup.rsh: rsh script, parses and rsh is clean, then wol script run backup.rsh, and sees Saved a copy in Backups/2026-11-04. On a computer without a Documents folder the same script says The copy did not work: cp: cannot stat '/home/aliceliddell/Documents': No such file or directory and ends with exit status 1.
If something goes wrong
| What you see | What it means and what to do |
|---|---|
zsh: permission denied: ./hello.rsh | The file may not run yet. Type chmod +x hello.rsh once, or use wol script run hello.rsh. |
rsh: ./copy.rsh:2: cp exited 1 | The command on line 2 failed and the script stopped. The line above it is what the command said. Fix the cause, or rescue it (step 5). |
rsh: lss: command not found | A command name is misspelled, or the program is not installed. |
index 0 outside of array bounds with IndexError | The script needs an argument and got none. Add it after the name: ./count.rsh Holiday. |
a value in a command is nil | A variable you put in a command holds nothing (Ruby calls that nil). rsh stops instead of running the command with a missing word. Check where the variable is set. |
| A line you meant as a command ran as Ruby | Its first word is also a variable or method in your script, such as date after date = …. Put $ in front to force a command: $ date +%A. |
undefined method with NoMethodError | A Ruby word is misspelled, or it is not in the Ruby that comes with rsh. For your home folder, write ENV.fetch("HOME"). |
bad.rsh:3:0: syntax error, unexpected end of file | rsh stopped understanding the file at line 3: usually an end or a closing quote mark is missing above it. wol script check shows this without running anything; fix the line, save, check again. |
Where to learn more
The rsh page shows more of what rsh does, with each job written both as a shell script and in rsh. Scripts that change settings shows what WolOS asks before a script changes a setting, and Scripts and shells how to run a script on another computer.
Related
- Your first shell scriptWrite a shell script from nothing: what a script is, the first line, making it run, running it, a variable, a loop, and what to do when it goes wrong.
- Scripts that change settingsWrite a small Ruby script in a text editor, check it with wol script check, run it with wol script run, and see what WolOS asks before a script changes anything.
- Scripts and shellsRun sh, bash and Ruby scripts with wol script: checked before they run, as you, every change asked on screen and every run recorded. And choose the shell new terminal windows open in, PowerShell included.
- What a terminal isThe window where you type instead of click: what the prompt, a command, an argument and a path are, how to copy and paste, Tab, Ctrl+C, and your first five commands.
- PowerShell basicsUse PowerShell on WolOS: add it, open it, the Verb-Noun commands, objects in the pipeline, help, and making it the shell of every new terminal window.