SEARCH

Enter your search query in the box above ^, or use the forum search tool.

You are not logged in.

#1 2015-04-28 06:55:01

johnraff
nullglob
From: Nagoya, Japan
Registered: 2009-01-07
Posts: 4,148
Website

simple script to restart any process

Copying over crunchbang's tint2restart to bunsen I thought a whole script just to restart tint2 after 1 second seemed overkill, so wrote a new one to kill and restart any process if you give it the whole command line. It uses pkill's -fx options so the whole line must match to be killed. If nothing matches, the process will be started anyway.

For example, if you give it 'bl-restart conky -q' then only the conky which was started with 'conky -q' will be restarted.

If you send an integer before the command line it will wait that many seconds before restarting.

That's what it's suposed to do anyway.  big_smile

If anyone hits a snag I'd be delighted to know about it before it goes into bunsen-utilities.

#!/bin/sh
# restart any process
#
# usage: bl-restart [decimal] command arg1 arg2...
# The process matching the exact command line will be restarted after 1s,
# or by other number if passed before command.

help='usage: bl-restart [decimal] command arg1 arg2...
bl-restart -h|--help

Kills process matching full command line
and restarts after 1 sec, or "decimal" seconds if supplied.
(Floating-point is supported.)'

[ "$1" = '-h' ] || [ "$1" = '--help' ] && { echo "$help"; exit 0;}

delay=1

#type "$1" >/dev/null 2>&1 || {
command -v "$1" >/dev/null 2>&1 || {
    case "$1" in
    *[!0-9.]*)
        echo "$1 is not a command and not an integer.

$help"
        exit 1
        ;;
    *)
        delay=$1
        shift
        ;;
    esac
}

pkill -fx "$*" && sleep $delay
(setsid "$@" & )

exit 0

edit 150430: Swap 'command -v' for 'type' and add . to the glob.
(It probably won't be needed in bunsen-utilities as it turns out.  roll )

Last edited by johnraff (2015-04-30 09:15:57)


John
--------------------
( a boring Japan blog , Japan Links, idle twitterings  and GitStuff )
#! forum moderator    BunsenLabs

Offline

Be excellent to each other!

#2 2015-04-28 10:52:49

iMBeCil
WAAAT?
From: Edrychwch o'ch cwmpas
Registered: 2012-03-22
Posts: 1,026
Website

Re: simple script to restart any process

^Nice work, and nice utility, johnraff.

However, I would strongly recommend that option parameter (waiting time in seconds) should be specified as an option, like:

$ bl-restart [-w int] command arg1 arg2...

Reason: in theory, one could have program named '42' ... how would bl-restart restart this program with your script? Not to mention that it yould wati for 42 seconds lol

And of course ... it would be much more unix-style to specify option with '-' ...

(It is not complicated to script it, and if you can wait 48 hours, I can supply the script with '-w' optional option.)


Postpone all your duties; if you die, you won't have to do them ..
--> The very new BL forum! <--

Offline

#3 2015-04-28 12:32:08

cpoakes
#! CrunchBanger
From: Tucson, Arizona
Registered: 2012-05-19
Posts: 202

Re: simple script to restart any process

@johnraff: I like it.  I prefer generalized and reusable solutions.

If you are going to provide command validation, I think it should be consistent and print an error whether the command appears as parameter $1 or $2. I don't like the use of "type".  While it is instrinsic and faster than "which", it also returns true for shell keywords and builtin commands.  It is possible to validate a command that is shell intrinsic but not a real executable and fail in the setsid fork. Or you could just forgo command validation altogether and accept the standard handling for a failed setsid.

Reworked:

#!/bin/sh
# restart any process
#
# usage: bl-restart [int] command arg1 arg2...
# The process matching the exact command line will be restarted after 1s,
# or by other number if passed before command.

help='usage: bl-restart [integer] command arg1 arg2...
bl-restart -h|--help

Kills process matching full command line
and restarts after 1 sec, or "integer" seconds if supplied.'

[ "$1" = '-h' ] || [ "$1" = '--help' ] && { echo "$help"; exit 0;}

case "$1" in
*[!0-9]*)
    delay=1
    ;;
*)
    delay=$1
    shift
    ;;
esac
which "$1" >/dev/null || { printf "$1 is not a command.\n\n$help\n"; exit 1; }

pkill -fx "$*" && sleep $delay
(setsid "$@" & )

# Unnecessary, sub-shell supplies 0 exit value whether command executes or not
#exit 0

Also, GNU sleep will accept floating point values.  You could add a "." to the digit pattern if you think there is any call for partial second wait.  I could think of a use for 0.1 or 0.5.  And "sleep 0" is valid even if unnecessary...

