How to grep a file then print it out? Unix - bash

while true
do
if($update)
then
who | awk {'print$1'} > first_user_list #store original user list
update=false
fi
who | awk {'print$1'} > updated_user_list
(diff first_user_list updated_user_list) | cut -c 3- > in_out_list
inOutVar='cat in_out_list' #<----here's my problem
length_first=$(wc -l < updated_user_list)
length_update=$(wc -l < first_user_list)
if [[ "$length_first" -lt "$length_update" ]]; then
echo -e "$inOutVar" " has logged out"
update=true
elif [ "$length_first" -gt "$length_update" ]; then
echo -e "$inOutVar" " has logged in"
update=true
else
echo No user has logged in/out in the last 3 seconds
fi
sleep 3
done
How would i go by printing out the users names who has logged out then " has logged out"
eg.
"johnsmith has logged out"
Pretty new to unix, any help or suggestions would be great, thanks in advance :)x

Your issue is that you used quotes instead of backticks. Since you are setting the variable equal to a command you need to use `` or $():
#!/bin/sh
while true; do
if($update)
then
who | awk {'print$1'} > first_user_list #store original user list
update=false
fi
who | awk {'print$1'} > updated_user_list
(diff first_user_list updated_user_list) | cut -c 3- > in_out_list
inOutVar=`cat in_out_list` ## use `` or $(), not ''
length_first=$(wc -l < updated_user_list)
length_update=$(wc -l < first_user_list)
if [[ "$length_first" -lt "$length_update" ]]; then
echo -e "$inOutVar" " has logged out"
update=true
elif [ "$length_first" -gt "$length_update" ]; then
echo -e "$inOutVar" " has logged in"
update=true
else
echo No user has logged in/out in the last 3 seconds
fi
sleep 3
That works on my system.

Related

Second subversion pre-commit hook not working

