Current activity logger - bash

Does anyone know of an app (for iOS or Mac) that asks for my current activity every hour or so? I see tons of apps that let you log your activities, but none that use popups/notifications to actively ask you.
I found a script that looks promising (source), but I'm having trouble implementing it so that it repeats every hour:
#!/bin/bash
echo What are you doing right now?
read -e what
echo `date` - $what >> timelog.txt

You could wrap the whole thing in a while loop and have it sleep for 1 hour after asking:
#!/bin/bash
while true
do
echo What are you doing right now?
read -e what
echo `date` - $what >> timelog.txt
sleep 3600
done

you could set that script up as a cron job. Here's a SE question on how to do it
https://apple.stackexchange.com/questions/9373/how-do-i-run-a-cron-job-on-a-mac

An improvement to get a graphical dialog with zenity (uses GTK+). For Mac OS cocoaDialog could be the thing to use.
#!/bin/bash
while true
do
input=$(zenity --text "What are you doing?" --entry --width 400)
retval=$?
case $retval in
0)
what=$input;;
1)
what="";;
esac
echo `date` - $what >> ~/Documents/timelog/timelog_`date +%F`.txt
sleep 3600
done

Related

Script executes but fails to increment

So I have this shell script that I think should run a given number of times, sleep then resume, and output the results to a log file
#!/bin/bash
log=/path/to/file/info.log
a=$(COMMAND1 | cut -d : -f 2)
b=$(COMMAND2 | grep VALUE| cut -c 7,8)
for i in {1..4}
do
echo "Test" $i >> $log
date >> $log
echo $a >> $log
echo "$((-113 + (($b * 2)))) VALUE" >> $log
sleep 60
done
When I run ps -ef | grep scriptname.sh it seems the script does run. Executes once then the PID is gone as if the run has completed.
I have tested the script and know that it is running and capturing the data I want. But I do not understand why its not incrementing and not sure why its ending earlier than expected.
info.log output sample
Test {1..4}
DATE IN UTC
EXPECTED VALUE OF a
EXPECTED VALUE OF b
Note that the output is literally "Test {1..4}" not "Test 1" "Test 2" Test 3" and so on, as I would expect.
I have run the script as ./scriptname.sh & and as /path/to/file/scriptname.sh &
I have read that there is a difference in running the script with sh and bash though I dont fully understand what effect that would have on the script. I am not a software person at all.
I have tried to run the script with nohup to keep it running in the background if I close the terminal. I also thought the & in the command was supposed to keep the script running in the background. Still it seems the script does not continue to run
I previously asked this question and it was closed, citing that it was similar to a post about the difference between sh and bash...but thats not my main question.
also echo "$BASH_VERSION" returns nothing, a blank line. echo "$-" returns smi, and I have no idea what that means. but bash --version returns:
BusyBox v1.17.1 (2019-11-26 10:41:00 PST) built-in shell (ash)
Enter 'help' for a list of built-in commands.
So my questions are:
If running the script with sh - is that done with ./scriptname.sh & and running the script with bash is /path/to/file/scriptname.sh &...and if so what effect does that have on how the script code is processed? that is - is using sh or bash. I do not fully understand the difference between the two
why does the script not continue to run when I close the terminal? This is my big concern. I would like to run this script hourly for a set period of time. Every time I try something and come back I get one instance in the log.
Neither brace expansion nor seq are part of the POSIX specification. Use a while loop.
log=/path/to/file/info.log
a=$(COMMAND1 | cut -d : -f 2)
b=$(COMMAND2 | grep VALUE| cut -c 7,8)
i=1
while [ "$i" -le 4 ]; do
printf 'Test %s\n' "$i"
date
printf '%s\n' "$a"
printf '%s\n' "$((-113 + (($b * 2)))) VALUE"
sleep 60
i=$((i+1))
done >> "$log"
(I suspect that you want to move the assignments to a and b inside the loop as well; right now, you are simply writing identical files to the log at each iteration.)

check for device connectivity on network then send action based on connectivity

