Im using inf-ruby mode in emacs, I really live it. But anyone know how to run a ruby script with arguments by inf-ruby? for instance, I need to pass argument arg0 and arg1 to test.rb
test.rb -arg0 -arg1
The short answer: instead of M-x run-ruby, call it with a prefix arg like so: C-u M-x run-ruby. This will allow you to edit the command line.
The long answer: don't. Instead re-structure your code so that you can test / call all the functionality without relying on parsing the command line arguments. Then do some simple tests from the command line whether your argument parsing works out okay.
Related
I want to know how to use switches at the command line in expect just like getopts in bash scripts.
Thanks in advance
See How to pass argument in expect through command line in shell script and http://www.tcl.tk/man/expect5.31/expect.1.html (Usage section).
Update: Expect is based on Tcl, and the usual method in Tcl to parse optional arguments from the command line as in getopts is the cmdline library package. This is part of tcllib, so you might need to install that if it's not already on your system.
So, I made a simply ruby script,
#!/usr/bin/env ruby
puts "Hello!"
When I try to run it in terminal it doesn't put "Hello!" on the screen. I have tried entering chmod +x test.rb (test.rb is the name of my file). When I run it, it doesn't give me an error, it just doesn't display "Hello!". Any help will be much appreciated. I have looked everywhere for a possible answer, and I have found nothing so far.
I'd guess that you're trying to run it as just test like this:
$ test
But test is a bash builtin command that doesn't produce any output, it just sets a return value. If you run your script properly:
$ ./test.rb
then you'll see something. Note the explicit ./ path, the current directory is rarely (and hopefully never) in your PATH so you need to say ./ to run something in the current directory (unless of course you're in /bin, /usr/bin, etc.).
In the comments you say that there are some Ctrl+M characters in your script:
$ cat -e test.rb
#!/usr/bin/env ruby^M^Mputs "Hello!"
I don't see any $s in that cat -e output so you don't have any actual end-of-line markers, just some carriage-return characters (that's the ^M). A single CR is an old MacOS end-of-line, Windows uses a CR-LF pair, and Unix (including OSX) uses just a single LF to mark the end of a line of text. Since you don't have any EOLs, the shell just sees a single line that looks like:
#!/usr/bin/env ruby ...
without an actual script for ruby to run, the shell just sees the shebang comment and nothing else. The result is that nothing noticeable happens when you run your script. Fix your EOLs and your script will start working sensibly. You might also want to look at your editor's settings so that it starts writing proper EOLs.
How are you calling this method. You would want to call this out by something like ruby test.rb if you are in the directory with the test.rb file. Another general tip for trying something out that doesn't work would be to go into irb on command line and try your program, like puts "Hello! to see if it is that particular code that is the problem.
I make a complex and long line command to successful login in a site. If I execute it in Console it work. But if I copy and paste the same line in a bash script it not work.
I tried a lot of thing, but accidentally discovery that if I NOT use the line
#!/bin/sh
it work! Why this happens in my mac OSX Lion? What this config line do in a bash script?
A bash script that is run via /bin/sh runs in sh compatibility mode, which means that many bash-specific features (herestrings, process substitution, etc.) will not work.
sh-4.2$ cat < <(echo 123)
sh: syntax error near unexpected token `<'
If you want to be able to use full bash syntax, use #!/bin/bash as your shebang line.
"#!/bin/sh" is a common idiom to insure that the correct interpreter is used to run the script. Here, "sh" is the "Bourne Shell". A good, standard "least common denominator" for shell scripts.
In your case, however, "#!/bin/sh" seems to be the wrong interpreter.
Here's a bit more info:
http://www.unix.com/answers-frequently-asked-questions/7077-what-does-usr-bin-ksh-mean.html
Originally, we only had one shell on unix. When you asked to run a
command, the shell would attempt to invoke one of the exec() system
calls on it. It the command was an executable, the exec would succeed
and the command would run. If the exec() failed, the shell would not
give up, instead it would try to interpet the command file as if it
were a shell script.
Then unix got more shells and the situation became confused. Most
folks would write scripts in one shell and type commands in another.
And each shell had differing rules for feeding scripts to an
interpreter.
This is when the "#! /" trick was invented. The idea was to let the
kernel's exec() system calls succeed with shell scripts. When the
kernel tries to exec() a file, it looks at the first 4 bytes which
represent an integer called a magic number. This tells the kernel if
it should try to run the file or not. So "#! /" was added to magic
numbers that the kernel knows and it was extended to actually be able
to run shell scripts by itself. But some people could not type "#! /",
they kept leaving the space out. So the kernel was exended a bit again
to allow "#!/" to work as a special 3 byte magic number.
So #! /usr/bin/ksh and
#!/usr/bin/ksh now mean the same thing. I always use the former since at least some kernels might still exist that don't understand the
latter.
And note that the first line is a signal to the kernel, and not to the
shell. What happens now is that when shells try to run scripts via
exec() they just succeed. And we never stumble on their various
fallback schemes.
The very first line of the script can be used to select which script interpreter to use.
With
#!/bin/bash
You are telling the shell to invoke /bin/bash interpreter to execute your script.
Assure that there are not spaces or empty lines before #!/bin/bash or it will not work.
I'm trying to write a bash script which will behave as a basic interpreter, but it doesn't seem to work: The custom interpreter doesn't appear to be invoked. What am I doing wrong?
Here's a simple setup illustrating the problem:
/bin/interpreter: [owned by root; executable]
#!/bin/bash
echo "I am an interpreter running " $1
/Users/zeph/script is owned by me, and is executable:
#!/bin/interpreter
Here are some commands for the custom interpreter.
From what I understand about the mechanics of hashbangs, the script should be executable as follows:
$ ./script
I am an interpreter running ./script
But this doesn't work. Instead the following happens:
$ ./script
./script: line 3: Here: command not found
...It appears that /bin/bash is trying to interpret the contents of ./script. What am I doing wrong?
Note: Although it appears that /bin/interpreter never invoked, I do get an error if it doesn't exist:
$ ./script
-bash: ./script: /bin/interpreter: bad interpreter: No such file or directory
(Second note: If it makes any difference, I'm doing this on MacOS X).
To make this work you could add the interpreter's interpreter (i.e. bash) to the shebang:
#!/bin/bash /bin/interpreter
Here are some commands for the custom interpreter.
bash will then run your interpreter with the script path in $1 as expected.
You can't use a script directly as a #! interpreter, but you can run the script indirectly via the env command using:
#!/usr/bin/env /bin/interpreter
/usr/bin/env is itself a binary, so is a valid interpreter for #!; and /bin/interpreter can be anything you like (a script of any variety, or binary) without having to put knowledge of its own interpreter into the calling script.
Read the execve man page for your system. It dictates how scripts are launched, and it should specify that the interpreter in a hash-bang line is a binary executable.
I asked a similar question in comp.unix.shell that raised some pertinent information.
There was a second branch of the same thread that carried the idea further.
The most general unix solution is to have the shebang point to a binary executable. But that executable program could be as simple as a single call to execl(). Both threads lead to example C source for a program called gscmd, which is little more than a wrapper to execv("gs",...).
I can run Bash shell commands from with a Ruby program or irb using backticks (and %x(), system, etc). But that does not work with history for some reason.
For example:
jones$ irb --simple-prompt
>> `whoami`
=> "jones\n"
>> `history`
(irb):2: command not found: history
=> ""
From within a Ruby program it produces this error:
/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31: command not found: history
In bash itself, those commands work fine
It's not that the Ruby call is invoking a new shell - it simply does not find that command...
Anyone know why? I'm stumped...
Most unix commands are implemented as executable files, and the backtick operator gives you the ability to execute these commands from within your script. However, some commands that are interpreted by bash are not executable files; they are features built-in to the bash command itself. history is one such command. The only way to execute this command is to first execute bash, then ask it to run that command.
You can use the command type to tell you the type of a particular command in order to know if you can exec it from a ruby (or python, perl, Tcl, etc script). For example:
$ type history
history is a shell builtin
$ type cat
cat is /bin/cat
You'll also find that you can't exec aliases defined in your .bashrc file either, since those aren't executable files either.
It helps to remember that exec'ing a command doesn't mean "run this shell command" but rather "run this executable file". If it's not an executable file, you can't exec it.
It's a built-in. In general, you can run built-ins by manually calling the shell:
`bash -c 'history'`
However, in this case, that will probably not be useful.
{~} ∴ which history
history: shell built-in command