How to get output from bash shell [duplicate] - linux

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
bash - automatically capture output of last executed command into a variable
For example
In Bash shell
user:/ & echo "Hello"
Hello
user:/ & date
Sat Mar 17 01:48:45 ICT 2012
How to get the "Hello" or "Sat Mar 17 01:48:45 ICT 2012" variables
I mean every output from command bash shell
The purpose of this point, I want to get those variables and do something with its.
Like, when echo Hello I want to reverse string to olleH and then print it out.
Something like this
echo "Hello"
olleH
More Information
In Command Line Interface ***Not in Shell Script
When I type a command echo,date (or whatever command) in the Command Line Interface, The output will show in the next line.
user:/ & echo "Hello" <br>
Hello
The "Hello" variable is the output of bash shell. So, I want to store output Hello into variable and pass into "Dictionary Script"
The Hello will matched and translated depend on Dictionary Script
Hello = Hi (Just example)
Now Hello translated into Hi, send back to shell and print out
Result
user:/ & echo "Hello" <br>
Hi
How can I grab the output?
Could I expose the Bash Shell source, edit and re-compile?
Could I grab from the /proc/BASHPID?

Attempt at answering edited question
From your edit, it sounds as if you want to have bash executing commands, but the outputs from bash should be passed to a 'transmogrifier' which changes the output according to your whims.
This is not going to be trivial; I'm not sure it will be usable for more than a few seconds of fun.
At one level, you want an interactive shell with its standard output (and maybe standard error) going to your modifier program:
bash -i 2>&1 | transmogrifier
For basic command line work, this will just about be usable, though line editing (even with just backspace) becomes a little problematic. Command line editing becomes intolerable if transmogrifier is changing what you appear to be typing as you type it. (I tried bash -i 2>&1 | tee, which worked surprisingly well, but tee just copies its input to its output; and I'm not sure why I chose tee instead of cat. An interrupt, though, killed the pipeline; just another thing you'd have to worry about.)
Attempt at answering unedited question
For the Hello, you would be best off using:
var1="Hello"
You could also use:
var1=$(echo "Hello")
For the date, you more or less must use the latter notation:
var2=$(date)
You can now do things with those variables, such as:
$ echo "$var1" | rev
olleH
$
Note that simple prompts such as '$' (for Bash and relatives) or '%' (for C shell and relatives) or '#' (for root) are conventional.
I had decided not to mention the use of backticks, but since mgilson commented about them, they do, indeed, exist, and you may come across them in older scripts, and you should not write them in your own scripts.
The $(...) notation for command substitution, as it is called, is simpler in nested scenarios, such as:
cd $(dirname $(dirname $(which gcc)))/lib
compared with the backtick notation for the same operation:
cd `dirname \'dirname \\\`which gcc\\\`\``/lib
(Don't even think of trying to get that second line into MarkDown for comments! That's why I've added this to the answer.)

Related

Automatic enter input in shell command line [duplicate]

This question already has answers here:
Have bash script answer interactive prompts [duplicate]
(6 answers)
Closed 5 years ago.
I am running a script (I can't edit it), and there are three yes/no questions. How can I automatically respond to these questions? I need to answer yes, yes, no (in that order).
Try this:
echo -e "yes\nyes\nno" | /path/to/your/script
From help echo:
-e: enable interpretation of the following backslash escapes
Pipe to Standard Input
Some scripts can take replies from standard input. One of the many ways to do this would be:
$ printf "%s\n" yes yes no | ./foo.sh
yes yes no
This is simple and easy to read, but relies on how your script internals handle standard input, and if you can't edit the target script that can sometimes be a problem.
Use Expect for Interactive Prompts
While you can sometimes get away with using standard input, interactive prompts are generally better handled by tools like Expect. For example, given a script foo.sh, you can write foo.exp to automate it.
Note: You can also use autoexpect to create a a script from an interactive session, which you can then edit if necessary. I'd highly recommend this for people new to Expect.
Bash Script: foo.sh
This is the script you might want to automate.
#!/usr/bin/env bash
for question in Foo Bar Baz; do
read -p "${question}? "
replies=("${replies[#]}" "$REPLY")
done
echo "${replies[#]}"
Expect Script: foo.exp
Here is a simplistic Expect script to automate the Bash script above. Expect loops, branching, and regular expressions can provide much more flexibility than this oversimplified example shows, but it does show how easy a minimal Expect script can be!
#!/usr/bin/env expect
spawn -noecho /tmp/foo.sh
expect "Foo? " { send -- "1\r" }
expect "Bar? " { send -- "2\r" }
expect "Baz? " { send -- "3\r" }
interact
Sample Interactive Session
This is what your interactive session will look like when you run the Expect script. It will spawn your Bash script, and respond as instructed to each different prompt.
$ /tmp/foo.exp
Foo? 1
Bar? 2
Baz? 3
1 2 3

predefined input in a nohup shell script [duplicate]

I have a script that calls an application that requires user input, e.g. run app that requires user to type in 'Y' or 'N'.
How can I get the shell script not to ask the user for the input but rather use the value from a predefined variable in the script?
In my case there will be two questions that require input.
You can pipe in whatever text you'd like on stdin and it will be just the same as having the user type it themselves. For example to simulating typing "Y" just use:
echo "Y" | myapp
or using a shell variable:
echo $ANSWER | myapp
There is also a unix command called "yes" that outputs a continuous stream of "y" for apps that ask lots of questions that you just want to answer in the affirmative.
If the app reads from stdin (as opposed to from /dev/tty, as e.g. the passwd program does), then multiline input is the perfect candidate for a here-document.
#!/bin/sh
the_app [app options here] <<EOF
Yes
No
Maybe
Do it with $SHELL
Quit
EOF
As you can see, here-documents even allow parameter substitution. If you don't want this, use <<'EOF'.
the expect command for more complicated situations, you system should have it. Haven't used it much myself, but I suspect its what you're looking for.
$ man expect
http://oreilly.com/catalog/expect/chapter/ch03.html
I prefer this way: If You want multiple inputs... you put in multiple echo statements as so:
{ echo Y; Y; } | sh install.sh >> install.out
In the example above... I am feeding two inputs into the install.sh script. Then... at the end, I am piping the script output to a log file to be archived and viewed for later.

Bash here document - suppress printing code to the screen?

I am writing a script to become a user (let's call it genomics) via the cmd "sudo /etc/bgenomics" (this is setup by our admin) and run some bash code as that user, namely run a cmd, catch the exit code and take the appropriate action.
The problem is the bash code inside the here doc get printed to the screen, which is distracting and looks really unelegant.
Here's an illustration:
#!/bin/bash
name='George'
sudo /etc/bgenomics <<Q
/bin/bash
if (( 2 == 2 )); then
echo "my name is $name"
grep zzz /etc # will return nothing and $? = 1
echo \$? # this should be 1 after the above cmd
fi
Q
The if statement is just there to show how annoying it is when printed.
Right now all of the following is printed to the screen:
Script started, file is /var/tmp/genomicstraces/c060644.20140617143003.11536
Script done, file is /var/tmp/genomicstraces/c060644.20140617143003.11536
brainiac-login-02$brainiac-login-02$/bin/bash
bash-3.2$ if (( 2 == 2 )); then
> echo "my name is George"
> grep zzz /etc # will return nothing and 0 = 1
> echo $? # this should be 1 after the above cmd
> fi
my name is George
1
The only parts I want to see are "my name is George" and "1". Can it be done?
Is another process calling this script? Output shouldn't normally appear unless bash is called with '-x'. Try modifying the first line of your script if you cannot disable echo in the calling process:
#!/bin/bash +x
You may also want to remove the call to /bin/bash after the sudo command unless you really wish to start another shell within your shell.
The here document supplies input to the bgenomics script via its standard input. What happens to that input is up to that script.
If you want the script to print some of its input, and not print some of its input, you have to modify the script.
If bgenomics is actually a wrapper for an interactive shell session (as it seems to be, judging by the Script started and Script done traces), then here documents are not the best way to feed input into it.
A good way is to use the expect utility, which controls interactive programs via a pseudo-terminal device and provides a scripting language with a great deal of control. expect can suppress all unwanted input from an interactive program. It can look for specific outputs from the program, and supply responses. For instance it can look for a login: string coming from the interactive session, and send a user name.
The program bgenomics has an invocation of script in it to record what the script did. Talk to the person in charge of that to understand what their intentions are. Until you understand the purpose of bgenomics you risk screwing up what the author of that is trying to do.
$ script /tmp/junk.txt
Script started, file is /tmp/junk.txt
$ date # this is a child shell of the script command
Tue Jun 17 21:04:14 EDT 2014
$ exit
Script done, file is /tmp/junk.txt

call bash script and fill input data from another bash script

I have a bash script, a.sh
And when I run a.sh, I need to fill several read. Let's say it like this
./a.sh
Please input a comment for script usage
test (I need to type this line mannually when running the script a.sh, and type "enter" to continue)
Now I call a.sh in my new script b.sh. Can I let b.sh to fill in the "test" string automaticlly ?
And one other question, a.sh owns lots of prints to the console, can I mute the prints from a.sh by doing something in my b.sh without changing a.sh ?
Thanks.
Within broad limits, you can have one script supply the standard input to another script.
However, you'd probably still see the prompts, even though you'd not see anything that satisfies those prompts. That would look bad. Also, depending on what a.sh does, you might need it to read more information from standard input — but you'd have to ensure the script calling it supplies the right information.
Generally, though, you try to avoid this. Scripts that prompt for input are bad for automation. It is better to supply the inputs via command line arguments. That makes it easy for your second script, b.sh, to drive a.sh.
a.sh
#!/bin/bash
read myvar
echo "you typed ${myvar}"
b.sh
#!/bin/bash
echo "hello world"
You can do this in 2 methods:
$ ./b.sh | ./a.sh
you typed hello world
$ ./a.sh <<< `./b.sh`
you typed hello world

Use return value of a shell command as a value in shell script? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Capturing multiple line output to a bash variable
For example I want to run ls command and take the return list as a value kept in a array in shell script.
Something like
run
#ls
fileA
fileB
fileC
kept this return list in a variable that keeps a array
variable A = ["fileA","fileB","fileC"];
I cannot give the exact notation for code since I do not know how to write shell script. After I learn this, I 'll.
#!/bin/bash
variableA=$(ls)
echo $variableA
That should be your shell script assuming that you have bash
Then all you'd need to do is chmod +x shell_script to make it executable.
If you use ls > contents.file the result of ls is saved to a file called contents.file.
Remember, > rewrites the entire file while >> appends to the last line.
variableA=$(ls)
echo "$variableA"

Resources