I am fairly new to bash script even though I have some experience.
I am looking for my Raspberry Pi to detect my phone when it becomes available on the network, when it does so to play an audio clip, I have managed do this via the script below.
I have a problem, however, when my phone becomes available on the network, I do not want the audio to keep looping; I need it to play once and then stop playing the audio clip once it has already played. However, I do want the script to keep on running so it can detect the next time my phone becomes available on the network.
Maybe there is a better way of doing it, if there is I would love to hear your suggestions.
#!/bin/sh
if ping -c 10 192.168.1.4 &> /dev/null
then
kodi-send --action="PlayMedia(/storage/music/welcome.mp3)"
ping 192.168.1.4 &> /dev/null
else
./checkforerikphone.sh
fi
try this
#!/bin/bash
while : ; do
if ping -c 10 192.168.1.4 &> /dev/null ; then
kodi-send --action="PlayMedia(/storage/music/welcome.mp3)"
fi
sleep 600
done
This solution runs forever while :. and every 10 minutes, checks if your phone is active. So this significantly reduces the noise in your life, but it also lets you know that your phone is still connected.
You could change sleep 600 to sleep 300 and check every 5 minutes, or of course you can change 600 to any number of seconds you comforatable with.
Not a perfect solution per your spec, but managing lock files can be complicated.
Get comfortable with this solution and then think about adding something like
if ping ... ; then
if ! [[ -e /tmp/phoneOnLine ]] ; then
kodi-send ...
echo "Found phone at $(date)" > /tmp/phoneOnLine
fi
else
echo "no phone found"
/bin/rm -f /tmp/phoneOnLine
fi
You will definitely find corner cases where this doesn't work, so be prepared to debug the code. I would add an echo msg inside of each logic path (if/else/...). to understand how the code is working.
Also to prevent script for being faked out, I would delete the file at startup.
So a possible complete solution is
#!/bin/bash
#file may not exist, ignore error msg with "2> /dev/null"
/bin/rm -f /tmp/phoneOnLine 2> /dev/null
#loop forever
while : ; do
# check for phone
if ping -c 10 192.168.1.4 &> /dev/null ; then
# check for "lock" file
if ! [[ -e /tmp/phoneOnLine ]] ; then
kodi-send --action="PlayMedia(/storage/music/welcome.mp3)"
echo "Found phone at $(date)" > /tmp/phoneOnLine
else
echo "Phone already found"
fi # !! -e /tmp/ph
else # no ping
echo "no phone found"
/bin/rm -f /tmp/phoneOnLine 2>/dev/null
fi # ping
sleep 600
done
Try following:
#!/bin/bash
#when result of ping $? is 0, the phone is detected
ACTIVE=0
#default startup as NOT ACTIVE(not detected) => !0
pre_available=1
# loop forever
while :
do
#ping and store outcome in "available"
ping -c 10 192.168.0.8 > /dev/null
available=$?
#if phone was not active and just got active (detected)
if [[ "$pre_available" != "$ACTIVE" && "$available" == "$ACTIVE" ]]
then
#do your stuff
kodi-send --action="PlayMedia(/storage/music/welcome.mp3)"
fi
#store availability for next iteration
pre_available=$available
done

How to write info to the file from bash script and see the result immediately?

I need help. I can't understand how I can write information to the file from bash script and see the result immediately.
For example:
#!/usr/bin/env bash
PID=$$
echo "PID is $PID"
echo $PID > my_script.pid
echo "Sleeping..."
sleep 5
echo "Finished"
PID number appears in console immediately, but in the file I see it after script finished.
I have Mac OS X Yosemite 10.10.3.
I tried a lot of stuff with flush buffering. NO result:(
Please, help!
Update.
My goal is to define if another instance of that script is still running. I decided to use pid file and condition:
PID=`cat $PID_FILE`
if ps -p $PID > /dev/null; then
echo "script already running"
exit 1
fi
Maybe there is a more efficient way?
You must be trying to read it too soon. To confirm that it's being written right away change the script to:
#!/usr/bin/env bash
PID=$$
echo "PID is $PID"
echo "$PID written to file." >> my_script.pid
echo "Sleeping..."
sleep 5
echo "Finished"
Then run:
touch my_script.pid
tail -F my_script.pid &
./my_script.sh
The tail -F command will run on the background and will output whatever is written to my_script.pid shortly after it's written. The delay you see is on tail, once echo returns it is written.
Sorry for misunderstanding. Actually it works fine. The problem in GUI tool (PyCharm) where I checked out file modification. It has interesting delay.
So when I check out previous PID from the same script it works fine:)
Thanks a lot fernan for help;)

Why my shell script is in standby in the background till I bring it back on the foreground?

