Expect scripting basics - expect

I am new to Expect scripting and I would like to know any link where I can start with the basics of Expect scripting.
Syntax of commands
How to run and test the script.

Get the book Exploring Expect. Expect is an extension of Tcl, so go through the Tcl tutorial.
A quick tutorial on how to make a script executable:
You need a "shebang" line to let the OS know how to interpret your script
You need to give the file executable permissions
You need to put the script in a directory that's in your $PATH, or invoke it with a full or relative path.
$ cat > test.exp << END
#!/usr/bin/expect -f
send_user "hello world\n"
END
$ chmod a+x test.exp
$ ./test.exp
hello world
While you are developing and testing your Expect script, put
exp_internal 1
at the beginning.

Related

How to create a AS400 shell script (.ksh) file

I am new to shell script on iSeries, but i have created one sample script:
#!/bin/ksh
cd /QIBM/Userdata/employeedetails/
pwd
ls -ltr
I placed it under /QIBM/testscript.ksh and tried to run the script on the main menu using STRQSH CMD('/QIBM/testscript.ksh')
I got this error, can someone please let me know what did do wrong here?
qsh: 001-0014 Command /QIBM/testscript.ksh not found.
Press ENTER to end terminal session.
I am wondering, is it possible to create shell script on the iSeries (AS/400)?
It is certainly possible to create a shell script.
The default shell is Qshell which can be referenced as /bin/qsh or /bin/sh.
echo '#!/bin/sh
pwd
ls -ltr' > $HOME/testscript.sh
To run it:
STRQSH CMD('$HOME/testscript.sh')
Korn shell is available with IBM PASE for i at /qopensys/usr/bin/sh or /qopensys/usr/bin/ksh.
Also I would advise against putting things in the /QIBM directory. I suggest $HOME or /opt. See the Filesystem Hierarchy Standard for more information.
Did you make the script executable? Unless you have *ALLOBJ authority, you must mark the script executable by executing either
chmod 755 /QIBM/testscript.ksh from a shell or
CHGAUT OBJ('/QIBM/testscript.ksh') USER(USRNAME) DTAAUT(*RWX) from CL
It also looks like you maybe forgot the # in the first line, unless it's just a Stack Overflow formatting mistake. Your first line should be:
#!/QOpenSys/usr/bin/ksh
as ksh is not found in /bin on IBM i.

Why won't my Ruby script execute?

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.

Can a script be used as an interpreter by the #! hashbang line?

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",...).

How to run multiple Unix commands in one time?

I'm still new to Unix. Is it possible to run multiple commands of Unix in one time? Such as write all those commands that I want to run in a file, then after I call that file, it will run all the commands inside that file? or is there any way(or better) which i do not know?
Thanks for giving all the comments and suggestions, I will appreciate it.
Short answer is, yes. The concept is known as shell scripting, or bash scripts (a common shell). In order to create a simple bash script, create a text file with this at the top:
#!/bin/bash
Then paste your commands inside of it, one to a line.
Save your file, usually with the .sh extension (but not required) and you can run it like:
sh foo.sh
Or you could change the permissions to make it executable:
chmod u+x foo.sh
Then run it like:
./foo.sh
Lots of resources available on this site and the web for more info, if needed.
echo 'hello' && echo 'world'
Just separate your commands with &&
We can run multiple commands in shell by using ; as separator between multiple commands
For example,
ant clean;ant
If we use && as separator then next command will be running if last command is successful.
you can also use a semicolon ';' and run multiple commands, like :
$ls ; who
Yep, just put all your commands in one file and then
bash filename
This will run the commands in sequence. If you want them all to run in parallel (i.e. don't wait for commands to finish) then add an & to the end of each line in the file
If you want to use multiple commands at command line, you can use pipes to perform the operations.
grep "Hello" <file-name> | wc -l
It will give number of times "Hello" exist in that file.
Sure. It's called a "shell script". In bash, put all the commands in a file with the suffix "sh". Then run this:
chmod +x myfile.sh
then type
. ./myFile
or
source ./myfile
or just
./myfile
To have the commands actually run at the same time you can use the job ability of zsh
$ zsh -c "[command1] [command1 arguments] & ; [command2] [command2 arguments]"
Or if you are running zsh as your current shell:
$ ping google.com & ; ping 127.0.0.1
The ; is a token that lets you put another command on the same line that is run directly after the first command.
The & is a token placed after a command to run it in the background.

Execute commands inside another process?

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`

Resources