I am trying to get the entire output of a bash script to save to a file. I currently have one argument (ip address) at the beginning of the code looks like this:
#!/bin/bash
USAGE="Usage: $0 [<IP address>]"
if [ "$#" == "0" ]; then
echo "$USAGE"
exit 1
fi
ip_addr=$1
What I'd like to do is add another argument called "output", that the entire output of the script will save to. I'm aware I could just run myscript.sh | tee textfile.txt, but I'd like to make the script a little easier to run for others.
Thanks in advance,
hcaw
After the usage message, add the following line:
exec > "$2"
This will redirect standard output for the rest of the script to the file named in the 2nd argument.
Then run using
myscript 192.0.2.42 output.txt
Related
I am trying to send an output of an executed shell script, to a log file.
However I want to put a timestamp at the start of the line for every output, so I created a function to do that.
But how do I pass the results of the executed shell script, into the function?
#This is a sample of the executed file testrun.sh
#!/bin/bash
echo "Script Executed."
#Actual script being run
#!/bin/bash
testlog="/home/usr/testlog.log"
log_to_file() {
echo "$(date '+%Y-%m-%d %H:%M:%S') $1" >> $testlog
}
sh /home/usr/testrun.sh >> log_to_file
If i were to log it normally, i would just do
sh /home/usr/testrun.sh >> $testlog
But how do I pass in the output of testrun.sh, into the function log_to_file, so that I can log the output to the file with the timestamp?
You can of course do a
log_to_file "$(sh /home/usr/testrun.sh)"
Of course if your testrun.sh produces more than one line of output, only the first one gets the timestamp as prefix.
Use a while read loop to get each line into a variable that you can pass to log_to_file.
/home/usr/testrun.sh | while read -r line; do
log_to_file "$line"
done >> "$testlog"
You could also use the ts command instead of your function
/home/usr/testrun.sh | ts >> "$testlog"
unfortunately I'm struggling with some kind of a "simple idea".
Within my Bash Script I'm checking a variable and if it's set I'll print output to the user (kind of verbose / show output).
[ ! -z $boolVerbose ] && fnc_print2user "i" "Print to user in one-line"
That's working pretty fine for me.
Now I have commands which don't allow suppressing their output, so I want to hide it or show it if my variable above is set/not empty.
I tried the following (and several other options..), to run the command as it is (means: showing output), expect the variable is not set/is empty, then it should append "&> /dev/null" to the command before (so suppress the output).
commandWithOutput $([ -z $boolVerbose ] && echo " &> /dev/null")
The script is running fine if I set my verbose Variable, but if it's not set my commandWithOutput throws an error that there're invalid arguments set (if I hard code to suppress every time it's working like charm).
Is it possible to do some kind of dynamic command adjustments like above in a one-liner or do I have to built real if-else statements with different commandWithOutput methods inside?
Thanks in advance for your ideas & help! :-)
I think this roughly gives you what you wanted :
commandWithOutput &> /dev/$([ -z "$boolVerbose" ] && echo null || echo stdout)
Redirect the output to a different file descriptor. Use exec to redirect this descriptor to output or to /dev/null as you need.
#!/bin/bash
for hide in 0 1 ; do
if ((hide)) ; then
exec 3>/dev/null
else
exec 3>&1
fi
echo $hide: something >&3
exec 3>&-
done
I am using simple script to print the arguments. But not able to do so.
i am using cat command to add content to a file.
[root#cen06gst ~]# cat<<EOF>pass.sh
echo " you have passed me" $#
> EOF
But when i am seeing the file content again using cat , this is showing
[root#cen06gst ~]# cat pass.sh
echo " you have passed me"
Cat only is a command line tool to concatenate and print to the screen, it doesn't modify the file. Read
man cat
If you want to run your script, run
./pass.sh argument
It is also good practice to start your script with a shebang:
#!/bin/bash
Without it the system doesn't know what language to use to process the script.
I need to read command line arguments. First arg is script name. second one is redirection operator i.e. "<" and third one is input filename. When I tried to use "$#", I got 0. When I used "$*", it gave me nothing. I have to use "<" this operator. My input file consists of all user input data. If I don't use the operator, It asks user for the input. Can someone please help me? Thank you !
Command Line :
./script_name < input_file
Script:
echo "$*" # gave nothing
echo "$#" # gave me 0
I need to read input filename and store it to some variable. Then I have to change the extension of it. Any help/suggestions should be appreciated.
When a user runs:
./script_name <input_file
...that's exactly equivalent to if they did the following:
(exec <input_file; exec ./script_name)
...first redirecting stdin from input_file, then invoking the script named ./script_name without any arguments.
There are operating-system-specific interfaces you can use to get the filename associated with a handle (when it has one), but to use one of these would make your script only able to run on an operating system providing that interface; it's not worth it.
# very, very linux-specific, won't work for "cat foo | ./yourscript", generally evil
if filename=$(readlink /proc/self/fd/0) && [[ -e $filename ]]; then
set -- "$#" "$filename" # append filename to the end of the argument list
fi
If you want to avoid prompting for input when an argument is given, and to have the filename of that argument, then don't take it on stdin but as an argument, and do the redirection yourself within the script:
#!/bin/bash
if [[ $1 ]]; then
exec <"$1" # this redirects your stdin to come from the file
fi
# ...put other logic here...
...and have users invoke your script as:
./script_name input_file
Just as ./yourscript <filename runs yourscript with the contents of filename on its standard input, a script invoked with ./yourscript filename which invokes exec <"$1" will have the contents of filename on its stdin after executing that command.
< is used for input redirection. And whatever is at the right side of < is NOT a command line argument.
So, when you do ./script_name < input_file , there will be zero (0) command line arguments passed to the script, hence $# will be zero.
For your puprpose you need to call your script as:
./script_name input_file
And in your script you can change the extension with something like:
mv -- "$1" "${1}_new_extension"
Edit: This was not what OP wanted to do.
Altough, there is already another spot on answer, I will write this for the sake of completeness. If you have to use the '<' redirection you can do something like this in your script.
while read filename; do
mv -- "$filename" "${filename}_bak"
done
And call the script as, ./script < input_file. However, note that you will not be able to take inputs from stdin in this case.
Unfortunately, if you're hoping to take redirection operators as arguments to your script, you're not going to be able to do that without surrounding your command line arguments in quotes:
./script_name "<input_file"
The reason for this is that the shell (at least bash or zsh) processes the command before ever invoking your script. When the shell interprets your command, it reads:
[shell command (./script_name)][shell input redirection (<input_file)]
invoking your script with quotes effectively results in:
[shell command (./script_name)][script argument ("<input_file")]
Sorry this is a few years late; hopefully someone will find this useful.
how can i make a bash script to tell the script this:
i will tell the bash like:
#!/bin/bash
include /usr/local/serverinfo.txt or.sh
rsync -avz $location root#$host:/$location2
all of this $location, $host , $location2, to be entered in /usr/local/serverinfo.txt
how can i tell the bash script to get this infos from the file,
if i put them in the same file will work just perfect, however i whant it to be outside of the file, any ideea?
let me know, thanks.
You can use source, or equivalently ., which takes another file as an argument and executes it. This assumes that the file you are sourceing contains valid bash syntax.
script.sh:
#!/bin/bash
var=1
source inc.sh # or . inc.sh
echo $var
inc.sh
var=2
output:
2
This depends on how the data in serverinfo.txt is formatted.
If it is a simple list like
/this/is/the/first/location
/this/is/the/host
/this/is/the/second/location
then you can do
location=$(sed -n '1p' /path/to/serverinfo.txt)
host=$(sed -n '2p' /path/to/serverinfo.txt)
location2=$(sed -n '3p' /path/to/serverinfo.txt)