I have a shell script which is executing a php script (worker for beanstalkd).
Here is the script:
#!/bin/bash
if [ $# -eq 0 ]
then
echo "You need to specify an argument"
exit 0;
fi
CMD="/var/webserver/user/bin/console $#";
echo "$CMD";
nice $CMD;
ERR=$?
## Possibilities
# 97 - planned pause/restart
# 98 - planned restart
# 99 - planned stop, exit.
# 0 - unplanned restart (as returned by "exit;")
# - Anything else is also unplanned paused/restart
if [ $ERR -eq 97 ]
then
# a planned pause, then restart
echo "97: PLANNED_PAUSE - wait 1";
sleep 1;
exec $0 $#;
fi
if [ $ERR -eq 98 ]
then
# a planned restart - instantly
echo "98: PLANNED_RESTART";
exec $0 $#;
fi
if [ $ERR -eq 99 ]
then
# planned complete exit
echo "99: PLANNED_SHUTDOWN";
exit 0;
fi
If I execute the script manually, like this:
[user#host]$ ./workers.sh
It's working perfectly, I can see the output of my PHP script.
But if I detach the process from the console, like this:
[user#host]$ ./workers.sh &
It's not working anymore. However I can see the process in the background.
[user#host]$ jobs
[1]+ Stopped ./workers.sh email
The Queue jobs server is filling with jobs and none of them are processed until I bring the detached script in the foreground, like this:
[user#host]$ fg
At this moment I see all the job being process by my PHP script. I have no idea why this is happening. Could you help, please?
Thanks, Maxime
EDIT:
I've create a shell script to run x workers, I'm sharing it here. Not sure it's the best way to do it but it's working well at the moment:
#!/bin/bash
WORKER_PATH="/var/webserver/user/workers.sh"
declare -A Queue
Queue[email]=2
Queue[process-images]=5
for key in "${!Queue[#]}"
do
echo "Launching ${Queue[$key]} instance(s) of $key Worker..."
CMD="$WORKER_PATH $key"
for (( l=1; l<=${Queue[$key]}; l++ ))
do
INSTANCE="$CMD $l"
echo "lnch instance $INSTANCE"
nice $INSTANCE > /dev/null 2> /dev/null &
done
done
Background processes are not allowed to write to the terminal, which your script tries to do with the echo statements. You just need to redirect standard output to a file when you put it to the background.
[user#host]$ ./workers.sh > workers.output 2> workers.error &
(I've redirected standard error as well, just to be safe.)

How do I echo a period every 2 seconds while 'yum -y update' is running?

I am writing a script to do some default configuration of customers' servers, and have it nearly working 100%.
What I cannot figure out is how to run yum -y update in some kind of a loop that echoes a "." every two seconds while it is updating.
Here is a code example to help explain a little more
YUMLOG=/var/log/config.log
while [ yum -y update > $YUMLOG 2>&1 ]
do
echo "."
sleep 2
done
Obviously, that doesn't work, but I don't know what changes to make so that it does work. I have other parts in the code that give me this 'progress bar' effect, but nothing inside of a loop. For example:
if [ $SETXENNET != "y" ]; then
sleep 1
cp $TEMPLATEDIR/rc.local.template $TEMPLATEDIR/rc.local.new
echo "."
sleep 1
cp $TEMPLATEDIR/rc.local.new /etc/rc.local
echo "."
sleep 1
chmod a+x /etc/rc.local
echo "."
sleep 1
else
sleep 1
cp $TEMPLATEDIR/rc.local.xen.template $TEMPLATEDIR/rc.local.xen.new
echo "."
sleep 1
cp $TEMPLATEDIR/rc.local.xen.new /etc/rc.local
echo "."
sleep 1
chmod a+x /etc/rc.local
echo "."
sleep 1
fi
And, before I get people yelling at me for all the 'sleeps', I had to have a way to show progress of the script because the people running it will not have any idea what they are doing (they just read keystrokes from a checklist and check off when something has been done).
So, I needed a nice, clean, easy way for them to 1) see what is happening in plain English (i.e. 'done', or 'skipped') and 2) visualize that the script is still running, even if nothing is displayed on screen.
Last, I cannot make a global change to the way I am showing progress, there is too much code to have to make changes to everything it does. But, if that is the absolute only answer, I guess that may be what I have to do...some day...
How about something like this? The dots are printed in a function that executes in the background. When yum is finished running, you can kill it.
#!/bin/bash
function dots {
while : ; do
echo -n ". "
sleep 2s
done
}
dots &
pid=$!
# do real work here
sleep 15s
kill -9 $pid
echo "done!"
You can do something like this. Have yum work in the background, and first create a temporary file, then delete it afterwards. The main process just loops, sleeps and prints while the file exists:
(touch tmpfile ; yum ... ; rm tmpfile)&
(while test -e tmpfile ; do echo . ; sleep 2 ; done)

Resources