I have the following scenario. I have a shell script that is generated automatically, that I want to run. The general format of the script looks something like this:
#!/bin/sh
command_1 #something like mkdir dir1 or chmod -R 775 dir1, you get the idea
command_2
...
...
command_n
Like I said the script will be automatically generated in a way that I don't have much control of the commands that are written in the script (the purpose of the script is to use it for fuzz testing, so it makes sense). The problem is that some commands require some sort of user input (for example "chfs --some arguments" will sometimes prompt me for the root password), and therefore the script will not pass to the next command until it gets the proper input.
So, my question is: Is there a way to skip the commands that require user input when they are met in such a script, so that the script finishes and executes all the other commands? Any idea is greatly appreciated.
You can use expect script to work around this, something like this
spawn /bin/bash yourscipt.sh
expect "password:"
# Send the password, and then wait for a shell prompt.
send "xxxxx\r"
Here XXXX isyour password.
Lets say your script requires a user to enter a choice interactively.
User press y then again it askes user name.
User enter his name and then script continues.
Enter choice (y/n):_
Enter name :_
So you can pass inputs by preparing an input file with choices written in each line.
content of input file :
y
Inderdeep
And run the script as : cat inputfile | ./script
Related
I want to make a script in Linux, that starts a program (in the terminal), and then write what I want in the context of the already running program.
For example, I have myScript.sh :
#!/bin/bash
echo "I want to open pgcli"
pgcli -h #ARGUMENTS#
....
When I run it from a terminal, this of course get stuck when the pgcli starts. And when I manually finish it, the following statements are executed.
What I'mt trying to do is: when pgcli starts and ask me for password, the script to write the password IN the context of the program (and then, another SQL statements).
Can this be done in a script? If so, how could I do it?
Thanks!
assuming your program reads from stdin,
if you have a file containing all the needed input like so:
password
sql query1
sql query2
then you can do something like:
cat input | pgcli
in your script. Or just do
echo "input" | pgcli
I am writing a wrapper shell script wrapper.sh to run bunch of other already available scripts owned by other people and I cannot touch those scripts.
The problem is, there is one script that runs some db specific activities - db_perf_clean.sh. That script is normally executed manually and it prompts for a password at run time. There is no way I can supply the password to it as a parameter and I cannot modify that script. As such I know the db password and I can provide it in wrapper.sh.
Please let me know how can I run that db_perf_clean.sh script inside wrapper.sh like in a silent mode.
Sometimes a script will insist that a password be read from the tty. Often, it will read from stdin. If so, try:
echo password | db_perf_clean.sh
The above has the disadvantage that the password will appear in ps. To avoid that, hide the password in a file and use that file for stdin:
db_perf_clean.sh <file_with_password
If you want the command to be silent, you can throwaway its output:
db_perf_clean.sh <file_with_password >/dev/null 2>&1
Under bash, as opposed to generic shell, that can be slightly simplified:
db_perf_clean.sh <file_with_password &>/dev/null
I found out little different approach instead of writing a password in a file and that worked too ->
db_pass="somevalue"
sh db_perf_clean.sh<<EOM
$db_pass
EOM
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
I'm making a shell script and I want to know if it's possible to write directly to the command line when the script is executed ?
Example :
user#localhost:/home/user$./script.sh
... output
... another output
... another output
... last output
user#localhost:/home/user$I want to write here on the command line
I don't want to "echo" some text, I want to write directly at the prompt.
Thanks!
No, you can't do that. If you want user to invoke your provided command after your script is finished - why not just prompt user for confirmation?
If you just want the text to show up there, but not be able to do anything with it, you can do this.
File test.sh:
echo "Output"
./test2.sh &
File test2.sh:
echo "Output2"
Notice how the first script calls the second script with the & at the end.
In this case, "Output2" will be written to the prompt, but it can't be deleted and will have no effect on the next command at all. But if this is something you're doing to grab the user's attention, it would work.
In ksh:
print -s $(script)
will print to the command history. Wrap this in a function and you'll have something close to what you are asking for.
If you are using X environment install xclip and xdotool, then:
#!/bin/bash
your scripts....
echo -n your command to write 2>&1|xclip
xdotool click 2
i created a crontab which will run a bash script test.sh. This test.sh file requires some input from the user, and saves the user input into a variable. How do i ensure that the user input will be saved to a variable in test.sh, and when crontab runs the script i can get the output i want?
for e.g i have 2 files, file1.sh and file2.sh. i put file2.sh in file 1.sh. i then run file1.sh, get the user input, and save it somewhere. crontab will run file2.sh, and retrieve the value from the "saved somewhere variable". is there anyway for this?
If the input is read by the script from stdin, just redirect input from a file (using a wrapper script).
#! /bin/sh
test.sh < data.in
If this does not work for you (i.e. you have your script calling some interactive shell program like telnet, you can use Expect to automate the interaction.
file1.sh gets user input and writes it to /etc/file2.dat
file2.sh reads /etc/file2.dat and does whatever it needs
This seems like a strange thing to do. Ask yourself these questions:
Do you really want a popup asking the user for an input value every time the cron runs?
What happens when there's no one at the keyboard?