cygwin: timeout syntax always fails - bash

With Cygwin, I tried to use "timeout" to make my script sleep for a few seconds.
But even when I did it according to its syntax it always asks me to try --help, meaning I gave the wrong forms.
Here are the things I've tried
timeout 5
timeout 5s
timeout 5.0s
timeout 5.
None of which worked.
Any ideas?!

I don't think timeout does what you think it does. From the man page:
timeout [OPTION] NUMBER[SUFFIX] COMMAND [ARG]...
Start COMMAND, and kill it if still running after NUMBER seconds. SUFFIX may be 's' for seconds (the default), 'm' for minutes, 'h' for hours or 'd' for days.
You need to give it that command. Here's a simple example:
$ date; timeout 5 sleep 10; date
Thu, Nov 01, 2012 3:19:28 PM
Thu, Nov 01, 2012 3:19:33 PM
As you can see, only 5 seconds elapsed even though I ran sleep 10. That's because it timed out after 5 seconds and the timeout command killed it.

Related

Shell script: How to loop run two programs?

I'm running an Ubuntu server to mine crypto. It's not a very stable coin yet and their main node gets disconnected sometimes. When this happens it crashes the program through fatal error.
At first I wrote a loop script so it would keep running after a crash and just try again after 15 seconds:
while true;
do ./miner <somecodetoconfiguretheminer> &&break;
sleep 15
done;
This works, but is inefficient. Sometimes the loop will keep running for 30 minutes until the main node is back up - which costs me 30 minutes of hashing power unused. So I want it to run a second miner for 15 minutes to mine another coin, then check the first miner again if its working yet.
So basically: Start -> Mine coin 1 -> if crash -> Mine coin 2 for 15 minutes -> go to Start
I tried the script below but the server just becomes unresponsive once the first miner disconnects:
while true;
do ./miner1 <somecodetoconfiguretheminer> &&break;
timeout 900 ./miner2
sleep 15
done;
Ive read through several topics / questions on how &&break works, timeout works and how while true works but I can't figure out what I'm missing here.
Thanks in advance for the help!
A much simpler solution would be to run both of the programs all the time, and lower the priority of the less-preferred one. On Linux and similar systems, that is:
nice -10 ./miner2loop.sh &
./miner1loop.sh
Then the scripts can be similar to your first one.
Okay, so after trial and error - and some help - I found out that there is nothing wrong with my initial code. Timeout appears to behave differently on my linux instance when used in terminal than in a bash script. If used in Terminal it behaves as it should, it counts down and then kills the process it started. If used in bash however - it acts as if I typed 'sleep' and then after counting down stops.
Apparently this has to do with my Ubuntu instance (running on a VPS). Even though I installed latest versions of coreutils, have all the latest versions installed through apt-get update etc. This is the case for me on Digital Ocean as well as Google Compute.
The solution is to use the Timeout code as a function within the bash script, as found on another thread in stackoverflow. I named the function timeout2 as to not confuse the system in triggering the not properly working timeout command:
#!/bin/bash
# Executes command with a timeout
# Params:
# $1 timeout in seconds
# $2 command
# Returns 1 if timed out 0 otherwise
timeout2() {
time=$1
# start the command in a subshell to avoid problem with pipes
# (spawn accepts one command)
command="/bin/sh -c "$2""
expect -c "set echo "-noecho"; set timeout $time; spawn -noecho
$command; expect timeout { exit 1 } eof { exit 0 }"
if [ $? = 1 ] ; then
echo "Timeout after ${time} seconds"
fi
}
while true;
do
./miner1 <parameters for miner> && break;
sleep 5
timeout2 300 ./miner2 <parameters for miner>
done;

Bash Scripting on Ubuntu - write a log entry when idle time exceeds 5 minutes

I'm working on an Ubuntu computer and I want to write a script that will send a date and time and idle time to a log file whenever the computer is idle on the GUI console for more than 5 minutes.
I've found that xprintidle will do the monitoring for me but I don't know how to write the script to watch for it to get to 5 minutes and then output to the log.
How about
while true; do
idle=$(xprintidle)
if [[ $idle -gt 300000 ]]; then
# more than 5 minutes (in milliseconds)
date "+%F %T $idle" >> $HOME/idle.log
fi
sleep 300
done

Bash script for do loop that detects a time period elapsed and then continues

I have a script that runs through a list of servers to connect to and grabs by SCP over files to store
Occasionally due to various reasons one of the servers crashes and my script gets stuck for around 4 hours before moving on through the list.
I would like to be able to detect a connection issue or a period of time elapsed after script has started and kill that command and move on to next.
I suspect that this would involve a wait or sleep and continue but I am new to loops and bash
#!/bin/bash
#
# Generate a list of backups to grab
df|grep backups|awk -F/ '{ print $NF }'>/tmp/backuplistsmb
# Get each backup in turn
for BACKUP in `cat /tmp/backuplistsmb`
do
cd /srv/backups/$BACKUP
scp -o StrictHostKeyChecking=no $BACKUP:* .
sleep 3h
done
The above script works fine but does get stuck for 4 hours should there be a connection issue. It is worth noting that some of the transfers take 10 mins and some 2.5 hours
Any ideas or help would very appreciated
Try to use the timeout program for that:
Usage:
timeout [OPTION] DURATION COMMAND [ARG]...
E.g. time (timeout 3 sleep 5) will run for 3 secs.
So in your code you can use:
timeout 300 scp -o StrictHostKeyChecking=no $BACKUP:* .
This limits the copy to 5 minutes.

Running a program with timeout

I am running the timeout command of GNU Coreutils,
gtimeout 600 python myprogram.py
According to the manual,
duration is a floating point number followed by an optional unit:
‘s’ for seconds (the default) ‘m’ for minutes ‘h’ for hours ‘d’ for
days
Thus, the 'python myprogram.py part should terminate within 600 seconds (10 minutes). To my surprise, the command actually timeouts after 1 hour. Why?
It's possible that your program ignores SIGTERM, the signal which is used by gtimeout to "kindly ask the program to terminate".
You can have gtimeout use SIGKILL instead, which can't be ignored or blocked, by adding the parameter -s 9 like this:
gtimeout -s 9 python myprogram.py

Make bash report when a subcommand takes too long?

Can I configure bash to report how long each command takes to execute, if it's longer than some threshold?
I thought I recalled some setting for this, but can't find it either in bash(1) or google.
The idea, in case it's not clear, would be something like this:
% SUBCMDTMOUT=30
% sleep 29 # 29 seconds elapse
% sleep 30 # 30 seconds elapse
% sleep 31 # 31 seconds elapse
bash: subcommand `sleep 31' took 31 seconds to complete.
%
Prepend time to your command and then parse the output of time through any condition to get your desired output.
Example:
$ time sleep 15
real 0m15.003s
user 0m0.000s
sys 0m0.002s
#chepner probably has it right: REPORTTIME in zsh (though that only tracks CPU time; I suspect my mystery problem is some kind of network wait). But since I'm not motivated enough to convert my login shell for this, the specific answer to my question is "nope."

Resources