I have a tcl script file called hello.tcl, with the following content:
puts "hello world"
When I run it on bash using the command,
tclsh hello.tcl
I get the hello print.
However, if I use tclsh -f instead of just tclsh above, I don't get any print, only the tcl prompt. Why don't I get any prints in the second case?
tclsh syntax is:
tclsh ?-encoding name? ?fileName arg arg ...?
That means you can call it like this:
tclsh hell.tcl
tclsh -encoding (something) hell.tcl
Anything else is an error. Instead of barking at you, tclsh silently ignores the error and open up the shell.
Tcl Command Notation
I found Tcl command notation a bit strange at first, and could not find any reference any where. However, here are what I understand:
The ? ... ? notation means optional
Tcl commands use a single dash as opposed to double dash: -encoding instead of '--encoding`
Manual
As for help, I installed ActiveState Tcl 8.5 and it comes with a file called ActiveTclHelp8.5.chm, which is my bible. This file is very detailed, with complete search capability. I cannot give you that file for fear of legal implications, but you can install ActiveState Tcl to get it.
Related
How can I check if a program exists within a fish script?
I know that there is no absolute solution with Bash, but using if type PROGRAM >/dev/null 2>&1; then... gave good results.
Is there something similar with fish?
There is type -q, as in
if type -q $program
# do stuff
end
which returns 0 if something is a function, builtin or external program (i.e. if it is something fish will execute).
There is also command -sq, which will return 0 only if it is an external program.
For both of these the "-q" flag silences all output. For command the "-s" makes it just look for a command instead of executing it directly.
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
I want to be able to start a process and send input to it immediately.
Take Bash as an example.
The following code will enter another Bash process and then print "Hello World!" on the screen after I have terminated the process with "exit"
bash
echo "Hello World!"
Is there a way to enter bash and then print "Hello World!" INSIDE that process?
I'm using Ruby and Bash on Ubuntu.
UPDATE: This question was not intended to be Bash specific. Bash was just an example. It would be better if someone could post an answer that handles all other binaries.
You may be looking for the expect tool.
bash -c 'echo "Hello World!"'
You can also try writing bash script and invoking it:
bash ./myscript
or put #!/bin/bash as the first line in a text file and it will be invoked using bash like any other executable:
./myscript
Update0
Bash is an interpreter. There are many other interpreters, I'd highly recommend you take a look at Python, you can send instructions to be interpreted to these programs easily enough.
You might also be referring to the Unix IO-model, in which case you may want to ask a question relating to the use of piping with stdin and stdout.
%x(some external bash commands)
`ls -1`