@@ -19,14 +19,20 @@ type retryCfg struct {
1919 Attempts int
2020 Delay time.Duration
2121 Timeout time.Duration
22+ // InBash indicates whether the passed command should be run inside Bash.
23+ InBash bool
2224}
2325
2426func retryCommand () * cobra.Command {
2527 cfg := & retryCfg {}
2628
2729 cmd := & cobra.Command {
28- Use : "retry -- <command>" ,
29- Example : `` ,
30+ Use : "retry -- <command>" ,
31+ Example : `
32+ retry -a 5 -- curl http://localhost:8080/healthz
33+
34+ retry -a 5 -b -- "[ $((RANDOM % 5)) -eq 0 ] && exit 0 || exit 10"
35+ ` ,
3036 RunE : func (cmd * cobra.Command , args []string ) error {
3137 return cfg .Run (cmd , args )
3238 },
@@ -35,6 +41,7 @@ func retryCommand() *cobra.Command {
3541 cmd .Flags ().IntVarP (& cfg .Attempts , "attempts" , "a" , 1 , "Number of times to retry" )
3642 cmd .Flags ().DurationVarP (& cfg .Delay , "delay" , "d" , 1 * time .Second , "Delay between attempts" )
3743 cmd .Flags ().DurationVarP (& cfg .Timeout , "timeout" , "t" , 5 * time .Minute , "Timeout for the command" )
44+ cmd .Flags ().BoolVarP (& cfg .InBash , "in-bash" , "b" , false , "Run the passed Bash inside a Bash shell" )
3845
3946 return cmd
4047}
@@ -53,15 +60,15 @@ func (c *retryCfg) Run(cmd *cobra.Command, args []string) error {
5360 defer cancel ()
5461
5562 l := clog .FromContext (ctx ).With ("command" , rawcmd )
56- l .InfoContext (ctx , "args received" , "args" , args )
63+ l .InfoContext (ctx , "args received" , "args" , args , "in-bash" , c . InBash )
5764
5865 attempt := 0
5966 err := retry .Do (
6067 func () error {
6168 attempt ++
6269 l .InfoContextf (ctx , "[%d/%d] attempting command" , attempt , c .Attempts )
6370
64- command := exec . CommandContext (ctx , args [ 0 ] , args [ 1 :] ... )
71+ command := newCommand (ctx , c . InBash , args )
6572 command .Stdout = cmd .OutOrStdout ()
6673 command .Stderr = cmd .ErrOrStderr ()
6774 command .Env = os .Environ ()
@@ -82,3 +89,18 @@ func (c *retryCfg) Run(cmd *cobra.Command, args []string) error {
8289
8390 return err
8491}
92+
93+ func newCommand (ctx context.Context , inShell bool , args []string ) * exec.Cmd {
94+ var c * exec.Cmd
95+ if inShell {
96+ shellArgs := make ([]string , 0 , len (args )+ 1 )
97+ shellArgs = append (shellArgs , "-c" )
98+ shellArgs = append (shellArgs , args ... )
99+
100+ c = exec .CommandContext (ctx , "/bin/bash" , shellArgs ... )
101+ } else {
102+ c = exec .CommandContext (ctx , args [0 ], args [1 :]... )
103+ }
104+
105+ return c
106+ }
0 commit comments