I've got this script that runs every time my Ubuntu machine wakes up and goes to sleep.
#!/bin/sh
if [ "${1}" == "pre" ]; then
# Do the thing you want before suspend here, e.g.:
echo "we are suspending at $(date)..." > /home/albin/stuff/suspend_test
elif [ "${1}" == "post" ]; then
# Do the thing you want after resume here, e.g.:
echo "...and we are back from $(date)" >> /home/albin/stuff/suspend_test
else
echo ".2..neither pre or post . $1 . $(date)" >> /home/albin/stuff/suspend_test
fi
This is found in the output file:
.2..neither pre or post . pre . tis 11 sep 2018 20:44:42 CEST
.2..neither pre or post . post . tis 11 sep 2018 20:45:06 CEST
.2..neither pre or post . pre . tis 11 sep 2018 22:12:52 CEST
.2..neither pre or post . post . ons 12 sep 2018 06:55:21 CEST
.2..neither pre or post . pre . ons 12 sep 2018 06:55:22 CEST
.2..neither pre or post . post . ons 12 sep 2018 06:55:43 CEST
.2..neither pre or post . pre . ons 12 sep 2018 07:13:28 CEST
.2..neither pre or post . post . ons 12 sep 2018 07:14:00 CEST
I've checked multiple guides on how to write bash conditionals without finding any issues. The $1 variable is available but ignored in the if statements
You are using == instead of = inside [ ], but that's a bashism. Recent versions of Ubuntu use dash as /bin/sh, and it does not support ==; it gets an error, which is interpreted as the test failing:
$ if [ foo == foo ]; then echo "The strings match"; else echo "The strings do *not* match"; fi
dash: 1: [: foo: unexpected operator
The strings do *not* match
Solution: switch to =
$ if [ foo = foo ]; then echo "The strings match"; else echo "The strings do *not* match"; fi
The strings match
If you're going to use /bin/sh instead of /bin/bash, you really need to watch out for bashisms. There's a good page on this in the Ubuntu wiki. Either that, or switch to /bin/bash.
P.s. If you're going to use bash extensions, I'd recommend using [[ ]] instead of [ ] for conditionals -- it fixes most of the syntactic oddities of [ ], and adds some useful new capabilities like pattern and regular expression matching.
Mostly likely, I think you got your redirection output wrong on line 4.
Must be :
echo "we are suspending at $(date)..." >> /home/albin/stuff/suspend_test
instead of
echo "we are suspending at $(date)..." > /home/albin/stuff/suspend_test
Also, I think $1 is neither equal to 'pre' or 'post'. From looking at the output you posted, I can't understand from why these strings "tis" and "ons" have come from.
Probably caller of this script passing you other arguments than post or pre.
Change log writing to use >> instead of > (to prevent overwriting log all time) and try add echo “${1}” >> log at first line, then you can see what arguments you got in your script
Related
I'm trying to add a title to my brief shell script for note taking, however I am unsure how to grab the string of text after calling the script. Currently I have:
note = note() {
cd ~/Sync
date >> notes.txt
echo "----------------------------\n" >> notes.txt
cat >> notes.txt
echo "\n" >> notes.txt
}
Which works fine for adding a note with a datestamp, however I want to be able to type a short title after the word note and output it separately.
So, in my terminal (ZSH) I want to be able to do the following:
~ note This is the title
~ This is the body text
[ctrl-d]
To produce:
Fri 14 Feb 2020 13:34:51 GMT
----------------------------
This is the title
This is the body text
I want to Analyse a logfile for specific Errors.
Therefore i want to be able to loop through the last x lines of the files and check every line with a specific REGEX Pattern and then define a specific return value.
The logfile Looks in case of success as follows at the Moment when i want to check it.
….
sftp> get blahblah/blahblah
sftp> bye
In case of an Error there is something between the two sftp lines.
What i allready tried is to solve the Problem with a specific regex which worked fine on some online Regex testers but couldn´t get it to work in ksh.
My current Approach is the following
LOG_FIL="test_log"
MODE="${1}"
check_log_file() {
ERRNBR=${1}
REGEX=${2}
TAIL=${3}
RETURN="0"
echo "ERRNBR = ${ERRNBR}"
echo "REGEX = ${REGEX}"
echo "TAIL = ${TAIL}"
while read line; do
echo "${line}"
if [[ "${line}" =~ ${REGEX} ]]; then
RETURN="0"
echo "bin hier"
else
RETURN=${ERRNBR}
echo "bin wo anders"
break
fi
done <<<$(tail -${TAIL} ${LOG_FIL})
echo "${RETURN}"
return ${RETURN}
}
echo "sftp> get cwi/cdk_final*" >> ${LOG_FIL}
if [ "${MODE}" == "1" ]; then
echo "Werner ist der beste" >>${LOG_FIL}
fi
check_log_file "22" "^(sftp> ).*$" "1"
echo "$?"
echo "sftp> bye" >> ${LOG_FIL}
check_log_file "21" "((sftp> ).*|(sftp> bye))" "2"
echo "$?"
The results i get are the following
edv> sh cdk_test4sftp.sh 1
ERRNBR = 22
REGEX = ^(sftp> ).*$
TAIL = 1
Werner ist der beste
bin wo anders
22
22
ERRNBR = 21
REGEX = ((sftp> ).*|(sftp> bye))
TAIL = 2
Werner ist der beste sftp> bye
bin hier
0
0
What i hoped to achieve was that the Output coming from the tail command would be seperated. So that i ccould test each line individually.
Your second regex:
((sftp> ).*|(sftp> bye))
Matches the following line, which is why your function returns 0:
Werner ist der beste sftp> bye
Since you want to match the following pattern on each line:
sftp> get blahblah/blahblah
sftp> bye
Your regex should look more like the first one you used to match:
^(sftp> ).*$
I made a small Bash-script to make my life easier. But I encountered a problem which I can't fix.
What I want
I've made a small script which will check for php-errors in a file each time that file gets saved/changed. This is done without me needing to run a command each time. So I run the Bash-script once on my second screen, and than each time when I save my PHP-file on screen one; I get the eventual errors shown on screen two automatically.
Basic algorithm
Get the hash of the file
Compare it to it's previous hash
If it differs, the file is changed/saved: Check if there are errors using the php -l command
Print out the result from php -l
Problem:
The result from php -l gets printed out before my code asked for it.
Code
#!/bin/bash
#Declaring basic variables here
fileToCheck="$1"
oldHash=("")
checksum=("")
#Function to get a striped line as long as the terminal width
function lineAmount {
cwidth=`tput cols`
lines=""
for i in $(seq $(expr $cwidth - 33)); do lines="$lines-";done
echo $lines
}
#Function to show the actual error
function showError {
msg=$1
time=`date +"%c"`
l=$(lineAmount)
if [ "$msg" == "No" ]
then
msg="No errors detected."
fi
printf "\n\n$time $l \n$msg\n"
}
#Start-screen------------------------------------------------
printf "Starting session for $1 at $time \n$(lineAmount)\n"
if [ ! -f $1 ]
then
echo "[Error] File $1 not found."
exit
fi
printf "\n\n\n"
#------------------------------------------
#Printing out error when file changed
while true
do
sleep 0.6
checksum=($(sha256sum $fileToCheck))
checksum=${checksum[0]}
if [ "$checksum" != "$oldHash" ]
then
error=$(php -l $fileToCheck)
oldHash=$checksum
showError $error
fi
done
Test file (test.php):
<?php
function foo() {
}
?>
Output of script:
Starting session for /home/name/Desktop/test.php at
-----------------------------------------------
Thu 11 Aug 2016 08:16:15 PM CEST -----------------------------------------------
No errors detected.
Now, in test.php I delete line 4:
<?php
function foo() {
?>
This will of course give an error, and my script shows that error:
Starting session for /home/name/Desktop/test.php at
-----------------------------------------------
Thu 11 Aug 2016 08:16:15 PM CEST -----------------------------------------------
No errors detected.
PHP Parse error: syntax error, unexpected end of file in /home/name/Desktop/test.php on line 6
Thu 11 Aug 2016 08:19:37 PM CEST ----------------------------------------------------------------------------------
Parse
But like you can see, this is not a nice output.
PHP Parse error: syntax error, unexpected end of file in /home/name/Desktop/test.php on line 6 should be printed below the second dotted line. Not below "No errors found." (The first output).
Expected output:
Starting session for /home/name/Desktop/test.php at
-----------------------------------------------
Thu 11 Aug 2016 08:16:15 PM CEST -----------------------------------------------
No errors detected.
Thu 11 Aug 2016 08:19:37 PM CEST ----------------------------------------------------------------------------------
PHP Parse error: syntax error, unexpected end of file in /home/name/Desktop/test.php on line 6
I tried a lot, I tried to change my algorithm a bit, searched up a lot; but it ain't working.
I guess the problem is somewhere on line 51, or 29. But I really can't see what's wrong.
Thanks!
Here's a stripped down and simplified version of your problem:
Why does this print an error message immediately instead of assigning it to the variable?
$ error=$(php -l test.php)
PHP Parse error: syntax error, unexpected end of file in test.php on line 5
php -l prints error messages to stderr like a good Unix citizen should. $(..) only captures stdout.
If you want to capture stdout and stderr together, you can use:
error=$(php -l $fileToCheck 2>&1)
You should also quote your variables so that the message is passed as a single parameter, since you're currently throwing away most of it (shellcheck is helpful):
showError "$error"
Being a good citizen, php also returns a useful exit code, so instead of trying to match a "No" to see if it's successful, you can just check the status directly:
if error=$(php -l $fileToCheck 2>&1)
then
echo "No problems"
else
echo "It failed with these messages: $error"
fi
I have been working on this on and off for the last two months, and despite how many times I look at it, I can't make it work.
This script checks daily log files for a user defined variable, so they don't have to look through every one manually. It worked great checking the current month, but if the user wants to check back 20 days, and today is the 12th of this month, I wanted to be able to then go back to the previous month (not look for the log file with a date of 20150399 and so on). I have checked the logic for my date/day computations, and they seem okay (if there is a better way to do that in BASH, I am open to suggestions). What happens when I try to debug is unexpected end of file. I am somewhat new to writing scripts that contain more than 20 or so lines, but I just can't come up with what I am missing.
I have tried various fixes, to no avail, but I think this is the last iteration.
Ideas?
#!/bin/bash
########################################################
# multi_log_chk.sh
# This script will take input from the user and report which
# CyberFusion MFT logs contain what the user is looking for.
# Hopefully this will save the user having to search through every
# stinking log file to find what they are looking for.
# 20150406 pxg007 started typing
# 20150413 pxg007 added && comparison for back out (line 28)
# added message for no entries found (line 32, 38, 48-52)
# Added some further description (line 16)
# 20150424 pxg007 Added logic to calculate previous month and if necessary, year. (Lines 16-24, 60-78 )
#
########################################################
currDate=`date +%d%B%C%y`
currDay=`date +%d`
currMnth=`date +%m`
currYear=`date +%C%y`
case $currMnth in #Let's establish number of days for previous month
05 | 07 | 10 | 12 ) lastMnthD=30;;
01 |02 | 04 | 06 | 09 | 08 | 11 ) lastMnthD=31;;
03 ) lastMnthD=28;; ##and screw leap year
esac
if [ $currMnth -eq 01 ]; then ##accounting for January
lastMnth=12
else
lastMnth=$((currMnth-1))
fi
if [ $lastMnth -eq 12 ]; then ## accounting for Dec of previous year
lastMnthYr=$((currYear-1))
else
lastMnthYr=$currYear
fi
echo "This script will find entries for your query in whatever available MFT logs you request."
echo " "
echo "For instance - how many log files have transfer entries with \"DOG\" in them?"
echo " "
echo "I also will also give an estimate of how many transfers per log file contain your query, give or take a couple."
echo " "
echo "This search is case sensitive, so \"DOG\" is *** NOT *** the same as \"dog\""
echo " "
read -p "What text you are looking for? Punctuation is okay, but no spaces please. " looking ### what we want to find
echo " "
echo "Today's date is: $currDate."
echo " "
read -p "How many days back do you want to search(up to 25)? " daysBack ### How far back we are going to look
if [ "$daysBack" == 0 ] && [ "$daysBack" >> 25 ]; then
echo "I said up to 25 days. We ain't got more than that!"
exit 1
fi
echo " "
echo "I am going to search through the last $daysBack days of log files for:\"$looking\" "
echo " "
read -p "Does this look right? Press N to quit, or any other key to continue: " affirm
if [ "$affirm" = N ] && [ "$affirm" = n ]; then ###Yes, anything other than "N" or "n" is a go
echo "Quitter!"
exit 1
else
nada=0 ### Used to test for finding anything
backDate=$((currDay-daysBack)) ### current month iterator (assuming query covers only current month)
if (("$daysBack" => "$currDay")); then ## If there are more logs requested than days in the month...
lastMnthCnt=$((daysBack-currDay)) ### how many days to check last month
lastMnthStrt=$((lastMnthD-lastMnthCnt)) ## last month start and iterator
backDate=$(currDay-(daysBack-lastMnthCnt)) # Setting the iterator if we have to go back a month
while (("$lastMnthStrt" <= "$lastMnthD" )); do
foundIt=$(grep "$looking" /CyberFusion/log/Log.txt."$lastMnthYr$lastMnth$lastMnthStrt" | parsecflog | wc -l )
howMany=$((foundIt/40+1)) ### Add one in case there are less than 40 lines in the record.
if (("$foundIt" > 0))
then
nada=$((nada+1))
echo "Log.txt.$lastMnthYr$lastMnth$lastMnthStrt contains $looking in approximately $howMany transfer records."
lastMnthStrt=$((lastMnthStrt+1))
echo " "
else
lastMnthStrt=$((lastMnthStrt+1))
fi
fi
backDate=$((currDay-daysBack)) ### current month iterator (assuming query covers only current month)
while (("$backDate" <= "$currDay")); do
foundIt=$(grep "$looking" /CyberFusion/log/Log.txt."$backDate" | parsecflog | wc -l )
howMany=$((foundIt/40+1)) ### Add one in case there are less than 40 lines in the record.
if (("$foundIt" > 0))
then
nada=$((nada+1))
echo "Log.txt.$backDate contains $looking in approximately $howMany transfer records."
backDate=$((backDate+1))
echo " "
else
backDate=$((backDate+1))
fi
if [ "$nada" \< 1 ]
then
echo " "
echo "I found no entries for $looking in any log file."
fi
You are missing the keyword 'done' on lines 81 and 96 and also a final 'fi' keyword on the last line.
Also as others suggested you can do
date -d "20 days ago" +"%d%B%C%y"
to easily get dates in the past
I am trying to have a function, called from PS1 which outputs something in a different colour, depending on what that something is.
In this case it's $?, the exit status of a program.
I am trying to get this function to output red text if the exit status is anything other than 0.
I have tried all possible variations of this, ways of representing that variable in the conditions and so forth and it just isn't working.
Instead of outputting what I expect it's just either always $LRED in one variation of this IF, or always $HII in another variation of this IF.
All relevant BASH is posted below, can you guys offer any insight?
...
# Custom Colour Alias
NM="\[\033[0;38m\]" # No background and white lines
HI="\[\033[1;36m\]" # Username colour
HII="\[\033[0;37m\]" # Name colour
SI="\[\033[1;32m\]" # Directory colour
IN="\[\033[0m\]" # Command input color
LRED="\[\033[1;31m\]"
BRW="\[\033[0;33m\]"
...
exitStatus ()
{
if [ $? -ne 0 ]
then
echo "$LRED\$?"
else
echo "\$?"
fi
#echo \$?
}
...
export PS1="\n$HII[ $LRED\u $SI\w$NM $HII]\n[ \! / \# / $(exitStatus) $HII]$LRED $ $IN"
CODE BASED ON SOLUTION
This is what I did based on the accepted answer below.
# Before Prompt
export PROMPT_COMMAND='EXSO=$?;\
if [[ $EXSO != 0 ]];\
then\
ERRMSG="$LRED$EXSO";\
else\
ERRMSG="$EXSO";\
fi;\
PS1="\n$HII[ $LRED\u $SI\W$NM $HII\! / \# / $ERRMSG $HII] $SI$ $IN";'
Problem is that your assignment to PS1 is only evaluated once, thus exitStatus is only called once. As Nirk also mentions you should use PROMPT_COMMAND. Set it to the command you want executed before every new prompt is displayed. An example:
PROMPT_COMMAND='if [ $? -ne 0 ]; then echo -n FAIL:;fi'
Will yell FAIL: before every new prompt if the previous command failed:
mogul#linuxine:~$ date
Sun Sep 29 21:13:53 CEST 2013
mogul#linuxine:~$ rm crappy_on_existent_file
rm: cannot remove ‘crappy_on_existent_file’: No such file or directory
FAIL:mogul#linuxine:~$