@iMBeCil: The "-w" suggestion makes sense.  Or always require (and always validate) an integer value.


programming and administering unix since 1976 (BSD, System III, Xenix, System V, Linux)

Offline

#4 2015-04-29 00:24:21

johnraff
nullglob
From: Nagoya, Japan
Registered: 2009-01-07
Posts: 4,148
Website

Re: simple script to restart any process

@iMBeCil & @cpoakes I was originally planning to have a unix-style option for the delay, like '-d 2' or whatever. However when I was testing that version I found myself typing 'bl-restart 4 conky -q' and getting an error. (of course) Since we're talking about a utility here which might sometimes be used directly from the terminal I thought saving the two extra keystrokes for -d was worth the extra checking in the script.

@iMBeCil The test 'type "$1" >/dev/null 2>&1 || ...'  determines if $1 is executable or not before checking if it's an integer, so integer commands like 42, if they exist, would be passed on normally.

@cpoakes The 'type $1' was not an attempt to validate the supplied command (though that could be done I suppose) but simply to decide if $1 was meant to be a delay value or not. I see your point about false positives with 'type' for shell builtins, but the use of 'which' in cases like this has been deprecated.

BashFAQ wrote:

We strongly recommend not using which.

Returning to that page now I see the recommended options all seem to rely on Bash. On sh, 'type -P' does not work, and 'command -v' returns success for a shell keyword. sad

I had been trying to keep it POSIX-compliant for portability, but maybe the easiest solution would be to return to bash, and use 'type -P'.

------------------------------

Actually, looking at damo's recent pipemenus, this might not be immediately needed on bunsen after all...


John
--------------------
( a boring Japan blog , Japan Links, idle twitterings  and GitStuff )
#! forum moderator    BunsenLabs

Offline

#5 2015-04-29 05:20:13

cpoakes
#! CrunchBanger
From: Tucson, Arizona
Registered: 2012-05-19
Posts: 202

Re: simple script to restart any process

@johnraff: I understand that which is not totally portable, and like that you are thinking about portability.  You could parse the output of type, but please no!  This would be too much fugliness in the name of portability:

(incomplete code)

case `type $1` in
*alias*)
   ...
*function*)
   ...
*builtin*)
   ...
*)
   ...
esac

Judging from the number of bash scripts in the repository, portability is not a goal of the BunsenLabs project anyway.  There are more significant portability issues (Debian dependencies) than one more bash script.


programming and administering unix since 1976 (BSD, System III, Xenix, System V, Linux)

Offline

#6 2015-04-30 01:37:25

johnraff
nullglob
From: Nagoya, Japan
Registered: 2009-01-07
Posts: 4,148
Website

Re: simple script to restart any process

^true. I wasn't thinking so much about BunsenLabs portability but that the script might be handy to someone in itself, outside of BL. It's such a simple task I'd rather it ran on any POSIX shell, if possible.

If it's not easily done, though, then by all means back to bash.

btw I understand the BashFAQ's objections to 'which' are not so much portability, but that neither the return value nor the output are reliable, even on bash.


John
--------------------
( a boring Japan blog , Japan Links, idle twitterings  and GitStuff )
#! forum moderator    BunsenLabs

Offline

#7 2015-04-30 08:16:37

cpoakes
#! CrunchBanger
From: Tucson, Arizona
Registered: 2012-05-19
Posts: 202

Re: simple script to restart any process

^I think it remains accurate to consider differing outputs/return values for identically named utilities to be a issues of portability.  Addressing such differences in utilities and shell implementations was the essence of portability long before the POSIX definition was created.


programming and administering unix since 1976 (BSD, System III, Xenix, System V, Linux)

Offline

#8 2015-04-30 09:10:03

johnraff
nullglob
From: Nagoya, Japan
Registered: 2009-01-07
Posts: 4,148
Website

Re: simple script to restart any process

cpoakes wrote:

..."type".  While it is instrinsic and faster than "which", it also returns true for shell keywords and builtin commands.

I got distracted a bit there, but on reflection, the purpose of that 'type' test was not to validate the user's input, but simply to check if the integer they supplied was meant to be a command or a sleep time. I don't think any shell keywords or builtin commands are integers, so the script can stay as it is, and if the command given is invalid it can just fail...

Maybe switch 'type' to 'command -v' though, and add a dot to the glob to allow sub-second sleeps.


John
--------------------
( a boring Japan blog , Japan Links, idle twitterings  and GitStuff )
#! forum moderator    BunsenLabs

Offline

Board footer

Powered by FluxBB

Copyright © 2012 CrunchBang Linux.
Proudly powered by Debian. Hosted by Linode.
Debian is a registered trademark of Software in the Public Interest, Inc.
Server: acrobat

Debian Logo