Im currently working on a Phpunit test and i was wondering if is it possible to get the Test Summary and store it to a variable so i can send it via Email?.
Time: 11.92 minutes, Memory: 20.00Mb
There were 4 failures:
1) BingTestTool::testPushCampaign_without_status
Failed asserting that two strings are equal.
--- Expected
+++ Actual
## ##
-''
+'Active'
Here is the result that phpunit outputs in the console, can i store this to a variable? so that i can send it tru email after the test run
If you run phpunit in your console then just pipe its output to mail:
$ phpunit | mail test#example.org -s 'Results of phpunit'
The -s command line argument allows setting the email's Subject.
If the execution of phpunit is just a step of a longer process (a deployment, for example) and you need the output for some processing, you can enclose the phpunit command into backquotes (``) or $() and use the expression as the right-hand side of an assignment:
RESULT="`phpunit`"
or
RESULT="$(phpunit)"
The double quotes around the expression are needed to keep the output (which is a multi-line string) as a single word and prevent the shell from interpreting it. There must be no spaces around the equal sign.
Now you can display it:
echo "$RESULT"
or pipe it to the input of various Unix programs. For example:
echo "$RESULT" | grep '^Time:' | cut -f1 -d,
feeds the content of variable $RESULT to grep that extracts and outputs only the line that starts with Time:; the output of grep is piped then to cut to keep only the first column using , as delimiter.
Related
I am trying to disable nodes from apache loadbalancer using shell script. I got some idea online but I am not able to understand piece of code written for disabling the nodes form loadbalancer. Below is the code I am referring:
disable() {
balancer=$1
worker=$2
if [ -z "$balancer" ] || [ -z "$worker" ]; then
echo "Usage: $0 [-s host] [-p port] [-m balancer-manager] disable balancer_name worker_route"
echo " balancer_name : balancer/cluster name"
echo " worker_route : worker route e.g.)"
exit 1
fi
echo "Disabling $2 of $1..."
nonce=`$CURL -s "http://${server}:${port}/${manager}" | grep nonce | grep "${balancer}" | sed "s/.*nonce=\(.*\)['\"].*/\1/" | tail -n 1`
if [ -z "$nonce" ]; then
echo "balancer_name ($balancer) not found"
exit 1
fi
Can you please help me understand the meaning of above mentioned code. Especially, about nonce.
Picking apart your command, you probably first need to understand how pipes work in Unix. Each command has standard input and standard output; the notation first | second is a pipeline where the standard output from first becomes the standard input for second; so instead of first printing anything, or second reading something from a file, we pass whatever first would print as the input for second.
nonce=... assigns ... to the variable nonce. The name suggests this is intended to be used as a cryptographic nonce.
`cmd` is an obsolescent synonym for $(cmd). This command substitution replaces (substitutes) the command cmd with its output. So the value of nonce will be whatever this subshell prints to standard output.
$CURL is probably going to run curl, but we can only guess. Usually you would make sure curl is on your PATH and simply use the literal command curl.
curl -s http://whatever fetches the contents of the URL and prints them to standard output. The -s option suppresses any status messages. The output gets piped to ...
grep nonce, which prints to standard output any line which contains a match of the regular expression nonce (which simply matches this text verbatim anywhere on a line) and suppresses all others; which then gets piped to ...
grep "${balancer}" which similarly prints only lines which match whatever regular expression the variable balancer contains (the braces are harmless but useless); which then gets piped to ...
sed "s/.*nonce=\(.*\)['\"].*/\1/" which picks out the stuff between the parentheses -- anything up to the last single or double quote after nonce=; which then gets piped to ...
tail -n 1 which discards all lines except the last one.
So in summary, pick out the last occurrence of nonce= from the content behind the remote URL, and print that, but only up to just before the first single or double quote.
This is all rather clumsy and inefficient; any pipe involving multiple grep and sed commands should probably be refactored to a simple Awk script.
nonce=$(curl -s "http://${server}:${port}/${manager}" |
awk -v b="$balancer" '/nonce/ && $0 ~ b {
sub(/^.*nonce=/, ""); sub(/[\047\042][^\047\042]*$/, ""); n=$0 }
END { print n }')
The sed command in particular looks slightly obscure; normally, we would expect the output we want to extract to be between quotes, but this extracts up to just before the last single or double quote. The command sed -n 's/.*\(stuff\).*/\1/p' would be the normal way to only print the lines from which we actually managed to extract stuff. But without seeing what the URL contains, we can only speculate about whether this is correct or not. Certainly the conventional syntax would have allowed the author to omit the first grep entirely.
Getting the last nonce is probably just a guardrail to make sure there is never more than one; I would assume we would normally expect only a single match.
grep, sed, and Awk all operate on regular expressions. If you are new to regex, perhaps visit the Stack Overflow regex tag info page and check out the list of learning resources near the end.
Going forward, probably try https://explainshell.com/ before asking for human assistance.
I'm currently writing a script that will ultimately parse some baseball player ID numbers from MLB's Gameday data. I have set up my script so far to input today's date into the URL and to accept a team name as a command line argument.
The next step is to pass the URL to curl to get a list of today's games and the find the appropriate one by using grep with the team name.
When I write this on the command line:
curl -s http://gd2.mlb.com/components/game/mlb/year_2017/month_05/day_20/ | grep tormlb
It works.
However, when I write this in my script:
mlb_dir=$(curl -s $url | grep $team)
echo $mlb_dir
I am returned a mess of HTML without any line breaks. $url is equivalent to the url in the code block above and $team is set to "tormlb" just like above.
I am confused how I can get the result I want when I use the command line but not when I run my script. Any clue where I am going wrong?
When you pass a variable to a command, the variable is expanded and then split into arguments by whitespace. echo then outputs its arguments separated by spaces.
To ensure the variable is treated as a single argument, wrap it in double quotes. You should also do this for the other variables you are using in your code.
mlb_dir=$(curl -s "$url" | grep "$team")
echo "$mlb_dir"
Further information: http://tldp.org/LDP/abs/html/quotingvar.html
Hello I'm a total beginner in shell scripting.
I have a log file named logA.log and a B.sh file.
In log file there are some lines and I want to find the number of a spesific word in that log (in last 10 line) by executing the B.sh
In B I wrote
#!/bin/bash
variableString = tail -10f /home/appuser/logA.log
grep ERROR $variableString | wc -l
but the output is:
variableString: command not found
I know "grep" line is working but I cannot reach the logA in b.sh.
How can I define a variable called variableString as last 10 line of logA
Your commands are ok but you have to be aware of the way to store command output: var=$(command). Also, you may get several lines, so quote the return command to keep the format. Hence, you should use:
variableString="$(tail -10f /home/appuser/logA.log)"
grep ERROR "$variableString" | wc -l
When you get the error
variableString: command not found
it is because as you define your syntax, bash interprets that has to execute the variableString command with the = tail -10f /home/appuser/logA.log parameters. See Basic bash script variable declaration - command not found for further information regarding this.
tail -f ("follow") will not finish, so it never gets to the next line. You probably meant tail -n 10 (the -n makes it POSIX compatible).
You cannot use spaces around equals signs when assigning a variable.
Variables are assigned to the string which the right-hand side evaluates to. Without special constructs, the result will simply be the literal string after the equals sign.
You should quote variables to avoid expansion.
In summary, you should use:
variableString=$(tail -10 /home/appuser/logA.log)
I need to get all the wars on a remote tomcat server printed via my bash script.
I am able to ssh on the remote server and execute the command to get wars with version :-
${SSH} ${DEST_USER}#${DESTHOST} "Command"
however if I am storing it in a variable I don't get any-thing:-
output=${SSH} ${DEST_USER}#${DESTHOST} "Command"
echo $output
Based on a bit research if I try it as
output=$(${SSH} ${DEST_USER}#${DESTHOST} "Command"
echo $output
I got my output stored (need to understand why?).
Secondly the output I got in a single line as:
abc_1.2.war ijk_2.2.war hij_3.2.war xyx_5.1.war
how can I format this output some thing like:
Name version
abc 1.2
ijk 2.2
hij 3.2
xyz 5.1
Bash handles lines like this:
a=b c=d command
by temporarily setting environment variables "a" and "c" only for the duration of the command. They are not normal shell variables, and they won't exist after the command completes.
When you write
output=${SSH} ${DEST_USER}#${DESTHOST} "Command"
you are setting the "output" variable to the contents of "$SSH" for the duration of the "$DEST_USER#$DESTHOST" command (I'd expect you would receive a "command not found" error).
The way to capture the output of a command, as you have discovered, is with the $() syntax
output=$($SSH $DEST_USER#$DESTHOST "Command")
(Note you don't always have to put braces around your variable names, that's only strictly necessary when you need to separate the variable name from surrounding text)
For your text formatting question:
output="abc_1.2.war ijk_2.2.war hij_3.2.war xyx_5.1.war"
{
echo Name version
for word in $output; do # no quotes around $output here!
IFS=_ read name version <<< "$word"
echo "$name" "${version%.*}"
done
} | column -t
Name version
abc 1.2
ijk 2.2
hij 3.2
xyx 5.1
Here I use braces to group the header and the lines from the for-loop together to send them to column. I don't assume you know all the file extensions, but I do assume each file has an extension. The "${version%.*}" part removes the last dot and any following characters from the end of the value of the "version" variable.
Try echo "$output" (i.e. quotes).
I can't help with the 'why' right now. However you can produce the desired output from the variable(containing single line) as follows :
echo "Name version"
echo $output | grep -Eo "[a-zA-Z]+_[0-9]+.[0-9]+"| tr '_' ' '
I have a script named password-for-object which I normally run like that:
$ password-for-object example.com
sOtzC0UY1K3EDYp8a6ltfA
I.e. it does an intricate hash calculation and outputs a password that I should use when accessing an object (for example, website) named example.com. I'll just double click the whole password, it gets copied into my buffer and I'll paste it into the form.
I've also learnt a trick on how to use such a script without making my password visible:
$ password-for-object example.com | xclip
This way output of a script ends up in X's primary buffer and I can insert it right into password field in the form and it's not shown on the screen.
The only problem with this way is that password-for-object outputs a string with trailing newline and thus "xclip" always catches up an extra symbol - this newline. If I omit output of newline in password-for-object, then I'll end up with messed up string without xclip, i.e. when I'm just putting it on the stdout. I use 2 shells: zsh and bash, and I'll get the following in zsh (note the extra % sign):
$ password-for-object example.com
sOtzC0UY1K3EDYp8a6ltfA%
$
Or the following in bash (note that prompt would be started on the same line):
$ password-for-object example.com
sOtzC0UY1K3EDYp8a6ltfA$
Any ideas on how to work around this issue? Is it possible to modify the script in a way so it will detect that xclip is in the pipeline and only output newline if it isn't?
If you change password-for-object so that it doesn't output a newline, you can call it with a script like:
#!/bin/bash
password-for-object "$1"
if [ -t 1 ]
then
echo
fi
The -t condition is described in the bash manual as:
-t fd
True if file descriptor fd is open and refers to a terminal.
See the following question:
How to detect if my shell script is running through a pipe?
Give this a try:
$ password-for-object example.com | tr -d '\n' | xclip
tr -d '\n' deletes the newline