I have a log file and simple bash script:
echo -e "$date $totalsize $dupsize $per" > log.txt
But when I execute this script, it write first line of log.txt and show me just last data.
I tried \n but does not working.
How can I write to new line when I execute this script?
I assume what you mean is that you want to append to the log.txt? In that case, use:
echo -e "$date $totalsize $dupsize $per" >> log.txt
Note the >> which means append.
Using > will create a new file (overwrite it) each time it's run, containing whatever you echo to it.
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"
I am trying to write a shell testing program which compares the output for my program with the sample program. I have stored a list of command in a text file, it looks like this:
commands.txt:
echo line A > a
echo line A > b
./program a b
and the shell test looks like this:
cat $testname | while read LINE
do
echo -e "$LINE$"
$LINE
done
but rather than crating files a and b the program produces the flowing:
echo line A > a
line A > a
echo line B > b
line B > b
How can I execute the command just like it was written in the shell file and redirect the out put to another file?
I think the only way to do that is to use eval:
cat "$testname" | while read -r; do
echo "$REPLY"
eval "$REPLY"
done
If you just run $LINE, it will perform word splitting, but not I/O redirection, so it'll just pass > as a normal argument to echo.
The shell processes redirections before word expansion, which means that the > inside the string is not interpreted by the shell in this context. You need to request explicitly that the string is interpreted as a full command, like this:
eval "$LINE"
If you would like to write the exact same lines inside of the commands.txt file, into another file, you can say;
echo "$line" >> WriteTheLines.txt
If you would like to execute the commands inside of the commands.txt file, and write the output of the commands into another file, you can say;
eval "$line" >> ExecuteTheCommands.txt
So as an example;
#!/bin/bash
input="/home/commands.txt"
while read line
do
echo "$line" >> WriteTheCommands.txt
eval "$line" >> ExecuteTheCommands.txt
done<"$input"
I'm starting to learn how to write shell scripts. I have them all placed in a folder 'personal-scripts' in my home directory. They are starting to add up though. To solve this, I am attempting to create a script that loops over the directory and gives me a brief sentence about what each script does.
For now I can only output the script location and names via:
scriptsinfo
#!/bin/bash
for filename in ~/personal-scripts/*
do
echo $filename
done
Since I don't want to go back and update this file manually, I want to place the about sentence inside each other script either as a comment or string variable that can be evaluated.
How can I read the contents of each other script in the folder and output their string/info about what they do in this script?
You can do that using head command, which prints the first n lines of a file.
test.sh
# this is about line
# date is 14-9-2017
script data
..
..
~# head -n 2 test.sh
# this is about line
# date is 14-9-2017
If you add the description on each second line of your script, (after #!/bin/bash then let use sed -n "2p" $filenamein your script. You can also add a separator between each script:
#!/bin/bash
for filename in ~/personal-scripts/*
do
echo "---------------------"
echo $filename
echo "---------------------"
sed -n "2p" $filename
done
The alternative is to put the description anywhere, in a line starting by e.g # about: then you can grep it:
#!/bin/bash
for filename in ~/personal-scripts/*
do
echo "---------------------"
echo $filename
echo "---------------------"
grep "# about:" $filename | sed 's/# about://'
done
The | sed 's/# about://' is there to keep the description only.
If you have a comment inside all your scripts with a specific pattern such as
#info : This script runs daily
Then you can simply grep for the pattern and append to the name of the script in each line.
for filename in ~/personal-scripts/*
do
echo "$i : $(grep '#info' $i)"
done
So I was just starting learning bash scripting. I encountered a question in a book.
An example testfile contains following content.
$ cat testfile
This is the first line.
This is the second line.
This is the third line.
And the script file is like:
#!/bin/bash
# testing input/output file descriptor
exec 3<> testfile
read line <&3
echo "Read: $line"
echo "This is a test line" >&3
After running the script, the testfile became:
$ cat testfile
This is the first line.
This is a test line
ine.
This is the third line.
I understand why that script changes the testfile. My question is why
"ine." starts from a new line? Does echo command automatically add a newline character to the end of the string?
echo -n is what you seek: the option -n
instructs echo to "do not output the trailing newline".
FWIW: man echo on your platform will instruct what options the /bin/echo command understands. But since you mention bash as shell: bash has an internal implementation of echo (a so-called "builtin")
I have the following bash script top_script.sh
#!/bin/bash
# "Usage: $0 JOBNAME LOGFILE"
JOBNAME=$1
LOGFILE=$2
JOB_OUTPUT=$($1 2>&1)
echo ${JOB_OUTPUT} >> "${LOGFILE}"
that is supposed to be invoked like this
top_script.sh script_to_run.sh log.txt
If script_to_run.sh has multiple echo statements, e.g.
echo Line 1 from $0
echo Line 2 from $0
then what I get in log.txt is
Line 1 from script_to_run.sh Line 2 from script_to_run.sh
i.e. all this output gets concatenated into a single line. I suspect that the reason is line #5 in the first code block above. How can I modify it to ensure separate echos print into separate lines in log.txt?
Not that it really matters, but in case you are wondering, top_script.sh gets generated automatically form some a config file.
echo "${JOB_OUTPUT}" >> "${LOGFILE}"