Spaces is nice to have on OS X—it is just the concept of workspaces moved to Aqua. The only problem with it is that it relies heavily on the mouse/GUI side of things. You can switch workspaces easily enough with Cmd + number but moving windows around is a bit trickier. The least inconvenient way of doing this is to click on the desired window and while keeping the mouse button pressed, use the Cmd + number for the desired workspace. Hopefully next update will allow something like Shift + Cmd + number to move the currently focused window.
Displaying articles with tag unix
Posted by rue, Sat Oct 14 00:54:00 UTC 2006
The preliminary release of rs is out! You can view the documentation for more information.
Using rs
rs uses Readline which means that you can use the arrow keys to go up and down in history and back and forth in the current line.
Executing Ruby code
You should be able to execute any Ruby code on the line:1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
rs> 5 + 6 => 11 rs> rs> class Foo ..> def bar ..> puts 'Baz' ..> end ..> end => nil rs> Foo.new.bar Baz => nil rs> |
Output and environment control
You can affect the output using $config values of ruby_return, prompt and continuation_prompt. $config (and $env) behave like OpenStructs with the distinction that a method ending with ? returns a boolean and one ending with ! will set the attribute to true.
The prompts are #evaled so you can put arbitrary code in there. Be mindful that a static string has to be enclosed in quotes for it to work properly.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
rs> 1 + 1 => 2 rs> $config.ruby_return = false rs> 1 + 1 rs> $config.ruby_return! => true rs> rs> $config.prompt => "'rs> '" rs> $config.prompt = '"#{Dir.pwd}> "' => '"#{Dir.pwd}> "' /tmp> '/home/me'.to_fso.cd /home/me> '/tmp'.to_fso.cd /tmp> class Foo ..> end /tmp> $config.continuation_prompt = $config.prompt => '"#{Dir.pwd}> "' /tmp> class Foo /tmp> end /tmp> $config.prompt = "'rs> '"; $config.continuation_prompt = "'..> '" |
FileSystemObjects
FSOs give a relatively object-like interface to files and paths and incorporate several File, FileUtils, Dir etc. methods.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
rs> '/tmp'.to_fso.methods.sort => ["/", "<", "<<", "==", "===", "=~", ">", ">>", "__id__", "__send__", "append_to", "args", "basename", "blockdev?", "cat", "cd", "chardev?", "chmod", "chmod_R", "chown", "chown_R", "class", "clone", "compare", "cp", "cp_r", "directory?", "dirname", "display", "dup", "eql?", "equal?", "exec", "executable?", "executable_real?", "exist?", "exists?", "extend", "extname", "file?", "find", "freeze", "frozen?", "ftype", "glob", "grpowned?", "hash", "id", "inspect", "install", "instance_eval", "instance_of?", "instance_variable_get", "instance_variable_set", "instance_variables", "is_a?", "kind_of?", "ln", "ln_s", "ln_sf", "lstat", "method", "methods", "mkdir", "mkdir_p", "mv", "nil?", "object_id", "owned?", "path", "pipe", "pipe?", "private_methods", "protected_methods", "public_methods", "readable?", "readable_real?", "readlink", "relative_path", "respond_to?", "rm", "rm_r", "rm_rf", "rmdir", "run", "send", "setgid?", "setuid?", "singleton_methods", "size", "size?", "socket?", "split", "stat", "sticky?", "symlink", "symlink?", "taint", "tainted?", "to_a", "to_os", "to_s", "touch", "truncate", "type", "umask", "unlink", "untaint", "writable?", "writable_real?", "write_to", "zero?", "|"] rs> |
1 2 3 4 5 6 7 8 9 10 11 12 |
rs> '/tmp'.to_fso.directory? => true rs> '/tmp/quux'.to_fso.exist? => false rs> '/tmp'.to_fso.cd {'./quux'.to_fso.touch} => nil rs> '/tmp/quux'.to_fso.exist? => true rs> '/tmp/quux'.to_fso.rm => ['/tmp/quux'] rs> '/tmp/quux'.to_fso.exist? => false |
Executing programs
FSOs containing executable files may (unsurprisingly) be executed. One thing to know about the processing of FSOs is that currently any filename that does not start with ./, ../, / or ~/ is considered to be ‘unqualified’ and must exist in $PATH. In addition to this, unknown methods at the top-level are first treated as unqualified files (falling back on normal if not found). The UI provides special handling and will automatically run executables. Arguments may also be given.1 2 3 4 5 6 7 8 9 10 11 12 13 |
rs> 'ls'.to_fso.run ... => nil rs> ls ... => nil rs> ls '-la' ... => nil rs> 'ls'.to_fso.args('-l') ... => nil rs> |
Input redirection
More or less arbitrary objects can be ‘redirected’, > indicating overwriting and >> appending. In both cases, the file will be created if it does not exist.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
rs> '/tmp/foo'.to_fso.touch => ["/tmp/foo"] rs> '/tmp/foo'.to_fso.cat => nil rs> '/tmp/foo'.to_fso < "Foo" => 3 rs> '/tmp/foo'.to_fso.cat Foo => nil rs> '/tmp/foo'.to_fso << 45 => 2 rs> '/tmp/foo'.to_fso.cat Foo45 => nil rs> '/tmp/nonexist'.to_fso < '/tmp/foo'.to_fso.read => 5 rs> '/tmp/nonexist'.to_fso.cat Foo45 => nil rs> |
1 2 3 4 5 6 7 8 9 |
rs> '/tmp/nonexist'.to_fso.cat Foo45 => nil rs> 78 >> '/tmp/nonexist'.to_fso => 2 rs> '/tmp/nonexist'.to_fso.cat Foo4578 => nil rs> |
Pipes
Executable programs (and/or static input) can be chained together to an arbitrary degree using ObjectStreams, also known as pipes.
The result of a piping operation can be queried with #result (this is done automatically by the UI if the value of the expression is an OS).
Alternatively, an iterator interface is exposed with #each (an other Enumerable methods).
A few modifications take place on a Ruby object being piped: Arrays are newline-joined, #to_proc objects are #called and everything else is set to its #to_s representation.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
rs> ls | wc
8 8 46
=> nil
rs> (ls | wc).result
=> [" 8 8 46"]
rs> "foo\nbar" | wc('-l')
2
=> nil
rs> "foo\nbar" | wc('-l')
2
=> nil
rs> (ls | tr('a-z A-Z')).each {|f| p f.reverse}
"ELIFEKAR"
"SCRAD_"
"NIB"
"OOB"
"COD"
"BIL"
"BR.PUTES"
"TSET"
=> #<IO:0x65be40>
rs> lambda {"foo\nbar"} | wc
2 2 8
=> nil
rs>
|
Posted by rue, Wed Sep 13 02:33:00 UTC 2006
pdumpfs /home/name /backup > /backup/log 2> /backup/errlog
In my case, I set up a cronjob to do exactly that and /backup is actually a NFS mount on a newly minted Solaris 10 fileserver on which I will have more later.
Posted by rue, Sun Sep 10 01:45:00 UTC 2006
Someone asked about ruSH on ruby-talk at a time when I had been pondering about making an interim announcement myself. I am working on a Ruby shell again though I deleted all previous work (except from the repository, of course) and have renamed the project rs.
The approach is slightly different this time. The 0.1 release which is hopefully not too far off will feature most of the basic functionality but in pure Ruby syntax. 0.2, eventually, would add a parser for more traditional-looking shell syntax. Currently I am pretty close to 0.1 but I am revisiting the piping (or ObjectStreaming) a bit to add some simplicity :)
Contrived syntax difference example:1 2 3 4 5 6 7 8 |
# 0.1 Normal ls('-la').| .map {|i| i.reverse} >> '~/revls.txt' # 0.1 Strict (this should be optional for certain environs) ls('-la').pipe_to.map {|i| i.reverse}.append_to '~/revls.txt'.to_fso # 0.2 ls -la | .map {|i| i.reverse} >> ~/revls.txt |