I am trying to add a second pre-commit script and it seems not to be catching when I place it in the hook.
The first script basically locks a file from being editing. The second script look at a path and compares a string value to a file that is being committed and if it matches then it will error.
#!/bin/sh
REPOS="$1"
TXN="$2"
GREP=/bin/grep
SED=/bin/sed
AWK=/usr/bin/awk
SVNLOOK=/usr/bin/svnlook
AUTHOR=`$SVNLOOK author -t "$TXN" "$REPOS"`
if [ "$AUTHOR" == "testuser" ]; then
exit 0
fi
if [ "$AUTHOR" == "" ]; then
exit 0
fi
CHANGED=`$SVNLOOK changed -t "$TXN" "$REPOS" | $GREP "^[U|A]" | $AWK '{print $2}'`
COMPARE=`$SVNLOOK diff -t "$TXN" "$REPOS"`
#Operation 001 Beginning
#Restrict users from commiting against testfile
for PATH in $CHANGED
do
if [[ "$PATH" == *path/to/file/testfile.txt ]]; then
#allow testuser to have universal commit permissions in this path.
if [ "$AUTHOR" == "testuser" ]; then
exit 0
else
#User is trying to modify testfile.txt
echo "Only testuser can edit testfile.txt." 1>&2
exit 1
fi
fi
done
#Operation 001 Completed
#Operation 002 Beginning
#Restrict commits based on string found in file
for PATH in $COMPARE
do
if [[ "$PATH" == *path/to/look/at/only/* ]]; then
$SVNLOOK diff -t "$TXN" "$REPOS" | egrep 'string1|string2|string3' > /dev/null && { echo "Cannot commit using string1, string2 or string3 in files trying to commit" 1>&2; exit 1; }
else exit 0;
fi
done
#Operation 002 Completed
It keeps successfully committing the file even though the string is present. Any ideas why it wouldn't be catching it?
Your first test:
if [ "$AUTHOR" == "testuser" ]; then
exit 0
fi
It causes an abort (with zero exit value) if the AUTHOR is testuser!
So your second test:
if [ "$AUTHOR" == "testuser" ]; then
exit 0
else
#User is trying to modify testfile.txt
echo "Only testuser can edit testfile.txt." 1>&2
exit 1
fi
It's unnecessary because at this point the AUTHOR isn't testuser!
And maybe would better instead of your for-loop:
if $SVNLOOK changed -t "$TXN" "$REPOS" | $GREP "^[U|A]" | $AWK '{print $2}' | grep -q 'path/to/file/testfile.txt'; then
echo "Only testuser can edit testfile.txt." 1>&2
exit 1
fi
The if [[ "$PATH" == *path/to/file/testfile.txt ]]; then test doesn't work because this test doesn't understand shell variables (and would better enclose between quotation marks because of *).
And I would replace the
for PATH in $COMPARE
do
if [[ "$PATH" == *path/to/look/at/only/* ]]; then
part to
if echo ${COMPARE} | grep -q "path/to/look/at/only"; then

Getting command line argument that stores in a variable

I am writing a bash script to finger the first three line of user's info.
ex:
$ ./c.sh bob unknown
Login: bob Name: Bob
Directory: /u1/h7/bob Shell: /bin/tcsh
Office: AA 044, x8361 Home Phone: 000-000-0000
unknown: no such user.
Here is my code so far
#!/bin/bash
if [ $# == 0 ]; then
echo "Usage: ./c.sh Login/Username"
exit
else
i=$#
j=1
while [ "$j" -le "$i" ]; do
finger ${$j} | head -n+3
echo
j=$(($j+1))
done
fi
instead of giving what user types for the command line arguments, ${$j} is giving me the the value of $j, any suggestion and help for how to get the login/username? I've tried $($j), $((j)), ${$j}....
The easy answer: stop using unnecessary indirection:
#!/bin/bash
if (( $# == 0 )); then
echo "Usage: ./c.sh Login/Username"
exit
else
while [[ $1 ]]; do
finger "$1" | head -n+3
echo
shift
done
fi
or…
…
for user; do # equivalent to `for user in "$#"; do`
finger "$user" | head -n+3
…
done
You could write it this way:
i=$#
j=1
while [ $j -le $i ]; do
finger "${#:j++:1}" | head -n+3
echo
done
…but you don't need to work that hard.
#!/bin/bash
if [[ $# -eq 0 ]]; then
echo "Usage: $0 Login/Username"
exit
else
for ARG in "$#"; do
finger "$ARG" | head -n 3
echo # If you want a newline
done
fi
As simple as it can be.

Shell Script improvement for getting diff result

I have shell Script written which does a job of comparing two files and and gives me result in a HTML format for defects. But i want to improve it so that i can only get modified files defects instead of legacy defects also. I am using this script to get Coverity report.
while read line; do
n=$((++n))
if echo $line | grep '^[[:space:]]*>' &>/dev/null; then
if [ $(($n % 2)) -eq 1 ]; then
# TODO somehow get proper defect number from html
# echo "Defect num: $(($n/2 + 1))"
def_num=$((++def_num))
fi
echo $line | sed -n -e 's/>[[:space:]]*\(.*\)/\1/p'
if [ $(($n % 2)) -eq 0 ]; then
echo "-------------------------------"
fi
done < <(diff -y -W 200 ./cov-results-base/result.filt ./cov-results-changed/result.filt)
echo "==============================="
echo
echo "Number of defects in old code: $(tac cov-results-base/summary.xml |
sed -n '/num/{s|<num>\(.*\)</num>|\1|p; q;}')"
echo "Number of defects in new code: $(tac cov-results-changed/summary.xml |
sed -n '/num/{s|<num>\(.*\)</num>|\1|p; q;}')"
This enables you to get the last modification time of a file and the compare with the current time.
now=`date +%s`
modified=`stat -c "%Y" $file`
if [ $(($now-$modified)) -gt 0 ]; then
echo "not modified";
else
echo "modified";
fi
I hope that this is what you wanted.

Shell script to specify a user is logged into computer

username=$1
freq=$2
checkuser()
{
if who grep "$1"
then
sleep 60
fi
}
if [ -n "$1" ]
then
echo "Enter username"
read username
checkuser
echo -e "$1 is logged on \a"
echo -e "$1 logged in at `date`">>LOG
checkuser
else
echo "User is not logged on"
fi
I need to integrate a second argument into my code which allows for the user to specify after what time should the script check to see who is logged in. I have it set to 60 seconds currently and this needs to be the default frequency. I tried to use another function but to no avail. I thought of something like this...
if [ "$2" -ne 0 ]
then
freq=$2
else
freq=60
Thanks William for that was very helpful!! I changed the code a bit and came up with this. I now need to add a 3rd argument "X" which when selected just sends a message to the LOGFILE and not to the screen. I made an attempt but not doing as intended.
username=$1
freq=${2:-10}
X=$3
checkuser()
{
whoami|grep "$1";
}
while checkuser "$username"
do
echo -e "$1 is logged on \a"
echo "$1 logged in at `date`">>LOGFILE
sleep $freq
exit 0
done
echo "User is not logged in"
if [ "$3" -ne 1 ]
then
echo "$1 logged in at `date`"LOGFILE
fi
username=$1
freq=${2:-60} # Set a default frequency
checkuser(){ who | grep -q "$1"; }
while ! checkuser "$username"; do
echo "User is not logged on"
sleep $freq
done
echo "$1 is logged on"
Also note that you can simplify the setting of username:
username=${1:-$( echo "Enter username: "; read u; echo $u; )}
echo 'Enter id'
read id
res=`who | grep "$id" | wc -l`
if [ $res -eq 0 ]
then
echo 'user is not logged in'
else
echo 'user is logged in'
fi
A simple shell script that takes the username as input and determines whether the user is currently logged in.
if [[ $# -eq 0 ]]; then
echo "Usage: " $0 "username"
exit 1
fi
result="$(who | grep $1 | wc -l)"
if [[ $result -gt 0 ]]; then
echo "$1 is currently logged in"
else
echo "$1 is not logged in"
fi
exit 0

Validate Emails with Bash

I try to validate an email with a shell script. Is there a easy example to validate a mail? Asked google but just found crap and PHP (also crap..).
Thanks and regards.
If you explicitly state bash on the #! line, you can uses regexes:
#!/bin/bash
if [[ $email =~ '(.+)#(.+)' ]] ; then
user=${BASH_REMATCH[1]}
host=${BASH_REMATCH[2]}
fi
If you are serious about programing with bash, read the man page all the way through. Twice. Also read the Bash FAQ.
Validate script.
The meaning of this script, is to be sure from all emails that are valid or not before sending them email.
this script check a list of emails.
#!/bin/bash
#:
#: e-mail.verify.sh
#:
#: Date: 2011/14/12 13:14 PM IST
#: Author: Louay _at_ louie.msh#gmail.com
#: Discription: Verify (or) Validate the Hotmail Adresses.
#:
#:
#: First we create a Expect script to be sourced for us.
if [ ! $# == 1 ]
then
echo "Invalid Args $0 Filename"
exit 0
fi
#: Verifying the Hotmail adressess.
#: First verify the network Connections
C_R="\e[01;31m" ## Colors
C_B="\e[01;30m"
C_G="\e[01;32m"
C_END="\e[00m"
SMTPSERV=`host -t mx hotmail.com |grep 5 | grep mx2.hotmail.com |cut -d " " -f 7| sed 's/\.$//'`
ping -c2 $SMTPSERV >/dev/null
if [ "$?" -eq 0 ]
then
echo -e "Internet Connection" "\t\t\t\t\t\t$C_G[ OK ]$C_END"
echo -e "$SMTPSERV is AVAILABLE."
echo -n "Verifing"
for (( i=0; i<5; i++ ))
do
echo -n ".."
sleep 1
done
echo
else
echo -e "Internet Connection:" "\t\t\t\t\t\t$C_R[ FAIL ]$C_END" ""
echo -e "$SMTPSERV is Unavialable."
echo -e "Check your Network settings."
exit 0
fi
COUNT=0
RM_FILE="validemails.txt"
rm -f $RM_FILE
cat $1 | while read LINE; do
{
MAFR="MAIL FROM: <louie.msh#gmail.COM>"
MATO="RCPT TO: <$LINE>"
#: ^variablies declared for not get escaped in the next cat command, where
#: we set the $MAFR in the expect script.
cat << __EOF > e-veri
#!/bin/expect
#:
#: Date: 2011/14/12 01:14 PM
#: Author: Louay Mshelim_at_ louie.msh#gmail.com
#: Discription: Expect Script to Verify/Validate the Hotmail Adresses.
#:
set VMAFR "$MAFR"
set VMATO "$MATO"
spawn nc -C mx4.hotmail.com 25
expect "Sending"
send "HELO mx4.hotmail.com\r"
expect "OK"
send "\$VMAFR\r"
expect "OK"
send "\$VMATO\r"
expect "250"
send "quit\r"
expect eof
__EOF
#: Running the expect script and extracting the Results.txt
expect e-veri > Results.txt
grep 550 Results.txt >/dev/null
if [ "$?" -eq 0 ]
then
echo -e $LINE >> invalid.txt #invalid E-mails
else
echo -e "$LINE" >> validemails.txt
fi
}
done
echo -e "Valid E-mail have been saved to $C_R[ validemails.txt ]$C_END"
#: END
Here is an improved and working version of the script by codevour:
#!/bin/bash
# check for valid usage
if [ x$1 = 'x' ]
then
echo "Usage: $0 <email address>"
exit 1
fi
mailcmd=`mktemp`
# grabbing fields
user=`echo $1 | perl -p -e 's/^([^#]+)#([^\#]+)$/$1/g'`
host=`echo $1 | perl -p -e 's/^([^#]+)#([^\#]+)$/$2/g'`
mxhost=`host -t mx $host|perl -p -e 's/.* ([^ ]+)\.$/$1/g'|sort -R|tail -1`
# compose email commands
echo -ne "helo example.com\r\n" > $mailcmd
echo -ne "mail from: <tester#example.com>\r\n" >> $mailcmd
echo -ne "rcpt to: <$1>\r\n" >> $mailcmd
echo -ne "quit\r\n" >> $mailcmd
# check for mail results
mailresult=`cat $mailcmd | nc $mxhost 25| grep ^550 | wc -c`
if [ $mailresult -eq 0 ]
then
echo $1 "is valid"
exit 0
else
echo $1 "is not valid"
exit 1
fi
# clean up
rm $mailcmd
You mean something like this?
#!/bin/bash
# check for valid usage
if [ x$1 = 'x' ]
then
echo "Usage: $0 <email address>"
exit 1
fi
# grabbing fields
user=`echo $1 | cut -f1 -d\#`
host=`echo $1 | cut -f2 -d\#`
mxhost=`host -t mx $host | cut -f7 -d\ `
len=`echo $mxhost | wc -c`
len=`expr $len - 2`
mxhost=`echo $mxhost | cut -b1 -$len`
# compose email commands
echo -ne "helo test.com\r\n" > mailcmd
echo -ne "mail from: test\#test.com\r\n" >> mailcmd
echo -ne "rcpt to: $1\r\n" >> mailcmd
echo -ne "quit\r\n" >> mailcmd
# check for mail results
mailresult=`cat mailcmd | nc $mxhost 25| grep ^550 | wc -c`
if [ $mailresult -eq 0 ]
then
echo $1 "is valid"
exit 0
else
echo $1 "is not valid"
exit 1
fi
# clean up
rm mailcmd
Found at:
Fun things in Life - Simple Bash Email Validator
My any suggestion for the latter script, check work with multiple servers that accept checks without authentication, using nslookup who knows:
For example code in:
http://www.vivaolinux.com.br/script/Simples-Verificador-de-Email-Gmail
see the code below in the site.
I hope I have contributed and I hope to collaborate as well.
Thank you.
You can use like this,
read emailId
if echo "${emailId}" | grep '^[a-zA-Z0-9]*#[a-zA-Z0-9]*\.[a-zA-Z0-9]*$' >/dev/null; then
echo Valid
else
echo Not Valid
fi

Resources