File retry-1737025645.819c129.obscpio of Package retry
07070100000000000041FD0000000000000000000000016788E86D00000000000000000000000000000000000000000000002100000000retry-1737025645.819c129/.github07070100000001000041FD0000000000000000000000016788E86D00000000000000000000000000000000000000000000002B00000000retry-1737025645.819c129/.github/workflows07070100000002000081B40000000000000000000000016788E86D000001CA000000000000000000000000000000000000003200000000retry-1737025645.819c129/.github/workflows/ci.yml---
name: ci
# yamllint disable-line rule:truthy
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: unit tests
run: |
make test-unit
style:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Static checks
run: |
sudo apt-get install shellcheck
export PATH=.:$PATH
make checkbashisms checkstyle
07070100000003000081B40000000000000000000000016788E86D00000020000000000000000000000000000000000000002400000000retry-1737025645.819c129/.gitignore/test-more-bash/
/checkbashisms
07070100000004000081B40000000000000000000000016788E86D0000027C000000000000000000000000000000000000002600000000retry-1737025645.819c129/.mergify.yml---
pull_request_rules:
- name: automatic merge
conditions:
- and: &base_checks
- base=main
- -label~=^acceptance-tests-needed|not-ready
- "status-success~=test"
- "status-success~=style"
- and:
- "#approved-reviews-by>=1"
- "#changes-requested-reviews-by=0"
# https://doc.mergify.io/examples.html#require-all-requested-reviews-to-be-approved
- "#review-requested=0"
actions: &merge
merge:
method: merge
- name: automatic merge on special label
conditions:
- and: *base_checks
- "label=merge-fast"
actions: *merge
07070100000005000081B40000000000000000000000016788E86D00000436000000000000000000000000000000000000002100000000retry-1737025645.819c129/LICENSEMIT License
Copyright Oliver Kurz
Copyright SUSE LLC
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
07070100000006000081B40000000000000000000000016788E86D0000060D000000000000000000000000000000000000002200000000retry-1737025645.819c129/Makefile.PHONY: all
all:
.PHONY: test
test: checkstyle test-unit
.PHONY: test-unit
test-unit: test-more-bash
@command -v prove >/dev/null 2>&1 || echo "Command 'git' not found, can not get test-more-bash to execute tests"
prove -r test/
test-more-bash:
@command -v git >/dev/null 2>&1 || echo "Command 'git' not found, can not get test-more-bash to execute tests"
git clone https://github.com/ingydotnet/test-more-bash.git --depth 1 -b 0.0.5
checkbashisms:
@command -v wget >/dev/null 2>&1 || echo "Command 'wget' not found, can not download checkbashisms"
wget -q https://salsa.debian.org/debian/devscripts/-/raw/main/scripts/checkbashisms.pl -O checkbashisms
chmod +x checkbashisms
command -v checkbashisms >/dev/null || echo "Downloaded checkbashisms. You can check the file and add to PATH, then call make again"
.PHONY: checkstyle
checkstyle: test-shellcheck test-checkbashisms
.PHONY: test-shellcheck
test-shellcheck:
@command -v shellcheck >/dev/null 2>&1 || echo "Command 'shellcheck' not found, can not execute shell script checks"
shellcheck -x $$(file --mime-type * | sed -n 's/^\(.*\):.*text\/x-shellscript.*$$/\1/p')
.PHONY: test-checkbashisms
test-checkbashisms:
@command -v checkbashisms >/dev/null 2>&1 || echo "Command 'checkbashisms' not found, can not execute shell script checks"
checkbashisms -x $$(file --mime-type * | sed -n 's/^\(.*\):.*text\/x-shellscript.*$$/\1/p')
.PHONY: install
install:
install -m 755 retry "$(DESTDIR)"/usr/bin/retry
install -m 755 count-fail-ratio "$(DESTDIR)"/usr/bin/count-fail-ratio
07070100000007000081B40000000000000000000000016788E86D00000A01000000000000000000000000000000000000002300000000retry-1737025645.819c129/README.md# retry 
A simply retry tool in plain POSIX sh.
## How to use
Simply call
```
retry $cmd
```
to execute `$cmd` and on failure retry multiple times with some waiting time
between calls. Multiple command line parameters exist to tweak execution.
It is possible to specify no waiting time if desired:
```
retry -s 0 $cmd
```
If it is necessary to specify command line parameters to `$cmd` separate the
arguments with `--` like this:
```
retry -- $cmd --my-argument -X 3
```
Often it is desired to command the execution with a timeout. This can be done
with the `timeout` command from [GNU
coreutils](https://www.gnu.org/software/coreutils/) already present on many
systems. Either use with a global timeout:
```
timeout 10 retry $cmd
```
to execute `$cmd` with retrying but only wait up to 10s in total. Or with a
timeout per execution:
```
retry -- timeout 10 $cmd
```
### count-fail-ratio - simple statistics about retries
Another tool provided is "count-fail-ratio" which can count fails, the fail
ratio, the failure probability and timing information from repeated command
calls. Simply call
```
count-fail-ratio $cmd
```
to execute `$cmd` automatically multiple times collecting the mentioned
statistics.
Further options to count-fail-ratio can be specified by runtime variables. For
example to change the number of runs from the default of 20 set the variable
"runs" while disabling computing timing information:
```
runs=100 timing=0 count-fail-ratio $cmd
```
For the complete list of variables take a look into the script file
count-fail-ratio itself.
## Contribute
This project lives in https://github.com/okurz/retry
Feel free to add issues in github or send pull requests.
### Rules for commits
* For git commit messages use the rules stated on
[How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/) as
a reference
If this is too much hassle for you feel free to provide incomplete pull
requests for consideration or create an issue with a code change proposal.
### Local testing
#### Functional testing
This is done with the [Test::More bash
library](https://github.com/ingydotnet/test-more-bash).
It will be automatically cloned.
To execute tests call
```
make test
```
#### Style checks
```
make checkstyle
```
## Alternatives
* https://github.com/minfrin/retry - an older C implementation which is also
available in Debian and Ubuntu.
## License
This project is licensed under the MIT license, see LICENSE file for details.
07070100000008000081FD0000000000000000000000016788E86D000006C0000000000000000000000000000000000000002A00000000retry-1737025645.819c129/count-fail-ratio#!/bin/bash -e
# shellcheck disable=SC2048
[ "$1" = "-h" ] || [ "$1" = "--help" ] && echo "Run an arbitrary command multiple times and count failures and fail ratio" && exit
fails="${fails:-0}"
runs="${runs:-"20"}"
start="${start:-1}"
timing="${timing:-1}"
if [ "$timing" = 1 ]; then t_start=$(date +%s%N); fi
declare -a times=()
for ((i=start; i <= runs; i++)); do
echo "## Run $i"
if [ "$timing" = 1 ]; then t_run_start=$(date +%s%N); fi
"$@" || fails=$((fails+1))
if [ "$timing" = 1 ]; then
t_run_end=$(date +%s%N)
runtime=$(( (t_run_end - t_run_start) / 1000000 ))
times+=("$runtime")
fi
p=$(bc <<< "scale=9;${fails}/${i}")
standard_error=$(bc <<< "scale=9;sqrt(${p}*(1 - ${p})/${i})")
# critical value (z_value) for a 95% confidence level. In this
# case, the critical value is approximately 1.96.
z_value=1.96
me=$(bc <<< "scale=9;${z_value}*${standard_error}")
echo -n "## $(basename "$0"): Run: $i. Fails: $fails. Fail ratio $(bc <<< "r=${p} * 100;scale=2;r/1")±$(bc <<< "r=${me}*100;scale=2;r/1")%"
[[ $fails = 0 ]] && echo -n ". No fails, computed failure probability < $(bc <<< "scale=2;3 * 100/${i}")%"
echo ""
if [ "$timing" = 1 ]; then
t_end=$(date +%s%N)
# Compute standard deviation
sum=0
for time in "${times[@]}"; do
sum=$((sum + time))
done
mean=$((sum / i))
variance=0
for time in "${times[@]}"; do
diff=$((time - mean))
variance=$((variance + diff*diff))
done
stddev=$(bc <<< "scale=2;sqrt(${variance}/${i})")
echo "## mean runtime: $(( (t_end - t_start) / i / 1000000 ))±$stddev ms"
fi
done
07070100000009000041FD0000000000000000000000016788E86D00000000000000000000000000000000000000000000001E00000000retry-1737025645.819c129/dist0707010000000A000041FD0000000000000000000000016788E86D00000000000000000000000000000000000000000000002200000000retry-1737025645.819c129/dist/rpm0707010000000B000081B40000000000000000000000016788E86D000004E3000000000000000000000000000000000000002D00000000retry-1737025645.819c129/dist/rpm/retry.spec#
# spec file for package retry
#
# Copyright SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via http://bugs.opensuse.org/
#
Name: retry
Version: 1
Release: 0
Summary: A simple tool for retrying command executions in plain POSIX sh
License: MIT
Group: Development/Tools/Other
BuildArch: noarch
Url: https://github.com/okurz/retry
Source0: %{name}-%{version}.tar.xz
Requires: util-linux
%description
A simple tool for retrying command executions in plain POSIX sh.
%prep
%setup -q
%build
%install
mkdir -p %{buildroot}%{_bindir}
%make_install
%check
%files
%{_bindir}/retry
%{_bindir}/count-fail-ratio
%changelog
0707010000000C000081FD0000000000000000000000016788E86D00000671000000000000000000000000000000000000001F00000000retry-1737025645.819c129/retry#!/bin/sh -e
usage() {
echo "usage: $0 [options] [cmd...]
options:
-h,--help Show this help
-r,--retries=RETRIES How many retries to do on command failure after
the initial try. Set -1 for infinite retries.
Defaults to 3.
-s,--sleep=SLEEP How many seconds to sleep between retries.
Defaults to 3 seconds.
-e,--exponential[=FACTOR] Enable simple exponential back-off algorithm.
Disabled by default, factor defaults to 2
(binary exponential back-off).
"
}
# parse arguments
opts=$(getopt \
--options +h,r:,s:,e:: \
--longoptions help,retries:,sleep:,exponential:: \
--name "$(basename "$0")" -- "$@") || { usage ; exit 1; }
eval set -- "$opts"
while [ $# -gt 0 ]; do
case "$1" in
-h | --help ) usage; exit 0 ;;
-r | --retries ) retries=$2; shift 2 ;;
-s | --sleep ) sleep=$2; shift 2 ;;
-e | --exponential ) exponential=${2:-2}; shift 2 ;;
-- ) shift; break ;;
* ) break ;;
esac
done
retries="${retries:-3}"
sleep="${sleep:-3}"
ret=0
retries_msg=""
while true; do
ret=0
"$@" && exit
ret=$?
if [ "$retries" = 0 ]; then
break
elif [ "$retries" != -1 ]; then
retries_msg="up to $retries more times "
retries=$((retries-1))
fi
echo "Retrying ${retries_msg}after sleeping ${sleep}s …" >&2
sleep "$sleep"
[ -n "$exponential" ] && sleep=$((sleep*exponential))
done
exit "$ret"
0707010000000D000041FD0000000000000000000000016788E86D00000000000000000000000000000000000000000000001E00000000retry-1737025645.819c129/test0707010000000E000081FD0000000000000000000000016788E86D0000055B000000000000000000000000000000000000003400000000retry-1737025645.819c129/test/01-count-fail-ratio.t#!/usr/bin/env bash
set -e
dir=$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)
TEST_MORE_PATH=$dir/../test-more-bash
BASHLIB="`
find $TEST_MORE_PATH -type d |
grep -E '/(bin|lib)$' |
xargs -n1 printf "%s:"`"
PATH=$BASHLIB$PATH
source bash+ :std
use Test::More
plan tests 9
call_cmd() {
$dir/../count-fail-ratio $*
}
rc=0
output=$(runs=3 call_cmd true 2>&1) || rc=$?
is "$rc" 0 'successful run for no fails'
like "$output" 'Run: 3. Fails: 0. Fail ratio 0.*%. No fails, computed failure probability < 100.00%' 'counted all successes'
rc=0
output=$(runs=30 call_cmd true 2>&1) || rc=$?
is "$rc" 0 'successful run for many no fails'
like "$output" 'Run: 30. Fails: 0. Fail ratio 0.*%.*< 10.00%' 'computed failure probability lowers to < 10% for enough runs'
rc=0
output=$(runs=3 call_cmd false 2>&1) || rc=$?
is "$rc" 0 'successful run for all fails'
like "$output" 'count-fail-ratio: Run: 3. Fails: 3. Fail ratio 100.00.*%' 'counted all fails'
rc=0
tmp="${tmp:-"/tmp/tmp.fail-once-every-third-call"}"
echo 0 > $tmp
output=$(runs=10 call_cmd $dir/fail-once-every-third-call 2>&1) || rc=$?
is "$rc" 0 'successful run for sporadically failing script'
like "$output" 'count-fail-ratio: Run: 10. Fails: 3. Fail ratio 30.00±28.40%' 'counted sporadic failure'
output=$(runs=1 timing=1 call_cmd false 2>&1)
like "$output" 'mean runtime' 'timing info shows up'
0707010000000F000081FD0000000000000000000000016788E86D000007A1000000000000000000000000000000000000002900000000retry-1737025645.819c129/test/01-retry.t#!/usr/bin/env bash
set -e
dir=$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)
TEST_MORE_PATH=$dir/../test-more-bash
BASHLIB="`
find $TEST_MORE_PATH -type d |
grep -E '/(bin|lib)$' |
xargs -n1 printf "%s:"`"
PATH=$BASHLIB$PATH
source bash+ :std
use Test::More
plan tests 18
PATH=$dir/..:$PATH
sleep() { :;}
export -f sleep
ok "$(retry)" 'retry without parameter is ok'
like "$(retry --help)" usage: 'retry help is shown'
ok $? 'calling help returns success'
set +e; out=$(retry --unknown-option 2>&1); rc=$?; set -e
is $rc 1 'calling with unknown option returns failure'
like "$out" 'unrecognized option.*usage:' 'retry help is shown for unknown option'
ok "$(retry -s 0 true)" 'successful command returns success'
is "$(retry -s 0 true)" '' 'successful command does not show any output by default'
set +e; out=$(retry -s 0 false 2>&1); rc=$?; set -e
like "$out" 'Retrying up to 3 more.*Retrying up to 1' 'failing command retries'
is $rc 1 'failing command returns no success'
set +e; out=$(retry -s 1 -e -r 2 false 2>&1); rc=$?; set -e
like "$out" 'sleeping 1s.*sleeping 2s' 'sleep amount doubles'
is $rc 1 'failing command returns no success'
set +e; out=$(retry -r 1 -- sh -c 'echo -n .; false' 2>/dev/null); set -e
is "$out" '..' 'specified number of tries (1+retries)'
set +e; out=$(retry -r 0 -s 0 false 2>&1); rc=$?; set -e
is $rc 1 'failing command without retry returns no success'
set +e; out=$(retry -r 0 -s 0 true 2>&1); rc=$?; set -e
is $rc 0 'passing command without retry returns no error'
trap "rm -f 'run_count.txt'" EXIT
set +e; out=$(retry -r 2 -s 0 $dir/success_on_third.sh 2>&1); rc=$?; set -e
like "$out" 'Retrying up to 2 more' 'number of retries printed'
is $rc 0 'pass on last run is success'
set +e; out=$(retry -r-1 -s 0 $dir/success_on_third.sh 2>&1); rc=$?; set -e
like "$out" 'Retrying after sleeping' 'infinite retries without number of retries'
is $rc 0 'pass on last run with infinite retries is success'
07070100000010000081FD0000000000000000000000016788E86D000000F3000000000000000000000000000000000000003900000000retry-1737025645.819c129/test/fail-once-every-third-call#!/bin/bash
TMPDIR="${TMPDIR:-"/tmp"}"
tmp="${tmp:-"$TMPDIR/tmp.$(basename "$0")"}"
if [ -e "$tmp" ]; then
attempts="$(cat "$tmp")"
fi
if [[ -z "$attempts" ]]; then
attempts=0
fi
((attempts++))
echo "$attempts" > "$tmp"
((attempts%3))
07070100000011000081FD0000000000000000000000016788E86D00000292000000000000000000000000000000000000003200000000retry-1737025645.819c129/test/success_on_third.sh#!/bin/bash
# Set the path to the file that will store the run count in /var/run directory
count_file="run_count.txt"
# Initialize the count file if it doesn't exist
if [ ! -f "$count_file" ]; then
echo "0" > "$count_file"
fi
# Read the current run count from the file
run_count=$(<"$count_file")
# Increment the run count
((run_count++))
# Write the updated run count back to the file
echo "$run_count" > "$count_file"
# Check if it's the third run and exit with an error if true
if [ "$((run_count % 3))" -gt 0 ]; then
echo "Failing on the run!"
exit 1
fi
# Your script logic goes here
echo "Script is running successfully on run $run_count"
07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!36 blocks